1*61c4878aSAndroid Build Coastguard Worker // Copyright 2020 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker #include "pw_bytes/endian.h"
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker #include <array>
18*61c4878aSAndroid Build Coastguard Worker #include <cstddef>
19*61c4878aSAndroid Build Coastguard Worker
20*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard Worker namespace pw::bytes {
23*61c4878aSAndroid Build Coastguard Worker namespace {
24*61c4878aSAndroid Build Coastguard Worker
25*61c4878aSAndroid Build Coastguard Worker constexpr endian kNonNative =
26*61c4878aSAndroid Build Coastguard Worker (endian::native == endian::little) ? endian::big : endian::little;
27*61c4878aSAndroid Build Coastguard Worker
28*61c4878aSAndroid Build Coastguard Worker // ConvertOrderTo/From
29*61c4878aSAndroid Build Coastguard Worker //
30*61c4878aSAndroid Build Coastguard Worker // ConvertOrderTo and ConvertOrderFrom are implemented identically, but are
31*61c4878aSAndroid Build Coastguard Worker // provided as separate functions to improve readability where they are used.
32*61c4878aSAndroid Build Coastguard Worker //
33*61c4878aSAndroid Build Coastguard Worker // clang-format off
34*61c4878aSAndroid Build Coastguard Worker
35*61c4878aSAndroid Build Coastguard Worker // Native endianess conversions (should do nothing)
36*61c4878aSAndroid Build Coastguard Worker
37*61c4878aSAndroid Build Coastguard Worker // Convert unsigned to native endianness
38*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(endian::native, uint8_t{0x12}) == uint8_t{0x12});
39*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(endian::native, uint16_t{0x0011}) == uint16_t{0x0011});
40*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(endian::native, uint32_t{0x33221100}) == uint32_t{0x33221100});
41*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(endian::native, uint64_t{0x0011223344556677}) == uint64_t{0x0011223344556677});
42*61c4878aSAndroid Build Coastguard Worker
43*61c4878aSAndroid Build Coastguard Worker // Convert signed to native endianness
44*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(endian::native, int8_t{0x12}) == int8_t{0x12});
45*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(endian::native, int16_t{0x0011}) == int16_t{0x0011});
46*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(endian::native, int32_t{0x33221100}) == int32_t{0x33221100});
47*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(endian::native, int64_t{0x0011223344556677}) == int64_t{0x0011223344556677});
48*61c4878aSAndroid Build Coastguard Worker
49*61c4878aSAndroid Build Coastguard Worker // Convert unsigned from native endianness
50*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(endian::native, uint8_t{0x12}) == uint8_t{0x12});
51*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(endian::native, uint16_t{0x0011}) == uint16_t{0x0011});
52*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(endian::native, uint32_t{0x33221100}) == uint32_t{0x33221100});
53*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(endian::native, uint64_t{0x0011223344556677}) == uint64_t{0x0011223344556677});
54*61c4878aSAndroid Build Coastguard Worker
55*61c4878aSAndroid Build Coastguard Worker // Convert signed from native endianness
56*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(endian::native, int8_t{0x12}) == int8_t{0x12});
57*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(endian::native, int16_t{0x0011}) == int16_t{0x0011});
58*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(endian::native, int32_t{0x33221100}) == int32_t{0x33221100});
59*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(endian::native, int64_t{0x0011223344556677}) == int64_t{0x0011223344556677});
60*61c4878aSAndroid Build Coastguard Worker
61*61c4878aSAndroid Build Coastguard Worker // Non-native endianess conversions (should reverse byte order)
62*61c4878aSAndroid Build Coastguard Worker
63*61c4878aSAndroid Build Coastguard Worker // Convert unsigned to non-native endianness
64*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(kNonNative, uint8_t{0x12}) == uint8_t{0x12});
65*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(kNonNative, uint16_t{0x0011}) == uint16_t{0x1100});
66*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(kNonNative, uint32_t{0x33221100}) == uint32_t{0x00112233});
67*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(kNonNative, uint64_t{0x0011223344556677}) == uint64_t{0x7766554433221100});
68*61c4878aSAndroid Build Coastguard Worker
69*61c4878aSAndroid Build Coastguard Worker // Convert signed to non-native endianness
70*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(kNonNative, int8_t{0x12}) == int8_t{0x12});
71*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(kNonNative, int16_t{0x0011}) == int16_t{0x1100});
72*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(kNonNative, int32_t{0x33221100}) == int32_t{0x00112233});
73*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderTo(kNonNative, int64_t{0x0011223344556677}) == int64_t{0x7766554433221100});
74*61c4878aSAndroid Build Coastguard Worker
75*61c4878aSAndroid Build Coastguard Worker // Convert unsigned from non-native endianness
76*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(kNonNative, uint8_t{0x12}) == uint8_t{0x12});
77*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(kNonNative, uint16_t{0x0011}) == uint16_t{0x1100});
78*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(kNonNative, uint32_t{0x33221100}) == uint32_t{0x00112233});
79*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(kNonNative, uint64_t{0x0011223344556677}) == uint64_t{0x7766554433221100});
80*61c4878aSAndroid Build Coastguard Worker
81*61c4878aSAndroid Build Coastguard Worker // Convert signed from non-native endianness
82*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(kNonNative, int8_t{0x12}) == int8_t{0x12});
83*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(kNonNative, int16_t{0x0011}) == int16_t{0x1100});
84*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(kNonNative, int32_t{0x33221100}) == int32_t{0x00112233});
85*61c4878aSAndroid Build Coastguard Worker static_assert(ConvertOrderFrom(kNonNative, int64_t{0x0011223344556677}) == int64_t{0x7766554433221100});
86*61c4878aSAndroid Build Coastguard Worker
87*61c4878aSAndroid Build Coastguard Worker // clang-format on
88*61c4878aSAndroid Build Coastguard Worker
89*61c4878aSAndroid Build Coastguard Worker template <typename T, typename U>
Equal(const T & lhs,const U & rhs)90*61c4878aSAndroid Build Coastguard Worker constexpr bool Equal(const T& lhs, const U& rhs) {
91*61c4878aSAndroid Build Coastguard Worker if (sizeof(lhs) != sizeof(rhs) || std::size(lhs) != std::size(rhs)) {
92*61c4878aSAndroid Build Coastguard Worker return false;
93*61c4878aSAndroid Build Coastguard Worker }
94*61c4878aSAndroid Build Coastguard Worker
95*61c4878aSAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(lhs); ++i) {
96*61c4878aSAndroid Build Coastguard Worker if (lhs[i] != rhs[i]) {
97*61c4878aSAndroid Build Coastguard Worker return false;
98*61c4878aSAndroid Build Coastguard Worker }
99*61c4878aSAndroid Build Coastguard Worker }
100*61c4878aSAndroid Build Coastguard Worker
101*61c4878aSAndroid Build Coastguard Worker return true;
102*61c4878aSAndroid Build Coastguard Worker }
103*61c4878aSAndroid Build Coastguard Worker
104*61c4878aSAndroid Build Coastguard Worker // CopyInOrder copies a value to a std::array with the specified endianness.
105*61c4878aSAndroid Build Coastguard Worker //
106*61c4878aSAndroid Build Coastguard Worker // clang-format off
107*61c4878aSAndroid Build Coastguard Worker
108*61c4878aSAndroid Build Coastguard Worker // 8-bit little
109*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::little, '?'),
110*61c4878aSAndroid Build Coastguard Worker Array<'?'>()));
111*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::little, uint8_t{0x10}),
112*61c4878aSAndroid Build Coastguard Worker Array<0x10>()));
113*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::little, static_cast<int8_t>(0x10)),
114*61c4878aSAndroid Build Coastguard Worker Array<0x10>()));
115*61c4878aSAndroid Build Coastguard Worker
116*61c4878aSAndroid Build Coastguard Worker // 8-bit big
117*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::big, '?'),
118*61c4878aSAndroid Build Coastguard Worker Array<'?'>()));
119*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::big, static_cast<uint8_t>(0x10)),
120*61c4878aSAndroid Build Coastguard Worker Array<0x10>()));
121*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::big, static_cast<int8_t>(0x10)),
122*61c4878aSAndroid Build Coastguard Worker Array<0x10>()));
123*61c4878aSAndroid Build Coastguard Worker
124*61c4878aSAndroid Build Coastguard Worker // 16-bit little
125*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::little, uint16_t{0xAB12}),
126*61c4878aSAndroid Build Coastguard Worker Array<0x12, 0xAB>()));
127*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::little, static_cast<int16_t>(0xAB12)),
128*61c4878aSAndroid Build Coastguard Worker Array<0x12, 0xAB>()));
129*61c4878aSAndroid Build Coastguard Worker
130*61c4878aSAndroid Build Coastguard Worker // 16-bit big
131*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::big, uint16_t{0xAB12}),
132*61c4878aSAndroid Build Coastguard Worker Array<0xAB, 0x12>()));
133*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::big, static_cast<int16_t>(0xAB12)),
134*61c4878aSAndroid Build Coastguard Worker Array<0xAB, 0x12>()));
135*61c4878aSAndroid Build Coastguard Worker
136*61c4878aSAndroid Build Coastguard Worker // 32-bit little
137*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::little, uint32_t{0xAABBCCDD}),
138*61c4878aSAndroid Build Coastguard Worker Array<0xDD, 0xCC, 0xBB, 0xAA>()));
139*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::little, static_cast<int32_t>(0xAABBCCDD)),
140*61c4878aSAndroid Build Coastguard Worker Array<0xDD, 0xCC, 0xBB, 0xAA>()));
141*61c4878aSAndroid Build Coastguard Worker
142*61c4878aSAndroid Build Coastguard Worker // 32-bit big
143*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::big, uint32_t{0xAABBCCDD}),
144*61c4878aSAndroid Build Coastguard Worker Array<0xAA, 0xBB, 0xCC, 0xDD>()));
145*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::big, static_cast<int32_t>(0xAABBCCDD)),
146*61c4878aSAndroid Build Coastguard Worker Array<0xAA, 0xBB, 0xCC, 0xDD>()));
147*61c4878aSAndroid Build Coastguard Worker
148*61c4878aSAndroid Build Coastguard Worker // 64-bit little
149*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::little, uint64_t{0xAABBCCDD11223344}),
150*61c4878aSAndroid Build Coastguard Worker Array<0x44, 0x33, 0x22, 0x11, 0xDD, 0xCC, 0xBB, 0xAA>()));
151*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::little, static_cast<int64_t>(0xAABBCCDD11223344ull)),
152*61c4878aSAndroid Build Coastguard Worker Array<0x44, 0x33, 0x22, 0x11, 0xDD, 0xCC, 0xBB, 0xAA>()));
153*61c4878aSAndroid Build Coastguard Worker
154*61c4878aSAndroid Build Coastguard Worker // 64-bit big
155*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::big, uint64_t{0xAABBCCDD11223344}),
156*61c4878aSAndroid Build Coastguard Worker Array<0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22, 0x33, 0x44>()));
157*61c4878aSAndroid Build Coastguard Worker static_assert(Equal(CopyInOrder(endian::big, static_cast<int64_t>(0xAABBCCDD11223344ull)),
158*61c4878aSAndroid Build Coastguard Worker Array<0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22, 0x33, 0x44>()));
159*61c4878aSAndroid Build Coastguard Worker
160*61c4878aSAndroid Build Coastguard Worker // clang-format on
161*61c4878aSAndroid Build Coastguard Worker
162*61c4878aSAndroid Build Coastguard Worker constexpr const char* kNumber = "\x11\x22\x33\x44\xaa\xbb\xcc\xdd";
163*61c4878aSAndroid Build Coastguard Worker
164*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, 8Bit_Big) {
165*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint8_t>(endian::big, "\0"), 0u);
166*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint8_t>(endian::big, "\x80"), 0x80u);
167*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint8_t>(endian::big, kNumber), 0x11u);
168*61c4878aSAndroid Build Coastguard Worker
169*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int8_t>(endian::big, "\0"), 0);
170*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int8_t>(endian::big, "\x80"), -128);
171*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int8_t>(endian::big, kNumber), 0x11);
172*61c4878aSAndroid Build Coastguard Worker }
173*61c4878aSAndroid Build Coastguard Worker
174*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, 8Bit_Little) {
175*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint8_t>(endian::little, "\0"), 0u);
176*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint8_t>(endian::little, "\x80"), 0x80u);
177*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint8_t>(endian::little, kNumber), 0x11u);
178*61c4878aSAndroid Build Coastguard Worker
179*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int8_t>(endian::little, "\0"), 0);
180*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int8_t>(endian::little, "\x80"), -128);
181*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int8_t>(endian::little, kNumber), 0x11);
182*61c4878aSAndroid Build Coastguard Worker }
183*61c4878aSAndroid Build Coastguard Worker
184*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, 16Bit_Big) {
185*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint16_t>(endian::big, "\0\0"), 0u);
186*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint16_t>(endian::big, "\x80\0"), 0x8000u);
187*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint16_t>(endian::big, kNumber), 0x1122u);
188*61c4878aSAndroid Build Coastguard Worker
189*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int16_t>(endian::big, "\0\0"), 0);
190*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int16_t>(endian::big, "\x80\0"), -32768);
191*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int16_t>(endian::big, kNumber), 0x1122);
192*61c4878aSAndroid Build Coastguard Worker }
193*61c4878aSAndroid Build Coastguard Worker
194*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, 16Bit_Little) {
195*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint16_t>(endian::little, "\0\0"), 0u);
196*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint16_t>(endian::little, "\x80\0"), 0x80u);
197*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint16_t>(endian::little, kNumber), 0x2211u);
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int16_t>(endian::little, "\0\0"), 0);
200*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int16_t>(endian::little, "\x80\0"), 0x80);
201*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int16_t>(endian::little, kNumber), 0x2211);
202*61c4878aSAndroid Build Coastguard Worker }
203*61c4878aSAndroid Build Coastguard Worker
204*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, 32Bit_Big) {
205*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint32_t>(endian::big, "\0\0\0\0"), 0u);
206*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint32_t>(endian::big, "\x80\0\0\0"), 0x80000000u);
207*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint32_t>(endian::big, kNumber), 0x11223344u);
208*61c4878aSAndroid Build Coastguard Worker
209*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int32_t>(endian::big, "\0\0\0\0"), 0);
210*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int32_t>(endian::big, "\x80\0\0\0"), -2147483648);
211*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int32_t>(endian::big, kNumber), 0x11223344);
212*61c4878aSAndroid Build Coastguard Worker }
213*61c4878aSAndroid Build Coastguard Worker
214*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, 32Bit_Little) {
215*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint32_t>(endian::little, "\0\0\0\0"), 0u);
216*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint32_t>(endian::little, "\x80\0\0\0"), 0x80u);
217*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint32_t>(endian::little, kNumber), 0x44332211u);
218*61c4878aSAndroid Build Coastguard Worker
219*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int32_t>(endian::little, "\0\0\0\0"), 0);
220*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int32_t>(endian::little, "\x80\0\0\0"), 0x80);
221*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int32_t>(endian::little, kNumber), 0x44332211);
222*61c4878aSAndroid Build Coastguard Worker }
223*61c4878aSAndroid Build Coastguard Worker
224*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, 64Bit_Big) {
225*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint64_t>(endian::big, "\0\0\0\0\0\0\0\0"), 0u);
226*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint64_t>(endian::big, "\x80\0\0\0\0\0\0\0"),
227*61c4878aSAndroid Build Coastguard Worker 0x80000000'00000000llu);
228*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint64_t>(endian::big, kNumber), 0x11223344AABBCCDDu);
229*61c4878aSAndroid Build Coastguard Worker
230*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int64_t>(endian::big, "\0\0\0\0\0\0\0\0"), 0);
231*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int64_t>(endian::big, "\x80\0\0\0\0\0\0\0"),
232*61c4878aSAndroid Build Coastguard Worker static_cast<int64_t>(1llu << 63));
233*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int64_t>(endian::big, kNumber), 0x11223344AABBCCDD);
234*61c4878aSAndroid Build Coastguard Worker }
235*61c4878aSAndroid Build Coastguard Worker
236*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, 64Bit_Little) {
237*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint64_t>(endian::little, "\0\0\0\0\0\0\0\0"), 0u);
238*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint64_t>(endian::little, "\x80\0\0\0\0\0\0\0"), 0x80u);
239*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<uint64_t>(endian::little, kNumber),
240*61c4878aSAndroid Build Coastguard Worker 0xDDCCBBAA44332211u);
241*61c4878aSAndroid Build Coastguard Worker
242*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int64_t>(endian::little, "\0\0\0\0\0\0\0\0"), 0);
243*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int64_t>(endian::little, "\x80\0\0\0\0\0\0\0"), 0x80);
244*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(ReadInOrder<int64_t>(endian::little, kNumber),
245*61c4878aSAndroid Build Coastguard Worker static_cast<int64_t>(0xDDCCBBAA44332211));
246*61c4878aSAndroid Build Coastguard Worker }
247*61c4878aSAndroid Build Coastguard Worker
TEST(ReadInOrder,StdArray)248*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, StdArray) {
249*61c4878aSAndroid Build Coastguard Worker std::array<std::byte, 4> buffer = Array<1, 2, 3, 4>();
250*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x04030201, ReadInOrder<int32_t>(endian::little, buffer));
251*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x01020304, ReadInOrder<int32_t>(endian::big, buffer));
252*61c4878aSAndroid Build Coastguard Worker }
253*61c4878aSAndroid Build Coastguard Worker
TEST(ReadInOrder,CArray)254*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, CArray) {
255*61c4878aSAndroid Build Coastguard Worker char buffer[5] = {1, 2, 3, 4, 99};
256*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x04030201, ReadInOrder<int32_t>(endian::little, buffer));
257*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x01020304, ReadInOrder<int32_t>(endian::big, buffer));
258*61c4878aSAndroid Build Coastguard Worker }
259*61c4878aSAndroid Build Coastguard Worker
TEST(ReadInOrder,BoundsChecking_Ok)260*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, BoundsChecking_Ok) {
261*61c4878aSAndroid Build Coastguard Worker constexpr auto buffer = Array<1, 2, 3, 4>();
262*61c4878aSAndroid Build Coastguard Worker uint16_t value = 0;
263*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(ReadInOrder(endian::little, buffer, value));
264*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x0201, value);
265*61c4878aSAndroid Build Coastguard Worker }
266*61c4878aSAndroid Build Coastguard Worker
TEST(ReadInOrder,BoundsChecking_TooSmall)267*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, BoundsChecking_TooSmall) {
268*61c4878aSAndroid Build Coastguard Worker constexpr auto buffer = Array<1, 2, 3>();
269*61c4878aSAndroid Build Coastguard Worker int32_t value = 0;
270*61c4878aSAndroid Build Coastguard Worker EXPECT_FALSE(ReadInOrder(endian::little, buffer, value));
271*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0, value);
272*61c4878aSAndroid Build Coastguard Worker }
273*61c4878aSAndroid Build Coastguard Worker
TEST(ReadInOrder,PartialLittleEndian)274*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, PartialLittleEndian) {
275*61c4878aSAndroid Build Coastguard Worker constexpr auto buffer = Array<1, 2, 3, 4>();
276*61c4878aSAndroid Build Coastguard Worker
277*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x00000000, ReadInOrder<int32_t>(endian::little, buffer.data(), 0));
278*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x00000001, ReadInOrder<int32_t>(endian::little, buffer.data(), 1));
279*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x00000201, ReadInOrder<int32_t>(endian::little, buffer.data(), 2));
280*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x00030201, ReadInOrder<int32_t>(endian::little, buffer.data(), 3));
281*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x04030201, ReadInOrder<int32_t>(endian::little, buffer.data(), 4));
282*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x04030201, ReadInOrder<int32_t>(endian::little, buffer.data(), 5));
283*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x04030201,
284*61c4878aSAndroid Build Coastguard Worker ReadInOrder<int32_t>(endian::little, buffer.data(), 100));
285*61c4878aSAndroid Build Coastguard Worker }
286*61c4878aSAndroid Build Coastguard Worker
TEST(ReadInOrder,PartialBigEndian)287*61c4878aSAndroid Build Coastguard Worker TEST(ReadInOrder, PartialBigEndian) {
288*61c4878aSAndroid Build Coastguard Worker constexpr auto buffer = Array<1, 2, 3, 4>();
289*61c4878aSAndroid Build Coastguard Worker
290*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x00000000, ReadInOrder<int32_t>(endian::big, buffer.data(), 0));
291*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x01000000, ReadInOrder<int32_t>(endian::big, buffer.data(), 1));
292*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x01020000, ReadInOrder<int32_t>(endian::big, buffer.data(), 2));
293*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x01020300, ReadInOrder<int32_t>(endian::big, buffer.data(), 3));
294*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x01020304, ReadInOrder<int32_t>(endian::big, buffer.data(), 4));
295*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x01020304, ReadInOrder<int32_t>(endian::big, buffer.data(), 5));
296*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(0x01020304, ReadInOrder<int32_t>(endian::big, buffer.data(), 100));
297*61c4878aSAndroid Build Coastguard Worker }
298*61c4878aSAndroid Build Coastguard Worker
299*61c4878aSAndroid Build Coastguard Worker } // namespace
300*61c4878aSAndroid Build Coastguard Worker } // namespace pw::bytes
301