LittleBigEndian.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // LittleBigEndian.h fixed for 64-bits added union
  2. //
  3. #ifndef LITTLEBIGENDIAN_H
  4. #define LITTLEBIGENDIAN_H
  5. // Determine Little-Endian or Big-Endian
  6. #define CURRENT_BYTE_ORDER (*(int *)"\x01\x02\x03\x04")
  7. #define LITTLE_ENDIAN_BYTE_ORDER 0x04030201
  8. #define BIG_ENDIAN_BYTE_ORDER 0x01020304
  9. #define PDP_ENDIAN_BYTE_ORDER 0x02010403
  10. #define IS_LITTLE_ENDIAN (CURRENT_BYTE_ORDER == LITTLE_ENDIAN_BYTE_ORDER)
  11. #define IS_BIG_ENDIAN (CURRENT_BYTE_ORDER == BIG_ENDIAN_BYTE_ORDER)
  12. #define IS_PDP_ENDIAN (CURRENT_BYTE_ORDER == PDP_ENDIAN_BYTE_ORDER)
  13. // Forward declaration
  14. template<typename T>
  15. struct LittleEndian;
  16. template<typename T>
  17. struct BigEndian;
  18. // Little-Endian template
  19. #pragma pack(push,1)
  20. template<typename T>
  21. struct LittleEndian
  22. {
  23. union
  24. {
  25. unsigned char bytes[sizeof(T)];
  26. T raw_value;
  27. };
  28. LittleEndian(T t = T())
  29. {
  30. operator =(t);
  31. }
  32. LittleEndian(const LittleEndian<T> & t)
  33. {
  34. raw_value = t.raw_value;
  35. }
  36. LittleEndian(const BigEndian<T> & t)
  37. {
  38. for (unsigned i = 0; i < sizeof(T); i++)
  39. bytes[i] = t.bytes[sizeof(T)-1-i];
  40. }
  41. operator const T() const
  42. {
  43. T t = T();
  44. for (unsigned i = 0; i < sizeof(T); i++)
  45. t |= T(bytes[i]) << (i << 3);
  46. return t;
  47. }
  48. const T operator = (const T t)
  49. {
  50. for (unsigned i = 0; i < sizeof(T); i++)
  51. bytes[sizeof(T)-1 - i] = static_cast<unsigned char>(t >> (i << 3));
  52. return t;
  53. }
  54. // operators
  55. const T operator += (const T t)
  56. {
  57. return (*this = *this + t);
  58. }
  59. const T operator -= (const T t)
  60. {
  61. return (*this = *this - t);
  62. }
  63. const T operator *= (const T t)
  64. {
  65. return (*this = *this * t);
  66. }
  67. const T operator /= (const T t)
  68. {
  69. return (*this = *this / t);
  70. }
  71. const T operator %= (const T t)
  72. {
  73. return (*this = *this % t);
  74. }
  75. LittleEndian<T> operator ++ (int)
  76. {
  77. LittleEndian<T> tmp(*this);
  78. operator ++ ();
  79. return tmp;
  80. }
  81. LittleEndian<T> & operator ++ ()
  82. {
  83. for (unsigned i = 0; i < sizeof(T); i++)
  84. {
  85. ++bytes[i];
  86. if (bytes[i] != 0)
  87. break;
  88. }
  89. return (*this);
  90. }
  91. LittleEndian<T> operator -- (int)
  92. {
  93. LittleEndian<T> tmp(*this);
  94. operator -- ();
  95. return tmp;
  96. }
  97. LittleEndian<T> & operator -- ()
  98. {
  99. for (unsigned i = 0; i < sizeof(T); i++)
  100. {
  101. --bytes[i];
  102. if (bytes[i] != (T)(-1))
  103. break;
  104. }
  105. return (*this);
  106. }
  107. };
  108. #pragma pack(pop)
  109. // Big-Endian template
  110. #pragma pack(push,1)
  111. template<typename T>
  112. struct BigEndian
  113. {
  114. union
  115. {
  116. unsigned char bytes[sizeof(T)];
  117. T raw_value;
  118. };
  119. BigEndian(T t = T())
  120. {
  121. operator =(t);
  122. }
  123. BigEndian(const BigEndian<T> & t)
  124. {
  125. raw_value = t.raw_value;
  126. }
  127. BigEndian(const LittleEndian<T> & t)
  128. {
  129. for (unsigned i = 0; i < sizeof(T); i++)
  130. bytes[i] = t.bytes[sizeof(T)-1-i];
  131. }
  132. operator const T() const
  133. {
  134. T t = T();
  135. for (unsigned i = 0; i < sizeof(T); i++)
  136. t |= T(bytes[sizeof(T) - 1 - i]) << (i << 3);
  137. return t;
  138. }
  139. const T operator = (const T t)
  140. {
  141. for (unsigned i = 0; i < sizeof(T); i++)
  142. bytes[sizeof(T) - 1 - i] = t >> (i << 3);
  143. return t;
  144. }
  145. // operators
  146. const T operator += (const T t)
  147. {
  148. return (*this = *this + t);
  149. }
  150. const T operator -= (const T t)
  151. {
  152. return (*this = *this - t);
  153. }
  154. const T operator *= (const T t)
  155. {
  156. return (*this = *this * t);
  157. }
  158. const T operator /= (const T t)
  159. {
  160. return (*this = *this / t);
  161. }
  162. const T operator %= (const T t)
  163. {
  164. return (*this = *this % t);
  165. }
  166. BigEndian<T> operator ++ (int)
  167. {
  168. BigEndian<T> tmp(*this);
  169. operator ++ ();
  170. return tmp;
  171. }
  172. BigEndian<T> & operator ++ ()
  173. {
  174. for (unsigned i = 0; i < sizeof(T); i++)
  175. {
  176. ++bytes[sizeof(T) - 1 - i];
  177. if (bytes[sizeof(T) - 1 - i] != 0)
  178. break;
  179. }
  180. return (*this);
  181. }
  182. BigEndian<T> operator -- (int)
  183. {
  184. BigEndian<T> tmp(*this);
  185. operator -- ();
  186. return tmp;
  187. }
  188. BigEndian<T> & operator -- ()
  189. {
  190. for (unsigned i = 0; i < sizeof(T); i++)
  191. {
  192. --bytes[sizeof(T) - 1 - i];
  193. if (bytes[sizeof(T) - 1 - i] != (T)(-1))
  194. break;
  195. }
  196. return (*this);
  197. }
  198. };
  199. #pragma pack(pop)
  200. #endif // LITTLEBIGENDIAN_H