1*61c4878aSAndroid Build Coastguard Worker
2*61c4878aSAndroid Build Coastguard Worker // Copyright 2022 The Pigweed Authors
3*61c4878aSAndroid Build Coastguard Worker //
4*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
5*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
6*61c4878aSAndroid Build Coastguard Worker // the License at
7*61c4878aSAndroid Build Coastguard Worker //
8*61c4878aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
9*61c4878aSAndroid Build Coastguard Worker //
10*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
14*61c4878aSAndroid Build Coastguard Worker // the License.
15*61c4878aSAndroid Build Coastguard Worker
16*61c4878aSAndroid Build Coastguard Worker #include "pw_bytes/bit.h"
17*61c4878aSAndroid Build Coastguard Worker
18*61c4878aSAndroid Build Coastguard Worker #include <cstdint>
19*61c4878aSAndroid Build Coastguard Worker #include <cstring>
20*61c4878aSAndroid Build Coastguard Worker
21*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
22*61c4878aSAndroid Build Coastguard Worker
23*61c4878aSAndroid Build Coastguard Worker namespace pw::bytes {
24*61c4878aSAndroid Build Coastguard Worker namespace {
25*61c4878aSAndroid Build Coastguard Worker
26*61c4878aSAndroid Build Coastguard Worker // SignExtend unsigned integer values into signed integers.
27*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kNegative24Bits = 0x00FACADE;
28*61c4878aSAndroid Build Coastguard Worker constexpr int32_t kExtendedNegative24Bits = SignExtend<24>(kNegative24Bits);
29*61c4878aSAndroid Build Coastguard Worker static_assert(kExtendedNegative24Bits == static_cast<int32_t>(0xFFFACADE));
30*61c4878aSAndroid Build Coastguard Worker
31*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kPositive20Bits = 0x00000ACE;
32*61c4878aSAndroid Build Coastguard Worker constexpr int32_t kExtendedPositive20Bits = SignExtend<20>(kPositive20Bits);
33*61c4878aSAndroid Build Coastguard Worker static_assert(kExtendedPositive20Bits == static_cast<int32_t>(0x00000ACE));
34*61c4878aSAndroid Build Coastguard Worker
35*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kNegative12Bits = 0x00000ACE;
36*61c4878aSAndroid Build Coastguard Worker constexpr int32_t kExtendedNegative12Bits = SignExtend<12>(kNegative12Bits);
37*61c4878aSAndroid Build Coastguard Worker static_assert(kExtendedNegative12Bits == static_cast<int32_t>(0xFFFFFACE));
38*61c4878aSAndroid Build Coastguard Worker
39*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t k32Bits = 0b10100000101000001010000010100000;
40*61c4878aSAndroid Build Coastguard Worker // ExtractBits: extract single bit.
41*61c4878aSAndroid Build Coastguard Worker constexpr uint8_t kZeroBit = ExtractBits<uint8_t, 4, 4>(k32Bits);
42*61c4878aSAndroid Build Coastguard Worker static_assert(kZeroBit == 0);
43*61c4878aSAndroid Build Coastguard Worker constexpr uint8_t kOneBit = ExtractBits<uint8_t, 5, 5>(k32Bits);
44*61c4878aSAndroid Build Coastguard Worker static_assert(kOneBit == 1);
45*61c4878aSAndroid Build Coastguard Worker // ExtractBits: extract 16 bits from uint32_t to uint16_t.
46*61c4878aSAndroid Build Coastguard Worker constexpr uint16_t kExtracted16Bits = 0b1010000010100000;
47*61c4878aSAndroid Build Coastguard Worker constexpr uint16_t k15To0Bits = ExtractBits<uint32_t, 15, 0>(k32Bits);
48*61c4878aSAndroid Build Coastguard Worker static_assert(k15To0Bits == kExtracted16Bits);
49*61c4878aSAndroid Build Coastguard Worker constexpr uint16_t k23To8Bits = ExtractBits<uint16_t, 23, 8>(k32Bits);
50*61c4878aSAndroid Build Coastguard Worker static_assert(k23To8Bits == kExtracted16Bits);
51*61c4878aSAndroid Build Coastguard Worker constexpr uint16_t k31To16Bits = ExtractBits<uint16_t, 31, 16>(k32Bits);
52*61c4878aSAndroid Build Coastguard Worker static_assert(k31To16Bits == kExtracted16Bits);
53*61c4878aSAndroid Build Coastguard Worker // ExtractBits: extract 31 bits.
54*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kExtracted31Bits = 0b1010000010100000101000001010000;
55*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t k31To1Bits = ExtractBits<uint32_t, 31, 1>(k32Bits);
56*61c4878aSAndroid Build Coastguard Worker static_assert(k31To1Bits == kExtracted31Bits);
57*61c4878aSAndroid Build Coastguard Worker // ExtractBits: extract all bits.
58*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t k31To0Bits = ExtractBits<uint32_t, 31, 0>(k32Bits);
59*61c4878aSAndroid Build Coastguard Worker static_assert(k31To0Bits == k32Bits);
60*61c4878aSAndroid Build Coastguard Worker
TEST(Endian,NativeIsBigOrLittle)61*61c4878aSAndroid Build Coastguard Worker TEST(Endian, NativeIsBigOrLittle) {
62*61c4878aSAndroid Build Coastguard Worker EXPECT_TRUE(endian::native == endian::little ||
63*61c4878aSAndroid Build Coastguard Worker endian::native == endian::big);
64*61c4878aSAndroid Build Coastguard Worker }
65*61c4878aSAndroid Build Coastguard Worker
TEST(Endian,NativeIsCorrect)66*61c4878aSAndroid Build Coastguard Worker TEST(Endian, NativeIsCorrect) {
67*61c4878aSAndroid Build Coastguard Worker constexpr uint32_t kInteger = 0x11223344u;
68*61c4878aSAndroid Build Coastguard Worker int8_t bytes[sizeof(kInteger)] = {};
69*61c4878aSAndroid Build Coastguard Worker std::memcpy(bytes, &kInteger, sizeof(kInteger));
70*61c4878aSAndroid Build Coastguard Worker
71*61c4878aSAndroid Build Coastguard Worker if (endian::native == endian::little) {
72*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(bytes[0], 0x44);
73*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(bytes[1], 0x33);
74*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(bytes[2], 0x22);
75*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(bytes[3], 0x11);
76*61c4878aSAndroid Build Coastguard Worker } else {
77*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(bytes[0], 0x11);
78*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(bytes[1], 0x22);
79*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(bytes[2], 0x33);
80*61c4878aSAndroid Build Coastguard Worker EXPECT_EQ(bytes[3], 0x44);
81*61c4878aSAndroid Build Coastguard Worker }
82*61c4878aSAndroid Build Coastguard Worker }
83*61c4878aSAndroid Build Coastguard Worker
84*61c4878aSAndroid Build Coastguard Worker } // namespace
85*61c4878aSAndroid Build Coastguard Worker } // namespace pw::bytes
86