|  | // Copyright 2020 The Pigweed Authors | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); you may not | 
|  | // use this file except in compliance with the License. You may obtain a copy of | 
|  | // the License at | 
|  | // | 
|  | //     https://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 
|  | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | 
|  | // License for the specific language governing permissions and limitations under | 
|  | // the License. | 
|  |  | 
|  | #include "pw_bytes/byte_builder.h" | 
|  |  | 
|  | #include <array> | 
|  | #include <cstddef> | 
|  |  | 
|  | #include "gtest/gtest.h" | 
|  |  | 
|  | using std::byte; | 
|  |  | 
|  | template <typename... Args> | 
|  | constexpr std::array<byte, sizeof...(Args)> MakeBytes(Args... args) noexcept { | 
|  | return {static_cast<byte>(args)...}; | 
|  | } | 
|  |  | 
|  | namespace pw { | 
|  | namespace { | 
|  |  | 
|  | TEST(ByteBuilder, EmptyBuffer_SizeAndMaxSizeAreCorrect) { | 
|  | ByteBuilder bb(ByteSpan{}); | 
|  |  | 
|  | EXPECT_TRUE(bb.empty()); | 
|  | EXPECT_EQ(0u, bb.size()); | 
|  | EXPECT_EQ(0u, bb.max_size()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, NonEmptyBufferOfSize0_SizeAndMaxSizeAreCorrect) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuilder bb(buffer); | 
|  |  | 
|  | EXPECT_TRUE(bb.empty()); | 
|  | EXPECT_EQ(0u, bb.size()); | 
|  | EXPECT_EQ(3u, bb.max_size()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Constructor_InsertsEmptyBuffer) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuilder bb(buffer); | 
|  |  | 
|  | EXPECT_TRUE(bb.empty()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, EmptyBuffer_Append) { | 
|  | ByteBuilder bb(ByteSpan{}); | 
|  | EXPECT_TRUE(bb.empty()); | 
|  |  | 
|  | auto bytesTestLiteral = MakeBytes(0x04, 0x05); | 
|  |  | 
|  | EXPECT_FALSE(bb.append(bytesTestLiteral.data(), 2).ok()); | 
|  | EXPECT_EQ(0u, bb.size()); | 
|  | EXPECT_EQ(0u, bb.max_size()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, NonEmptyBufferOfSize0_Append) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuilder bb(buffer); | 
|  | EXPECT_TRUE(bb.empty()); | 
|  |  | 
|  | auto bytesTestLiteral = MakeBytes(0x04, 0x05); | 
|  |  | 
|  | EXPECT_TRUE(bb.append(bytesTestLiteral.data(), 2).ok()); | 
|  | EXPECT_EQ(byte{0x04}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0x05}, bb.data()[1]); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, NonEmptyBufferOfSize0_Append_Partial_NotResourceExhausted) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuilder bb(buffer); | 
|  |  | 
|  | EXPECT_TRUE(bb.empty()); | 
|  |  | 
|  | auto bytesTestLiteral = MakeBytes(0x04, 0x05, 0x06, 0x07); | 
|  |  | 
|  | EXPECT_TRUE(bb.append(bytesTestLiteral.data(), 3).ok()); | 
|  | EXPECT_EQ(byte{0x04}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0x05}, bb.data()[1]); | 
|  | EXPECT_EQ(byte{0x06}, bb.data()[2]); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, NonEmptyBufferOfSize0_Append_Partial_ResourceExhausted) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuilder bb(buffer); | 
|  |  | 
|  | EXPECT_TRUE(bb.empty()); | 
|  |  | 
|  | auto bytesTestLiteral = MakeBytes(0x04, 0x05, 0x06, 0x07); | 
|  |  | 
|  | EXPECT_FALSE(bb.append(bytesTestLiteral.data(), 4).ok()); | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, bb.status()); | 
|  | EXPECT_EQ(0u, bb.size()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Append_RepeatedBytes) { | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.empty()); | 
|  |  | 
|  | EXPECT_TRUE(bb.append(7, byte{0x04}).ok()); | 
|  |  | 
|  | for (size_t i = 0; i < 7; i++) { | 
|  | EXPECT_EQ(byte{0x04}, bb.data()[i]); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Append_Bytes_Full) { | 
|  | ByteBuffer<8> bb; | 
|  |  | 
|  | EXPECT_EQ(8u, bb.max_size() - bb.size()); | 
|  |  | 
|  | EXPECT_TRUE(bb.append(8, byte{0x04}).ok()); | 
|  |  | 
|  | for (size_t i = 0; i < 8; i++) { | 
|  | EXPECT_EQ(byte{0x04}, bb.data()[i]); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Append_Bytes_Exhausted) { | 
|  | ByteBuffer<8> bb; | 
|  |  | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, bb.append(9, byte{0x04}).status()); | 
|  | EXPECT_EQ(0u, bb.size()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Append_Partial) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<12> bb; | 
|  |  | 
|  | EXPECT_TRUE(bb.append(buffer.data(), 2).ok()); | 
|  | EXPECT_EQ(2u, bb.size()); | 
|  | EXPECT_EQ(byte{0x01}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0x02}, bb.data()[1]); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, EmptyBuffer_Resize_WritesNothing) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuilder bb(buffer); | 
|  |  | 
|  | bb.resize(0); | 
|  | EXPECT_TRUE(bb.ok()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, EmptyBuffer_Resize_Larger_Fails) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuilder bb(buffer); | 
|  |  | 
|  | bb.resize(1); | 
|  | EXPECT_EQ(Status::OUT_OF_RANGE, bb.append(9, byte{0x04}).status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Resize_Smaller) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  |  | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | bb.resize(1); | 
|  | EXPECT_TRUE(bb.ok()); | 
|  | EXPECT_EQ(1u, bb.size()); | 
|  | EXPECT_EQ(byte{0x01}, bb.data()[0]); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Resize_Clear) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  |  | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | bb.resize(0); | 
|  | EXPECT_TRUE(bb.ok()); | 
|  | EXPECT_EQ(0u, bb.size()); | 
|  | EXPECT_TRUE(bb.empty()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Resize_Larger_Fails) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  |  | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | EXPECT_EQ(3u, bb.size()); | 
|  | bb.resize(5); | 
|  | EXPECT_EQ(3u, bb.size()); | 
|  | EXPECT_EQ(bb.status(), Status::OUT_OF_RANGE); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Status_StartsOk) { | 
|  | ByteBuffer<16> bb; | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Status_StatusUpdate) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<2> bb; | 
|  |  | 
|  | EXPECT_FALSE(bb.append(buffer).ok()); | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, bb.status()); | 
|  |  | 
|  | bb.resize(4); | 
|  | EXPECT_EQ(Status::OUT_OF_RANGE, bb.status()); | 
|  |  | 
|  | EXPECT_FALSE(bb.append(buffer.data(), 0).ok()); | 
|  | EXPECT_EQ(Status::OUT_OF_RANGE, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, Status_ClearStatus_SetsStatusToOk) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<2> bb; | 
|  |  | 
|  | EXPECT_FALSE(bb.append(buffer).ok()); | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, bb.status()); | 
|  |  | 
|  | bb.clear_status(); | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, PushBack) { | 
|  | ByteBuffer<12> bb; | 
|  | bb.push_back(byte{0x01}); | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | EXPECT_EQ(1u, bb.size()); | 
|  | EXPECT_EQ(byte{0x01}, bb.data()[0]); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, PushBack_Full) { | 
|  | ByteBuffer<1> bb; | 
|  | bb.push_back(byte{0x01}); | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | EXPECT_EQ(1u, bb.size()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, PushBack_Full_ResourceExhausted) { | 
|  | ByteBuffer<1> bb; | 
|  | bb.push_back(byte{0x01}); | 
|  | bb.push_back(byte{0x01}); | 
|  |  | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, bb.status()); | 
|  | EXPECT_EQ(1u, bb.size()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, PopBack) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<3> bb; | 
|  |  | 
|  | bb.append(buffer.data(), 3); | 
|  |  | 
|  | bb.pop_back(); | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | EXPECT_EQ(2u, bb.size()); | 
|  | EXPECT_EQ(byte{0x01}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0x02}, bb.data()[1]); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, PopBack_Empty) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<3> bb; | 
|  | bb.append(buffer.data(), 3); | 
|  |  | 
|  | bb.pop_back(); | 
|  | bb.pop_back(); | 
|  | bb.pop_back(); | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | EXPECT_EQ(0u, bb.size()); | 
|  | EXPECT_TRUE(bb.empty()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Assign) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<10> one; | 
|  | ByteBuffer<10> two; | 
|  |  | 
|  | one.append(buffer.data(), 3); | 
|  | EXPECT_EQ(byte{0x01}, one.data()[0]); | 
|  | EXPECT_EQ(byte{0x02}, one.data()[1]); | 
|  | EXPECT_EQ(byte{0x03}, one.data()[2]); | 
|  |  | 
|  | two = one; | 
|  | EXPECT_EQ(byte{0x01}, two.data()[0]); | 
|  | EXPECT_EQ(byte{0x02}, two.data()[1]); | 
|  | EXPECT_EQ(byte{0x03}, two.data()[2]); | 
|  |  | 
|  | auto bytesTestLiteral = MakeBytes(0x04, 0x05, 0x06, 0x07); | 
|  | one.append(bytesTestLiteral.data(), 2); | 
|  | two.append(bytesTestLiteral.data(), 4); | 
|  | EXPECT_EQ(5u, one.size()); | 
|  | EXPECT_EQ(7u, two.size()); | 
|  | EXPECT_EQ(byte{0x04}, one.data()[3]); | 
|  | EXPECT_EQ(byte{0x05}, one.data()[4]); | 
|  | EXPECT_EQ(byte{0x04}, two.data()[3]); | 
|  | EXPECT_EQ(byte{0x05}, two.data()[4]); | 
|  | EXPECT_EQ(byte{0x06}, two.data()[5]); | 
|  | EXPECT_EQ(byte{0x07}, two.data()[6]); | 
|  |  | 
|  | two.push_back(byte{0x01}); | 
|  | two.push_back(byte{0x01}); | 
|  | two.push_back(byte{0x01}); | 
|  | two.push_back(byte{0x01}); | 
|  | ASSERT_EQ(Status::RESOURCE_EXHAUSTED, two.status()); | 
|  |  | 
|  | one = two; | 
|  | EXPECT_EQ(byte{0x01}, two.data()[7]); | 
|  | EXPECT_EQ(byte{0x01}, two.data()[8]); | 
|  | EXPECT_EQ(byte{0x01}, two.data()[9]); | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, one.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, CopyConstructFromSameSize) { | 
|  | ByteBuffer<10> one; | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  |  | 
|  | one.append(buffer.data(), 3); | 
|  | EXPECT_EQ(byte{0x01}, one.data()[0]); | 
|  | EXPECT_EQ(byte{0x02}, one.data()[1]); | 
|  | EXPECT_EQ(byte{0x03}, one.data()[2]); | 
|  |  | 
|  | ByteBuffer<10> two(one); | 
|  | EXPECT_EQ(byte{0x01}, two.data()[0]); | 
|  | EXPECT_EQ(byte{0x02}, two.data()[1]); | 
|  | EXPECT_EQ(byte{0x03}, two.data()[2]); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, CopyConstructFromSmaller) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<2> one; | 
|  | one.append(buffer.data(), 2); | 
|  | ByteBuffer<3> two(one); | 
|  |  | 
|  | EXPECT_EQ(byte{0x01}, two.data()[0]); | 
|  | EXPECT_EQ(byte{0x02}, two.data()[1]); | 
|  | EXPECT_EQ(Status::OK, two.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, ResizeError_NoDataAddedAfter) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  |  | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | EXPECT_EQ(3u, bb.size()); | 
|  | bb.resize(5); | 
|  | EXPECT_EQ(3u, bb.size()); | 
|  | EXPECT_EQ(bb.status(), Status::OUT_OF_RANGE); | 
|  |  | 
|  | bb.PutInt8(0xFE); | 
|  | EXPECT_EQ(3u, bb.size()); | 
|  | EXPECT_EQ(bb.status(), Status::OUT_OF_RANGE); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuilder, AddingNoBytesToZeroSizedByteBuffer) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<0> bb; | 
|  |  | 
|  | EXPECT_TRUE(bb.append(buffer.data(), 0).ok()); | 
|  | EXPECT_EQ(0u, bb.size()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Putting8ByteInts_Full) { | 
|  | ByteBuffer<2> bb; | 
|  | bb.PutInt8(0xFE); | 
|  | bb.PutUint8(0x02); | 
|  |  | 
|  | EXPECT_EQ(byte{0xFE}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0x02}, bb.data()[1]); | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Putting8ByteInts_Exhausted) { | 
|  | ByteBuffer<2> bb; | 
|  | bb.PutInt8(0xFE); | 
|  | bb.PutUint8(0x02); | 
|  | bb.PutUint8(0x05); | 
|  |  | 
|  | EXPECT_EQ(byte{0xFE}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0x02}, bb.data()[1]); | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Putting16ByteInts_Full_kLittleEndian) { | 
|  | ByteBuffer<4> bb; | 
|  | bb.PutInt16(0xFFF7); | 
|  | bb.PutUint16(0x0008); | 
|  |  | 
|  | EXPECT_EQ(byte{0xF7}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0xFF}, bb.data()[1]); | 
|  | EXPECT_EQ(byte{0x08}, bb.data()[2]); | 
|  | EXPECT_EQ(byte{0x00}, bb.data()[3]); | 
|  |  | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Putting16ByteInts_Exhausted_kBigEndian) { | 
|  | ByteBuffer<5> bb; | 
|  | bb.PutInt16(0xFFF7, ByteOrder::kBigEndian); | 
|  | bb.PutUint16(0x0008, ByteOrder::kBigEndian); | 
|  |  | 
|  | EXPECT_EQ(byte{0xFF}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0xF7}, bb.data()[1]); | 
|  | EXPECT_EQ(byte{0x00}, bb.data()[2]); | 
|  | EXPECT_EQ(byte{0x08}, bb.data()[3]); | 
|  |  | 
|  | bb.PutInt16(0xFAFA, ByteOrder::kBigEndian); | 
|  | EXPECT_EQ(4u, bb.size()); | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Putting32ByteInts_Full_kLittleEndian) { | 
|  | ByteBuffer<8> bb; | 
|  | bb.PutInt32(0xFFFFFFF1); | 
|  | bb.PutUint32(0x00000014); | 
|  |  | 
|  | EXPECT_EQ(byte{0xF1}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0xFF}, bb.data()[1]); | 
|  | EXPECT_EQ(byte{0xFF}, bb.data()[2]); | 
|  | EXPECT_EQ(byte{0xFF}, bb.data()[3]); | 
|  | EXPECT_EQ(byte{0x14}, bb.data()[4]); | 
|  | EXPECT_EQ(byte{0x00}, bb.data()[5]); | 
|  | EXPECT_EQ(byte{0x00}, bb.data()[6]); | 
|  | EXPECT_EQ(byte{0x00}, bb.data()[7]); | 
|  |  | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Putting32ByteInts_Exhausted_kBigEndian) { | 
|  | ByteBuffer<10> bb; | 
|  | bb.PutInt32(0xF92927B2, ByteOrder::kBigEndian); | 
|  | bb.PutUint32(0x0C90739E, ByteOrder::kBigEndian); | 
|  |  | 
|  | EXPECT_EQ(byte{0xF9}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0x29}, bb.data()[1]); | 
|  | EXPECT_EQ(byte{0x27}, bb.data()[2]); | 
|  | EXPECT_EQ(byte{0xB2}, bb.data()[3]); | 
|  | EXPECT_EQ(byte{0x0C}, bb.data()[4]); | 
|  | EXPECT_EQ(byte{0x90}, bb.data()[5]); | 
|  | EXPECT_EQ(byte{0x73}, bb.data()[6]); | 
|  | EXPECT_EQ(byte{0x9E}, bb.data()[7]); | 
|  |  | 
|  | bb.PutInt32(-114743374, ByteOrder::kBigEndian); | 
|  | EXPECT_EQ(8u, bb.size()); | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Putting64ByteInts_Full_kLittleEndian) { | 
|  | ByteBuffer<16> bb; | 
|  | bb.PutInt64(0x000001E8A7A0D569); | 
|  | bb.PutUint64(0xFFFFFE17585F2A97); | 
|  |  | 
|  | EXPECT_EQ(byte{0x69}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0xD5}, bb.data()[1]); | 
|  | EXPECT_EQ(byte{0xA0}, bb.data()[2]); | 
|  | EXPECT_EQ(byte{0xA7}, bb.data()[3]); | 
|  | EXPECT_EQ(byte{0xE8}, bb.data()[4]); | 
|  | EXPECT_EQ(byte{0x01}, bb.data()[5]); | 
|  | EXPECT_EQ(byte{0x00}, bb.data()[6]); | 
|  | EXPECT_EQ(byte{0x00}, bb.data()[7]); | 
|  | EXPECT_EQ(byte{0x97}, bb.data()[8]); | 
|  | EXPECT_EQ(byte{0x2A}, bb.data()[9]); | 
|  | EXPECT_EQ(byte{0x5F}, bb.data()[10]); | 
|  | EXPECT_EQ(byte{0x58}, bb.data()[11]); | 
|  | EXPECT_EQ(byte{0x17}, bb.data()[12]); | 
|  | EXPECT_EQ(byte{0xFE}, bb.data()[13]); | 
|  | EXPECT_EQ(byte{0xFF}, bb.data()[14]); | 
|  | EXPECT_EQ(byte{0xFF}, bb.data()[15]); | 
|  |  | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Putting64ByteInts_Exhausted_kBigEndian) { | 
|  | ByteBuffer<20> bb; | 
|  | bb.PutUint64(0x000001E8A7A0D569, ByteOrder::kBigEndian); | 
|  | bb.PutInt64(0xFFFFFE17585F2A97, ByteOrder::kBigEndian); | 
|  |  | 
|  | EXPECT_EQ(byte{0x00}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0x00}, bb.data()[1]); | 
|  | EXPECT_EQ(byte{0x01}, bb.data()[2]); | 
|  | EXPECT_EQ(byte{0xE8}, bb.data()[3]); | 
|  | EXPECT_EQ(byte{0xA7}, bb.data()[4]); | 
|  | EXPECT_EQ(byte{0xA0}, bb.data()[5]); | 
|  | EXPECT_EQ(byte{0xD5}, bb.data()[6]); | 
|  | EXPECT_EQ(byte{0x69}, bb.data()[7]); | 
|  | EXPECT_EQ(byte{0xFF}, bb.data()[8]); | 
|  | EXPECT_EQ(byte{0xFF}, bb.data()[9]); | 
|  | EXPECT_EQ(byte{0xFE}, bb.data()[10]); | 
|  | EXPECT_EQ(byte{0x17}, bb.data()[11]); | 
|  | EXPECT_EQ(byte{0x58}, bb.data()[12]); | 
|  | EXPECT_EQ(byte{0x5F}, bb.data()[13]); | 
|  | EXPECT_EQ(byte{0x2A}, bb.data()[14]); | 
|  | EXPECT_EQ(byte{0x97}, bb.data()[15]); | 
|  |  | 
|  | bb.PutInt64(-6099875637501324530, ByteOrder::kBigEndian); | 
|  | EXPECT_EQ(16u, bb.size()); | 
|  | EXPECT_EQ(Status::RESOURCE_EXHAUSTED, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, PuttingInts_MixedTypes_MixedEndian) { | 
|  | ByteBuffer<16> bb; | 
|  | bb.PutUint8(0x03); | 
|  | bb.PutInt16(0xFD6D, ByteOrder::kBigEndian); | 
|  | bb.PutUint32(0x482B3D9E); | 
|  | bb.PutInt64(0x9A1C3641843DF317, ByteOrder::kBigEndian); | 
|  | bb.PutInt8(0xFB); | 
|  |  | 
|  | EXPECT_EQ(byte{0x03}, bb.data()[0]); | 
|  | EXPECT_EQ(byte{0xFD}, bb.data()[1]); | 
|  | EXPECT_EQ(byte{0x6D}, bb.data()[2]); | 
|  | EXPECT_EQ(byte{0x9E}, bb.data()[3]); | 
|  | EXPECT_EQ(byte{0x3D}, bb.data()[4]); | 
|  | EXPECT_EQ(byte{0x2B}, bb.data()[5]); | 
|  | EXPECT_EQ(byte{0x48}, bb.data()[6]); | 
|  | EXPECT_EQ(byte{0x9A}, bb.data()[7]); | 
|  | EXPECT_EQ(byte{0x1C}, bb.data()[8]); | 
|  | EXPECT_EQ(byte{0x36}, bb.data()[9]); | 
|  | EXPECT_EQ(byte{0x41}, bb.data()[10]); | 
|  | EXPECT_EQ(byte{0x84}, bb.data()[11]); | 
|  | EXPECT_EQ(byte{0x3D}, bb.data()[12]); | 
|  | EXPECT_EQ(byte{0xF3}, bb.data()[13]); | 
|  | EXPECT_EQ(byte{0x17}, bb.data()[14]); | 
|  | EXPECT_EQ(byte{0xFB}, bb.data()[15]); | 
|  |  | 
|  | EXPECT_EQ(Status::OK, bb.status()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | auto it = bb.begin(); | 
|  | EXPECT_EQ(*it, byte{0x01}); | 
|  |  | 
|  | ++it; | 
|  | EXPECT_EQ(*it, byte{0x02}); | 
|  | EXPECT_EQ(it - bb.begin(), 1); | 
|  |  | 
|  | ++it; | 
|  | EXPECT_EQ(*it, byte{0x03}); | 
|  | EXPECT_EQ(it - bb.begin(), 2); | 
|  |  | 
|  | ++it; | 
|  | EXPECT_EQ(it, bb.end()); | 
|  | EXPECT_EQ(static_cast<size_t>(it - bb.begin()), bb.size()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_PreIncrement) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | auto it = bb.begin(); | 
|  | EXPECT_EQ(*(++it), byte{0x02}); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_PostIncrement) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | auto it = bb.begin(); | 
|  | EXPECT_EQ(*(it++), byte{0x01}); | 
|  | EXPECT_EQ(*it, byte{0x02}); | 
|  | EXPECT_EQ(*(it++), byte{0x02}); | 
|  | EXPECT_EQ(*it, byte{0x03}); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_PreDecrement) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  | auto it = bb.begin(); | 
|  |  | 
|  | EXPECT_EQ(*it, byte{0x01}); | 
|  | ++it; | 
|  | EXPECT_EQ(*it, byte{0x02}); | 
|  | ++it; | 
|  | EXPECT_EQ(*it, byte{0x03}); | 
|  | ++it; | 
|  | EXPECT_EQ(it, bb.end()); | 
|  |  | 
|  | --it; | 
|  | EXPECT_EQ(*it, byte{0x03}); | 
|  | --it; | 
|  | EXPECT_EQ(*it, byte{0x02}); | 
|  | --it; | 
|  | EXPECT_EQ(*it, byte{0x01}); | 
|  | EXPECT_EQ(it, bb.begin()); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_PostDecrement) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  | auto it = bb.begin(); | 
|  |  | 
|  | it += 2; | 
|  | EXPECT_EQ(*it, byte{0x03}); | 
|  |  | 
|  | EXPECT_EQ(*(it--), byte{0x03}); | 
|  | EXPECT_EQ(*it, byte{0x02}); | 
|  | EXPECT_EQ(*(it--), byte{0x02}); | 
|  | EXPECT_EQ(*it, byte{0x01}); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_PlusEquals) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  | auto it = bb.begin(); | 
|  |  | 
|  | it += 2; | 
|  | EXPECT_EQ(*it, byte{0x03}); | 
|  |  | 
|  | it += -1; | 
|  | EXPECT_EQ(*it, byte{0x02}); | 
|  |  | 
|  | it += 1; | 
|  | EXPECT_EQ(*it, byte{0x03}); | 
|  |  | 
|  | it += -2; | 
|  | EXPECT_EQ(*it, byte{0x01}); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_MinusEquals) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  | auto it = bb.begin(); | 
|  |  | 
|  | it -= -2; | 
|  | EXPECT_EQ(*it, byte{0x03}); | 
|  |  | 
|  | it -= +1; | 
|  | EXPECT_EQ(*it, byte{0x02}); | 
|  |  | 
|  | it -= -1; | 
|  | EXPECT_EQ(*it, byte{0x03}); | 
|  |  | 
|  | it -= +2; | 
|  | EXPECT_EQ(*it, byte{0x01}); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_Plus) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  | auto it = bb.begin(); | 
|  |  | 
|  | auto test = it + 2; | 
|  | EXPECT_EQ(*test, byte{0x03}); | 
|  |  | 
|  | test = test + -1; | 
|  | EXPECT_EQ(*test, byte{0x02}); | 
|  |  | 
|  | test = test + 1; | 
|  | EXPECT_EQ(*test, byte{0x03}); | 
|  |  | 
|  | test = test + (-2); | 
|  | EXPECT_EQ(*test, byte{0x01}); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_Minus) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  | auto it = bb.begin(); | 
|  |  | 
|  | auto test = it - (-2); | 
|  | EXPECT_EQ(*test, byte{0x03}); | 
|  |  | 
|  | test = test - 1; | 
|  | EXPECT_EQ(*test, byte{0x02}); | 
|  |  | 
|  | test = test - (-1); | 
|  | EXPECT_EQ(*test, byte{0x03}); | 
|  |  | 
|  | test = test - 2; | 
|  | EXPECT_EQ(*test, byte{0x01}); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_LessThan) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | auto it_1 = bb.begin(); | 
|  | auto it_2 = it_1 + 2; | 
|  | EXPECT_EQ(*it_1, byte{0x01}); | 
|  | EXPECT_EQ(*it_2, byte{0x03}); | 
|  | EXPECT_TRUE(it_1 < it_2); | 
|  |  | 
|  | it_1++; | 
|  | it_2--; | 
|  | EXPECT_EQ(*it_1, byte{0x02}); | 
|  | EXPECT_EQ(*it_2, byte{0x02}); | 
|  | EXPECT_FALSE(it_1 < it_2); | 
|  |  | 
|  | it_1++; | 
|  | it_2--; | 
|  | EXPECT_EQ(*it_1, byte{0x03}); | 
|  | EXPECT_EQ(*it_2, byte{0x01}); | 
|  | EXPECT_FALSE(it_1 < it_2); | 
|  | EXPECT_TRUE(it_2 < it_1); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_GreaterThan) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | auto it_1 = bb.begin(); | 
|  | auto it_2 = it_1 + 2; | 
|  | EXPECT_EQ(*it_1, byte{0x01}); | 
|  | EXPECT_EQ(*it_2, byte{0x03}); | 
|  | EXPECT_FALSE(it_1 > it_2); | 
|  |  | 
|  | it_1++; | 
|  | it_2--; | 
|  | EXPECT_EQ(*it_1, byte{0x02}); | 
|  | EXPECT_EQ(*it_2, byte{0x02}); | 
|  | EXPECT_FALSE(it_1 > it_2); | 
|  |  | 
|  | it_1++; | 
|  | it_2--; | 
|  | EXPECT_EQ(*it_1, byte{0x03}); | 
|  | EXPECT_EQ(*it_2, byte{0x01}); | 
|  | EXPECT_TRUE(it_1 > it_2); | 
|  | EXPECT_FALSE(it_2 > it_1); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_LessThanEqual_GreaterThanEqual) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | auto it_1 = bb.begin(); | 
|  | auto it_2 = it_1 + 2; | 
|  | EXPECT_EQ(*it_1, byte{0x01}); | 
|  | EXPECT_EQ(*it_2, byte{0x03}); | 
|  | EXPECT_FALSE(it_1 >= it_2); | 
|  | EXPECT_TRUE(it_1 <= it_2); | 
|  |  | 
|  | it_1++; | 
|  | it_2--; | 
|  | EXPECT_EQ(*it_1, byte{0x02}); | 
|  | EXPECT_EQ(*it_2, byte{0x02}); | 
|  | EXPECT_TRUE(it_1 >= it_2); | 
|  | EXPECT_TRUE(it_1 <= it_2); | 
|  |  | 
|  | it_1++; | 
|  | it_2--; | 
|  | EXPECT_EQ(*it_1, byte{0x03}); | 
|  | EXPECT_EQ(*it_2, byte{0x01}); | 
|  | EXPECT_FALSE(it_1 <= it_2); | 
|  | EXPECT_TRUE(it_1 >= it_2); | 
|  | } | 
|  |  | 
|  | TEST(ByteBuffer, Iterator_Indexing) { | 
|  | std::array<byte, 3> buffer = MakeBytes(0x01, 0x02, 0x03); | 
|  | ByteBuffer<8> bb; | 
|  | EXPECT_TRUE(bb.append(buffer).ok()); | 
|  |  | 
|  | auto it = bb.begin(); | 
|  | EXPECT_EQ(it[0], byte{0x01}); | 
|  | EXPECT_EQ(it[1], byte{0x02}); | 
|  | EXPECT_EQ(it[2], byte{0x03}); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  | }  // namespace pw |