You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

endian.h 12 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. // Copyright 2017 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. #ifndef ABSL_BASE_INTERNAL_ENDIAN_H_
  16. #define ABSL_BASE_INTERNAL_ENDIAN_H_
  17. #include <cstdint>
  18. #include <cstdlib>
  19. #include "absl/base/casts.h"
  20. #include "absl/base/config.h"
  21. #include "absl/base/internal/unaligned_access.h"
  22. #include "absl/base/port.h"
  23. namespace absl
  24. {
  25. ABSL_NAMESPACE_BEGIN
  26. inline uint64_t gbswap_64(uint64_t host_int)
  27. {
  28. #if ABSL_HAVE_BUILTIN(__builtin_bswap64) || defined(__GNUC__)
  29. return __builtin_bswap64(host_int);
  30. #elif defined(_MSC_VER)
  31. return _byteswap_uint64(host_int);
  32. #else
  33. return (((host_int & uint64_t{0xFF}) << 56) | ((host_int & uint64_t{0xFF00}) << 40) | ((host_int & uint64_t{0xFF0000}) << 24) | ((host_int & uint64_t{0xFF000000}) << 8) | ((host_int & uint64_t{0xFF00000000}) >> 8) | ((host_int & uint64_t{0xFF0000000000}) >> 24) | ((host_int & uint64_t{0xFF000000000000}) >> 40) | ((host_int & uint64_t{0xFF00000000000000}) >> 56));
  34. #endif
  35. }
  36. inline uint32_t gbswap_32(uint32_t host_int)
  37. {
  38. #if ABSL_HAVE_BUILTIN(__builtin_bswap32) || defined(__GNUC__)
  39. return __builtin_bswap32(host_int);
  40. #elif defined(_MSC_VER)
  41. return _byteswap_ulong(host_int);
  42. #else
  43. return (((host_int & uint32_t{0xFF}) << 24) | ((host_int & uint32_t{0xFF00}) << 8) | ((host_int & uint32_t{0xFF0000}) >> 8) | ((host_int & uint32_t{0xFF000000}) >> 24));
  44. #endif
  45. }
  46. inline uint16_t gbswap_16(uint16_t host_int)
  47. {
  48. #if ABSL_HAVE_BUILTIN(__builtin_bswap16) || defined(__GNUC__)
  49. return __builtin_bswap16(host_int);
  50. #elif defined(_MSC_VER)
  51. return _byteswap_ushort(host_int);
  52. #else
  53. return (((host_int & uint16_t{0xFF}) << 8) | ((host_int & uint16_t{0xFF00}) >> 8));
  54. #endif
  55. }
  56. #ifdef ABSL_IS_LITTLE_ENDIAN
  57. // Portable definitions for htonl (host-to-network) and friends on little-endian
  58. // architectures.
  59. inline uint16_t ghtons(uint16_t x)
  60. {
  61. return gbswap_16(x);
  62. }
  63. inline uint32_t ghtonl(uint32_t x)
  64. {
  65. return gbswap_32(x);
  66. }
  67. inline uint64_t ghtonll(uint64_t x)
  68. {
  69. return gbswap_64(x);
  70. }
  71. #elif defined ABSL_IS_BIG_ENDIAN
  72. // Portable definitions for htonl (host-to-network) etc on big-endian
  73. // architectures. These definitions are simpler since the host byte order is the
  74. // same as network byte order.
  75. inline uint16_t ghtons(uint16_t x)
  76. {
  77. return x;
  78. }
  79. inline uint32_t ghtonl(uint32_t x)
  80. {
  81. return x;
  82. }
  83. inline uint64_t ghtonll(uint64_t x)
  84. {
  85. return x;
  86. }
  87. #else
  88. #error \
  89. "Unsupported byte order: Either ABSL_IS_BIG_ENDIAN or " \
  90. "ABSL_IS_LITTLE_ENDIAN must be defined"
  91. #endif // byte order
  92. inline uint16_t gntohs(uint16_t x)
  93. {
  94. return ghtons(x);
  95. }
  96. inline uint32_t gntohl(uint32_t x)
  97. {
  98. return ghtonl(x);
  99. }
  100. inline uint64_t gntohll(uint64_t x)
  101. {
  102. return ghtonll(x);
  103. }
  104. // Utilities to convert numbers between the current hosts's native byte
  105. // order and little-endian byte order
  106. //
  107. // Load/Store methods are alignment safe
  108. namespace little_endian
  109. {
  110. // Conversion functions.
  111. #ifdef ABSL_IS_LITTLE_ENDIAN
  112. inline uint16_t FromHost16(uint16_t x)
  113. {
  114. return x;
  115. }
  116. inline uint16_t ToHost16(uint16_t x)
  117. {
  118. return x;
  119. }
  120. inline uint32_t FromHost32(uint32_t x)
  121. {
  122. return x;
  123. }
  124. inline uint32_t ToHost32(uint32_t x)
  125. {
  126. return x;
  127. }
  128. inline uint64_t FromHost64(uint64_t x)
  129. {
  130. return x;
  131. }
  132. inline uint64_t ToHost64(uint64_t x)
  133. {
  134. return x;
  135. }
  136. inline constexpr bool IsLittleEndian()
  137. {
  138. return true;
  139. }
  140. #elif defined ABSL_IS_BIG_ENDIAN
  141. inline uint16_t FromHost16(uint16_t x)
  142. {
  143. return gbswap_16(x);
  144. }
  145. inline uint16_t ToHost16(uint16_t x)
  146. {
  147. return gbswap_16(x);
  148. }
  149. inline uint32_t FromHost32(uint32_t x)
  150. {
  151. return gbswap_32(x);
  152. }
  153. inline uint32_t ToHost32(uint32_t x)
  154. {
  155. return gbswap_32(x);
  156. }
  157. inline uint64_t FromHost64(uint64_t x)
  158. {
  159. return gbswap_64(x);
  160. }
  161. inline uint64_t ToHost64(uint64_t x)
  162. {
  163. return gbswap_64(x);
  164. }
  165. inline constexpr bool IsLittleEndian()
  166. {
  167. return false;
  168. }
  169. #endif /* ENDIAN */
  170. inline uint8_t FromHost(uint8_t x)
  171. {
  172. return x;
  173. }
  174. inline uint16_t FromHost(uint16_t x)
  175. {
  176. return FromHost16(x);
  177. }
  178. inline uint32_t FromHost(uint32_t x)
  179. {
  180. return FromHost32(x);
  181. }
  182. inline uint64_t FromHost(uint64_t x)
  183. {
  184. return FromHost64(x);
  185. }
  186. inline uint8_t ToHost(uint8_t x)
  187. {
  188. return x;
  189. }
  190. inline uint16_t ToHost(uint16_t x)
  191. {
  192. return ToHost16(x);
  193. }
  194. inline uint32_t ToHost(uint32_t x)
  195. {
  196. return ToHost32(x);
  197. }
  198. inline uint64_t ToHost(uint64_t x)
  199. {
  200. return ToHost64(x);
  201. }
  202. inline int8_t FromHost(int8_t x)
  203. {
  204. return x;
  205. }
  206. inline int16_t FromHost(int16_t x)
  207. {
  208. return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x)));
  209. }
  210. inline int32_t FromHost(int32_t x)
  211. {
  212. return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x)));
  213. }
  214. inline int64_t FromHost(int64_t x)
  215. {
  216. return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x)));
  217. }
  218. inline int8_t ToHost(int8_t x)
  219. {
  220. return x;
  221. }
  222. inline int16_t ToHost(int16_t x)
  223. {
  224. return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x)));
  225. }
  226. inline int32_t ToHost(int32_t x)
  227. {
  228. return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x)));
  229. }
  230. inline int64_t ToHost(int64_t x)
  231. {
  232. return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x)));
  233. }
  234. // Functions to do unaligned loads and stores in little-endian order.
  235. inline uint16_t Load16(const void* p)
  236. {
  237. return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
  238. }
  239. inline void Store16(void* p, uint16_t v)
  240. {
  241. ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
  242. }
  243. inline uint32_t Load32(const void* p)
  244. {
  245. return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p));
  246. }
  247. inline void Store32(void* p, uint32_t v)
  248. {
  249. ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
  250. }
  251. inline uint64_t Load64(const void* p)
  252. {
  253. return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p));
  254. }
  255. inline void Store64(void* p, uint64_t v)
  256. {
  257. ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
  258. }
  259. } // namespace little_endian
  260. // Utilities to convert numbers between the current hosts's native byte
  261. // order and big-endian byte order (same as network byte order)
  262. //
  263. // Load/Store methods are alignment safe
  264. namespace big_endian
  265. {
  266. #ifdef ABSL_IS_LITTLE_ENDIAN
  267. inline uint16_t FromHost16(uint16_t x)
  268. {
  269. return gbswap_16(x);
  270. }
  271. inline uint16_t ToHost16(uint16_t x)
  272. {
  273. return gbswap_16(x);
  274. }
  275. inline uint32_t FromHost32(uint32_t x)
  276. {
  277. return gbswap_32(x);
  278. }
  279. inline uint32_t ToHost32(uint32_t x)
  280. {
  281. return gbswap_32(x);
  282. }
  283. inline uint64_t FromHost64(uint64_t x)
  284. {
  285. return gbswap_64(x);
  286. }
  287. inline uint64_t ToHost64(uint64_t x)
  288. {
  289. return gbswap_64(x);
  290. }
  291. inline constexpr bool IsLittleEndian()
  292. {
  293. return true;
  294. }
  295. #elif defined ABSL_IS_BIG_ENDIAN
  296. inline uint16_t FromHost16(uint16_t x)
  297. {
  298. return x;
  299. }
  300. inline uint16_t ToHost16(uint16_t x)
  301. {
  302. return x;
  303. }
  304. inline uint32_t FromHost32(uint32_t x)
  305. {
  306. return x;
  307. }
  308. inline uint32_t ToHost32(uint32_t x)
  309. {
  310. return x;
  311. }
  312. inline uint64_t FromHost64(uint64_t x)
  313. {
  314. return x;
  315. }
  316. inline uint64_t ToHost64(uint64_t x)
  317. {
  318. return x;
  319. }
  320. inline constexpr bool IsLittleEndian()
  321. {
  322. return false;
  323. }
  324. #endif /* ENDIAN */
  325. inline uint8_t FromHost(uint8_t x)
  326. {
  327. return x;
  328. }
  329. inline uint16_t FromHost(uint16_t x)
  330. {
  331. return FromHost16(x);
  332. }
  333. inline uint32_t FromHost(uint32_t x)
  334. {
  335. return FromHost32(x);
  336. }
  337. inline uint64_t FromHost(uint64_t x)
  338. {
  339. return FromHost64(x);
  340. }
  341. inline uint8_t ToHost(uint8_t x)
  342. {
  343. return x;
  344. }
  345. inline uint16_t ToHost(uint16_t x)
  346. {
  347. return ToHost16(x);
  348. }
  349. inline uint32_t ToHost(uint32_t x)
  350. {
  351. return ToHost32(x);
  352. }
  353. inline uint64_t ToHost(uint64_t x)
  354. {
  355. return ToHost64(x);
  356. }
  357. inline int8_t FromHost(int8_t x)
  358. {
  359. return x;
  360. }
  361. inline int16_t FromHost(int16_t x)
  362. {
  363. return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x)));
  364. }
  365. inline int32_t FromHost(int32_t x)
  366. {
  367. return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x)));
  368. }
  369. inline int64_t FromHost(int64_t x)
  370. {
  371. return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x)));
  372. }
  373. inline int8_t ToHost(int8_t x)
  374. {
  375. return x;
  376. }
  377. inline int16_t ToHost(int16_t x)
  378. {
  379. return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x)));
  380. }
  381. inline int32_t ToHost(int32_t x)
  382. {
  383. return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x)));
  384. }
  385. inline int64_t ToHost(int64_t x)
  386. {
  387. return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x)));
  388. }
  389. // Functions to do unaligned loads and stores in big-endian order.
  390. inline uint16_t Load16(const void* p)
  391. {
  392. return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
  393. }
  394. inline void Store16(void* p, uint16_t v)
  395. {
  396. ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v));
  397. }
  398. inline uint32_t Load32(const void* p)
  399. {
  400. return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p));
  401. }
  402. inline void Store32(void* p, uint32_t v)
  403. {
  404. ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v));
  405. }
  406. inline uint64_t Load64(const void* p)
  407. {
  408. return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p));
  409. }
  410. inline void Store64(void* p, uint64_t v)
  411. {
  412. ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v));
  413. }
  414. } // namespace big_endian
  415. ABSL_NAMESPACE_END
  416. } // namespace absl
  417. #endif // ABSL_BASE_INTERNAL_ENDIAN_H_