bytes.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #ifndef TOR_BYTES_H
  6. #define TOR_BYTES_H
  7. /**
  8. * \file bytes.h
  9. *
  10. * \brief Inline functions for reading and writing multibyte values from
  11. * the middle of strings, and for manipulating byte order.
  12. **/
  13. #include <string.h>
  14. #include "lib/cc/torint.h"
  15. /* The uint8 variants are defined to make the code more uniform. */
  16. static inline uint8_t
  17. get_uint8(const void *cp)
  18. {
  19. return *(const uint8_t*)(cp);
  20. }
  21. static inline void
  22. set_uint8(void *cp, uint8_t v)
  23. {
  24. *(uint8_t*)cp = v;
  25. }
  26. /**
  27. * Read a 16-bit value beginning at <b>cp</b>. Equivalent to
  28. * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid
  29. * unaligned memory access.
  30. */
  31. static inline uint16_t
  32. get_uint16(const void *cp)
  33. {
  34. uint16_t v;
  35. memcpy(&v,cp,2);
  36. return v;
  37. }
  38. /**
  39. * Read a 32-bit value beginning at <b>cp</b>. Equivalent to
  40. * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
  41. * unaligned memory access.
  42. */
  43. static inline uint32_t
  44. get_uint32(const void *cp)
  45. {
  46. uint32_t v;
  47. memcpy(&v,cp,4);
  48. return v;
  49. }
  50. /**
  51. * Read a 64-bit value beginning at <b>cp</b>. Equivalent to
  52. * *(uint64_t*)(cp), but will not cause segfaults on platforms that forbid
  53. * unaligned memory access.
  54. */
  55. static inline uint64_t
  56. get_uint64(const void *cp)
  57. {
  58. uint64_t v;
  59. memcpy(&v,cp,8);
  60. return v;
  61. }
  62. /**
  63. * Set a 16-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
  64. * *(uint16_t*)(cp) = v, but will not cause segfaults on platforms that forbid
  65. * unaligned memory access. */
  66. static inline void
  67. set_uint16(void *cp, uint16_t v)
  68. {
  69. memcpy(cp,&v,2);
  70. }
  71. /**
  72. * Set a 32-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
  73. * *(uint32_t*)(cp) = v, but will not cause segfaults on platforms that forbid
  74. * unaligned memory access. */
  75. static inline void
  76. set_uint32(void *cp, uint32_t v)
  77. {
  78. memcpy(cp,&v,4);
  79. }
  80. /**
  81. * Set a 64-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
  82. * *(uint64_t*)(cp) = v, but will not cause segfaults on platforms that forbid
  83. * unaligned memory access. */
  84. static inline void
  85. set_uint64(void *cp, uint64_t v)
  86. {
  87. memcpy(cp,&v,8);
  88. }
  89. #ifdef WORDS_BIGENDIAN
  90. static inline uint16_t
  91. tor_htons(uint32_t a)
  92. {
  93. return a;
  94. }
  95. static inline uint16_t
  96. tor_ntohs(uint64_t a)
  97. {
  98. return a;
  99. }
  100. static inline uint32_t
  101. tor_htonl(uint32_t a)
  102. {
  103. return a;
  104. }
  105. static inline uint32_t
  106. tor_ntohl(uint64_t a)
  107. {
  108. return a;
  109. }
  110. static inline uint64_t
  111. tor_htonll(uint64_t a)
  112. {
  113. return a;
  114. }
  115. static inline uint64_t
  116. tor_ntohll(uint64_t a)
  117. {
  118. return a;
  119. }
  120. #else
  121. static inline uint16_t
  122. tor_htons(uint16_t a)
  123. {
  124. /* Our compilers will indeed recognize this as bswap. */
  125. return
  126. ((a & 0x00ff) << 8) |
  127. ((a & 0xff00) >> 8);
  128. }
  129. static inline uint16_t
  130. tor_ntohs(uint16_t a)
  131. {
  132. return tor_htons(a);
  133. }
  134. static inline uint32_t
  135. tor_htonl(uint32_t a)
  136. {
  137. /* Our compilers will indeed recognize this as bswap. */
  138. return
  139. ((a & 0x000000ff) <<24) |
  140. ((a & 0x0000ff00) << 8) |
  141. ((a & 0x00ff0000) >> 8) |
  142. ((a & 0xff000000) >>24);
  143. }
  144. static inline uint32_t
  145. tor_ntohl(uint32_t a)
  146. {
  147. return tor_htonl(a);
  148. }
  149. /** Return a uint64_t value from <b>a</b> in network byte order. */
  150. static inline uint64_t
  151. tor_htonll(uint64_t a)
  152. {
  153. /* Little endian. The worst... */
  154. return tor_htonl((uint32_t)(a>>32)) |
  155. (((uint64_t)tor_htonl((uint32_t)a))<<32);
  156. }
  157. /** Return a uint64_t value from <b>a</b> in host byte order. */
  158. static inline uint64_t
  159. tor_ntohll(uint64_t a)
  160. {
  161. return tor_htonll(a);
  162. }
  163. #endif
  164. #endif