1 /* 2 * libjingle 3 * Copyright 2004 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 #if defined(POSIX) && !defined(__native_client__) 32 #include <arpa/inet.h> 33 #endif 34 35 #ifdef WIN32 36 #include <stdlib.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: Optimized versions, with direct read/writes of 45 // integers in host-endian format, when the platform supports it. 46 47 inline void Set8(void* memory, size_t offset, uint8 v) { 48 static_cast<uint8*>(memory)[offset] = v; 49 } 50 51 inline uint8 Get8(const void* memory, size_t offset) { 52 return static_cast<const uint8*>(memory)[offset]; 53 } 54 55 inline void SetBE16(void* memory, uint16 v) { 56 Set8(memory, 0, static_cast<uint8>(v >> 8)); 57 Set8(memory, 1, static_cast<uint8>(v >> 0)); 58 } 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 67 inline void SetBE64(void* memory, uint64 v) { 68 Set8(memory, 0, static_cast<uint8>(v >> 56)); 69 Set8(memory, 1, static_cast<uint8>(v >> 48)); 70 Set8(memory, 2, static_cast<uint8>(v >> 40)); 71 Set8(memory, 3, static_cast<uint8>(v >> 32)); 72 Set8(memory, 4, static_cast<uint8>(v >> 24)); 73 Set8(memory, 5, static_cast<uint8>(v >> 16)); 74 Set8(memory, 6, static_cast<uint8>(v >> 8)); 75 Set8(memory, 7, static_cast<uint8>(v >> 0)); 76 } 77 78 inline uint16 GetBE16(const void* memory) { 79 return static_cast<uint16>((Get8(memory, 0) << 8) | 80 (Get8(memory, 1) << 0)); 81 } 82 83 inline uint32 GetBE32(const void* memory) { 84 return (static_cast<uint32>(Get8(memory, 0)) << 24) | 85 (static_cast<uint32>(Get8(memory, 1)) << 16) | 86 (static_cast<uint32>(Get8(memory, 2)) << 8) | 87 (static_cast<uint32>(Get8(memory, 3)) << 0); 88 } 89 90 inline uint64 GetBE64(const void* memory) { 91 return (static_cast<uint64>(Get8(memory, 0)) << 56) | 92 (static_cast<uint64>(Get8(memory, 1)) << 48) | 93 (static_cast<uint64>(Get8(memory, 2)) << 40) | 94 (static_cast<uint64>(Get8(memory, 3)) << 32) | 95 (static_cast<uint64>(Get8(memory, 4)) << 24) | 96 (static_cast<uint64>(Get8(memory, 5)) << 16) | 97 (static_cast<uint64>(Get8(memory, 6)) << 8) | 98 (static_cast<uint64>(Get8(memory, 7)) << 0); 99 } 100 101 inline void SetLE16(void* memory, uint16 v) { 102 Set8(memory, 0, static_cast<uint8>(v >> 0)); 103 Set8(memory, 1, static_cast<uint8>(v >> 8)); 104 } 105 106 inline void SetLE32(void* memory, uint32 v) { 107 Set8(memory, 0, static_cast<uint8>(v >> 0)); 108 Set8(memory, 1, static_cast<uint8>(v >> 8)); 109 Set8(memory, 2, static_cast<uint8>(v >> 16)); 110 Set8(memory, 3, static_cast<uint8>(v >> 24)); 111 } 112 113 inline void SetLE64(void* memory, uint64 v) { 114 Set8(memory, 0, static_cast<uint8>(v >> 0)); 115 Set8(memory, 1, static_cast<uint8>(v >> 8)); 116 Set8(memory, 2, static_cast<uint8>(v >> 16)); 117 Set8(memory, 3, static_cast<uint8>(v >> 24)); 118 Set8(memory, 4, static_cast<uint8>(v >> 32)); 119 Set8(memory, 5, static_cast<uint8>(v >> 40)); 120 Set8(memory, 6, static_cast<uint8>(v >> 48)); 121 Set8(memory, 7, static_cast<uint8>(v >> 56)); 122 } 123 124 inline uint16 GetLE16(const void* memory) { 125 return static_cast<uint16>((Get8(memory, 0) << 0) | 126 (Get8(memory, 1) << 8)); 127 } 128 129 inline uint32 GetLE32(const void* memory) { 130 return (static_cast<uint32>(Get8(memory, 0)) << 0) | 131 (static_cast<uint32>(Get8(memory, 1)) << 8) | 132 (static_cast<uint32>(Get8(memory, 2)) << 16) | 133 (static_cast<uint32>(Get8(memory, 3)) << 24); 134 } 135 136 inline uint64 GetLE64(const void* memory) { 137 return (static_cast<uint64>(Get8(memory, 0)) << 0) | 138 (static_cast<uint64>(Get8(memory, 1)) << 8) | 139 (static_cast<uint64>(Get8(memory, 2)) << 16) | 140 (static_cast<uint64>(Get8(memory, 3)) << 24) | 141 (static_cast<uint64>(Get8(memory, 4)) << 32) | 142 (static_cast<uint64>(Get8(memory, 5)) << 40) | 143 (static_cast<uint64>(Get8(memory, 6)) << 48) | 144 (static_cast<uint64>(Get8(memory, 7)) << 56); 145 } 146 147 // Check if the current host is big endian. 148 inline bool IsHostBigEndian() { 149 static const int number = 1; 150 return 0 == *reinterpret_cast<const char*>(&number); 151 } 152 153 inline uint16 HostToNetwork16(uint16 n) { 154 uint16 result; 155 SetBE16(&result, n); 156 return result; 157 } 158 159 inline uint32 HostToNetwork32(uint32 n) { 160 uint32 result; 161 SetBE32(&result, n); 162 return result; 163 } 164 165 inline uint64 HostToNetwork64(uint64 n) { 166 uint64 result; 167 SetBE64(&result, n); 168 return result; 169 } 170 171 inline uint16 NetworkToHost16(uint16 n) { 172 return GetBE16(&n); 173 } 174 175 inline uint32 NetworkToHost32(uint32 n) { 176 return GetBE32(&n); 177 } 178 179 inline uint64 NetworkToHost64(uint64 n) { 180 return GetBE64(&n); 181 } 182 183 } // namespace talk_base 184 185 #endif // TALK_BASE_BYTEORDER_H_ 186