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