Line data Source code
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_STUBS_PORT_H_
32 : #define GOOGLE_PROTOBUF_STUBS_PORT_H_
33 :
34 : #include <assert.h>
35 : #include <stdlib.h>
36 : #include <cstddef>
37 : #include <string>
38 : #include <string.h>
39 : #if defined(__osf__)
40 : // Tru64 lacks stdint.h, but has inttypes.h which defines a superset of
41 : // what stdint.h would define.
42 : #include <inttypes.h>
43 : #elif !defined(_MSC_VER)
44 : #include <stdint.h>
45 : #endif
46 :
47 : #undef PROTOBUF_LITTLE_ENDIAN
48 : #ifdef _WIN32
49 : // Assuming windows is always little-endian.
50 : // TODO(xiaofeng): The PROTOBUF_LITTLE_ENDIAN is not only used for
51 : // optimization but also for correctness. We should define an
52 : // different macro to test the big-endian code path in coded_stream.
53 : #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
54 : #define PROTOBUF_LITTLE_ENDIAN 1
55 : #endif
56 : #if defined(_MSC_VER) && _MSC_VER >= 1300
57 : // If MSVC has "/RTCc" set, it will complain about truncating casts at
58 : // runtime. This file contains some intentional truncating casts.
59 : #pragma runtime_checks("c", off)
60 : #endif
61 : #else
62 : #include <sys/param.h> // __BYTE_ORDER
63 : #if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \
64 : (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN)) && \
65 : !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
66 : #define PROTOBUF_LITTLE_ENDIAN 1
67 : #endif
68 : #endif
69 : #if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS)
70 : #ifdef LIBPROTOBUF_EXPORTS
71 : #define LIBPROTOBUF_EXPORT __declspec(dllexport)
72 : #else
73 : #define LIBPROTOBUF_EXPORT __declspec(dllimport)
74 : #endif
75 : #ifdef LIBPROTOC_EXPORTS
76 : #define LIBPROTOC_EXPORT __declspec(dllexport)
77 : #else
78 : #define LIBPROTOC_EXPORT __declspec(dllimport)
79 : #endif
80 : #else
81 : #define LIBPROTOBUF_EXPORT
82 : #define LIBPROTOC_EXPORT
83 : #endif
84 :
85 : // ===================================================================
86 : // from google3/base/port.h
87 : namespace google {
88 : namespace protobuf {
89 :
90 : typedef unsigned int uint;
91 :
92 : #ifdef _MSC_VER
93 : typedef signed __int8 int8;
94 : typedef __int16 int16;
95 : typedef __int32 int32;
96 : typedef __int64 int64;
97 :
98 : typedef unsigned __int8 uint8;
99 : typedef unsigned __int16 uint16;
100 : typedef unsigned __int32 uint32;
101 : typedef unsigned __int64 uint64;
102 : #else
103 : typedef signed char int8;
104 : typedef short int16;
105 : typedef int int32;
106 : typedef long long int64;
107 :
108 : typedef unsigned char uint8;
109 : typedef unsigned short uint16;
110 : typedef unsigned int uint32;
111 : typedef unsigned long long uint64;
112 : #endif
113 :
114 : // long long macros to be used because gcc and vc++ use different suffixes,
115 : // and different size specifiers in format strings
116 : #undef GOOGLE_LONGLONG
117 : #undef GOOGLE_ULONGLONG
118 : #undef GOOGLE_LL_FORMAT
119 :
120 : #ifdef _MSC_VER
121 : #define GOOGLE_LONGLONG(x) x##I64
122 : #define GOOGLE_ULONGLONG(x) x##UI64
123 : #define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...)
124 : #else
125 : #define GOOGLE_LONGLONG(x) x##LL
126 : #define GOOGLE_ULONGLONG(x) x##ULL
127 : #define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also.
128 : #endif
129 :
130 : static const int32 kint32max = 0x7FFFFFFF;
131 : static const int32 kint32min = -kint32max - 1;
132 : static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF);
133 : static const int64 kint64min = -kint64max - 1;
134 : static const uint32 kuint32max = 0xFFFFFFFFu;
135 : static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
136 :
137 : // -------------------------------------------------------------------
138 : // Annotations: Some parts of the code have been annotated in ways that might
139 : // be useful to some compilers or tools, but are not supported universally.
140 : // You can #define these annotations yourself if the default implementation
141 : // is not right for you.
142 :
143 : #ifndef GOOGLE_ATTRIBUTE_ALWAYS_INLINE
144 : #if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
145 : // For functions we want to force inline.
146 : // Introduced in gcc 3.1.
147 : #define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline))
148 : #else
149 : // Other compilers will have to figure it out for themselves.
150 : #define GOOGLE_ATTRIBUTE_ALWAYS_INLINE
151 : #endif
152 : #endif
153 :
154 : #ifndef GOOGLE_ATTRIBUTE_NOINLINE
155 : #if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
156 : // For functions we want to force not inline.
157 : // Introduced in gcc 3.1.
158 : #define GOOGLE_ATTRIBUTE_NOINLINE __attribute__ ((noinline))
159 : #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
160 : // Seems to have been around since at least Visual Studio 2005
161 : #define GOOGLE_ATTRIBUTE_NOINLINE __declspec(noinline)
162 : #else
163 : // Other compilers will have to figure it out for themselves.
164 : #define GOOGLE_ATTRIBUTE_NOINLINE
165 : #endif
166 : #endif
167 :
168 : #ifndef GOOGLE_ATTRIBUTE_DEPRECATED
169 : #ifdef __GNUC__
170 : // If the method/variable/type is used anywhere, produce a warning.
171 : #define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated))
172 : #else
173 : #define GOOGLE_ATTRIBUTE_DEPRECATED
174 : #endif
175 : #endif
176 :
177 : #ifndef GOOGLE_PREDICT_TRUE
178 : #ifdef __GNUC__
179 : // Provided at least since GCC 3.0.
180 : #define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
181 : #else
182 : #define GOOGLE_PREDICT_TRUE
183 : #endif
184 : #endif
185 :
186 : #ifndef GOOGLE_PREDICT_FALSE
187 : #ifdef __GNUC__
188 : // Provided at least since GCC 3.0.
189 : #define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
190 : #else
191 : #define GOOGLE_PREDICT_FALSE
192 : #endif
193 : #endif
194 :
195 : // Delimits a block of code which may write to memory which is simultaneously
196 : // written by other threads, but which has been determined to be thread-safe
197 : // (e.g. because it is an idempotent write).
198 : #ifndef GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN
199 : #define GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN()
200 : #endif
201 : #ifndef GOOGLE_SAFE_CONCURRENT_WRITES_END
202 : #define GOOGLE_SAFE_CONCURRENT_WRITES_END()
203 : #endif
204 :
205 : #if defined(__clang__) && defined(__has_cpp_attribute) \
206 : && !defined(GOOGLE_PROTOBUF_OS_APPLE)
207 : # if defined(GOOGLE_PROTOBUF_OS_NACL) || defined(EMSCRIPTEN) || \
208 : __has_cpp_attribute(clang::fallthrough)
209 : # define GOOGLE_FALLTHROUGH_INTENDED [[clang::fallthrough]]
210 : # endif
211 : #endif
212 :
213 : #ifndef GOOGLE_FALLTHROUGH_INTENDED
214 : # define GOOGLE_FALLTHROUGH_INTENDED
215 : #endif
216 :
217 : #define GOOGLE_GUARDED_BY(x)
218 : #define GOOGLE_ATTRIBUTE_COLD
219 :
220 : // x86 and x86-64 can perform unaligned loads/stores directly.
221 : #if defined(_M_X64) || defined(__x86_64__) || \
222 : defined(_M_IX86) || defined(__i386__)
223 :
224 : #define GOOGLE_UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))
225 : #define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
226 : #define GOOGLE_UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64 *>(_p))
227 :
228 : #define GOOGLE_UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val))
229 : #define GOOGLE_UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val))
230 : #define GOOGLE_UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64 *>(_p) = (_val))
231 :
232 : #else
233 : inline uint16 GOOGLE_UNALIGNED_LOAD16(const void *p) {
234 : uint16 t;
235 : memcpy(&t, p, sizeof t);
236 : return t;
237 : }
238 :
239 : inline uint32 GOOGLE_UNALIGNED_LOAD32(const void *p) {
240 : uint32 t;
241 : memcpy(&t, p, sizeof t);
242 : return t;
243 : }
244 :
245 : inline uint64 GOOGLE_UNALIGNED_LOAD64(const void *p) {
246 : uint64 t;
247 : memcpy(&t, p, sizeof t);
248 : return t;
249 : }
250 :
251 : inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16 v) {
252 : memcpy(p, &v, sizeof v);
253 : }
254 :
255 : inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32 v) {
256 : memcpy(p, &v, sizeof v);
257 : }
258 :
259 : inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) {
260 : memcpy(p, &v, sizeof v);
261 : }
262 : #endif
263 :
264 : #if defined(_MSC_VER)
265 : #define GOOGLE_THREAD_LOCAL __declspec(thread)
266 : #else
267 : #define GOOGLE_THREAD_LOCAL __thread
268 : #endif
269 :
270 : // The following guarantees declaration of the byte swap functions, and
271 : // defines __BYTE_ORDER for MSVC
272 : #ifdef _MSC_VER
273 : #include <stdlib.h> // NOLINT(build/include)
274 : #define __BYTE_ORDER __LITTLE_ENDIAN
275 : #define bswap_16(x) _byteswap_ushort(x)
276 : #define bswap_32(x) _byteswap_ulong(x)
277 : #define bswap_64(x) _byteswap_uint64(x)
278 :
279 : #elif defined(__APPLE__)
280 : // Mac OS X / Darwin features
281 : #include <libkern/OSByteOrder.h>
282 : #define bswap_16(x) OSSwapInt16(x)
283 : #define bswap_32(x) OSSwapInt32(x)
284 : #define bswap_64(x) OSSwapInt64(x)
285 :
286 : #elif defined(__GLIBC__) || defined(__CYGWIN__)
287 : #include <byteswap.h> // IWYU pragma: export
288 :
289 : #else
290 :
291 : static inline uint16 bswap_16(uint16 x) {
292 : return static_cast<uint16>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8));
293 : }
294 : #define bswap_16(x) bswap_16(x)
295 : static inline uint32 bswap_32(uint32 x) {
296 : return (((x & 0xFF) << 24) |
297 : ((x & 0xFF00) << 8) |
298 : ((x & 0xFF0000) >> 8) |
299 : ((x & 0xFF000000) >> 24));
300 : }
301 : #define bswap_32(x) bswap_32(x)
302 : static inline uint64 bswap_64(uint64 x) {
303 : return (((x & GOOGLE_ULONGLONG(0xFF)) << 56) |
304 : ((x & GOOGLE_ULONGLONG(0xFF00)) << 40) |
305 : ((x & GOOGLE_ULONGLONG(0xFF0000)) << 24) |
306 : ((x & GOOGLE_ULONGLONG(0xFF000000)) << 8) |
307 : ((x & GOOGLE_ULONGLONG(0xFF00000000)) >> 8) |
308 : ((x & GOOGLE_ULONGLONG(0xFF0000000000)) >> 24) |
309 : ((x & GOOGLE_ULONGLONG(0xFF000000000000)) >> 40) |
310 : ((x & GOOGLE_ULONGLONG(0xFF00000000000000)) >> 56));
311 : }
312 : #define bswap_64(x) bswap_64(x)
313 :
314 : #endif
315 :
316 : // ===================================================================
317 : // from google3/util/endian/endian.h
318 : LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x);
319 :
320 : class BigEndian {
321 : public:
322 : #ifdef PROTOBUF_LITTLE_ENDIAN
323 :
324 : static uint16 FromHost16(uint16 x) { return bswap_16(x); }
325 0 : static uint16 ToHost16(uint16 x) { return bswap_16(x); }
326 :
327 : static uint32 FromHost32(uint32 x) { return bswap_32(x); }
328 : static uint32 ToHost32(uint32 x) { return bswap_32(x); }
329 :
330 : static uint64 FromHost64(uint64 x) { return bswap_64(x); }
331 : static uint64 ToHost64(uint64 x) { return bswap_64(x); }
332 :
333 : static bool IsLittleEndian() { return true; }
334 :
335 : #else
336 :
337 : static uint16 FromHost16(uint16 x) { return x; }
338 : static uint16 ToHost16(uint16 x) { return x; }
339 :
340 : static uint32 FromHost32(uint32 x) { return x; }
341 : static uint32 ToHost32(uint32 x) { return x; }
342 :
343 : static uint64 FromHost64(uint64 x) { return x; }
344 : static uint64 ToHost64(uint64 x) { return x; }
345 :
346 : static bool IsLittleEndian() { return false; }
347 :
348 : #endif /* ENDIAN */
349 :
350 : // Functions to do unaligned loads and stores in big-endian order.
351 : static uint16 Load16(const void *p) {
352 0 : return ToHost16(GOOGLE_UNALIGNED_LOAD16(p));
353 : }
354 :
355 : static void Store16(void *p, uint16 v) {
356 : GOOGLE_UNALIGNED_STORE16(p, FromHost16(v));
357 : }
358 :
359 : static uint32 Load32(const void *p) {
360 0 : return ToHost32(GOOGLE_UNALIGNED_LOAD32(p));
361 : }
362 :
363 : static void Store32(void *p, uint32 v) {
364 : GOOGLE_UNALIGNED_STORE32(p, FromHost32(v));
365 : }
366 :
367 : static uint64 Load64(const void *p) {
368 : return ToHost64(GOOGLE_UNALIGNED_LOAD64(p));
369 : }
370 :
371 : static void Store64(void *p, uint64 v) {
372 : GOOGLE_UNALIGNED_STORE64(p, FromHost64(v));
373 : }
374 : };
375 :
376 :
377 : } // namespace protobuf
378 : } // namespace google
379 :
380 : #endif // GOOGLE_PROTOBUF_STUBS_PORT_H_
|