#include "coding/var_serial_vector.hpp" #include "testing/testing.hpp" #include "coding/byte_stream.hpp" #include "coding/hex.hpp" #include "coding/reader.hpp" #include "coding/writer.hpp" #include "base/macros.hpp" #include "std/random.hpp" #include "std/string.hpp" #include "std/vector.hpp" char const kHexSerial[] = "03000000" "01000000" "04000000" "06000000" "616263646566"; namespace { template void WriteVarSerialVector(ItT begin, ItT end, TDstStream & dst) { vector offsets; uint32_t offset = 0; for (ItT it = begin; it != end; ++it) { offset += it->size() * sizeof((*it)[0]); offsets.push_back(offset); } WriteToSink(dst, static_cast(end - begin)); for (size_t i = 0; i < offsets.size(); ++i) WriteToSink(dst, offsets[i]); for (ItT it = begin; it != end; ++it) { typename ItT::value_type const & v = *it; if (!v.empty()) dst.Write(&v[0], v.size() * sizeof(v[0])); } } } UNIT_TEST(WriteSerial) { vector elements; elements.push_back("a"); elements.push_back("bcd"); elements.push_back("ef"); string output; PushBackByteSink sink(output); WriteVarSerialVector(elements.begin(), elements.end(), sink); TEST_EQUAL(ToHex(output), kHexSerial, ()); } UNIT_TEST(WriteSerialWithWriter) { string output; MemWriter writer(output); VarSerialVectorWriter > recordWriter(writer, 3); writer.Write("a", 1); recordWriter.FinishRecord(); writer.Write("bcd", 3); recordWriter.FinishRecord(); writer.Write("ef", 2); recordWriter.FinishRecord(); TEST_EQUAL(ToHex(output), kHexSerial, ()); } UNIT_TEST(ReadSerial) { string serial(FromHex(string(kHexSerial))); MemReader memReader(&serial[0], serial.size()); ReaderSource memSource(memReader); VarSerialVectorReader reader(memSource); TEST_EQUAL(reader.Read(0), "a", ()); TEST_EQUAL(reader.Read(1), "bcd", ()); TEST_EQUAL(reader.Read(2), "ef", ()); } UNIT_TEST(EncodeDecode) { mt19937 rng(0); vector elements; for (size_t i = 0; i < 1024; ++i) { string s(1 + (rng() % 20), 0); for (size_t j = 0; j < s.size(); ++j) s[j] = static_cast(rng() % 26) + 'a'; elements.push_back(s); } string serial; PushBackByteSink sink(serial); WriteVarSerialVector(elements.begin(), elements.end(), sink); MemReader memReader(serial.c_str(), serial.size()); ReaderSource memSource(memReader); VarSerialVectorReader reader(memSource); for (size_t i = 0; i < elements.size(); ++i) TEST_EQUAL(reader.Read(static_cast(i)), elements[i], ()); }