// Copyright 2021 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_varint/stream.h" #include #include #include #include #include #include "gtest/gtest.h" #include "pw_stream/memory_stream.h" namespace pw::varint { namespace { template auto MakeBuffer(const char (&data)[kStringSize]) { constexpr size_t kSizeBytes = kStringSize - 1; static_assert(kSizeBytes <= 10, "Varint arrays never need be larger than 10"); std::array array; std::memcpy(array.data(), data, kSizeBytes); return array; } } // namespace TEST(VarintRead, Signed64_SingleByte) { int64_t value = -1234; { const auto buffer = MakeBuffer("\x00"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 1u); EXPECT_EQ(value, 0); } { const auto buffer = MakeBuffer("\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 1u); EXPECT_EQ(value, -1); } { const auto buffer = MakeBuffer("\x02"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 1u); EXPECT_EQ(value, 1); } { const auto buffer = MakeBuffer("\x03"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 1u); EXPECT_EQ(value, -2); } { const auto buffer = MakeBuffer("\x04"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 1u); EXPECT_EQ(value, 2); } } TEST(VarintRead, Signed64_MultiByte) { int64_t value = -1234; { const auto buffer = MakeBuffer("\x80\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 2u); EXPECT_EQ(value, 64); } { const auto buffer = MakeBuffer("\x81\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 2u); EXPECT_EQ(value, -65); } { const auto buffer = MakeBuffer("\x82\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 2u); EXPECT_EQ(value, 65); } { const auto buffer = MakeBuffer("\xff\xff\xff\xff\x0f"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 5u); EXPECT_EQ(value, std::numeric_limits::min()); } { const auto buffer = MakeBuffer("\xfe\xff\xff\xff\x0f"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 5u); EXPECT_EQ(value, std::numeric_limits::max()); } { const auto buffer = MakeBuffer("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 10u); EXPECT_EQ(value, std::numeric_limits::min()); } { const auto buffer = MakeBuffer("\xfe\xff\xff\xff\xff\xff\xff\xff\xff\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 10u); EXPECT_EQ(value, std::numeric_limits::max()); } } TEST(VarintRead, Unsigned64_SingleByte) { uint64_t value = 1234; { const auto buffer = MakeBuffer("\x00"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 1u); EXPECT_EQ(value, 0u); } { const auto buffer = MakeBuffer("\x04"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 1u); EXPECT_EQ(value, 4u); } { const auto buffer = MakeBuffer("\x41"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 1u); EXPECT_EQ(value, 65u); } } TEST(VarintRead, Unsigned64_MultiByte) { uint64_t value = -1234; { const auto buffer = MakeBuffer("\x80\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 2u); EXPECT_EQ(value, 128u); } { const auto buffer = MakeBuffer("\x81\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 2u); EXPECT_EQ(value, 129u); } { const auto buffer = MakeBuffer("\xfe\xff\xff\xff\x0f"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 5u); EXPECT_EQ(value, std::numeric_limits::max() - 1); } { const auto buffer = MakeBuffer("\xff\xff\xff\xff\x0f"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 5u); EXPECT_EQ(value, std::numeric_limits::max()); } { const auto buffer = MakeBuffer("\xfe\xff\xff\xff\xff\xff\xff\xff\xff\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 10u); EXPECT_EQ(value, std::numeric_limits::max() - 1); } { const auto buffer = MakeBuffer("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01"); stream::MemoryReader reader(buffer); const auto sws = Read(reader, &value); EXPECT_TRUE(sws.ok()); EXPECT_EQ(sws.size(), 10u); EXPECT_EQ(value, std::numeric_limits::max()); } } } // namespace pw::varint