1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#ifndef GOOGLE_PROTOBUF_ENDIAN_H__
32#define GOOGLE_PROTOBUF_ENDIAN_H__
33
34#if defined(_MSC_VER)
35#include <stdlib.h>
36#endif
37
38#include <cstdint>
39
40// Must be included last.
41#include <google/protobuf/port_def.inc>
42
43namespace google {
44namespace protobuf {
45namespace internal {
46
47inline uint64_t BSwap64(uint64_t host_int) {
48#if defined(PROTOBUF_BUILTIN_BSWAP64)
49 return PROTOBUF_BUILTIN_BSWAP64(host_int);
50#elif defined(_MSC_VER)
51 return _byteswap_uint64(host_int);
52#else
53 return (((host_int & uint64_t{0xFF}) << 56) |
54 ((host_int & uint64_t{0xFF00}) << 40) |
55 ((host_int & uint64_t{0xFF0000}) << 24) |
56 ((host_int & uint64_t{0xFF000000}) << 8) |
57 ((host_int & uint64_t{0xFF00000000}) >> 8) |
58 ((host_int & uint64_t{0xFF0000000000}) >> 24) |
59 ((host_int & uint64_t{0xFF000000000000}) >> 40) |
60 ((host_int & uint64_t{0xFF00000000000000}) >> 56));
61#endif
62}
63
64inline uint32_t BSwap32(uint32_t host_int) {
65#if defined(PROTOBUF_BUILTIN_BSWAP32)
66 return PROTOBUF_BUILTIN_BSWAP32(host_int);
67#elif defined(_MSC_VER)
68 return _byteswap_ulong(host_int);
69#else
70 return (((host_int & uint32_t{0xFF}) << 24) |
71 ((host_int & uint32_t{0xFF00}) << 8) |
72 ((host_int & uint32_t{0xFF0000}) >> 8) |
73 ((host_int & uint32_t{0xFF000000}) >> 24));
74#endif
75}
76
77inline uint16_t BSwap16(uint16_t host_int) {
78#if defined(PROTOBUF_BUILTIN_BSWAP16)
79 return PROTOBUF_BUILTIN_BSWAP16(host_int);
80#elif defined(_MSC_VER)
81 return _byteswap_ushort(host_int);
82#else
83 return (((host_int & uint16_t{0xFF}) << 8) |
84 ((host_int & uint16_t{0xFF00}) >> 8));
85#endif
86}
87
88namespace little_endian {
89
90inline uint16_t FromHost(uint16_t value) {
91#if defined(PROTOBUF_BIG_ENDIAN)
92 return BSwap16(value);
93#else
94 return value;
95#endif
96}
97
98inline uint32_t FromHost(uint32_t value) {
99#if defined(PROTOBUF_BIG_ENDIAN)
100 return BSwap32(value);
101#else
102 return value;
103#endif
104}
105
106inline uint64_t FromHost(uint64_t value) {
107#if defined(PROTOBUF_BIG_ENDIAN)
108 return BSwap64(value);
109#else
110 return value;
111#endif
112}
113
114inline uint16_t ToHost(uint16_t value) {
115#if defined(PROTOBUF_BIG_ENDIAN)
116 return BSwap16(value);
117#else
118 return value;
119#endif
120}
121
122inline uint32_t ToHost(uint32_t value) {
123#if defined(PROTOBUF_BIG_ENDIAN)
124 return BSwap32(value);
125#else
126 return value;
127#endif
128}
129
130inline uint64_t ToHost(uint64_t value) {
131#if defined(PROTOBUF_BIG_ENDIAN)
132 return BSwap64(value);
133#else
134 return value;
135#endif
136}
137
138} // namespace little_endian
139
140namespace big_endian {
141
142inline uint16_t FromHost(uint16_t value) {
143#if defined(PROTOBUF_BIG_ENDIAN)
144 return value;
145#else
146 return BSwap16(host_int: value);
147#endif
148}
149
150inline uint32_t FromHost(uint32_t value) {
151#if defined(PROTOBUF_BIG_ENDIAN)
152 return value;
153#else
154 return BSwap32(host_int: value);
155#endif
156}
157
158inline uint64_t FromHost(uint64_t value) {
159#if defined(PROTOBUF_BIG_ENDIAN)
160 return value;
161#else
162 return BSwap64(host_int: value);
163#endif
164}
165
166inline uint16_t ToHost(uint16_t value) {
167#if defined(PROTOBUF_BIG_ENDIAN)
168 return value;
169#else
170 return BSwap16(host_int: value);
171#endif
172}
173
174inline uint32_t ToHost(uint32_t value) {
175#if defined(PROTOBUF_BIG_ENDIAN)
176 return value;
177#else
178 return BSwap32(host_int: value);
179#endif
180}
181
182inline uint64_t ToHost(uint64_t value) {
183#if defined(PROTOBUF_BIG_ENDIAN)
184 return value;
185#else
186 return BSwap64(host_int: value);
187#endif
188}
189
190} // namespace big_endian
191
192} // namespace internal
193} // namespace protobuf
194} // namespace google
195
196#include <google/protobuf/port_undef.inc>
197
198#endif // GOOGLE_PROTOBUF_ENDIAN_H__
199