Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
6.8 KiB

  1. //===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file declares generic functions to read and write endian specific data.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_SUPPORT_ENDIAN_H
  14. #define LLVM_SUPPORT_ENDIAN_H
  15. #include "llvm/Support/AlignOf.h"
  16. #include "llvm/Support/Host.h"
  17. #include "llvm/Support/SwapByteOrder.h"
  18. #include "llvm/Support/type_traits.h"
  19. namespace llvm {
  20. namespace support {
  21. enum endianness {big, little, native};
  22. // These are named values for common alignments.
  23. enum {aligned = 0, unaligned = 1};
  24. namespace detail {
  25. /// \brief ::value is either alignment, or alignof(T) if alignment is 0.
  26. template<class T, int alignment>
  27. struct PickAlignment {
  28. enum {value = alignment == 0 ? AlignOf<T>::Alignment : alignment};
  29. };
  30. } // end namespace detail
  31. namespace endian {
  32. template<typename value_type, endianness endian>
  33. inline value_type byte_swap(value_type value) {
  34. if (endian != native && sys::IsBigEndianHost != (endian == big))
  35. return sys::SwapByteOrder(value);
  36. return value;
  37. }
  38. template<typename value_type,
  39. endianness endian,
  40. std::size_t alignment>
  41. inline value_type read(const void *memory) {
  42. value_type ret;
  43. memcpy(&ret,
  44. LLVM_ASSUME_ALIGNED(memory,
  45. (detail::PickAlignment<value_type, alignment>::value)),
  46. sizeof(value_type));
  47. return byte_swap<value_type, endian>(ret);
  48. }
  49. template<typename value_type,
  50. endianness endian,
  51. std::size_t alignment>
  52. inline void write(void *memory, value_type value) {
  53. value = byte_swap<value_type, endian>(value);
  54. memcpy(LLVM_ASSUME_ALIGNED(memory,
  55. (detail::PickAlignment<value_type, alignment>::value)),
  56. &value,
  57. sizeof(value_type));
  58. }
  59. } // end namespace endian
  60. namespace detail {
  61. template<typename value_type,
  62. endianness endian,
  63. std::size_t alignment>
  64. struct packed_endian_specific_integral {
  65. operator value_type() const {
  66. return endian::read<value_type, endian, alignment>(
  67. (const void*)Value.buffer);
  68. }
  69. void operator=(value_type newValue) {
  70. endian::write<value_type, endian, alignment>(
  71. (void*)Value.buffer, newValue);
  72. }
  73. private:
  74. AlignedCharArray<PickAlignment<value_type, alignment>::value,
  75. sizeof(value_type)> Value;
  76. };
  77. } // end namespace detail
  78. typedef detail::packed_endian_specific_integral
  79. <uint8_t, little, unaligned> ulittle8_t;
  80. typedef detail::packed_endian_specific_integral
  81. <uint16_t, little, unaligned> ulittle16_t;
  82. typedef detail::packed_endian_specific_integral
  83. <uint32_t, little, unaligned> ulittle32_t;
  84. typedef detail::packed_endian_specific_integral
  85. <uint64_t, little, unaligned> ulittle64_t;
  86. typedef detail::packed_endian_specific_integral
  87. <int8_t, little, unaligned> little8_t;
  88. typedef detail::packed_endian_specific_integral
  89. <int16_t, little, unaligned> little16_t;
  90. typedef detail::packed_endian_specific_integral
  91. <int32_t, little, unaligned> little32_t;
  92. typedef detail::packed_endian_specific_integral
  93. <int64_t, little, unaligned> little64_t;
  94. typedef detail::packed_endian_specific_integral
  95. <uint8_t, little, aligned> aligned_ulittle8_t;
  96. typedef detail::packed_endian_specific_integral
  97. <uint16_t, little, aligned> aligned_ulittle16_t;
  98. typedef detail::packed_endian_specific_integral
  99. <uint32_t, little, aligned> aligned_ulittle32_t;
  100. typedef detail::packed_endian_specific_integral
  101. <uint64_t, little, aligned> aligned_ulittle64_t;
  102. typedef detail::packed_endian_specific_integral
  103. <int8_t, little, aligned> aligned_little8_t;
  104. typedef detail::packed_endian_specific_integral
  105. <int16_t, little, aligned> aligned_little16_t;
  106. typedef detail::packed_endian_specific_integral
  107. <int32_t, little, aligned> aligned_little32_t;
  108. typedef detail::packed_endian_specific_integral
  109. <int64_t, little, aligned> aligned_little64_t;
  110. typedef detail::packed_endian_specific_integral
  111. <uint8_t, big, unaligned> ubig8_t;
  112. typedef detail::packed_endian_specific_integral
  113. <uint16_t, big, unaligned> ubig16_t;
  114. typedef detail::packed_endian_specific_integral
  115. <uint32_t, big, unaligned> ubig32_t;
  116. typedef detail::packed_endian_specific_integral
  117. <uint64_t, big, unaligned> ubig64_t;
  118. typedef detail::packed_endian_specific_integral
  119. <int8_t, big, unaligned> big8_t;
  120. typedef detail::packed_endian_specific_integral
  121. <int16_t, big, unaligned> big16_t;
  122. typedef detail::packed_endian_specific_integral
  123. <int32_t, big, unaligned> big32_t;
  124. typedef detail::packed_endian_specific_integral
  125. <int64_t, big, unaligned> big64_t;
  126. typedef detail::packed_endian_specific_integral
  127. <uint8_t, big, aligned> aligned_ubig8_t;
  128. typedef detail::packed_endian_specific_integral
  129. <uint16_t, big, aligned> aligned_ubig16_t;
  130. typedef detail::packed_endian_specific_integral
  131. <uint32_t, big, aligned> aligned_ubig32_t;
  132. typedef detail::packed_endian_specific_integral
  133. <uint64_t, big, aligned> aligned_ubig64_t;
  134. typedef detail::packed_endian_specific_integral
  135. <int8_t, big, aligned> aligned_big8_t;
  136. typedef detail::packed_endian_specific_integral
  137. <int16_t, big, aligned> aligned_big16_t;
  138. typedef detail::packed_endian_specific_integral
  139. <int32_t, big, aligned> aligned_big32_t;
  140. typedef detail::packed_endian_specific_integral
  141. <int64_t, big, aligned> aligned_big64_t;
  142. typedef detail::packed_endian_specific_integral
  143. <uint16_t, native, unaligned> unaligned_uint16_t;
  144. typedef detail::packed_endian_specific_integral
  145. <uint32_t, native, unaligned> unaligned_uint32_t;
  146. typedef detail::packed_endian_specific_integral
  147. <uint64_t, native, unaligned> unaligned_uint64_t;
  148. typedef detail::packed_endian_specific_integral
  149. <int16_t, native, unaligned> unaligned_int16_t;
  150. typedef detail::packed_endian_specific_integral
  151. <int32_t, native, unaligned> unaligned_int32_t;
  152. typedef detail::packed_endian_specific_integral
  153. <int64_t, native, unaligned> unaligned_int64_t;
  154. } // end namespace llvm
  155. } // end namespace support
  156. #endif