abseil-cpp/absl/base/internal/endian_test.cc
Go to the documentation of this file.
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/base/internal/endian.h"
16 
17 #include <algorithm>
18 #include <cstdint>
19 #include <limits>
20 #include <random>
21 #include <vector>
22 
23 #include "gtest/gtest.h"
24 #include "absl/base/config.h"
25 
26 namespace absl {
28 namespace {
29 
30 const uint64_t kInitialNumber{0x0123456789abcdef};
32 const uint32_t k32Value{0x01234567};
33 const uint16_t k16Value{0x0123};
34 const int kNumValuesToTest = 1000000;
35 const int kRandomSeed = 12345;
36 
37 #if defined(ABSL_IS_BIG_ENDIAN)
38 const uint64_t kInitialInNetworkOrder{kInitialNumber};
39 const uint64_t k64ValueLE{0xefcdab8967452301};
40 const uint32_t k32ValueLE{0x67452301};
41 const uint16_t k16ValueLE{0x2301};
42 
43 const uint64_t k64ValueBE{kInitialNumber};
44 const uint32_t k32ValueBE{k32Value};
45 const uint16_t k16ValueBE{k16Value};
46 #elif defined(ABSL_IS_LITTLE_ENDIAN)
47 const uint64_t kInitialInNetworkOrder{0xefcdab8967452301};
48 const uint64_t k64ValueLE{kInitialNumber};
49 const uint32_t k32ValueLE{k32Value};
50 const uint16_t k16ValueLE{k16Value};
51 
52 const uint64_t k64ValueBE{0xefcdab8967452301};
53 const uint32_t k32ValueBE{0x67452301};
54 const uint16_t k16ValueBE{0x2301};
55 #endif
56 
57 std::vector<uint16_t> GenerateAllUint16Values() {
58  std::vector<uint16_t> result;
59  result.reserve(size_t{1} << (sizeof(uint16_t) * 8));
62  result.push_back(static_cast<uint16_t>(i));
63  }
64  return result;
65 }
66 
67 template<typename T>
68 std::vector<T> GenerateRandomIntegers(size_t num_values_to_test) {
69  std::vector<T> result;
70  result.reserve(num_values_to_test);
71  std::mt19937_64 rng(kRandomSeed);
72  for (size_t i = 0; i < num_values_to_test; ++i) {
73  result.push_back(rng());
74  }
75  return result;
76 }
77 
78 void ManualByteSwap(char* bytes, int length) {
79  if (length == 1)
80  return;
81 
82  EXPECT_EQ(0, length % 2);
83  for (int i = 0; i < length / 2; ++i) {
84  int j = (length - 1) - i;
85  using std::swap;
86  swap(bytes[i], bytes[j]);
87  }
88 }
89 
90 template<typename T>
91 inline T UnalignedLoad(const char* p) {
92  static_assert(
93  sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8,
94  "Unexpected type size");
95 
96  switch (sizeof(T)) {
97  case 1: return *reinterpret_cast<const T*>(p);
98  case 2:
99  return ABSL_INTERNAL_UNALIGNED_LOAD16(p);
100  case 4:
101  return ABSL_INTERNAL_UNALIGNED_LOAD32(p);
102  case 8:
103  return ABSL_INTERNAL_UNALIGNED_LOAD64(p);
104  default:
105  // Suppresses invalid "not all control paths return a value" on MSVC
106  return {};
107  }
108 }
109 
110 template <typename T, typename ByteSwapper>
111 static void GBSwapHelper(const std::vector<T>& host_values_to_test,
112  const ByteSwapper& byte_swapper) {
113  // Test byte_swapper against a manual byte swap.
114  for (typename std::vector<T>::const_iterator it = host_values_to_test.begin();
115  it != host_values_to_test.end(); ++it) {
116  T host_value = *it;
117 
118  char actual_value[sizeof(host_value)];
119  memcpy(actual_value, &host_value, sizeof(host_value));
120  byte_swapper(actual_value);
121 
122  char expected_value[sizeof(host_value)];
123  memcpy(expected_value, &host_value, sizeof(host_value));
124  ManualByteSwap(expected_value, sizeof(host_value));
125 
126  ASSERT_EQ(0, memcmp(actual_value, expected_value, sizeof(host_value)))
127  << "Swap output for 0x" << std::hex << host_value << " does not match. "
128  << "Expected: 0x" << UnalignedLoad<T>(expected_value) << "; "
129  << "actual: 0x" << UnalignedLoad<T>(actual_value);
130  }
131 }
132 
133 void Swap16(char* bytes) {
134  ABSL_INTERNAL_UNALIGNED_STORE16(
135  bytes, gbswap_16(ABSL_INTERNAL_UNALIGNED_LOAD16(bytes)));
136 }
137 
138 void Swap32(char* bytes) {
139  ABSL_INTERNAL_UNALIGNED_STORE32(
140  bytes, gbswap_32(ABSL_INTERNAL_UNALIGNED_LOAD32(bytes)));
141 }
142 
143 void Swap64(char* bytes) {
144  ABSL_INTERNAL_UNALIGNED_STORE64(
145  bytes, gbswap_64(ABSL_INTERNAL_UNALIGNED_LOAD64(bytes)));
146 }
147 
148 TEST(EndianessTest, Uint16) {
150 }
151 
152 TEST(EndianessTest, Uint32) {
153  GBSwapHelper(GenerateRandomIntegers<uint32_t>(kNumValuesToTest), &Swap32);
154 }
155 
156 TEST(EndianessTest, Uint64) {
157  GBSwapHelper(GenerateRandomIntegers<uint64_t>(kNumValuesToTest), &Swap64);
158 }
159 
160 TEST(EndianessTest, ghtonll_gntohll) {
161  // Test that absl::ghtonl compiles correctly
162  uint32_t test = 0x01234567;
164 
165  uint64_t comp = absl::ghtonll(kInitialNumber);
166  EXPECT_EQ(comp, kInitialInNetworkOrder);
167  comp = absl::gntohll(kInitialInNetworkOrder);
168  EXPECT_EQ(comp, kInitialNumber);
169 
170  // Test that htonll and ntohll are each others' inverse functions on a
171  // somewhat assorted batch of numbers. 37 is chosen to not be anything
172  // particularly nice base 2.
173  uint64_t value = 1;
174  for (int i = 0; i < 100; ++i) {
175  comp = absl::ghtonll(absl::gntohll(value));
176  EXPECT_EQ(value, comp);
177  comp = absl::gntohll(absl::ghtonll(value));
178  EXPECT_EQ(value, comp);
179  value *= 37;
180  }
181 }
182 
183 TEST(EndianessTest, little_endian) {
184  // Check little_endian uint16_t.
185  uint64_t comp = little_endian::FromHost16(k16Value);
186  EXPECT_EQ(comp, k16ValueLE);
187  comp = little_endian::ToHost16(k16ValueLE);
188  EXPECT_EQ(comp, k16Value);
189 
190  // Check little_endian uint32_t.
191  comp = little_endian::FromHost32(k32Value);
192  EXPECT_EQ(comp, k32ValueLE);
193  comp = little_endian::ToHost32(k32ValueLE);
194  EXPECT_EQ(comp, k32Value);
195 
196  // Check little_endian uint64_t.
197  comp = little_endian::FromHost64(k64Value);
198  EXPECT_EQ(comp, k64ValueLE);
199  comp = little_endian::ToHost64(k64ValueLE);
200  EXPECT_EQ(comp, k64Value);
201 
202  // Check little-endian Load and store functions.
203  uint16_t u16Buf;
204  uint32_t u32Buf;
205  uint64_t u64Buf;
206 
208  EXPECT_EQ(u16Buf, k16ValueLE);
209  comp = little_endian::Load16(&u16Buf);
210  EXPECT_EQ(comp, k16Value);
211 
213  EXPECT_EQ(u32Buf, k32ValueLE);
214  comp = little_endian::Load32(&u32Buf);
215  EXPECT_EQ(comp, k32Value);
216 
218  EXPECT_EQ(u64Buf, k64ValueLE);
219  comp = little_endian::Load64(&u64Buf);
220  EXPECT_EQ(comp, k64Value);
221 }
222 
223 TEST(EndianessTest, big_endian) {
224  // Check big-endian Load and store functions.
225  uint16_t u16Buf;
226  uint32_t u32Buf;
227  uint64_t u64Buf;
228 
229  unsigned char buffer[10];
230  big_endian::Store16(&u16Buf, k16Value);
231  EXPECT_EQ(u16Buf, k16ValueBE);
232  uint64_t comp = big_endian::Load16(&u16Buf);
233  EXPECT_EQ(comp, k16Value);
234 
235  big_endian::Store32(&u32Buf, k32Value);
236  EXPECT_EQ(u32Buf, k32ValueBE);
237  comp = big_endian::Load32(&u32Buf);
238  EXPECT_EQ(comp, k32Value);
239 
240  big_endian::Store64(&u64Buf, k64Value);
241  EXPECT_EQ(u64Buf, k64ValueBE);
242  comp = big_endian::Load64(&u64Buf);
243  EXPECT_EQ(comp, k64Value);
244 
246  EXPECT_EQ(u16Buf, k16ValueBE);
247  comp = big_endian::Load16(buffer + 1);
248  EXPECT_EQ(comp, k16Value);
249 
251  EXPECT_EQ(u32Buf, k32ValueBE);
252  comp = big_endian::Load32(buffer + 1);
253  EXPECT_EQ(comp, k32Value);
254 
256  EXPECT_EQ(u64Buf, k64ValueBE);
257  comp = big_endian::Load64(buffer + 1);
258  EXPECT_EQ(comp, k64Value);
259 }
260 
261 } // namespace
263 } // namespace absl
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
absl::ABSL_NAMESPACE_BEGIN::Swap64
void Swap64(char *bytes)
Definition: abseil-cpp/absl/base/internal/endian_test.cc:143
regen-readme.it
it
Definition: regen-readme.py:15
absl::big_endian::Store16
void Store16(void *p, uint16_t v)
Definition: abseil-cpp/absl/base/internal/endian.h:257
absl::ABSL_NAMESPACE_BEGIN::kInitialNumber
const uint64_t kInitialNumber
Definition: abseil-cpp/absl/base/internal/endian_test.cc:30
absl::ABSL_NAMESPACE_BEGIN::k32Value
const uint32_t k32Value
Definition: abseil-cpp/absl/base/internal/endian_test.cc:32
absl::little_endian::Store64
void Store64(void *p, uint64_t v)
Definition: abseil-cpp/absl/base/internal/endian.h:183
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
absl::ABSL_NAMESPACE_BEGIN::kRandomSeed
const int kRandomSeed
Definition: abseil-cpp/absl/base/internal/endian_test.cc:35
test
Definition: spinlock_test.cc:36
absl::gntohl
uint32_t gntohl(uint32_t x)
Definition: abseil-cpp/absl/base/internal/endian.h:95
absl::ABSL_NAMESPACE_BEGIN::GenerateRandomIntegers
std::vector< T > GenerateRandomIntegers(size_t num_values_to_test)
Definition: abseil-cpp/absl/base/internal/endian_test.cc:68
absl::big_endian::Load16
uint16_t Load16(const void *p)
Definition: abseil-cpp/absl/base/internal/endian.h:253
absl::TEST
TEST(NotificationTest, SanityTest)
Definition: abseil-cpp/absl/synchronization/notification_test.cc:126
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
T
#define T(upbtypeconst, upbtype, ctype, default_value)
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
absl::little_endian::Store16
void Store16(void *p, uint16_t v)
Definition: abseil-cpp/absl/base/internal/endian.h:167
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
google::protobuf::ghtonl
uint32 ghtonl(uint32 x)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/common.cc:307
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::little_endian::Load64
uint64_t Load64(const void *p)
Definition: abseil-cpp/absl/base/internal/endian.h:179
absl::ABSL_NAMESPACE_BEGIN::kNumValuesToTest
const int kNumValuesToTest
Definition: abseil-cpp/absl/base/internal/endian_test.cc:34
absl::gntohll
uint64_t gntohll(uint64_t x)
Definition: abseil-cpp/absl/base/internal/endian.h:96
absl::ABSL_NAMESPACE_BEGIN::Swap32
void Swap32(char *bytes)
Definition: abseil-cpp/absl/base/internal/endian_test.cc:138
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
absl::swap
void swap(btree_map< K, V, C, A > &x, btree_map< K, V, C, A > &y)
Definition: abseil-cpp/absl/container/btree_map.h:474
absl::ABSL_NAMESPACE_BEGIN::GBSwapHelper
static void GBSwapHelper(const std::vector< T > &host_values_to_test, const ByteSwapper &byte_swapper)
Definition: abseil-cpp/absl/base/internal/endian_test.cc:111
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
std::swap
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:1226
absl::little_endian::Load16
uint16_t Load16(const void *p)
Definition: abseil-cpp/absl/base/internal/endian.h:163
buffer
char buffer[1024]
Definition: libuv/docs/code/idle-compute/main.c:8
min
#define min(a, b)
Definition: qsort.h:83
absl::gbswap_16
uint16_t gbswap_16(uint16_t host_int)
Definition: abseil-cpp/absl/base/internal/endian.h:60
absl::gbswap_64
ABSL_NAMESPACE_BEGIN uint64_t gbswap_64(uint64_t host_int)
Definition: abseil-cpp/absl/base/internal/endian.h:30
absl::gbswap_32
uint32_t gbswap_32(uint32_t host_int)
Definition: abseil-cpp/absl/base/internal/endian.h:47
value
const char * value
Definition: hpack_parser_table.cc:165
absl::ABSL_NAMESPACE_BEGIN::ManualByteSwap
void ManualByteSwap(char *bytes, int length)
Definition: abseil-cpp/absl/base/internal/endian_test.cc:78
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
absl::big_endian::Load64
uint64_t Load64(const void *p)
Definition: abseil-cpp/absl/base/internal/endian.h:269
absl::big_endian::Load32
uint32_t Load32(const void *p)
Definition: abseil-cpp/absl/base/internal/endian.h:261
absl::big_endian::Store32
void Store32(void *p, uint32_t v)
Definition: abseil-cpp/absl/base/internal/endian.h:265
absl::little_endian::Store32
void Store32(void *p, uint32_t v)
Definition: abseil-cpp/absl/base/internal/endian.h:175
absl::ABSL_NAMESPACE_BEGIN::GenerateAllUint16Values
std::vector< uint16_t > GenerateAllUint16Values()
Definition: abseil-cpp/absl/base/internal/endian_test.cc:57
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::little_endian::Load32
uint32_t Load32(const void *p)
Definition: abseil-cpp/absl/base/internal/endian.h:171
absl::big_endian::Store64
void Store64(void *p, uint64_t v)
Definition: abseil-cpp/absl/base/internal/endian.h:273
absl::ABSL_NAMESPACE_BEGIN::k64Value
const uint64_t k64Value
Definition: abseil-cpp/absl/base/internal/endian_test.cc:31
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
absl::ABSL_NAMESPACE_BEGIN::UnalignedLoad
T UnalignedLoad(const char *p)
Definition: abseil-cpp/absl/base/internal/endian_test.cc:91
absl::ABSL_NAMESPACE_BEGIN::Swap16
void Swap16(char *bytes)
Definition: abseil-cpp/absl/base/internal/endian_test.cc:133
absl::ABSL_NAMESPACE_BEGIN::k16Value
const uint16_t k16Value
Definition: abseil-cpp/absl/base/internal/endian_test.cc:33
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:19