byteorder.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #pragma once
  2. #include "defaults.h"
  3. // #define USE_GENERIC_ENDIAN_CVT
  4. #if defined(_linux_) && !defined(USE_GENERIC_ENDIAN_CVT)
  5. #include <byteswap.h>
  6. #elif defined(_darwin_)
  7. #if defined(_arm_) || defined(__IOS__)
  8. #include <architecture/byte_order.h>
  9. #else
  10. #include <machine/byte_order.h>
  11. #endif
  12. #else
  13. #include <util/generic/utility.h>
  14. #endif
  15. #if defined(_linux_) && !defined(USE_GENERIC_ENDIAN_CVT)
  16. #define SwapBytes16 bswap_16
  17. #define SwapBytes32 bswap_32
  18. #define SwapBytes64 bswap_64
  19. #elif defined(_darwin_)
  20. #ifdef _arm_
  21. #define SwapBytes16 _OSSwapInt16
  22. #define SwapBytes32 _OSSwapInt32
  23. #define SwapBytes64 _OSSwapInt64
  24. #else
  25. #define SwapBytes16 OSSwapInt16
  26. #define SwapBytes32 OSSwapInt32
  27. #define SwapBytes64 OSSwapInt64
  28. #endif
  29. #endif
  30. #ifndef SwapBytes16
  31. inline ui16 SwapBytes16(ui16 val) noexcept {
  32. #define byte_n(__val, __n) ((((unsigned char*)(&__val))[__n]))
  33. DoSwap(byte_n(val, 0), byte_n(val, 1));
  34. return val;
  35. #undef byte_n
  36. }
  37. #endif
  38. #ifndef SwapBytes32
  39. inline ui32 SwapBytes32(ui32 val) noexcept {
  40. #define byte_n(__val, __n) ((((unsigned char*)(&__val))[__n]))
  41. DoSwap(byte_n(val, 0), byte_n(val, 3));
  42. DoSwap(byte_n(val, 1), byte_n(val, 2));
  43. return val;
  44. #undef byte_n
  45. }
  46. #endif
  47. #ifndef SwapBytes64
  48. inline ui64 SwapBytes64(ui64 val) noexcept {
  49. union {
  50. ui64 val;
  51. ui32 p[2];
  52. } tmp, ret;
  53. tmp.val = val;
  54. ret.p[0] = SwapBytes32(tmp.p[1]);
  55. ret.p[1] = SwapBytes32(tmp.p[0]);
  56. return ret.val;
  57. }
  58. #endif
  59. // for convenience
  60. static inline ui8 SwapBytes8(ui8 v) noexcept {
  61. return v;
  62. }
  63. namespace NSwapBytes {
  64. template <unsigned N>
  65. struct TSwapBytesHelper {
  66. };
  67. #define DEF_SB(X) \
  68. template <> \
  69. struct TSwapBytesHelper<X> { \
  70. template <class T> \
  71. static inline T Swap(T t) noexcept { \
  72. return (T)SwapBytes##X((ui##X)t); \
  73. } \
  74. };
  75. DEF_SB(8)
  76. DEF_SB(16)
  77. DEF_SB(32)
  78. DEF_SB(64)
  79. #undef DEF_SB
  80. } // namespace NSwapBytes
  81. template <class T>
  82. inline T SwapBytes(T val) noexcept {
  83. return NSwapBytes::TSwapBytesHelper<sizeof(T) * 8>::Swap(val);
  84. }
  85. template <class T>
  86. inline T LittleToBig(T val) noexcept {
  87. return SwapBytes(val);
  88. }
  89. template <class T>
  90. inline T BigToLittle(T val) noexcept {
  91. return LittleToBig(val);
  92. }
  93. template <class T>
  94. inline T HostToInet(T val) noexcept {
  95. #if defined(_big_endian_)
  96. return val;
  97. #elif defined(_little_endian_)
  98. return LittleToBig(val);
  99. #else
  100. #error todo
  101. #endif
  102. }
  103. template <class T>
  104. inline T InetToHost(T val) noexcept {
  105. return HostToInet(val);
  106. }
  107. template <class T>
  108. inline T HostToLittle(T val) noexcept {
  109. #if defined(_big_endian_)
  110. return BigToLittle(val);
  111. #elif defined(_little_endian_)
  112. return val;
  113. #else
  114. #error todo
  115. #endif
  116. }
  117. template <class T>
  118. inline T LittleToHost(T val) noexcept {
  119. return HostToLittle(val);
  120. }