You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

port.h 16 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  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. #ifndef GOOGLE_PROTOBUF_STUBS_PORT_H_
  31. #define GOOGLE_PROTOBUF_STUBS_PORT_H_
  32. #include <assert.h>
  33. #include <cstdint>
  34. #include <stdlib.h>
  35. #include <cstddef>
  36. #include <string>
  37. #include <string.h>
  38. #include <google/protobuf/stubs/platform_macros.h>
  39. #include <google/protobuf/port_def.inc>
  40. #undef PROTOBUF_LITTLE_ENDIAN
  41. #ifdef _WIN32
  42. // Assuming windows is always little-endian.
  43. // TODO(xiaofeng): The PROTOBUF_LITTLE_ENDIAN is not only used for
  44. // optimization but also for correctness. We should define an
  45. // different macro to test the big-endian code path in coded_stream.
  46. #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
  47. #define PROTOBUF_LITTLE_ENDIAN 1
  48. #endif
  49. #if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
  50. // If MSVC has "/RTCc" set, it will complain about truncating casts at
  51. // runtime. This file contains some intentional truncating casts.
  52. #pragma runtime_checks("c", off)
  53. #endif
  54. #else
  55. #ifdef __APPLE__
  56. #include <machine/endian.h> // __BYTE_ORDER
  57. #elif defined(__FreeBSD__)
  58. #include <sys/endian.h> // __BYTE_ORDER
  59. #elif (defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__))
  60. #include <sys/isa_defs.h> // __BYTE_ORDER
  61. #elif defined(_AIX) || defined(__TOS_AIX__)
  62. #include <sys/machine.h> // BYTE_ORDER
  63. #else
  64. #if !defined(__QNX__)
  65. #include <endian.h> // __BYTE_ORDER
  66. #endif
  67. #endif
  68. #if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN)) && \
  69. !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
  70. #define PROTOBUF_LITTLE_ENDIAN 1
  71. #endif
  72. #endif
  73. // These #includes are for the byte swap functions declared later on.
  74. #ifdef _MSC_VER
  75. #include <stdlib.h> // NOLINT(build/include)
  76. #include <intrin.h>
  77. #elif defined(__APPLE__)
  78. #include <libkern/OSByteOrder.h>
  79. #elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__)
  80. #include <byteswap.h> // IWYU pragma: export
  81. #endif
  82. // Legacy: some users reference these (internal-only) macros even though we
  83. // don't need them any more.
  84. #if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS)
  85. #ifdef LIBPROTOBUF_EXPORTS
  86. #define LIBPROTOBUF_EXPORT __declspec(dllexport)
  87. #else
  88. #define LIBPROTOBUF_EXPORT __declspec(dllimport)
  89. #endif
  90. #ifdef LIBPROTOC_EXPORTS
  91. #define LIBPROTOC_EXPORT __declspec(dllexport)
  92. #else
  93. #define LIBPROTOC_EXPORT __declspec(dllimport)
  94. #endif
  95. #else
  96. #define LIBPROTOBUF_EXPORT
  97. #define LIBPROTOC_EXPORT
  98. #endif
  99. #define PROTOBUF_RUNTIME_DEPRECATED(message) PROTOBUF_DEPRECATED_MSG(message)
  100. #define GOOGLE_PROTOBUF_RUNTIME_DEPRECATED(message) \
  101. PROTOBUF_DEPRECATED_MSG(message)
  102. // ===================================================================
  103. // from google3/base/port.h
  104. #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
  105. // Define this to 1 if the code is compiled in C++11 mode; leave it
  106. // undefined otherwise. Do NOT define it to 0 -- that causes
  107. // '#ifdef LANG_CXX11' to behave differently from '#if LANG_CXX11'.
  108. #define LANG_CXX11 1
  109. #else
  110. #error "Protobuf requires at least C++11."
  111. #endif
  112. namespace google
  113. {
  114. namespace protobuf
  115. {
  116. using ConstStringParam = const std::string&;
  117. typedef unsigned int uint;
  118. typedef int8_t int8;
  119. typedef int16_t int16;
  120. typedef int32_t int32;
  121. typedef int64_t int64;
  122. typedef uint8_t uint8;
  123. typedef uint16_t uint16;
  124. typedef uint32_t uint32;
  125. typedef uint64_t uint64;
  126. static const int32 kint32max = 0x7FFFFFFF;
  127. static const int32 kint32min = -kint32max - 1;
  128. static const int64 kint64max = int64_t{0x7FFFFFFFFFFFFFFF};
  129. static const int64 kint64min = -kint64max - 1;
  130. static const uint32 kuint32max = 0xFFFFFFFFu;
  131. static const uint64 kuint64max = uint64_t{0xFFFFFFFFFFFFFFFFu};
  132. #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
  133. defined(MEMORY_SANITIZER)
  134. #ifdef __cplusplus
  135. extern "C"
  136. {
  137. #endif // __cplusplus
  138. uint16_t __sanitizer_unaligned_load16(const void* p);
  139. uint32_t __sanitizer_unaligned_load32(const void* p);
  140. uint64_t __sanitizer_unaligned_load64(const void* p);
  141. void __sanitizer_unaligned_store16(void* p, uint16_t v);
  142. void __sanitizer_unaligned_store32(void* p, uint32_t v);
  143. void __sanitizer_unaligned_store64(void* p, uint64_t v);
  144. #ifdef __cplusplus
  145. } // extern "C"
  146. #endif // __cplusplus
  147. inline uint16_t GOOGLE_UNALIGNED_LOAD16(const void* p)
  148. {
  149. return __sanitizer_unaligned_load16(p);
  150. }
  151. inline uint32_t GOOGLE_UNALIGNED_LOAD32(const void* p)
  152. {
  153. return __sanitizer_unaligned_load32(p);
  154. }
  155. inline uint64_t GOOGLE_UNALIGNED_LOAD64(const void* p)
  156. {
  157. return __sanitizer_unaligned_load64(p);
  158. }
  159. inline void GOOGLE_UNALIGNED_STORE16(void* p, uint16_t v)
  160. {
  161. __sanitizer_unaligned_store16(p, v);
  162. }
  163. inline void GOOGLE_UNALIGNED_STORE32(void* p, uint32_t v)
  164. {
  165. __sanitizer_unaligned_store32(p, v);
  166. }
  167. inline void GOOGLE_UNALIGNED_STORE64(void* p, uint64_t v)
  168. {
  169. __sanitizer_unaligned_store64(p, v);
  170. }
  171. #elif defined(GOOGLE_PROTOBUF_USE_UNALIGNED) && GOOGLE_PROTOBUF_USE_UNALIGNED
  172. #define GOOGLE_UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16_t*>(_p))
  173. #define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32_t*>(_p))
  174. #define GOOGLE_UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64_t*>(_p))
  175. #define GOOGLE_UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16_t*>(_p) = (_val))
  176. #define GOOGLE_UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32_t*>(_p) = (_val))
  177. #define GOOGLE_UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64_t*>(_p) = (_val))
  178. #else
  179. inline uint16_t GOOGLE_UNALIGNED_LOAD16(const void* p)
  180. {
  181. uint16_t t;
  182. memcpy(&t, p, sizeof t);
  183. return t;
  184. }
  185. inline uint32_t GOOGLE_UNALIGNED_LOAD32(const void* p)
  186. {
  187. uint32_t t;
  188. memcpy(&t, p, sizeof t);
  189. return t;
  190. }
  191. inline uint64_t GOOGLE_UNALIGNED_LOAD64(const void* p)
  192. {
  193. uint64_t t;
  194. memcpy(&t, p, sizeof t);
  195. return t;
  196. }
  197. inline void GOOGLE_UNALIGNED_STORE16(void* p, uint16_t v)
  198. {
  199. memcpy(p, &v, sizeof v);
  200. }
  201. inline void GOOGLE_UNALIGNED_STORE32(void* p, uint32_t v)
  202. {
  203. memcpy(p, &v, sizeof v);
  204. }
  205. inline void GOOGLE_UNALIGNED_STORE64(void* p, uint64_t v)
  206. {
  207. memcpy(p, &v, sizeof v);
  208. }
  209. #endif
  210. #if defined(GOOGLE_PROTOBUF_OS_NACL) || (defined(__ANDROID__) && defined(__clang__) && (__clang_major__ == 3 && __clang_minor__ == 8) && (__clang_patchlevel__ < 275480))
  211. #define GOOGLE_PROTOBUF_USE_PORTABLE_LOG2
  212. #endif
  213. // The following guarantees declaration of the byte swap functions.
  214. #ifdef _MSC_VER
  215. #define bswap_16(x) _byteswap_ushort(x)
  216. #define bswap_32(x) _byteswap_ulong(x)
  217. #define bswap_64(x) _byteswap_uint64(x)
  218. #elif defined(__APPLE__)
  219. // Mac OS X / Darwin features
  220. #define bswap_16(x) OSSwapInt16(x)
  221. #define bswap_32(x) OSSwapInt32(x)
  222. #define bswap_64(x) OSSwapInt64(x)
  223. #elif !defined(__linux__) && !defined(__ANDROID__) && !defined(__CYGWIN__)
  224. #ifndef bswap_16
  225. static inline uint16_t bswap_16(uint16_t x)
  226. {
  227. return static_cast<uint16_t>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8));
  228. }
  229. #define bswap_16(x) bswap_16(x)
  230. #endif
  231. #ifndef bswap_32
  232. static inline uint32_t bswap_32(uint32_t x)
  233. {
  234. return (((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24));
  235. }
  236. #define bswap_32(x) bswap_32(x)
  237. #endif
  238. #ifndef bswap_64
  239. static inline uint64_t bswap_64(uint64_t x)
  240. {
  241. return (((x & uint64_t{0xFFu}) << 56) | ((x & uint64_t{0xFF00u}) << 40) | ((x & uint64_t{0xFF0000u}) << 24) | ((x & uint64_t{0xFF000000u}) << 8) | ((x & uint64_t{0xFF00000000u}) >> 8) | ((x & uint64_t{0xFF0000000000u}) >> 24) | ((x & uint64_t{0xFF000000000000u}) >> 40) | ((x & uint64_t{0xFF00000000000000u}) >> 56));
  242. }
  243. #define bswap_64(x) bswap_64(x)
  244. #endif
  245. #endif
  246. // ===================================================================
  247. // from google3/util/bits/bits.h
  248. class Bits
  249. {
  250. public:
  251. static uint32_t Log2FloorNonZero(uint32_t n)
  252. {
  253. #if defined(__GNUC__)
  254. return 31 ^ static_cast<uint32_t>(__builtin_clz(n));
  255. #elif defined(_MSC_VER)
  256. unsigned long where;
  257. _BitScanReverse(&where, n);
  258. return where;
  259. #else
  260. return Log2FloorNonZero_Portable(n);
  261. #endif
  262. }
  263. static uint32_t Log2FloorNonZero64(uint64_t n)
  264. {
  265. // Older versions of clang run into an instruction-selection failure when
  266. // it encounters __builtin_clzll:
  267. // https://bugs.chromium.org/p/nativeclient/issues/detail?id=4395
  268. // This includes arm-nacl-clang and clang in older Android NDK versions.
  269. // To work around this, when we build with those we use the portable
  270. // implementation instead.
  271. #if defined(__GNUC__) && !defined(GOOGLE_PROTOBUF_USE_PORTABLE_LOG2)
  272. return 63 ^ static_cast<uint32_t>(__builtin_clzll(n));
  273. #elif defined(_MSC_VER) && defined(_M_X64)
  274. unsigned long where;
  275. _BitScanReverse64(&where, n);
  276. return where;
  277. #else
  278. return Log2FloorNonZero64_Portable(n);
  279. #endif
  280. }
  281. private:
  282. static int Log2FloorNonZero_Portable(uint32_t n)
  283. {
  284. if (n == 0)
  285. return -1;
  286. int log = 0;
  287. uint32_t value = n;
  288. for (int i = 4; i >= 0; --i)
  289. {
  290. int shift = (1 << i);
  291. uint32_t x = value >> shift;
  292. if (x != 0)
  293. {
  294. value = x;
  295. log += shift;
  296. }
  297. }
  298. assert(value == 1);
  299. return log;
  300. }
  301. static int Log2FloorNonZero64_Portable(uint64_t n)
  302. {
  303. const uint32_t topbits = static_cast<uint32_t>(n >> 32);
  304. if (topbits == 0)
  305. {
  306. // Top bits are zero, so scan in bottom bits
  307. return static_cast<int>(Log2FloorNonZero(static_cast<uint32_t>(n)));
  308. }
  309. else
  310. {
  311. return 32 + static_cast<int>(Log2FloorNonZero(topbits));
  312. }
  313. }
  314. };
  315. // ===================================================================
  316. // from google3/util/endian/endian.h
  317. PROTOBUF_EXPORT uint32_t ghtonl(uint32_t x);
  318. class BigEndian
  319. {
  320. public:
  321. #ifdef PROTOBUF_LITTLE_ENDIAN
  322. static uint16_t FromHost16(uint16_t x)
  323. {
  324. return bswap_16(x);
  325. }
  326. static uint16_t ToHost16(uint16_t x)
  327. {
  328. return bswap_16(x);
  329. }
  330. static uint32_t FromHost32(uint32_t x)
  331. {
  332. return bswap_32(x);
  333. }
  334. static uint32_t ToHost32(uint32_t x)
  335. {
  336. return bswap_32(x);
  337. }
  338. static uint64_t FromHost64(uint64_t x)
  339. {
  340. return bswap_64(x);
  341. }
  342. static uint64_t ToHost64(uint64_t x)
  343. {
  344. return bswap_64(x);
  345. }
  346. static bool IsLittleEndian()
  347. {
  348. return true;
  349. }
  350. #else
  351. static uint16_t FromHost16(uint16_t x)
  352. {
  353. return x;
  354. }
  355. static uint16_t ToHost16(uint16_t x)
  356. {
  357. return x;
  358. }
  359. static uint32_t FromHost32(uint32_t x)
  360. {
  361. return x;
  362. }
  363. static uint32_t ToHost32(uint32_t x)
  364. {
  365. return x;
  366. }
  367. static uint64_t FromHost64(uint64_t x)
  368. {
  369. return x;
  370. }
  371. static uint64_t ToHost64(uint64_t x)
  372. {
  373. return x;
  374. }
  375. static bool IsLittleEndian()
  376. {
  377. return false;
  378. }
  379. #endif /* ENDIAN */
  380. // Functions to do unaligned loads and stores in big-endian order.
  381. static uint16_t Load16(const void* p)
  382. {
  383. return ToHost16(GOOGLE_UNALIGNED_LOAD16(p));
  384. }
  385. static void Store16(void* p, uint16_t v)
  386. {
  387. GOOGLE_UNALIGNED_STORE16(p, FromHost16(v));
  388. }
  389. static uint32_t Load32(const void* p)
  390. {
  391. return ToHost32(GOOGLE_UNALIGNED_LOAD32(p));
  392. }
  393. static void Store32(void* p, uint32_t v)
  394. {
  395. GOOGLE_UNALIGNED_STORE32(p, FromHost32(v));
  396. }
  397. static uint64_t Load64(const void* p)
  398. {
  399. return ToHost64(GOOGLE_UNALIGNED_LOAD64(p));
  400. }
  401. static void Store64(void* p, uint64_t v)
  402. {
  403. GOOGLE_UNALIGNED_STORE64(p, FromHost64(v));
  404. }
  405. };
  406. } // namespace protobuf
  407. } // namespace google
  408. #include <google/protobuf/port_undef.inc>
  409. #endif // GOOGLE_PROTOBUF_STUBS_PORT_H_