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