Line data Source code
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 3668 : get_uint8(const void *cp) 24 : { 25 3668 : 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 2696 : set_uint8(void *cp, uint8_t v) 32 : { 33 2696 : *(uint8_t*)cp = v; 34 2696 : } 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 5228 : get_uint16(const void *cp) 43 : { 44 5228 : uint16_t v; 45 5228 : memcpy(&v,cp,2); 46 5228 : 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 1343910 : get_uint32(const void *cp) 55 : { 56 1343910 : uint32_t v; 57 1343910 : memcpy(&v,cp,4); 58 1343910 : 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 1139 : get_uint64(const void *cp) 67 : { 68 1139 : uint64_t v; 69 1139 : memcpy(&v,cp,8); 70 1139 : 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 4964 : set_uint16(void *cp, uint16_t v) 79 : { 80 4964 : memcpy(cp,&v,2); 81 4964 : } 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 75947 : set_uint32(void *cp, uint32_t v) 88 : { 89 75947 : memcpy(cp,&v,4); 90 75947 : } 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 27161 : set_uint64(void *cp, uint64_t v) 97 : { 98 27161 : memcpy(cp,&v,8); 99 27161 : } 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 4 : tor_htons(uint16_t a) 143 : { 144 : /* Our compilers will indeed recognize this as bswap. */ 145 4 : return 146 4 : ((a & 0x00ff) << 8) | 147 4 : ((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 4 : tor_ntohs(uint16_t a) 155 : { 156 4 : 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 57984 : tor_htonl(uint32_t a) 164 : { 165 : /* Our compilers will indeed recognize this as bswap. */ 166 57984 : return 167 57984 : ((a & 0x000000ff) <<24) | 168 57984 : ((a & 0x0000ff00) << 8) | 169 57984 : ((a & 0x00ff0000) >> 8) | 170 57984 : ((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 6 : tor_ntohl(uint32_t a) 178 : { 179 6 : 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 28909 : tor_htonll(uint64_t a) 185 : { 186 : /* Little endian. The worst... */ 187 28909 : return tor_htonl((uint32_t)(a>>32)) | 188 28909 : (((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 1141 : tor_ntohll(uint64_t a) 194 : { 195 1141 : return tor_htonll(a); 196 : } 197 : #endif /* defined(WORDS_BIGENDIAN) */ 198 : 199 : #endif /* !defined(TOR_BYTES_H) */