hendian.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #ifndef HV_ENDIAN_H_
  2. #define HV_ENDIAN_H_
  3. #include "hplatform.h"
  4. #if defined(OS_MAC)
  5. #include <libkern/OSByteOrder.h>
  6. #define htobe16(v) OSSwapHostToBigInt16(v)
  7. #define htobe32(v) OSSwapHostToBigInt32(v)
  8. #define htobe64(v) OSSwapHostToBigInt64(v)
  9. #define be16toh(v) OSSwapBigToHostInt16(v)
  10. #define be32toh(v) OSSwapBigToHostInt32(v)
  11. #define be64toh(v) OSSwapBigToHostInt64(v)
  12. #define htole16(v) OSSwapHostToLittleInt16(v)
  13. #define htole32(v) OSSwapHostToLittleInt32(v)
  14. #define htole64(v) OSSwapHostToLittleInt64(v)
  15. #define le16toh(v) OSSwapLittleToHostInt16(v)
  16. #define le32toh(v) OSSwapLittleToHostInt32(v)
  17. #define le64toh(v) OSSwapLittleToHostInt64(v)
  18. #elif defined(OS_WIN)
  19. #define htobe16(v) htons(v)
  20. #define htobe32(v) htonl(v)
  21. #define htobe64(v) htonll(v)
  22. #define be16toh(v) ntohs(v)
  23. #define be32toh(v) ntohl(v)
  24. #define be64toh(v) ntohll(v)
  25. #if (BYTE_ORDER == LITTLE_ENDIAN)
  26. #define htole16(v) (v)
  27. #define htole32(v) (v)
  28. #define htole64(v) (v)
  29. #define le16toh(v) (v)
  30. #define le32toh(v) (v)
  31. #define le64toh(v) (v)
  32. #elif (BYTE_ORDER == BIG_ENDIAN)
  33. #define htole16(v) __builtin_bswap16(v)
  34. #define htole32(v) __builtin_bswap32(v)
  35. #define htole64(v) __builtin_bswap64(v)
  36. #define le16toh(v) __builtin_bswap16(v)
  37. #define le32toh(v) __builtin_bswap32(v)
  38. #define le64toh(v) __builtin_bswap64(v)
  39. #endif
  40. #else
  41. #include <endian.h>
  42. #endif
  43. #define PI8(p) *(int8_t*)(p)
  44. #define PI16(p) *(int16_t*)(p)
  45. #define PI32(p) *(int32_t*)(p)
  46. #define PI64(p) *(int64_t*)(p)
  47. #define PU8(p) *(uint8_t*)(p)
  48. #define PU16(p) *(uint16_t*)(p)
  49. #define PU32(p) *(uint32_t*)(p)
  50. #define PU64(p) *(uint64_t*)(p)
  51. #define PF32(p) *(float*)(p)
  52. #define PF64(p) *(double*)(p)
  53. #define GET_BE16(p) be16toh(PU16(p))
  54. #define GET_BE32(p) be32toh(PU32(p))
  55. #define GET_BE64(p) be64toh(PU64(p))
  56. #define GET_LE16(p) le16toh(PU16(p))
  57. #define GET_LE32(p) le32toh(PU32(p))
  58. #define GET_LE64(p) le64toh(PU64(p))
  59. #define PUT_BE16(p, v) PU16(p) = htobe16(v)
  60. #define PUT_BE32(p, v) PU32(p) = htobe32(v)
  61. #define PUT_BE64(p, v) PU64(p) = htobe64(v)
  62. #define PUT_LE16(p, v) PU16(p) = htole16(v)
  63. #define PUT_LE32(p, v) PU32(p) = htole32(v)
  64. #define PUT_LE64(p, v) PU64(p) = htole64(v)
  65. // NOTE: uint8_t* p = (uint8_t*)buf;
  66. #define POP_BE8(p, v) v = *p; ++p
  67. #define POP_BE16(p, v) v = be16toh(PU16(p)); p += 2
  68. #define POP_BE32(p, v) v = be32toh(PU32(p)); p += 4
  69. #define POP_BE64(p, v) v = be64toh(PU64(p)); p += 8
  70. #define POP_LE8(p, v) v= *p; ++p
  71. #define POP_LE16(p, v) v = le16toh(PU16(p)); p += 2
  72. #define POP_LE32(p, v) v = le32toh(PU32(p)); p += 4
  73. #define POP_LE64(p, v) v = le64toh(PU64(p)); p += 8
  74. #define PUSH_BE8(p, v) *p = v; ++p
  75. #define PUSH_BE16(p, v) PU16(p) = htobe16(v); p += 2
  76. #define PUSH_BE32(p, v) PU32(p) = htobe32(v); p += 4
  77. #define PUSH_BE64(p, v) PU64(p) = htobe64(v); p += 8
  78. #define PUSH_LE8(p, v) *p = v; ++p
  79. #define PUSH_LE16(p, v) PU16(p) = htole16(v); p += 2
  80. #define PUSH_LE32(p, v) PU32(p) = htole32(v); p += 4
  81. #define PUSH_LE64(p, v) PU64(p) = htole64(v); p += 8
  82. // NOTE: NET_ENDIAN = BIG_ENDIAN
  83. #define POP8(p, v) POP_BE8(p, v)
  84. #define POP16(p, v) POP_BE16(p, v)
  85. #define POP32(p, v) POP_BE32(p, v)
  86. #define POP64(p, v) POP_BE64(p, v)
  87. #define POP_N(p, v, n) memcpy(v, p, n); p += n
  88. #define PUSH8(p, v) PUSH_BE8(p, v)
  89. #define PUSH16(p, v) PUSH_BE16(p, v)
  90. #define PUSH32(p, v) PUSH_BE32(p, v)
  91. #define PUSH64(p, v) PUSH_BE64(p, v)
  92. #define PUSH_N(p, v, n) memcpy(p, v, n); p += n
  93. static inline int detect_endian() {
  94. union {
  95. char c;
  96. short s;
  97. } u;
  98. u.s = 0x1122;
  99. return u.c ==0x11 ? BIG_ENDIAN : LITTLE_ENDIAN;
  100. }
  101. #ifdef __cplusplus
  102. template <typename T>
  103. uint8_t* serialize(uint8_t* buf, T value, int host_endian = LITTLE_ENDIAN, int buf_endian = BIG_ENDIAN) {
  104. size_t size = sizeof(T);
  105. uint8_t* pDst = buf;
  106. uint8_t* pSrc = (uint8_t*)&value;
  107. if (host_endian == buf_endian) {
  108. memcpy(pDst, pSrc, size);
  109. }
  110. else {
  111. for (int i = 0; i < size; ++i) {
  112. pDst[i] = pSrc[size-i-1];
  113. }
  114. }
  115. return buf+size;
  116. }
  117. template <typename T>
  118. uint8_t* deserialize(uint8_t* buf, T* value, int host_endian = LITTLE_ENDIAN, int buf_endian = BIG_ENDIAN) {
  119. size_t size = sizeof(T);
  120. uint8_t* pSrc = buf;
  121. uint8_t* pDst = (uint8_t*)value;
  122. if (host_endian == buf_endian) {
  123. memcpy(pDst, pSrc, size);
  124. }
  125. else {
  126. for (int i = 0; i < size; ++i) {
  127. pDst[i] = pSrc[size-i-1];
  128. }
  129. }
  130. return buf+size;
  131. }
  132. #endif // __cplusplus
  133. #endif // HV_ENDIAN_H_