/src/jsoncons/include/jsoncons/utility/binary.hpp
Line | Count | Source |
1 | | #ifndef JSONCONS_UTILITY_BINARY_HPP |
2 | | #define JSONCONS_UTILITY_BINARY_HPP |
3 | | |
4 | | #include <cfloat> |
5 | | #include <cmath> |
6 | | #include <cstddef> |
7 | | #include <cstdint> |
8 | | #include <cstring> // std::memcpy |
9 | | #include <type_traits> // std::enable_if |
10 | | |
11 | | #include <jsoncons/config/jsoncons_config.hpp> |
12 | | |
13 | | namespace jsoncons { |
14 | | namespace binary { |
15 | | |
16 | | // byte_swap |
17 | | |
18 | | template<class T> |
19 | | typename std::enable_if<std::is_integral<T>::value && sizeof(T) == sizeof(uint8_t),T>::type |
20 | | byte_swap(T val) |
21 | 3.35M | { |
22 | 3.35M | return val; |
23 | 3.35M | } |
24 | | |
25 | | template<class T> |
26 | | typename std::enable_if<std::is_integral<T>::value && sizeof(T) == sizeof(uint16_t),T>::type |
27 | | byte_swap(T val) |
28 | 7.35k | { |
29 | 7.35k | #if defined(JSONCONS_BYTE_SWAP_16) |
30 | 7.35k | return JSONCONS_BYTE_SWAP_16(val); |
31 | | #else |
32 | | return (static_cast<uint16_t>(val) >> 8) | (static_cast<uint16_t>(val) << 8); |
33 | | #endif |
34 | 7.35k | } |
35 | | |
36 | | template<class T> |
37 | | typename std::enable_if<std::is_integral<T>::value && sizeof(T) == sizeof(uint32_t),T>::type |
38 | | byte_swap(T val) |
39 | 173k | { |
40 | 173k | #if defined(JSONCONS_BYTE_SWAP_32) |
41 | 173k | return JSONCONS_BYTE_SWAP_32(val); |
42 | | #else |
43 | | uint32_t tmp = ((static_cast<uint32_t>(val) << 8) & 0xff00ff00) | ((static_cast<uint32_t>(val) >> 8) & 0xff00ff); |
44 | | return (tmp << 16) | (tmp >> 16); |
45 | | #endif |
46 | 173k | } _ZN8jsoncons6binary9byte_swapIiEENSt3__19enable_ifIXaasr3std11is_integralIT_EE5valueeqstS4_Lm4EES4_E4typeES4_ Line | Count | Source | 39 | 8.23k | { | 40 | 8.23k | #if defined(JSONCONS_BYTE_SWAP_32) | 41 | 8.23k | return JSONCONS_BYTE_SWAP_32(val); | 42 | | #else | 43 | | uint32_t tmp = ((static_cast<uint32_t>(val) << 8) & 0xff00ff00) | ((static_cast<uint32_t>(val) >> 8) & 0xff00ff); | 44 | | return (tmp << 16) | (tmp >> 16); | 45 | | #endif | 46 | 8.23k | } |
_ZN8jsoncons6binary9byte_swapIjEENSt3__19enable_ifIXaasr3std11is_integralIT_EE5valueeqstS4_Lm4EES4_E4typeES4_ Line | Count | Source | 39 | 165k | { | 40 | 165k | #if defined(JSONCONS_BYTE_SWAP_32) | 41 | 165k | return JSONCONS_BYTE_SWAP_32(val); | 42 | | #else | 43 | | uint32_t tmp = ((static_cast<uint32_t>(val) << 8) & 0xff00ff00) | ((static_cast<uint32_t>(val) >> 8) & 0xff00ff); | 44 | | return (tmp << 16) | (tmp >> 16); | 45 | | #endif | 46 | 165k | } |
|
47 | | |
48 | | template<class T> |
49 | | typename std::enable_if<std::is_integral<T>::value && sizeof(T) == sizeof(uint64_t),T>::type |
50 | | byte_swap(T val) |
51 | 17.7k | { |
52 | 17.7k | #if defined(JSONCONS_BYTE_SWAP_64) |
53 | 17.7k | return JSONCONS_BYTE_SWAP_64(val); |
54 | | #else |
55 | | uint64_t tmp = ((static_cast<uint64_t>(val) & 0x00000000ffffffffull) << 32) | ((static_cast<uint64_t>(val) & 0xffffffff00000000ull) >> 32); |
56 | | tmp = ((tmp & 0x0000ffff0000ffffull) << 16) | ((tmp & 0xffff0000ffff0000ull) >> 16); |
57 | | return ((tmp & 0x00ff00ff00ff00ffull) << 8) | ((tmp & 0xff00ff00ff00ff00ull) >> 8); |
58 | | #endif |
59 | 17.7k | } _ZN8jsoncons6binary9byte_swapIlEENSt3__19enable_ifIXaasr3std11is_integralIT_EE5valueeqstS4_Lm8EES4_E4typeES4_ Line | Count | Source | 51 | 16.2k | { | 52 | 16.2k | #if defined(JSONCONS_BYTE_SWAP_64) | 53 | 16.2k | return JSONCONS_BYTE_SWAP_64(val); | 54 | | #else | 55 | | uint64_t tmp = ((static_cast<uint64_t>(val) & 0x00000000ffffffffull) << 32) | ((static_cast<uint64_t>(val) & 0xffffffff00000000ull) >> 32); | 56 | | tmp = ((tmp & 0x0000ffff0000ffffull) << 16) | ((tmp & 0xffff0000ffff0000ull) >> 16); | 57 | | return ((tmp & 0x00ff00ff00ff00ffull) << 8) | ((tmp & 0xff00ff00ff00ff00ull) >> 8); | 58 | | #endif | 59 | 16.2k | } |
_ZN8jsoncons6binary9byte_swapImEENSt3__19enable_ifIXaasr3std11is_integralIT_EE5valueeqstS4_Lm8EES4_E4typeES4_ Line | Count | Source | 51 | 1.53k | { | 52 | 1.53k | #if defined(JSONCONS_BYTE_SWAP_64) | 53 | 1.53k | return JSONCONS_BYTE_SWAP_64(val); | 54 | | #else | 55 | | uint64_t tmp = ((static_cast<uint64_t>(val) & 0x00000000ffffffffull) << 32) | ((static_cast<uint64_t>(val) & 0xffffffff00000000ull) >> 32); | 56 | | tmp = ((tmp & 0x0000ffff0000ffffull) << 16) | ((tmp & 0xffff0000ffff0000ull) >> 16); | 57 | | return ((tmp & 0x00ff00ff00ff00ffull) << 8) | ((tmp & 0xff00ff00ff00ff00ull) >> 8); | 58 | | #endif | 59 | 1.53k | } |
|
60 | | |
61 | | template<class T> |
62 | | typename std::enable_if<std::is_floating_point<T>::value && sizeof(T) == sizeof(uint32_t),T>::type |
63 | | byte_swap(T val) |
64 | 165k | { |
65 | 165k | uint32_t x; |
66 | 165k | std::memcpy(&x,&val,sizeof(uint32_t)); |
67 | 165k | uint32_t y = byte_swap(x); |
68 | 165k | T val2; |
69 | 165k | std::memcpy(&val2,&y,sizeof(uint32_t)); |
70 | 165k | return val2; |
71 | 165k | } |
72 | | |
73 | | template<class T> |
74 | | typename std::enable_if<std::is_floating_point<T>::value && sizeof(T) == sizeof(uint64_t),T>::type |
75 | | byte_swap(T val) |
76 | 1.53k | { |
77 | 1.53k | uint64_t x; |
78 | 1.53k | std::memcpy(&x,&val,sizeof(uint64_t)); |
79 | 1.53k | uint64_t y = byte_swap(x); |
80 | 1.53k | T val2; |
81 | 1.53k | std::memcpy(&val2,&y,sizeof(uint64_t)); |
82 | 1.53k | return val2; |
83 | 1.53k | } |
84 | | |
85 | | struct uint128_holder |
86 | | { |
87 | | uint64_t lo; |
88 | | uint64_t hi; |
89 | | }; |
90 | | |
91 | | template<class T> |
92 | | typename std::enable_if<std::is_floating_point<T>::value && sizeof(T) == 2*sizeof(uint64_t),T>::type |
93 | | byte_swap(T val) |
94 | | { |
95 | | uint128_holder x; |
96 | | uint8_t buf[2*sizeof(uint64_t)]; |
97 | | std::memcpy(buf,&val,2*sizeof(uint64_t)); |
98 | | std::memcpy(&x.lo,buf,sizeof(uint64_t)); |
99 | | std::memcpy(&x.hi,buf+sizeof(uint64_t),sizeof(uint64_t)); |
100 | | |
101 | | uint128_holder y; |
102 | | y.lo = byte_swap(x.hi); |
103 | | y.hi = byte_swap(x.lo); |
104 | | |
105 | | T val2; |
106 | | std::memcpy(&val2,&y,2*sizeof(uint64_t)); |
107 | | |
108 | | return val2; |
109 | | } |
110 | | // native_to_big |
111 | | |
112 | | template <typename T,typename OutputIt,typename Endian=endian> |
113 | | typename std::enable_if<Endian::native == Endian::big,void>::type |
114 | | native_to_big(T val, OutputIt d_first) |
115 | | { |
116 | | uint8_t buf[sizeof(T)]; |
117 | | std::memcpy(buf, &val, sizeof(T)); |
118 | | for (auto item : buf) |
119 | | { |
120 | | *d_first++ = item; |
121 | | } |
122 | | } |
123 | | |
124 | | template <typename T,typename OutputIt,typename Endian=endian> |
125 | | typename std::enable_if<Endian::native == Endian::little,void>::type |
126 | | native_to_big(T val, OutputIt d_first) |
127 | | { |
128 | | T val2 = byte_swap(val); |
129 | | uint8_t buf[sizeof(T)]; |
130 | | std::memcpy(buf, &val2, sizeof(T)); |
131 | | for (auto item : buf) |
132 | | { |
133 | | *d_first++ = item; |
134 | | } |
135 | | } |
136 | | |
137 | | // native_to_little |
138 | | |
139 | | template <typename T,typename OutputIt,typename Endian = endian> |
140 | | typename std::enable_if<Endian::native == Endian::little,void>::type |
141 | | native_to_little(T val, OutputIt d_first) |
142 | | { |
143 | | uint8_t buf[sizeof(T)]; |
144 | | std::memcpy(buf, &val, sizeof(T)); |
145 | | for (auto item : buf) |
146 | | { |
147 | | *d_first++ = item; |
148 | | } |
149 | | } |
150 | | |
151 | | template <typename T,typename OutputIt,typename Endian=endian> |
152 | | typename std::enable_if<Endian::native == Endian::big, void>::type |
153 | | native_to_little(T val, OutputIt d_first) |
154 | | { |
155 | | T val2 = byte_swap(val); |
156 | | uint8_t buf[sizeof(T)]; |
157 | | std::memcpy(buf, &val2, sizeof(T)); |
158 | | for (auto item : buf) |
159 | | { |
160 | | *d_first++ = item; |
161 | | } |
162 | | } |
163 | | |
164 | | // big_to_native |
165 | | |
166 | | template <typename T,typename Endian=endian> |
167 | | typename std::enable_if<Endian::native == Endian::big,T>::type |
168 | | big_to_native(const uint8_t* first, std::size_t count) |
169 | | { |
170 | | if (sizeof(T) > count) |
171 | | { |
172 | | return T{}; |
173 | | } |
174 | | T val; |
175 | | std::memcpy(&val,first,sizeof(T)); |
176 | | return val; |
177 | | } |
178 | | |
179 | | template <typename T,typename Endian=endian> |
180 | | typename std::enable_if<Endian::native == Endian::little,T>::type |
181 | | big_to_native(const uint8_t* first, std::size_t count) |
182 | 3.55M | { |
183 | 3.55M | if (sizeof(T) > count) |
184 | 0 | { |
185 | 0 | return T{}; |
186 | 0 | } |
187 | 3.55M | T val; |
188 | 3.55M | std::memcpy(&val,first,sizeof(T)); |
189 | 3.55M | return byte_swap(val); |
190 | 3.55M | } std::__1::enable_if<jsoncons::detail::endian::native==jsoncons::detail::endian::little, signed char>::type jsoncons::binary::big_to_native<signed char, jsoncons::detail::endian>(unsigned char const*, unsigned long) Line | Count | Source | 182 | 3.35M | { | 183 | 3.35M | if (sizeof(T) > count) | 184 | 0 | { | 185 | 0 | return T{}; | 186 | 0 | } | 187 | 3.35M | T val; | 188 | 3.35M | std::memcpy(&val,first,sizeof(T)); | 189 | 3.35M | return byte_swap(val); | 190 | 3.35M | } |
std::__1::enable_if<jsoncons::detail::endian::native==jsoncons::detail::endian::little, short>::type jsoncons::binary::big_to_native<short, jsoncons::detail::endian>(unsigned char const*, unsigned long) Line | Count | Source | 182 | 7.35k | { | 183 | 7.35k | if (sizeof(T) > count) | 184 | 0 | { | 185 | 0 | return T{}; | 186 | 0 | } | 187 | 7.35k | T val; | 188 | 7.35k | std::memcpy(&val,first,sizeof(T)); | 189 | 7.35k | return byte_swap(val); | 190 | 7.35k | } |
std::__1::enable_if<jsoncons::detail::endian::native==jsoncons::detail::endian::little, int>::type jsoncons::binary::big_to_native<int, jsoncons::detail::endian>(unsigned char const*, unsigned long) Line | Count | Source | 182 | 8.23k | { | 183 | 8.23k | if (sizeof(T) > count) | 184 | 0 | { | 185 | 0 | return T{}; | 186 | 0 | } | 187 | 8.23k | T val; | 188 | 8.23k | std::memcpy(&val,first,sizeof(T)); | 189 | 8.23k | return byte_swap(val); | 190 | 8.23k | } |
std::__1::enable_if<jsoncons::detail::endian::native==jsoncons::detail::endian::little, long>::type jsoncons::binary::big_to_native<long, jsoncons::detail::endian>(unsigned char const*, unsigned long) Line | Count | Source | 182 | 16.2k | { | 183 | 16.2k | if (sizeof(T) > count) | 184 | 0 | { | 185 | 0 | return T{}; | 186 | 0 | } | 187 | 16.2k | T val; | 188 | 16.2k | std::memcpy(&val,first,sizeof(T)); | 189 | 16.2k | return byte_swap(val); | 190 | 16.2k | } |
std::__1::enable_if<jsoncons::detail::endian::native==jsoncons::detail::endian::little, float>::type jsoncons::binary::big_to_native<float, jsoncons::detail::endian>(unsigned char const*, unsigned long) Line | Count | Source | 182 | 165k | { | 183 | 165k | if (sizeof(T) > count) | 184 | 0 | { | 185 | 0 | return T{}; | 186 | 0 | } | 187 | 165k | T val; | 188 | 165k | std::memcpy(&val,first,sizeof(T)); | 189 | 165k | return byte_swap(val); | 190 | 165k | } |
std::__1::enable_if<jsoncons::detail::endian::native==jsoncons::detail::endian::little, double>::type jsoncons::binary::big_to_native<double, jsoncons::detail::endian>(unsigned char const*, unsigned long) Line | Count | Source | 182 | 1.53k | { | 183 | 1.53k | if (sizeof(T) > count) | 184 | 0 | { | 185 | 0 | return T{}; | 186 | 0 | } | 187 | 1.53k | T val; | 188 | 1.53k | std::memcpy(&val,first,sizeof(T)); | 189 | 1.53k | return byte_swap(val); | 190 | 1.53k | } |
|
191 | | |
192 | | // little_to_native |
193 | | |
194 | | template <typename T,typename Endian=endian> |
195 | | typename std::enable_if<Endian::native == Endian::little,T>::type |
196 | | little_to_native(const uint8_t* first, std::size_t count) |
197 | | { |
198 | | if (sizeof(T) > count) |
199 | | { |
200 | | return T{}; |
201 | | } |
202 | | T val; |
203 | | std::memcpy(&val,first,sizeof(T)); |
204 | | return val; |
205 | | } |
206 | | |
207 | | template <typename T,typename Endian=endian> |
208 | | typename std::enable_if<Endian::native == Endian::big,T>::type |
209 | | little_to_native(const uint8_t* first, std::size_t count) |
210 | | { |
211 | | if (sizeof(T) > count) |
212 | | { |
213 | | return T{}; |
214 | | } |
215 | | T val; |
216 | | std::memcpy(&val,first,sizeof(T)); |
217 | | return byte_swap(val); |
218 | | } |
219 | | |
220 | | } // namespace binary |
221 | | } // namespace jsoncons |
222 | | |
223 | | #endif // JSONCONS_UTILITY_BINARY_HPP |