00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/base/internal/endian.h"
00016
00017 #include <algorithm>
00018 #include <cstdint>
00019 #include <limits>
00020 #include <random>
00021 #include <vector>
00022
00023 #include "gtest/gtest.h"
00024 #include "absl/base/config.h"
00025
00026 namespace absl {
00027 namespace {
00028
00029 const uint64_t kInitialNumber{0x0123456789abcdef};
00030 const uint64_t k64Value{kInitialNumber};
00031 const uint32_t k32Value{0x01234567};
00032 const uint16_t k16Value{0x0123};
00033 const int kNumValuesToTest = 1000000;
00034 const int kRandomSeed = 12345;
00035
00036 #if defined(ABSL_IS_BIG_ENDIAN)
00037 const uint64_t kInitialInNetworkOrder{kInitialNumber};
00038 const uint64_t k64ValueLE{0xefcdab8967452301};
00039 const uint32_t k32ValueLE{0x67452301};
00040 const uint16_t k16ValueLE{0x2301};
00041
00042 const uint64_t k64ValueBE{kInitialNumber};
00043 const uint32_t k32ValueBE{k32Value};
00044 const uint16_t k16ValueBE{k16Value};
00045 #elif defined(ABSL_IS_LITTLE_ENDIAN)
00046 const uint64_t kInitialInNetworkOrder{0xefcdab8967452301};
00047 const uint64_t k64ValueLE{kInitialNumber};
00048 const uint32_t k32ValueLE{k32Value};
00049 const uint16_t k16ValueLE{k16Value};
00050
00051 const uint64_t k64ValueBE{0xefcdab8967452301};
00052 const uint32_t k32ValueBE{0x67452301};
00053 const uint16_t k16ValueBE{0x2301};
00054 #endif
00055
00056 template<typename T>
00057 std::vector<T> GenerateAllValuesForType() {
00058 std::vector<T> result;
00059 T next = std::numeric_limits<T>::min();
00060 while (true) {
00061 result.push_back(next);
00062 if (next == std::numeric_limits<T>::max()) {
00063 return result;
00064 }
00065 ++next;
00066 }
00067 }
00068
00069 template<typename T>
00070 std::vector<T> GenerateRandomIntegers(size_t numValuesToTest) {
00071 std::vector<T> result;
00072 std::mt19937_64 rng(kRandomSeed);
00073 for (size_t i = 0; i < numValuesToTest; ++i) {
00074 result.push_back(rng());
00075 }
00076 return result;
00077 }
00078
00079 void ManualByteSwap(char* bytes, int length) {
00080 if (length == 1)
00081 return;
00082
00083 EXPECT_EQ(0, length % 2);
00084 for (int i = 0; i < length / 2; ++i) {
00085 int j = (length - 1) - i;
00086 using std::swap;
00087 swap(bytes[i], bytes[j]);
00088 }
00089 }
00090
00091 template<typename T>
00092 inline T UnalignedLoad(const char* p) {
00093 static_assert(
00094 sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8,
00095 "Unexpected type size");
00096
00097 switch (sizeof(T)) {
00098 case 1: return *reinterpret_cast<const T*>(p);
00099 case 2:
00100 return ABSL_INTERNAL_UNALIGNED_LOAD16(p);
00101 case 4:
00102 return ABSL_INTERNAL_UNALIGNED_LOAD32(p);
00103 case 8:
00104 return ABSL_INTERNAL_UNALIGNED_LOAD64(p);
00105 default:
00106
00107 return {};
00108 }
00109 }
00110
00111 template <typename T, typename ByteSwapper>
00112 static void GBSwapHelper(const std::vector<T>& host_values_to_test,
00113 const ByteSwapper& byte_swapper) {
00114
00115 for (typename std::vector<T>::const_iterator it = host_values_to_test.begin();
00116 it != host_values_to_test.end(); ++it) {
00117 T host_value = *it;
00118
00119 char actual_value[sizeof(host_value)];
00120 memcpy(actual_value, &host_value, sizeof(host_value));
00121 byte_swapper(actual_value);
00122
00123 char expected_value[sizeof(host_value)];
00124 memcpy(expected_value, &host_value, sizeof(host_value));
00125 ManualByteSwap(expected_value, sizeof(host_value));
00126
00127 ASSERT_EQ(0, memcmp(actual_value, expected_value, sizeof(host_value)))
00128 << "Swap output for 0x" << std::hex << host_value << " does not match. "
00129 << "Expected: 0x" << UnalignedLoad<T>(expected_value) << "; "
00130 << "actual: 0x" << UnalignedLoad<T>(actual_value);
00131 }
00132 }
00133
00134 void Swap16(char* bytes) {
00135 ABSL_INTERNAL_UNALIGNED_STORE16(
00136 bytes, gbswap_16(ABSL_INTERNAL_UNALIGNED_LOAD16(bytes)));
00137 }
00138
00139 void Swap32(char* bytes) {
00140 ABSL_INTERNAL_UNALIGNED_STORE32(
00141 bytes, gbswap_32(ABSL_INTERNAL_UNALIGNED_LOAD32(bytes)));
00142 }
00143
00144 void Swap64(char* bytes) {
00145 ABSL_INTERNAL_UNALIGNED_STORE64(
00146 bytes, gbswap_64(ABSL_INTERNAL_UNALIGNED_LOAD64(bytes)));
00147 }
00148
00149 TEST(EndianessTest, Uint16) {
00150 GBSwapHelper(GenerateAllValuesForType<uint16_t>(), &Swap16);
00151 }
00152
00153 TEST(EndianessTest, Uint32) {
00154 GBSwapHelper(GenerateRandomIntegers<uint32_t>(kNumValuesToTest), &Swap32);
00155 }
00156
00157 TEST(EndianessTest, Uint64) {
00158 GBSwapHelper(GenerateRandomIntegers<uint64_t>(kNumValuesToTest), &Swap64);
00159 }
00160
00161 TEST(EndianessTest, ghtonll_gntohll) {
00162
00163 uint32_t test = 0x01234567;
00164 EXPECT_EQ(absl::gntohl(absl::ghtonl(test)), test);
00165
00166 uint64_t comp = absl::ghtonll(kInitialNumber);
00167 EXPECT_EQ(comp, kInitialInNetworkOrder);
00168 comp = absl::gntohll(kInitialInNetworkOrder);
00169 EXPECT_EQ(comp, kInitialNumber);
00170
00171
00172
00173
00174 uint64_t value = 1;
00175 for (int i = 0; i < 100; ++i) {
00176 comp = absl::ghtonll(absl::gntohll(value));
00177 EXPECT_EQ(value, comp);
00178 comp = absl::gntohll(absl::ghtonll(value));
00179 EXPECT_EQ(value, comp);
00180 value *= 37;
00181 }
00182 }
00183
00184 TEST(EndianessTest, little_endian) {
00185
00186 uint64_t comp = little_endian::FromHost16(k16Value);
00187 EXPECT_EQ(comp, k16ValueLE);
00188 comp = little_endian::ToHost16(k16ValueLE);
00189 EXPECT_EQ(comp, k16Value);
00190
00191
00192 comp = little_endian::FromHost32(k32Value);
00193 EXPECT_EQ(comp, k32ValueLE);
00194 comp = little_endian::ToHost32(k32ValueLE);
00195 EXPECT_EQ(comp, k32Value);
00196
00197
00198 comp = little_endian::FromHost64(k64Value);
00199 EXPECT_EQ(comp, k64ValueLE);
00200 comp = little_endian::ToHost64(k64ValueLE);
00201 EXPECT_EQ(comp, k64Value);
00202
00203
00204 uint16_t u16Buf;
00205 uint32_t u32Buf;
00206 uint64_t u64Buf;
00207
00208 little_endian::Store16(&u16Buf, k16Value);
00209 EXPECT_EQ(u16Buf, k16ValueLE);
00210 comp = little_endian::Load16(&u16Buf);
00211 EXPECT_EQ(comp, k16Value);
00212
00213 little_endian::Store32(&u32Buf, k32Value);
00214 EXPECT_EQ(u32Buf, k32ValueLE);
00215 comp = little_endian::Load32(&u32Buf);
00216 EXPECT_EQ(comp, k32Value);
00217
00218 little_endian::Store64(&u64Buf, k64Value);
00219 EXPECT_EQ(u64Buf, k64ValueLE);
00220 comp = little_endian::Load64(&u64Buf);
00221 EXPECT_EQ(comp, k64Value);
00222 }
00223
00224 TEST(EndianessTest, big_endian) {
00225
00226 uint16_t u16Buf;
00227 uint32_t u32Buf;
00228 uint64_t u64Buf;
00229
00230 unsigned char buffer[10];
00231 big_endian::Store16(&u16Buf, k16Value);
00232 EXPECT_EQ(u16Buf, k16ValueBE);
00233 uint64_t comp = big_endian::Load16(&u16Buf);
00234 EXPECT_EQ(comp, k16Value);
00235
00236 big_endian::Store32(&u32Buf, k32Value);
00237 EXPECT_EQ(u32Buf, k32ValueBE);
00238 comp = big_endian::Load32(&u32Buf);
00239 EXPECT_EQ(comp, k32Value);
00240
00241 big_endian::Store64(&u64Buf, k64Value);
00242 EXPECT_EQ(u64Buf, k64ValueBE);
00243 comp = big_endian::Load64(&u64Buf);
00244 EXPECT_EQ(comp, k64Value);
00245
00246 big_endian::Store16(buffer + 1, k16Value);
00247 EXPECT_EQ(u16Buf, k16ValueBE);
00248 comp = big_endian::Load16(buffer + 1);
00249 EXPECT_EQ(comp, k16Value);
00250
00251 big_endian::Store32(buffer + 1, k32Value);
00252 EXPECT_EQ(u32Buf, k32ValueBE);
00253 comp = big_endian::Load32(buffer + 1);
00254 EXPECT_EQ(comp, k32Value);
00255
00256 big_endian::Store64(buffer + 1, k64Value);
00257 EXPECT_EQ(u64Buf, k64ValueBE);
00258 comp = big_endian::Load64(buffer + 1);
00259 EXPECT_EQ(comp, k64Value);
00260 }
00261
00262 }
00263 }