#include "coding/varint.hpp" #include "testing/testing.hpp" #include "coding/byte_stream.hpp" #include "base/macros.hpp" #include "base/stl_add.hpp" namespace { template void TestVarUint(T const x) { vector data; PushBackByteSink > dst(data); WriteVarUint(dst, x); ArrayByteSource src(&data[0]); TEST_EQUAL(ReadVarUint(src), x, ()); size_t const bytesRead = src.PtrUC() - &data[0]; TEST_EQUAL(bytesRead, data.size(), (x)); } template void TestVarInt(T const x) { vector data; PushBackByteSink > dst(data); WriteVarInt(dst, x); ArrayByteSource src(&data[0]); TEST_EQUAL(ReadVarInt(src), x, ()); size_t const bytesRead = src.PtrUC() - &data[0]; TEST_EQUAL(bytesRead, data.size(), (x)); } } UNIT_TEST(VarUint0) { // TestVarUint(static_cast(0)); // TestVarUint(static_cast(0)); TestVarUint(static_cast(0)); TestVarUint(static_cast(0)); } UNIT_TEST(VarUintMinus1) { // TestVarUint(static_cast(-1)); // TestVarUint(static_cast(-1)); TestVarUint(static_cast(-1)); TestVarUint(static_cast(-1)); } UNIT_TEST(VarUint32) { for (int b = 0; b <= 32; ++b) for (uint64_t i = (1ULL << b) - 3; i <= uint32_t(-1) && i <= (1ULL << b) + 147; ++i) TestVarUint(static_cast(i)); } UNIT_TEST(VarInt32) { for (int b = 0; b <= 32; ++b) { for (uint64_t i = (1ULL << b) - 3; i <= uint32_t(-1) && i <= (1ULL << b) + 147; ++i) { TestVarInt(static_cast(i)); TestVarInt(static_cast(-i)); } } int const bound = 10000; for (int i = -bound; i <= bound; ++i) TestVarInt(static_cast(i)); for (int i = 0; i <= bound; ++i) TestVarUint(static_cast(i)); } UNIT_TEST(VarIntSize) { vector data; PushBackByteSink > dst(data); WriteVarInt(dst, 60); TEST_EQUAL(data.size(), 1, ()); data.clear(); WriteVarInt(dst, -60); TEST_EQUAL(data.size(), 1, ()); data.clear(); WriteVarInt(dst, 120); TEST_EQUAL(data.size(), 2, ()); data.clear(); WriteVarInt(dst, -120); TEST_EQUAL(data.size(), 2, ()); } UNIT_TEST(VarIntMax) { TestVarUint(uint32_t(-1)); TestVarUint(uint64_t(-1)); TestVarInt(int32_t(2147483647)); TestVarInt(int32_t(-2147483648LL)); TestVarInt(int64_t(9223372036854775807LL)); // TestVarInt(int64_t(-9223372036854775808LL)); } UNIT_TEST(ReadVarInt64Array_EmptyArray) { vector result; void const * pEnd = ReadVarInt64Array(NULL, (void *)0, MakeBackInsertFunctor(result)); TEST_EQUAL(result, vector(), ("UntilBufferEnd")); TEST_EQUAL(reinterpret_cast(pEnd), 0, ("UntilBufferEnd")); pEnd = ReadVarInt64Array(NULL, (size_t)0, MakeBackInsertFunctor(result)); TEST_EQUAL(result, vector(), ("GivenSize")); TEST_EQUAL(reinterpret_cast(pEnd), 0, ("GivenSize")); } UNIT_TEST(ReadVarInt64Array) { vector values; // Fill in values. { int64_t const baseValues [] = { 0, 127, 128, (2 << 28) - 1, (2 << 28), (2LL << 31), (2LL << 31) - 1, 0xFFFFFFFF - 1, 0xFFFFFFFF, 0xFFFFFFFFFFULL }; for (size_t i = 0; i < ARRAY_SIZE(baseValues); ++i) { values.push_back(baseValues[i]); values.push_back(-baseValues[i]); } sort(values.begin(), values.end()); values.erase(unique(values.begin(), values.end()), values.end()); } // Test all subsets. for (size_t i = 1; i < 1U << values.size(); ++i) { vector testValues; for (size_t j = 0; j < values.size(); ++j) if (i & (1 << j)) testValues.push_back(values[j]); vector data; { PushBackByteSink > dst(data); for (size_t j = 0; j < testValues.size(); ++j) WriteVarInt(dst, testValues[j]); } ASSERT_GREATER(data.size(), 0, ()); { // Factor out variables here to show the obvious compiler error. // clang 3.5, loop optimization. /// @todo Need to check with the new XCode (and clang) update. void const * pDataStart = &data[0]; void const * pDataEnd = &data[0] + data.size(); vector result; void const * pEnd = ReadVarInt64Array(pDataStart, pDataEnd, MakeBackInsertFunctor(result)); TEST_EQUAL(pEnd, pDataEnd, ("UntilBufferEnd", data.size())); TEST_EQUAL(result, testValues, ("UntilBufferEnd", data.size())); } { vector result; void const * pEnd = ReadVarInt64Array(&data[0], testValues.size(), MakeBackInsertFunctor(result)); TEST_EQUAL(pEnd, &data[0] + data.size(), ("GivenSize", data.size())); TEST_EQUAL(result, testValues, ("GivenSize", data.size())); } } }