BlueToe
an alternative GATT/BLE implementation
Loading...
Searching...
No Matches
bits.hpp
1#ifndef BLUETOE_BITS_HPP
2#define BLUETOE_BITS_HPP
3
4#include <cstdint>
5#include <type_traits>
6
7namespace bluetoe {
8namespace details {
9
10 constexpr std::uint16_t read_handle( const std::uint8_t* h )
11 {
12 return *h + ( *( h + 1 ) << 8 );
13 }
14
15 constexpr std::uint16_t read_16bit_uuid( const std::uint8_t* h )
16 {
17 return read_handle( h );
18 }
19
20 constexpr std::uint16_t read_16bit( const std::uint8_t* h )
21 {
22 return read_handle( h );
23 }
24
25 constexpr std::uint32_t read_24bit( const std::uint8_t* h )
26 {
27 return static_cast< std::uint32_t >( read_16bit( h ) ) | ( static_cast< std::uint32_t >( *( h + 2 ) ) << 16 );
28 }
29
30 constexpr std::uint32_t read_32bit( const std::uint8_t* p )
31 {
32 return static_cast< std::uint32_t >( read_16bit( p ) )
33 | ( static_cast< std::uint32_t >( read_16bit( p + 2 ) ) << 16 );
34 }
35
36 constexpr std::uint64_t read_64bit( const std::uint8_t* p )
37 {
38 return static_cast< std::uint64_t >( read_32bit( p ) )
39 | ( static_cast< std::uint64_t >( read_32bit( p + 4 ) ) << 32 );
40 }
41
42 inline std::uint8_t* write_handle( std::uint8_t* out, std::uint16_t handle )
43 {
44 out[ 0 ] = handle & 0xff;
45 out[ 1 ] = handle >> 8;
46
47 return out + 2;
48 }
49
50 inline std::uint8_t* write_16bit_uuid( std::uint8_t* out, std::uint16_t uuid )
51 {
52 return write_handle( out, uuid );
53 }
54
55 inline std::uint8_t* write_16bit( std::uint8_t* out, std::uint16_t bits16 )
56 {
57 return write_handle( out, bits16 );
58 }
59
60 inline std::uint8_t* write_32bit( std::uint8_t* out, std::uint32_t bits32 )
61 {
62 return write_16bit( write_16bit( out, bits32 & 0xffff ), bits32 >> 16 );
63 }
64
65 inline std::uint8_t* write_64bit( std::uint8_t* out, std::uint64_t bits64 )
66 {
67 return write_32bit( write_32bit( out, bits64 & 0xffffffff ), bits64 >> 32 );
68 }
69
70 inline std::uint8_t* write_byte( std::uint8_t* out, std::uint8_t byte )
71 {
72 *out = byte;
73 return out + 1;
74 }
75
84 template < typename I >
85 typename std::make_signed< I >::type distance( I start, I end )
86 {
87 static_assert( std::is_unsigned< I >::value, "I has to be an unsigned type" );
88
89 if ( start > end )
90 return -distance( end, start );
91
92 const I positive = end - start;
93 const I negative = start + ~I(0) - end + 1;
94
95 return positive < negative
96 ? positive
97 : -negative;
98 }
99
100 template < std::size_t N, typename I >
101 typename std::make_signed< I >::type distance_n( I start, I end )
102 {
103 static_assert( std::is_unsigned< I >::value, "I has to be an unsigned type" );
104
105 if ( start > end )
106 return -distance_n< N >( end, start );
107
108 const I positive = end - start;
109 const I negative = start + I(1 << N) - end;
110
111 return positive < negative
112 ? positive
113 : -negative;
114 }
115}
116}
117#endif