1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_BASE_BYTEORDER_H__ 29 #define TALK_BASE_BYTEORDER_H__ 30 31 #ifdef POSIX 32 #include <arpa/inet.h> 33 #endif 34 35 #ifdef WIN32 36 #include <winsock2.h> 37 #endif 38 39 #include "talk/base/basictypes.h" 40 41 namespace talk_base { 42 43 // Reading and writing of little and big-endian numbers from memory 44 // TODO: Add HostEndian #defines (HE) 45 // TODO: Consider NetworkEndian as synonym for BigEndian, for clarity in use. 46 // TODO: Consider creating optimized versions, such as direct read/writes of 47 // integers in host-endian format, when the platform supports it. 48 49 inline void Set8(void* memory, size_t offset, uint8 v) { 50 static_cast<uint8*>(memory)[offset] = v; 51 } 52 inline uint8 Get8(const void* memory, size_t offset) { 53 return static_cast<const uint8*>(memory)[offset]; 54 } 55 56 inline void SetBE16(void* memory, uint16 v) { 57 Set8(memory, 0, static_cast<uint8>(v >> 8)); 58 Set8(memory, 1, static_cast<uint8>(v >> 0)); 59 } 60 inline void SetBE32(void* memory, uint32 v) { 61 Set8(memory, 0, static_cast<uint8>(v >> 24)); 62 Set8(memory, 1, static_cast<uint8>(v >> 16)); 63 Set8(memory, 2, static_cast<uint8>(v >> 8)); 64 Set8(memory, 3, static_cast<uint8>(v >> 0)); 65 } 66 inline void SetBE64(void* memory, uint64 v) { 67 Set8(memory, 0, static_cast<uint8>(v >> 56)); 68 Set8(memory, 1, static_cast<uint8>(v >> 48)); 69 Set8(memory, 2, static_cast<uint8>(v >> 40)); 70 Set8(memory, 3, static_cast<uint8>(v >> 32)); 71 Set8(memory, 4, static_cast<uint8>(v >> 24)); 72 Set8(memory, 5, static_cast<uint8>(v >> 16)); 73 Set8(memory, 6, static_cast<uint8>(v >> 8)); 74 Set8(memory, 7, static_cast<uint8>(v >> 0)); 75 } 76 inline uint16 GetBE16(const void* memory) { 77 return (static_cast<uint16>(Get8(memory, 0)) << 8) 78 | (static_cast<uint16>(Get8(memory, 1)) << 0); 79 } 80 inline uint32 GetBE32(const void* memory) { 81 return (static_cast<uint32>(Get8(memory, 0)) << 24) 82 | (static_cast<uint32>(Get8(memory, 1)) << 16) 83 | (static_cast<uint32>(Get8(memory, 2)) << 8) 84 | (static_cast<uint32>(Get8(memory, 3)) << 0); 85 } 86 inline uint64 GetBE64(const void* memory) { 87 return (static_cast<uint64>(Get8(memory, 0)) << 56) 88 | (static_cast<uint64>(Get8(memory, 1)) << 48) 89 | (static_cast<uint64>(Get8(memory, 2)) << 40) 90 | (static_cast<uint64>(Get8(memory, 3)) << 32) 91 | (static_cast<uint64>(Get8(memory, 4)) << 24) 92 | (static_cast<uint64>(Get8(memory, 5)) << 16) 93 | (static_cast<uint64>(Get8(memory, 6)) << 8) 94 | (static_cast<uint64>(Get8(memory, 7)) << 0); 95 } 96 97 inline void SetLE16(void* memory, uint16 v) { 98 Set8(memory, 1, static_cast<uint8>(v >> 8)); 99 Set8(memory, 0, static_cast<uint8>(v >> 0)); 100 } 101 inline void SetLE32(void* memory, uint32 v) { 102 Set8(memory, 3, static_cast<uint8>(v >> 24)); 103 Set8(memory, 2, static_cast<uint8>(v >> 16)); 104 Set8(memory, 1, static_cast<uint8>(v >> 8)); 105 Set8(memory, 0, static_cast<uint8>(v >> 0)); 106 } 107 inline void SetLE64(void* memory, uint64 v) { 108 Set8(memory, 7, static_cast<uint8>(v >> 56)); 109 Set8(memory, 6, static_cast<uint8>(v >> 48)); 110 Set8(memory, 5, static_cast<uint8>(v >> 40)); 111 Set8(memory, 4, static_cast<uint8>(v >> 32)); 112 Set8(memory, 3, static_cast<uint8>(v >> 24)); 113 Set8(memory, 2, static_cast<uint8>(v >> 16)); 114 Set8(memory, 1, static_cast<uint8>(v >> 8)); 115 Set8(memory, 0, static_cast<uint8>(v >> 0)); 116 } 117 inline uint16 GetLE16(const void* memory) { 118 return (static_cast<uint16>(Get8(memory, 1)) << 8) 119 | (static_cast<uint16>(Get8(memory, 0)) << 0); 120 } 121 inline uint32 GetLE32(const void* memory) { 122 return (static_cast<uint32>(Get8(memory, 3)) << 24) 123 | (static_cast<uint32>(Get8(memory, 2)) << 16) 124 | (static_cast<uint32>(Get8(memory, 1)) << 8) 125 | (static_cast<uint32>(Get8(memory, 0)) << 0); 126 } 127 inline uint64 GetLE64(const void* memory) { 128 return (static_cast<uint64>(Get8(memory, 7)) << 56) 129 | (static_cast<uint64>(Get8(memory, 6)) << 48) 130 | (static_cast<uint64>(Get8(memory, 5)) << 40) 131 | (static_cast<uint64>(Get8(memory, 4)) << 32) 132 | (static_cast<uint64>(Get8(memory, 3)) << 24) 133 | (static_cast<uint64>(Get8(memory, 2)) << 16) 134 | (static_cast<uint64>(Get8(memory, 1)) << 8) 135 | (static_cast<uint64>(Get8(memory, 0)) << 0); 136 } 137 138 // Check if the current host is big endian. 139 inline bool IsHostBigEndian() { 140 static const int number = 1; 141 return (0 == *reinterpret_cast<const char*>(&number)); 142 } 143 144 inline uint16 HostToNetwork16(uint16 n) { 145 return htons(n); 146 } 147 148 inline uint32 HostToNetwork32(uint32 n) { 149 return htonl(n); 150 } 151 152 inline uint64 HostToNetwork64(uint64 n) { 153 // If the host is little endian, GetBE64 converts n to big network endian. 154 return IsHostBigEndian() ? n : GetBE64(&n); 155 } 156 157 inline uint16 NetworkToHost16(uint16 n) { 158 return ntohs(n); 159 } 160 161 inline uint32 NetworkToHost32(uint32 n) { 162 return ntohl(n); 163 } 164 165 inline uint64 NetworkToHost64(uint64 n) { 166 // If the host is little endian, GetBE64 converts n to little endian. 167 return IsHostBigEndian() ? n : GetBE64(&n); 168 } 169 170 } // namespace talk_base 171 172 #endif // TALK_BASE_BYTEORDER_H__ 173