• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Set8(void * memory,size_t offset,uint8 v)49 inline void Set8(void* memory, size_t offset, uint8 v) {
50   static_cast<uint8*>(memory)[offset] = v;
51 }
Get8(const void * memory,size_t offset)52 inline uint8 Get8(const void* memory, size_t offset) {
53   return static_cast<const uint8*>(memory)[offset];
54 }
55 
SetBE16(void * memory,uint16 v)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 }
SetBE32(void * memory,uint32 v)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 }
SetBE64(void * memory,uint64 v)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 }
GetBE16(const void * memory)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 }
GetBE32(const void * memory)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 }
GetBE64(const void * memory)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 
SetLE16(void * memory,uint16 v)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 }
SetLE32(void * memory,uint32 v)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 }
SetLE64(void * memory,uint64 v)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 }
GetLE16(const void * memory)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 }
GetLE32(const void * memory)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 }
GetLE64(const void * memory)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.
IsHostBigEndian()139 inline bool IsHostBigEndian() {
140   static const int number = 1;
141   return (0 == *reinterpret_cast<const char*>(&number));
142 }
143 
HostToNetwork16(uint16 n)144 inline uint16 HostToNetwork16(uint16 n) {
145   return htons(n);
146 }
147 
HostToNetwork32(uint32 n)148 inline uint32 HostToNetwork32(uint32 n) {
149   return htonl(n);
150 }
151 
HostToNetwork64(uint64 n)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 
NetworkToHost16(uint16 n)157 inline uint16 NetworkToHost16(uint16 n) {
158   return ntohs(n);
159 }
160 
NetworkToHost32(uint32 n)161 inline uint32 NetworkToHost32(uint32 n) {
162   return ntohl(n);
163 }
164 
NetworkToHost64(uint64 n)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