SwapByteOrder.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file declares generic and optimized functions to swap the byte order of
  15. // an integral type.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
  19. #define LLVM_SUPPORT_SWAPBYTEORDER_H
  20. #include "llvm/ADT/bit.h"
  21. #include <cstddef>
  22. #include <cstdint>
  23. #include <type_traits>
  24. #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \
  25. defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
  26. #include <endian.h>
  27. #elif defined(_AIX)
  28. #include <sys/machine.h>
  29. #elif defined(__sun)
  30. /* Solaris provides _BIG_ENDIAN/_LITTLE_ENDIAN selector in sys/types.h */
  31. #include <sys/types.h>
  32. #define BIG_ENDIAN 4321
  33. #define LITTLE_ENDIAN 1234
  34. #if defined(_BIG_ENDIAN)
  35. #define BYTE_ORDER BIG_ENDIAN
  36. #else
  37. #define BYTE_ORDER LITTLE_ENDIAN
  38. #endif
  39. #elif defined(__MVS__)
  40. #define BIG_ENDIAN 4321
  41. #define LITTLE_ENDIAN 1234
  42. #define BYTE_ORDER BIG_ENDIAN
  43. #else
  44. #if !defined(BYTE_ORDER) && !defined(_WIN32)
  45. #include <machine/endian.h>
  46. #endif
  47. #endif
  48. namespace llvm {
  49. /// ByteSwap_16 - This function returns a byte-swapped representation of
  50. /// the 16-bit argument.
  51. inline uint16_t ByteSwap_16(uint16_t value) { return llvm::byteswap(value); }
  52. /// This function returns a byte-swapped representation of the 32-bit argument.
  53. inline uint32_t ByteSwap_32(uint32_t value) { return llvm::byteswap(value); }
  54. /// This function returns a byte-swapped representation of the 64-bit argument.
  55. inline uint64_t ByteSwap_64(uint64_t value) { return llvm::byteswap(value); }
  56. namespace sys {
  57. #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
  58. constexpr bool IsBigEndianHost = true;
  59. #else
  60. constexpr bool IsBigEndianHost = false;
  61. #endif
  62. static const bool IsLittleEndianHost = !IsBigEndianHost;
  63. inline unsigned char getSwappedBytes(unsigned char C) { return llvm::byteswap(C); }
  64. inline signed char getSwappedBytes( signed char C) { return llvm::byteswap(C); }
  65. inline char getSwappedBytes( char C) { return llvm::byteswap(C); }
  66. inline unsigned short getSwappedBytes(unsigned short C) { return llvm::byteswap(C); }
  67. inline signed short getSwappedBytes( signed short C) { return llvm::byteswap(C); }
  68. inline unsigned int getSwappedBytes(unsigned int C) { return llvm::byteswap(C); }
  69. inline signed int getSwappedBytes( signed int C) { return llvm::byteswap(C); }
  70. inline unsigned long getSwappedBytes(unsigned long C) { return llvm::byteswap(C); }
  71. inline signed long getSwappedBytes( signed long C) { return llvm::byteswap(C); }
  72. inline unsigned long long getSwappedBytes(unsigned long long C) { return llvm::byteswap(C); }
  73. inline signed long long getSwappedBytes( signed long long C) { return llvm::byteswap(C); }
  74. inline float getSwappedBytes(float C) {
  75. union {
  76. uint32_t i;
  77. float f;
  78. } in, out;
  79. in.f = C;
  80. out.i = llvm::byteswap(in.i);
  81. return out.f;
  82. }
  83. inline double getSwappedBytes(double C) {
  84. union {
  85. uint64_t i;
  86. double d;
  87. } in, out;
  88. in.d = C;
  89. out.i = llvm::byteswap(in.i);
  90. return out.d;
  91. }
  92. template <typename T>
  93. inline std::enable_if_t<std::is_enum<T>::value, T> getSwappedBytes(T C) {
  94. return static_cast<T>(
  95. llvm::byteswap(static_cast<std::underlying_type_t<T>>(C)));
  96. }
  97. template<typename T>
  98. inline void swapByteOrder(T &Value) {
  99. Value = getSwappedBytes(Value);
  100. }
  101. } // end namespace sys
  102. } // end namespace llvm
  103. #endif
  104. #ifdef __GNUC__
  105. #pragma GCC diagnostic pop
  106. #endif