mirror of
https://github.com/fraillt/bitsery.git
synced 2026-06-08 08:13:56 +00:00
added -growable- function
This commit is contained in:
@@ -109,19 +109,24 @@ TEST(BufferBitsAndBytesOperations, BufferSizeIsCountedPerByteNotPerBit) {
|
||||
//read from buffer
|
||||
BufferReader br{range};
|
||||
uint16_t tmp;
|
||||
EXPECT_THAT(br.readBits(tmp,4), Eq(true));
|
||||
EXPECT_THAT(br.readBits(tmp,2), Eq(true));
|
||||
EXPECT_THAT(br.readBits(tmp,2), Eq(true));
|
||||
EXPECT_THAT(br.readBits(tmp,2), Eq(false));
|
||||
br.readBits(tmp,4);
|
||||
br.readBits(tmp,2);
|
||||
br.readBits(tmp,2);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
br.readBits(tmp,2);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));//false
|
||||
|
||||
//part of next byte
|
||||
BufferReader br1{range};
|
||||
EXPECT_THAT(br1.readBits(tmp,2), Eq(true));
|
||||
EXPECT_THAT(br1.readBits(tmp,7), Eq(false));
|
||||
br1.readBits(tmp,2);
|
||||
EXPECT_THAT(br1.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
br1.readBits(tmp,7);
|
||||
EXPECT_THAT(br1.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));//false
|
||||
|
||||
//bigger than byte
|
||||
BufferReader br2{range};
|
||||
EXPECT_THAT(br2.readBits(tmp,9), Eq(false));
|
||||
br2.readBits(tmp,9);
|
||||
EXPECT_THAT(br2.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));//false
|
||||
}
|
||||
|
||||
TEST(BufferBitsAndBytesOperations, ConsecutiveCallsToAlignHasNoEffect) {
|
||||
@@ -141,18 +146,20 @@ TEST(BufferBitsAndBytesOperations, ConsecutiveCallsToAlignHasNoEffect) {
|
||||
|
||||
unsigned char tmp;
|
||||
BufferReader br{bw.getWrittenRange()};
|
||||
EXPECT_THAT(br.readBits(tmp,2), Eq(true));
|
||||
br.readBits(tmp,2);
|
||||
EXPECT_THAT(tmp, Eq(3u));
|
||||
EXPECT_THAT(br.align(), Eq(true));
|
||||
|
||||
EXPECT_THAT(br.readBits(tmp,3), Eq(true));
|
||||
br.align();
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
br.readBits(tmp,3);
|
||||
br.align();
|
||||
br.align();
|
||||
br.align();
|
||||
EXPECT_THAT(tmp, Eq(7u));
|
||||
EXPECT_THAT(br.align(), Eq(true));
|
||||
EXPECT_THAT(br.align(), Eq(true));
|
||||
EXPECT_THAT(br.align(), Eq(true));
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
|
||||
EXPECT_THAT(br.readBits(tmp,4), Eq(true));
|
||||
br.readBits(tmp,4);
|
||||
EXPECT_THAT(tmp, Eq(15u));
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
}
|
||||
|
||||
TEST(BufferBitsAndBytesOperations, AlignWritesZerosBits) {
|
||||
@@ -166,18 +173,20 @@ TEST(BufferBitsAndBytesOperations, AlignWritesZerosBits) {
|
||||
bw.writeBits(3u, 2);
|
||||
bw.align();
|
||||
bw.flush();
|
||||
|
||||
auto range = bw.getWrittenRange();
|
||||
EXPECT_THAT(std::distance(range.begin(), range.end()), Eq(1));
|
||||
unsigned char tmp;
|
||||
BufferReader br1{bw.getWrittenRange()};
|
||||
BufferReader br1{range};
|
||||
br1.readBits(tmp,2);
|
||||
//read aligned bits
|
||||
EXPECT_THAT(br1.readBits(tmp,6), Eq(true));
|
||||
br1.readBits(tmp,6);
|
||||
EXPECT_THAT(tmp, Eq(0));
|
||||
|
||||
BufferReader br2{bw.getWrittenRange()};
|
||||
BufferReader br2{range};
|
||||
//read 2 bits
|
||||
br2.readBits(tmp,2);
|
||||
EXPECT_THAT(br2.align(), Eq(true));
|
||||
br2.align();
|
||||
EXPECT_THAT(br2.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
}
|
||||
|
||||
|
||||
@@ -219,12 +228,13 @@ TEST(BufferBitsAndBytesOperations, WriteAndReadBytes) {
|
||||
//read from buffer
|
||||
BufferReader br{range};
|
||||
IntegralTypes res{};
|
||||
EXPECT_THAT(br.readBytes<4>(res.b), Eq(true));
|
||||
EXPECT_THAT(br.readBytes<2>(res.c), Eq(true));
|
||||
EXPECT_THAT(br.readBytes<1>(res.d), Eq(true));
|
||||
EXPECT_THAT(br.readBytes<8>(res.a), Eq(true));
|
||||
EXPECT_THAT(br.readBytes<1>(res.e), Eq(true));
|
||||
EXPECT_THAT(br.readBuffer<1>(res.f, 2), Eq(true));
|
||||
br.readBytes<4>(res.b);
|
||||
br.readBytes<2>(res.c);
|
||||
br.readBytes<1>(res.d);
|
||||
br.readBytes<8>(res.a);
|
||||
br.readBytes<1>(res.e);
|
||||
br.readBuffer<1>(res.f, 2);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
//assert results
|
||||
|
||||
EXPECT_THAT(data.a, Eq(res.a));
|
||||
@@ -248,13 +258,9 @@ TEST(BufferBitsAndBytesOperations, ReadWriteBufferFncCanAcceptSignedData) {
|
||||
//read from buffer
|
||||
BufferReader br1{bw.getWrittenRange()};
|
||||
int16_t dst[DATA_SIZE]{};
|
||||
EXPECT_THAT(br1.readBuffer<2>(dst, DATA_SIZE), Eq(true));
|
||||
br1.readBuffer<2>(dst, DATA_SIZE);
|
||||
EXPECT_THAT(br1.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
EXPECT_THAT(dst, ContainerEq(src));
|
||||
|
||||
//read more than available
|
||||
BufferReader br2{bw.getWrittenRange()};
|
||||
int16_t dstMore[DATA_SIZE+1]{};
|
||||
EXPECT_THAT(br2.readBuffer<2>(dstMore, DATA_SIZE+1), Eq(false));
|
||||
}
|
||||
|
||||
TEST(BufferBitsAndBytesOperations, ReadWriteBufferCanWorkOnUnalignedData) {
|
||||
@@ -277,16 +283,37 @@ TEST(BufferBitsAndBytesOperations, ReadWriteBufferCanWorkOnUnalignedData) {
|
||||
uint8_t tmp{};
|
||||
br1.readBits(tmp, 4);
|
||||
EXPECT_THAT(tmp, Eq(15));
|
||||
EXPECT_THAT(br1.readBuffer<2>(dst, DATA_SIZE), Eq(true));
|
||||
br1.readBuffer<2>(dst, DATA_SIZE);
|
||||
EXPECT_THAT(br1.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
EXPECT_THAT(dst, ContainerEq(src));
|
||||
br1.readBits(tmp, 4);
|
||||
EXPECT_THAT(tmp, Eq(12));
|
||||
|
||||
//read more than available
|
||||
BufferReader br2{range};
|
||||
br2.readBits(tmp, 4);
|
||||
int16_t dstMore[DATA_SIZE+1]{};
|
||||
EXPECT_THAT(tmp, Eq(15));
|
||||
EXPECT_THAT(br2.readBuffer<2>(dstMore, DATA_SIZE+1), Eq(false));
|
||||
}
|
||||
|
||||
TEST(BufferBitsAndBytesOperations, RegressionTestReadBytesAfterReadBitsWithLotsOfZeroBits) {
|
||||
//setup data
|
||||
int16_t data[2]{0x0000, 0x7FFF};
|
||||
int16_t res[2]{};
|
||||
//create and write to buffer
|
||||
Buffer buf{};
|
||||
BufferWriter bw{buf};
|
||||
bw.writeBits(2u, 2);
|
||||
bw.writeBytes<2>(data[0]);
|
||||
bw.writeBytes<2>(data[1]);
|
||||
bw.align();
|
||||
bw.flush();
|
||||
auto range = bw.getWrittenRange();
|
||||
|
||||
//read from buffer
|
||||
BufferReader br{range};
|
||||
uint8_t tmp{};
|
||||
br.readBits(tmp, 2);
|
||||
EXPECT_THAT(tmp, Eq(2));
|
||||
br.readBytes<2>(res[0]);
|
||||
br.readBytes<2>(res[1]);
|
||||
br.align();
|
||||
EXPECT_THAT(res[0], Eq(data[0]));
|
||||
EXPECT_THAT(res[1], Eq(data[1]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <bitset>
|
||||
|
||||
using testing::Eq;
|
||||
using testing::ContainerEq;
|
||||
using bitsery::BufferWriter;
|
||||
using bitsery::BufferReader;
|
||||
using Buffer = bitsery::DefaultConfig::BufferType;
|
||||
@@ -42,7 +41,7 @@ struct IntegralTypes {
|
||||
int8_t f[2];
|
||||
};
|
||||
|
||||
TEST(BufferReading, ReadReturnsFalseIfNotEnoughBufferSize) {
|
||||
TEST(BufferReading, WhenReadingMoreThanAvailableThenEmptyBufferError) {
|
||||
//setup data
|
||||
uint8_t a = 111;
|
||||
|
||||
@@ -56,19 +55,34 @@ TEST(BufferReading, ReadReturnsFalseIfNotEnoughBufferSize) {
|
||||
bw.flush();
|
||||
//read from buffer
|
||||
BufferReader br{bw.getWrittenRange()};
|
||||
int16_t b;
|
||||
int32_t c;
|
||||
EXPECT_THAT(br.readBytes<4>(c), Eq(false));
|
||||
EXPECT_THAT(br.readBytes<2>(b), Eq(true));
|
||||
EXPECT_THAT(br.readBytes<2>(b), Eq(false));
|
||||
EXPECT_THAT(br.readBytes<1>(a), Eq(true));
|
||||
EXPECT_THAT(br.readBytes<1>(a), Eq(false));
|
||||
EXPECT_THAT(br.readBytes<2>(b), Eq(false));
|
||||
EXPECT_THAT(br.readBytes<4>(c), Eq(false));
|
||||
|
||||
br.readBytes<4>(c);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));
|
||||
}
|
||||
|
||||
TEST(BufferReading, ReadIsCompletedWhenAllBytesAreRead) {
|
||||
TEST(BufferReading, WhenErrorOccursThenAllOtherOperationsFailsForSameError) {
|
||||
//setup data
|
||||
uint8_t a = 111;
|
||||
|
||||
//create and write to buffer
|
||||
Buffer buf{};
|
||||
BufferWriter bw{buf};
|
||||
|
||||
bw.writeBytes<1>(a);
|
||||
bw.writeBytes<1>(a);
|
||||
bw.writeBytes<1>(a);
|
||||
bw.flush();
|
||||
//read from buffer
|
||||
BufferReader br{bw.getWrittenRange()};
|
||||
int32_t c;
|
||||
br.readBytes<4>(c);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));
|
||||
br.readBytes<1>(a);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));
|
||||
}
|
||||
|
||||
|
||||
TEST(BufferReading, ReadIsCompletedSuccessfullyWhenAllBytesAreReadWithoutErrors) {
|
||||
//setup data
|
||||
IntegralTypes data;
|
||||
data.b = 94545646;
|
||||
@@ -86,22 +100,59 @@ TEST(BufferReading, ReadIsCompletedWhenAllBytesAreRead) {
|
||||
//read from buffer
|
||||
BufferReader br{bw.getWrittenRange()};
|
||||
IntegralTypes res;
|
||||
EXPECT_THAT(br.readBytes<4>(res.b), Eq(true));
|
||||
EXPECT_THAT(br.readBytes<2>(res.c), Eq(true));
|
||||
EXPECT_THAT(br.isCompleted(), Eq(false));
|
||||
EXPECT_THAT(br.readBytes<1>(res.d), Eq(true));
|
||||
EXPECT_THAT(br.isCompleted(), Eq(true));
|
||||
EXPECT_THAT(br.readBytes<1>(res.d), Eq(false));
|
||||
EXPECT_THAT(br.isCompleted(), Eq(true));
|
||||
br.readBytes<4>(res.b);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
br.readBytes<2>(res.c);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
EXPECT_THAT(br.isCompletedSuccessfully(), Eq(false));
|
||||
br.readBytes<1>(res.d);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
EXPECT_THAT(br.isCompletedSuccessfully(), Eq(true));
|
||||
br.readBytes<1>(res.d);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));
|
||||
EXPECT_THAT(br.isCompletedSuccessfully(), Eq(false));
|
||||
|
||||
BufferReader br1{bw.getWrittenRange()};
|
||||
EXPECT_THAT(br1.readBytes<4>(res.b), Eq(true));
|
||||
EXPECT_THAT(br1.readBytes<2>(res.c), Eq(true));
|
||||
EXPECT_THAT(br1.isCompleted(), Eq(false));
|
||||
EXPECT_THAT(br1.readBytes<2>(res.c), Eq(false));
|
||||
EXPECT_THAT(br1.isCompleted(), Eq(false));
|
||||
EXPECT_THAT(br1.readBytes<1>(res.d), Eq(true));
|
||||
EXPECT_THAT(br1.isCompleted(), Eq(true));
|
||||
|
||||
br1.readBytes<4>(res.b);
|
||||
EXPECT_THAT(br1.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
br1.readBytes<2>(res.c);
|
||||
EXPECT_THAT(br1.getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
EXPECT_THAT(br1.isCompletedSuccessfully(), Eq(false));
|
||||
br1.readBytes<2>(res.c);
|
||||
EXPECT_THAT(br1.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));
|
||||
EXPECT_THAT(br1.isCompletedSuccessfully(), Eq(false));
|
||||
br1.readBytes<1>(res.d);
|
||||
EXPECT_THAT(br1.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));
|
||||
EXPECT_THAT(br1.isCompletedSuccessfully(), Eq(false));
|
||||
}
|
||||
|
||||
TEST(BufferReading, WhenReaderHasErrorsAllOperationsReadsReturnZero) {
|
||||
//setup data
|
||||
uint8_t a = 111;
|
||||
|
||||
//create and write to buffer
|
||||
Buffer buf{};
|
||||
BufferWriter bw{buf};
|
||||
|
||||
bw.writeBytes<1>(a);
|
||||
bw.writeBytes<1>(a);
|
||||
bw.writeBytes<1>(a);
|
||||
bw.flush();
|
||||
//read from buffer
|
||||
BufferReader br{bw.getWrittenRange()};
|
||||
int32_t c;
|
||||
br.readBytes<4>(c);
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));
|
||||
|
||||
int16_t r1= {-645};
|
||||
uint32_t r2[2] = {54898,87854};
|
||||
uint8_t r3 = 0xFF;
|
||||
|
||||
br.readBytes<2>(r1);
|
||||
br.readBuffer<4>(r2, 2);
|
||||
br.readBits(r3, 7);
|
||||
EXPECT_THAT(r1, Eq(0));
|
||||
EXPECT_THAT(r2[0], Eq(0u));
|
||||
EXPECT_THAT(r2[1], Eq(0u));
|
||||
EXPECT_THAT(r3, Eq(0u));
|
||||
}
|
||||
|
||||
119
tests/buffer_reading_errors.cpp
Normal file
119
tests/buffer_reading_errors.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
//MIT License
|
||||
//
|
||||
//Copyright (c) 2017 Mindaugas Vinkelis
|
||||
//
|
||||
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//of this software and associated documentation files (the "Software"), to deal
|
||||
//in the Software without restriction, including without limitation the rights
|
||||
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
//copies of the Software, and to permit persons to whom the Software is
|
||||
//furnished to do so, subject to the following conditions:
|
||||
//
|
||||
//The above copyright notice and this permission notice shall be included in all
|
||||
//copies or substantial portions of the Software.
|
||||
//
|
||||
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
//SOFTWARE.
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include "serialization_test_utils.h"
|
||||
|
||||
using testing::Eq;
|
||||
using bitsery::BufferWriter;
|
||||
using bitsery::BufferReader;
|
||||
using Buffer = bitsery::DefaultConfig::BufferType;
|
||||
|
||||
TEST(BufferReadingErrors, WhenContainerOrTextSizeIsMoreThanMaxThenInvalidBufferDataError) {
|
||||
SerializationContext ctx;
|
||||
std::string tmp = "larger text then allowed";
|
||||
ctx.createSerializer().text1b(tmp,100);
|
||||
ctx.createDeserializer().text1b(tmp, 10);
|
||||
EXPECT_THAT(ctx.br->getError(), Eq(bitsery::BufferReaderError::INVALID_BUFFER_DATA));
|
||||
}
|
||||
|
||||
TEST(BufferReadingErrors, WhenReadingBoolByteReadsMoreThanOneThenInvalidBufferDataErrorAndResultIsFalse) {
|
||||
SerializationContext ctx;
|
||||
auto ser = ctx.createSerializer();
|
||||
ser.value1b(uint8_t{1});
|
||||
ser.value1b(uint8_t{2});
|
||||
bool res{};
|
||||
auto des = ctx.createDeserializer();
|
||||
des.boolByte(res);
|
||||
EXPECT_THAT(res, Eq(true));
|
||||
des.boolByte(res);
|
||||
EXPECT_THAT(res, Eq(false));
|
||||
EXPECT_THAT(ctx.br->getError(), Eq(bitsery::BufferReaderError::INVALID_BUFFER_DATA));
|
||||
}
|
||||
|
||||
TEST(BufferReadingErrors, WhenReadingAlignHasNonZerosThenInvalidBufferDataError) {
|
||||
Buffer buf{};
|
||||
BufferWriter bw{buf};
|
||||
uint8_t tmp{0xFF};
|
||||
bw.writeBytes<1>(tmp);
|
||||
bw.flush();
|
||||
BufferReader br{bw.getWrittenRange()};
|
||||
|
||||
br.readBits(tmp,3);
|
||||
br.align();
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::INVALID_BUFFER_DATA));
|
||||
}
|
||||
|
||||
TEST(BufferReadingErrors, WhenReadingNewSessionInMiddleOfOldDataThenInvalidBufferError) {
|
||||
uint8_t tmp{0xFF};
|
||||
Buffer buf{};
|
||||
BufferWriter bw{buf};
|
||||
for (auto i = 0; i < 2; ++i) {
|
||||
bw.beginSession();
|
||||
bw.writeBytes<1>(tmp);
|
||||
bw.writeBytes<1>(tmp);
|
||||
bw.endSession();
|
||||
}
|
||||
bw.flush();
|
||||
BufferReader br{bw.getWrittenRange()};
|
||||
for (auto i = 0; i < 2; ++i) {
|
||||
br.beginSession();
|
||||
br.readBytes<1>(tmp);
|
||||
br.beginSession();
|
||||
br.readBytes<1>(tmp);
|
||||
br.endSession();
|
||||
br.endSession();
|
||||
}
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::INVALID_BUFFER_DATA));
|
||||
}
|
||||
|
||||
|
||||
TEST(BufferReadingErrors, WhenInitializingSessionsWhenNotEnoughDataThenInvalidBufferData) {
|
||||
uint8_t tmp1{0xFF};
|
||||
Buffer buf1{};
|
||||
BufferWriter bw1{buf1};
|
||||
bw1.writeBytes<1>(tmp1);
|
||||
bw1.flush();
|
||||
BufferReader br1{bw1.getWrittenRange()};
|
||||
br1.beginSession();
|
||||
EXPECT_THAT(br1.getError(), Eq(bitsery::BufferReaderError::INVALID_BUFFER_DATA));
|
||||
|
||||
Buffer buf2{};
|
||||
BufferWriter bw2{buf2};
|
||||
uint16_t tmp2{0x8000};
|
||||
bw2.writeBytes<2>(tmp2);
|
||||
bw2.flush();
|
||||
BufferReader br2{bw2.getWrittenRange()};
|
||||
br2.beginSession();
|
||||
EXPECT_THAT(br2.getError(), Eq(bitsery::BufferReaderError::INVALID_BUFFER_DATA));
|
||||
}
|
||||
|
||||
TEST(BufferReadingErrors, WhenInitializingSessionsWhereSessionsDataOffsetIsCorruptedThenInvalidBufferData) {
|
||||
Buffer buf{};
|
||||
BufferWriter bw{buf};
|
||||
bw.writeBytes<1>(uint8_t{1});
|
||||
bw.writeBytes<1>(uint8_t{1});
|
||||
bw.writeBytes<2>(uint16_t{10});
|
||||
BufferReader br{bw.getWrittenRange()};
|
||||
br.beginSession();
|
||||
EXPECT_THAT(br.getError(), Eq(bitsery::BufferReaderError::INVALID_BUFFER_DATA));
|
||||
}
|
||||
@@ -81,9 +81,10 @@ TYPED_TEST(BufferWriting, GetWrittenRangeReturnsBeginEndIterators) {
|
||||
}
|
||||
|
||||
TYPED_TEST(BufferWriting, WhenWritingBitsThenMustFlushWriter) {
|
||||
Buffer buf;
|
||||
bitsery::BufferWriter bw{buf};
|
||||
|
||||
using Config = typename TestFixture::type;
|
||||
using Buffer = typename Config::BufferType;
|
||||
Buffer buf{};
|
||||
bitsery::BasicBufferWriter<Config> bw{buf};
|
||||
bw.writeBits(3u, 2);
|
||||
auto range1 = bw.getWrittenRange();
|
||||
bw.flush();
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include "serialization_test_utils.h"
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
@@ -36,29 +37,29 @@ using testing::Eq;
|
||||
* overload to get container of types
|
||||
*/
|
||||
|
||||
template <typename Container>
|
||||
template<typename Container>
|
||||
Container getFilledContainer() {
|
||||
return {1,2,3,4,5,78,456,8,54};
|
||||
return {1, 2, 3, 4, 5, 78, 456, 8, 54};
|
||||
}
|
||||
|
||||
template <>
|
||||
template<>
|
||||
std::vector<MyStruct1> getFilledContainer<std::vector<MyStruct1>>() {
|
||||
return {
|
||||
{0,1},
|
||||
{2,3},
|
||||
{4,5},
|
||||
{6,7},
|
||||
{8,9},
|
||||
{11,34},
|
||||
{5134,1532}
|
||||
{0, 1},
|
||||
{2, 3},
|
||||
{4, 5},
|
||||
{6, 7},
|
||||
{8, 9},
|
||||
{11, 34},
|
||||
{5134, 1532}
|
||||
};
|
||||
}
|
||||
|
||||
template <>
|
||||
template<>
|
||||
std::list<MyStruct2> getFilledContainer<std::list<MyStruct2>>() {
|
||||
return {
|
||||
{MyStruct2::V1, {0,1}} ,
|
||||
{MyStruct2::V3, {-45,45}}
|
||||
{MyStruct2::V1, {0, 1}},
|
||||
{MyStruct2::V3, {-45, 45}}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -66,16 +67,16 @@ std::list<MyStruct2> getFilledContainer<std::list<MyStruct2>>() {
|
||||
* start testing session
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
class SerializeContainerArthmeticTypes:public testing::Test {
|
||||
template<typename T>
|
||||
class SerializeContainerDynamicSizeArthmeticTypes : public testing::Test {
|
||||
public:
|
||||
using TContainer = T;
|
||||
using TValue = typename T::value_type;
|
||||
|
||||
const TContainer src= getFilledContainer<TContainer>() ;
|
||||
const TContainer src = getFilledContainer<TContainer>();
|
||||
TContainer res{};
|
||||
|
||||
size_t getExpectedBufSize(const SerializationContext& ctx) const {
|
||||
size_t getExpectedBufSize(const SerializationContext &ctx) const {
|
||||
return ctx.containerSizeSerializedBytesCount(src.size()) + src.size() * sizeof(TValue);
|
||||
}
|
||||
};
|
||||
@@ -85,9 +86,9 @@ using SequenceContainersWithArthmeticTypes = ::testing::Types<
|
||||
std::list<float>,
|
||||
std::deque<unsigned short>>;
|
||||
|
||||
TYPED_TEST_CASE(SerializeContainerArthmeticTypes, SequenceContainersWithArthmeticTypes);
|
||||
TYPED_TEST_CASE(SerializeContainerDynamicSizeArthmeticTypes, SequenceContainersWithArthmeticTypes);
|
||||
|
||||
TYPED_TEST(SerializeContainerArthmeticTypes, Values) {
|
||||
TYPED_TEST(SerializeContainerDynamicSizeArthmeticTypes, Values) {
|
||||
SerializationContext ctx{};
|
||||
using TValue = typename TestFixture::TValue;
|
||||
|
||||
@@ -98,7 +99,7 @@ TYPED_TEST(SerializeContainerArthmeticTypes, Values) {
|
||||
EXPECT_THAT(this->res, ContainerEq(this->src));
|
||||
}
|
||||
|
||||
TYPED_TEST(SerializeContainerArthmeticTypes, CustomFunctionIncrements) {
|
||||
TYPED_TEST(SerializeContainerDynamicSizeArthmeticTypes, CustomFunctionIncrements) {
|
||||
SerializationContext ctx{};
|
||||
|
||||
auto ser = ctx.createSerializer();
|
||||
@@ -108,13 +109,13 @@ TYPED_TEST(SerializeContainerArthmeticTypes, CustomFunctionIncrements) {
|
||||
s.template value<sizeof(v)>(v);
|
||||
});
|
||||
auto des = ctx.createDeserializer();
|
||||
des.container(this->res, 1000, [](auto &s, auto&v ) {
|
||||
des.container(this->res, 1000, [](auto &s, auto &v) {
|
||||
s.template value<sizeof(v)>(v);
|
||||
//increment by 1 after reading
|
||||
v++;
|
||||
});
|
||||
//decrement result by 2, before comparing for eq
|
||||
for(auto& v:this->res)
|
||||
for (auto &v:this->res)
|
||||
v -= 2;
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(this->getExpectedBufSize(ctx)));
|
||||
@@ -122,29 +123,28 @@ TYPED_TEST(SerializeContainerArthmeticTypes, CustomFunctionIncrements) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
class SerializeContainerCompositeTypes:public testing::Test {
|
||||
template<typename T>
|
||||
class SerializeContainerDynamicSizeCompositeTypes : public testing::Test {
|
||||
public:
|
||||
using TContainer = T;
|
||||
using TValue = typename T::value_type;
|
||||
|
||||
const TContainer src= getFilledContainer<TContainer>();
|
||||
const TContainer src = getFilledContainer<TContainer>();
|
||||
TContainer res{};
|
||||
size_t getExpectedBufSize(const SerializationContext& ctx) const {
|
||||
|
||||
size_t getExpectedBufSize(const SerializationContext &ctx) const {
|
||||
return ctx.containerSizeSerializedBytesCount(src.size()) + src.size() * TValue::SIZE;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
using SequenceContainersWithCompositeTypes = ::testing::Types<
|
||||
using SerializeContainerDynamicSizeWithCompositeTypes = ::testing::Types<
|
||||
std::vector<MyStruct1>,
|
||||
std::list<MyStruct2>>;
|
||||
|
||||
TYPED_TEST_CASE(SerializeContainerCompositeTypes, SequenceContainersWithCompositeTypes);
|
||||
TYPED_TEST_CASE(SerializeContainerDynamicSizeCompositeTypes, SerializeContainerDynamicSizeWithCompositeTypes);
|
||||
|
||||
TYPED_TEST(SerializeContainerCompositeTypes, DefaultSerializeFunction) {
|
||||
TYPED_TEST(SerializeContainerDynamicSizeCompositeTypes, DefaultSerializeFunction) {
|
||||
SerializationContext ctx{};
|
||||
|
||||
ctx.createSerializer().container(this->src, 1000);
|
||||
@@ -155,15 +155,95 @@ TYPED_TEST(SerializeContainerCompositeTypes, DefaultSerializeFunction) {
|
||||
}
|
||||
|
||||
|
||||
TYPED_TEST(SerializeContainerCompositeTypes, CustomFunctionThatDoNothing) {
|
||||
TYPED_TEST(SerializeContainerDynamicSizeCompositeTypes, CustomFunctionThatDoNothing) {
|
||||
SerializationContext ctx{};
|
||||
|
||||
|
||||
auto emptyFnc = [](auto& s, auto& v) {};
|
||||
auto emptyFnc = [](auto &s, auto &v) {};
|
||||
ctx.createSerializer().container(this->src, 1000, emptyFnc);
|
||||
ctx.createDeserializer().container(this->res, 1000, emptyFnc);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(ctx.containerSizeSerializedBytesCount(this->src.size())));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class SerializeContainerFixedSizeArithmeticTypes : public testing::Test {
|
||||
public:
|
||||
using TContainer = T;
|
||||
|
||||
size_t getContainerSize() {
|
||||
T tmp{};
|
||||
return static_cast<size_t>(std::distance(std::begin(tmp), std::end(tmp)));
|
||||
}
|
||||
};
|
||||
|
||||
using StaticContainersWithIntegralTypes = ::testing::Types<
|
||||
std::array<int16_t, 4>,
|
||||
int16_t[4]>;
|
||||
|
||||
TYPED_TEST_CASE(SerializeContainerFixedSizeArithmeticTypes, StaticContainersWithIntegralTypes);
|
||||
|
||||
TYPED_TEST(SerializeContainerFixedSizeArithmeticTypes, ArithmeticValues) {
|
||||
using Container = typename TestFixture::TContainer;
|
||||
Container src{5, 9, 15, -459};
|
||||
Container res{};
|
||||
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().container<2>(src);
|
||||
ctx.createDeserializer().container<2>(res);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(this->getContainerSize() * 2));
|
||||
EXPECT_THAT(res, ContainerEq(src));
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
class SerializeContainerFixedSizeCompositeTypes : public SerializeContainerFixedSizeArithmeticTypes<T> {
|
||||
|
||||
};
|
||||
|
||||
using StaticContainersWithCompositeTypes = ::testing::Types<
|
||||
std::array<MyStruct1, 4>,
|
||||
MyStruct1[4]>;
|
||||
|
||||
TYPED_TEST_CASE(SerializeContainerFixedSizeCompositeTypes, StaticContainersWithCompositeTypes);
|
||||
|
||||
TYPED_TEST(SerializeContainerFixedSizeCompositeTypes, DefaultSerializationFunction) {
|
||||
using Container = typename TestFixture::TContainer;
|
||||
Container src{MyStruct1{0, 1}, MyStruct1{8, 9}, MyStruct1{11, 34}, MyStruct1{5134, 1532}};
|
||||
Container res{};
|
||||
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().container(src);
|
||||
ctx.createDeserializer().container(res);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(this->getContainerSize() * MyStruct1::SIZE));
|
||||
EXPECT_THAT(res, ContainerEq(src));
|
||||
}
|
||||
|
||||
TYPED_TEST(SerializeContainerFixedSizeCompositeTypes, CustomFunctionThatSerializesAnEmptyByteEveryElement) {
|
||||
using Container = typename TestFixture::TContainer;
|
||||
Container src{MyStruct1{0, 1}, MyStruct1{2, 3}, MyStruct1{4, 5}, MyStruct1{5134, 1532}};
|
||||
Container res{};
|
||||
|
||||
SerializationContext ctx;
|
||||
auto ser = ctx.createSerializer();
|
||||
ser.container(src, [](auto &s, auto &v) {
|
||||
char tmp{};
|
||||
s.object(v);
|
||||
s.value1b(tmp);
|
||||
});
|
||||
auto des = ctx.createDeserializer();
|
||||
des.container(res, [](auto &s, auto &v) {
|
||||
char tmp{};
|
||||
s.object(v);
|
||||
s.value1b(tmp);
|
||||
});
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(this->getContainerSize() * (MyStruct1::SIZE + sizeof(char))));
|
||||
EXPECT_THAT(res, ContainerEq(src));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -25,72 +25,72 @@
|
||||
#include "serialization_test_utils.h"
|
||||
using namespace testing;
|
||||
|
||||
TEST(SerializeSubstitution, WhenSubstitutedThenOnlyWriteIndexUsingMinRequiredBits) {
|
||||
TEST(SerializeEntropyEncoding, WhenEntropyEncodedThenOnlyWriteIndexUsingMinRequiredBits) {
|
||||
int32_t v = 4849;
|
||||
int32_t res;
|
||||
constexpr size_t N = 3;
|
||||
std::array<int32_t,N> subsitution{485,4849,89};
|
||||
int32_t entropyValues[3]{485,4849,89};
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().substitution<4>(v, subsitution);
|
||||
ctx.createDeserializer().substitution<4>(res, subsitution);
|
||||
ctx.createSerializer().entropy<4>(v, entropyValues);
|
||||
ctx.createDeserializer().entropy<4>(res, entropyValues);
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(1));
|
||||
|
||||
SerializationContext ctx1;
|
||||
ctx1.createSerializer().substitution<4>(v, subsitution);
|
||||
ctx1.createSerializer().entropy<4>(v, entropyValues);
|
||||
auto des = ctx1.createDeserializer();
|
||||
des.range(res, {0, N + 1});
|
||||
EXPECT_THAT(res, Eq(2));
|
||||
}
|
||||
|
||||
TEST(SerializeSubstitution, WhenNoSubstitutionThenWriteZeroBitsAndValueOrObject) {
|
||||
TEST(SerializeEntropyEncoding, WhenNoEntropyEncodedThenWriteZeroBitsAndValueOrObject) {
|
||||
int16_t v = 8945;
|
||||
int16_t res;
|
||||
std::array<int16_t,3> subsitution{485,4849,89};
|
||||
int16_t entropyValues[3]{485,4849,89};
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().substitution<2>(v, subsitution);
|
||||
ctx.createDeserializer().substitution<2>(res, subsitution);
|
||||
ctx.createSerializer().entropy<2>(v, entropyValues);
|
||||
ctx.createDeserializer().entropy<2>(res, entropyValues);
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(sizeof(int16_t)+1));
|
||||
}
|
||||
|
||||
TEST(SerializeSubstitution, CustomTypeSubstituted) {
|
||||
TEST(SerializeEntropyEncoding, CustomTypeEntropyEncoded) {
|
||||
MyStruct1 v = {12,10};
|
||||
MyStruct1 res;
|
||||
constexpr size_t N = 4;
|
||||
std::array<MyStruct1, N> subsitution = {
|
||||
MyStruct1 entropyValues[N]{
|
||||
MyStruct1{12,10}, MyStruct1{485, 454},
|
||||
MyStruct1{4849,89}, MyStruct1{0,1}};
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().substitution(v, subsitution);
|
||||
ctx.createDeserializer().substitution(res, subsitution);
|
||||
ctx.createSerializer().entropy(v, entropyValues);
|
||||
ctx.createDeserializer().entropy(res, entropyValues);
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(1));
|
||||
}
|
||||
|
||||
TEST(SerializeSubstitution, CustomTypeNotSubstituted) {
|
||||
TEST(SerializeEntropyEncoding, CustomTypeNotEntropyEncoded) {
|
||||
MyStruct1 v = {8945,4456};
|
||||
MyStruct1 res;
|
||||
constexpr size_t N = 4;
|
||||
std::array<MyStruct1, N> subsitution = {
|
||||
MyStruct1 entropyValues[N] {
|
||||
MyStruct1{12,10}, MyStruct1{485, 454},
|
||||
MyStruct1{4849,89}, MyStruct1{0,1}};
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().substitution(v, subsitution);
|
||||
ctx.createDeserializer().substitution(res, subsitution);
|
||||
ctx.createSerializer().entropy(v, entropyValues);
|
||||
ctx.createDeserializer().entropy(res, entropyValues);
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(MyStruct1::SIZE + 1));
|
||||
}
|
||||
|
||||
TEST(SerializeSubstitution, CustomFunctionNotSubstituted) {
|
||||
TEST(SerializeEntropyEncoding, CustomFunctionNotEntropyEncoded) {
|
||||
MyStruct1 v = {8945,4456};
|
||||
MyStruct1 res;
|
||||
constexpr size_t N = 4;
|
||||
std::array<MyStruct1, N> subsitution = {
|
||||
MyStruct1 entropyValues[N] {
|
||||
MyStruct1{12,10}, MyStruct1{485, 454},
|
||||
MyStruct1{4849,89}, MyStruct1{0,1}};
|
||||
|
||||
@@ -105,30 +105,30 @@ TEST(SerializeSubstitution, CustomFunctionNotSubstituted) {
|
||||
s.range(v.i1, rangeForValue);
|
||||
s.range(v.i2, rangeForValue);
|
||||
};
|
||||
ser.substitution(v, subsitution, serLambda);
|
||||
ser.entropy(v, entropyValues, serLambda);
|
||||
|
||||
auto des = ctx.createDeserializer();
|
||||
auto desLambda = [rangeForValue](auto& s, MyStruct1& v) {
|
||||
s.range(v.i1, rangeForValue);
|
||||
s.range(v.i2, rangeForValue);
|
||||
};
|
||||
des.substitution(res, subsitution, desLambda);
|
||||
des.entropy(res, entropyValues, desLambda);
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq((rangeForIndex.bitsRequired + rangeForValue.bitsRequired * 2 - 1) / 8 + 1 ));
|
||||
}
|
||||
|
||||
TEST(SerializeSubstitution, WhenSubstitutedThenCustomFunctionNotInvoked) {
|
||||
TEST(SerializeEntropyEncoding, WhenEntropyEncodedThenCustomFunctionNotInvoked) {
|
||||
MyStruct1 v = {4849,89};
|
||||
MyStruct1 res;
|
||||
constexpr size_t N = 4;
|
||||
std::array<MyStruct1, N> subsitution = {
|
||||
MyStruct1 entropyValues[N] {
|
||||
MyStruct1{12,10}, MyStruct1{485, 454},
|
||||
MyStruct1{4849,89}, MyStruct1{0,1}};
|
||||
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().substitution(v, subsitution, [](bitsery::Serializer<bitsery::BufferWriter>& ,const MyStruct1& ) {});
|
||||
ctx.createDeserializer().substitution(res, subsitution, [](bitsery::Deserializer<bitsery::BufferReader>&, MyStruct1& ) {});
|
||||
ctx.createSerializer().entropy(v, entropyValues, [](bitsery::Serializer<bitsery::BufferWriter>& ,const MyStruct1& ) {});
|
||||
ctx.createDeserializer().entropy(res, entropyValues, [](bitsery::Deserializer<bitsery::BufferReader>&, MyStruct1& ) {});
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(1));
|
||||
@@ -43,8 +43,8 @@ using testing::Eq;
|
||||
|
||||
template <typename T>
|
||||
void test(SerializationContext& ctx, const T& v, T& r) {
|
||||
ctx.createSerializer().extension4(v, extoptional{});
|
||||
ctx.createDeserializer().extension4(r, extoptional{});
|
||||
ctx.createSerializer().extend4b(v, extoptional{});
|
||||
ctx.createDeserializer().extend4b(r, extoptional{});
|
||||
}
|
||||
|
||||
TEST(SerializeExtensionOptional, EmptyOptional) {
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
//MIT License
|
||||
//
|
||||
//Copyright (c) 2017 Mindaugas Vinkelis
|
||||
//
|
||||
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//of this software and associated documentation files (the "Software"), to deal
|
||||
//in the Software without restriction, including without limitation the rights
|
||||
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
//copies of the Software, and to permit persons to whom the Software is
|
||||
//furnished to do so, subject to the following conditions:
|
||||
//
|
||||
//The above copyright notice and this permission notice shall be included in all
|
||||
//copies or substantial portions of the Software.
|
||||
//
|
||||
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
//SOFTWARE.
|
||||
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include "serialization_test_utils.h"
|
||||
#include <type_traits>
|
||||
|
||||
using testing::ContainerEq;
|
||||
using testing::Eq;
|
||||
|
||||
TEST(SerializeFSArrayStdArray, ArithmeticValues) {
|
||||
SerializationContext ctx;
|
||||
std::array<int, 4> src{5,9,15,-459};
|
||||
std::array<int, 4> res{};
|
||||
|
||||
ctx.createSerializer().array<sizeof(int)>(src);
|
||||
ctx.createDeserializer().array<sizeof(int)>(res);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(src.size() * sizeof(int)));
|
||||
EXPECT_THAT(res, ContainerEq(src));
|
||||
|
||||
}
|
||||
|
||||
TEST(SerializeFSArrayStdArray, CompositeTypes) {
|
||||
SerializationContext ctx;
|
||||
std::array<MyStruct1, 7> src{
|
||||
MyStruct1{0,1}, MyStruct1{2,3}, MyStruct1{4,5}, MyStruct1{6,7},
|
||||
MyStruct1{8,9}, MyStruct1{11,34}, MyStruct1{5134,1532}};
|
||||
std::array<MyStruct1, 7> res{};
|
||||
|
||||
ctx.createSerializer().array(src);
|
||||
ctx.createDeserializer().array(res);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(src.size() * MyStruct1::SIZE));
|
||||
EXPECT_THAT(res, ContainerEq(src));
|
||||
}
|
||||
//
|
||||
//
|
||||
TEST(SerializeFSArrayStdArray, CustomFunctionThatSerializesAnEmptyByteEveryElement) {
|
||||
SerializationContext ctx;
|
||||
std::array<MyStruct1, 7> src{
|
||||
MyStruct1{0,1}, MyStruct1{2,3}, MyStruct1{4,5}, MyStruct1{6,7},
|
||||
MyStruct1{8,9}, MyStruct1{11,34}, MyStruct1{5134,1532}};
|
||||
std::array<MyStruct1, 7> res{};
|
||||
|
||||
|
||||
auto ser = ctx.createSerializer();
|
||||
ser.array(src, [](auto &s, auto& v) {
|
||||
char tmp{};
|
||||
s.object(v);
|
||||
s.value1(tmp);
|
||||
});
|
||||
auto des = ctx.createDeserializer();
|
||||
des.array(res, [](auto &s, auto& v) {
|
||||
char tmp{};
|
||||
s.object(v);
|
||||
s.value1(tmp);
|
||||
});
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(src.size() * (MyStruct1::SIZE + sizeof(char))));
|
||||
EXPECT_THAT(res, ContainerEq(src));
|
||||
}
|
||||
|
||||
TEST(SerializeFSArrayCArray, ArithmeticValuesSettingValueSizeExplicitly) {
|
||||
SerializationContext ctx;
|
||||
int src[4]{5,9,15,-459};
|
||||
int res[4]{};
|
||||
|
||||
ctx.createSerializer().array<sizeof(int)>(src);
|
||||
ctx.createDeserializer().array<sizeof(int)>(res);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(std::extent<decltype(src)>::value * sizeof(int)));
|
||||
EXPECT_THAT(res, ContainerEq(src));
|
||||
|
||||
}
|
||||
|
||||
TEST(SerializeFSArrayCArray, CompositeTypes) {
|
||||
SerializationContext ctx;
|
||||
MyStruct1 src[]{
|
||||
MyStruct1{0,1}, MyStruct1{2,3}, MyStruct1{4,5}, MyStruct1{6,7},
|
||||
MyStruct1{8,9}, MyStruct1{11,34}, MyStruct1{5134,1532}};
|
||||
MyStruct1 res[7]{};
|
||||
|
||||
ctx.createSerializer().array(src);
|
||||
ctx.createDeserializer().array(res);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(std::extent<decltype(src)>::value * MyStruct1::SIZE));
|
||||
EXPECT_THAT(res, ContainerEq(src));
|
||||
}
|
||||
//
|
||||
//
|
||||
TEST(SerializeFSArrayCArray, CustomFunctionThatSerializesAnEmptyByteEveryElement) {
|
||||
SerializationContext ctx;
|
||||
MyStruct1 src[]{
|
||||
MyStruct1{0,1}, MyStruct1{2,3}, MyStruct1{4,5}, MyStruct1{6,7},
|
||||
MyStruct1{8,9}, MyStruct1{11,34}, MyStruct1{5134,1532}};
|
||||
MyStruct1 res[7]{};
|
||||
|
||||
|
||||
auto ser = ctx.createSerializer();
|
||||
ser.array(src, [](auto& s, auto& v) {
|
||||
char tmp{};
|
||||
s.object(v);
|
||||
s.value1(tmp);
|
||||
});
|
||||
auto des = ctx.createDeserializer();
|
||||
des.array(res, [](auto& s, auto& v) {
|
||||
char tmp{};
|
||||
s.object(v);
|
||||
s.value1(tmp);
|
||||
});
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(std::extent<decltype(src)>::value * (MyStruct1::SIZE + sizeof(char))));
|
||||
EXPECT_THAT(res, ContainerEq(src));
|
||||
}
|
||||
412
tests/serialization_growable.cpp
Normal file
412
tests/serialization_growable.cpp
Normal file
@@ -0,0 +1,412 @@
|
||||
//MIT License
|
||||
//
|
||||
//Copyright (c) 2017 Mindaugas Vinkelis
|
||||
//
|
||||
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//of this software and associated documentation files (the "Software"), to deal
|
||||
//in the Software without restriction, including without limitation the rights
|
||||
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
//copies of the Software, and to permit persons to whom the Software is
|
||||
//furnished to do so, subject to the following conditions:
|
||||
//
|
||||
//The above copyright notice and this permission notice shall be included in all
|
||||
//copies or substantial portions of the Software.
|
||||
//
|
||||
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
//SOFTWARE.
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include "serialization_test_utils.h"
|
||||
|
||||
using namespace testing;
|
||||
|
||||
using Buffer = typename bitsery::DefaultConfig::BufferType;
|
||||
using DiffType = typename Buffer::difference_type;
|
||||
|
||||
struct DataV1 {
|
||||
int32_t v1;
|
||||
};
|
||||
|
||||
struct DataV2 {
|
||||
int32_t v1;
|
||||
int32_t v2;
|
||||
};
|
||||
|
||||
struct DataV3 {
|
||||
int32_t v1;
|
||||
int32_t v2;
|
||||
int32_t v3;
|
||||
};
|
||||
|
||||
|
||||
TEST(SerializeGrowable, WriteSessionsDataAtBufferEndAfterFlush) {
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().growable(int8_t{}, [] (auto& s, auto& v) { });
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(0));
|
||||
ctx.bw->flush();
|
||||
EXPECT_THAT(ctx.getBufferSize(), Gt(0));
|
||||
}
|
||||
|
||||
|
||||
TEST(SerializeGrowable, SessionDataConsistOfSessionsEndPosAnd2BytesSessionsDataOffset) {
|
||||
SerializationContext ctx;
|
||||
|
||||
|
||||
constexpr size_t DATA_SIZE = 4;
|
||||
int32_t data{};
|
||||
|
||||
ctx.createSerializer().growable(data, [](auto&s, auto& v) { s.value4b(v);});
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(3 + DATA_SIZE));
|
||||
|
||||
//read value back
|
||||
auto& br = *(ctx.br);
|
||||
br.readBytes<DATA_SIZE>(data);
|
||||
|
||||
size_t sessionEnd{};
|
||||
//there should start session data with first size of session
|
||||
bitsery::details::readSize(br, sessionEnd);
|
||||
EXPECT_THAT(sessionEnd, Eq(DATA_SIZE));
|
||||
//this is the the offset from the end of buffer where actual data ends
|
||||
uint16_t sessionsOffset{};//bufferEnd - sessionsOffset = dataEnd
|
||||
br.readBytes<2>(sessionsOffset);
|
||||
EXPECT_THAT(sessionsOffset, Eq(1+2));//1byte for session info, 2 bytes for session offset variable
|
||||
auto range = ctx.bw->getWrittenRange();
|
||||
auto dSize = std::distance(range.begin(), std::next(range.end(), -sessionsOffset));
|
||||
EXPECT_THAT(dSize, Eq(DATA_SIZE));
|
||||
}
|
||||
|
||||
TEST(SerializeGrowable, WhenNestedSessionsThenStoreEachDepthAndSize) {
|
||||
SerializationContext ctx;
|
||||
DataV3 data{19457,846, 498418};
|
||||
ctx.createSerializer();
|
||||
ctx.bw->beginSession();
|
||||
ctx.bw->writeBytes<4>(data.v1);
|
||||
ctx.bw->beginSession();
|
||||
ctx.bw->writeBytes<4>(data.v2);
|
||||
ctx.bw->endSession();
|
||||
ctx.bw->beginSession();
|
||||
ctx.bw->writeBytes<4>(data.v3);
|
||||
ctx.bw->endSession();
|
||||
ctx.bw->endSession();
|
||||
DataV3 res{};
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
ctx.br->readBytes<4>(res.v1);
|
||||
ctx.br->readBytes<4>(res.v2);
|
||||
ctx.br->readBytes<4>(res.v3);
|
||||
//read data correctly
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
EXPECT_THAT(res.v3, Eq(data.v3));
|
||||
size_t sessionEnd[3];
|
||||
//read sessions sizes
|
||||
bitsery::details::readSize(*(ctx.br), sessionEnd[0]);
|
||||
bitsery::details::readSize(*(ctx.br),sessionEnd[1]);
|
||||
bitsery::details::readSize(*(ctx.br), sessionEnd[2]);
|
||||
EXPECT_THAT(sessionEnd[0], Eq(12));
|
||||
EXPECT_THAT(sessionEnd[1], Eq(8));
|
||||
EXPECT_THAT(sessionEnd[2], Eq(12));
|
||||
}
|
||||
|
||||
TEST(SerializeGrowable, WhenSessionsDataIsMoreThan0x7FFFThenWrite4BytesForSessionsOffset) {
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer();
|
||||
//create more sessions that can fit in 2 bytes
|
||||
for (auto i = 0u; i < 0x8000; ++i) {
|
||||
ctx.bw->beginSession();
|
||||
ctx.bw->endSession();
|
||||
}
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(0x8000+4));
|
||||
uint8_t tmp{};
|
||||
for (auto i = 0u; i < 0x8000; ++i) {
|
||||
ctx.br->beginSession();
|
||||
ctx.br->endSession();
|
||||
}
|
||||
|
||||
EXPECT_THAT(ctx.br->getError(), Eq(bitsery::BufferReaderError::NO_ERROR));
|
||||
ctx.br->readBytes<1>(tmp);
|
||||
EXPECT_THAT(ctx.br->getError(), Eq(bitsery::BufferReaderError::BUFFER_OVERFLOW));
|
||||
}
|
||||
|
||||
TEST(SerializeGrowable, MultipleSessionsReadSameVersionData) {
|
||||
SerializationContext ctx;
|
||||
DataV2 data{8454,987451};
|
||||
ctx.createSerializer();
|
||||
auto& bw = (*ctx.bw);
|
||||
for (auto i = 0; i < 10; ++i) {
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v1);
|
||||
bw.writeBytes<4>(data.v2);
|
||||
bw.endSession();
|
||||
}
|
||||
//create more sessions that can fit in 2 bytes
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
DataV2 res{};
|
||||
auto& br = (*ctx.br);
|
||||
for (auto i = 0; i < 10; ++i) {
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v1);
|
||||
br.readBytes<4>(res.v2);
|
||||
br.endSession();
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
}
|
||||
EXPECT_THAT(ctx.br->isCompletedSuccessfully(), Eq(true));
|
||||
}
|
||||
|
||||
TEST(SerializeGrowable, MultipleSessionsReadNewerVersionData) {
|
||||
SerializationContext ctx;
|
||||
DataV3 data{8454,987451,54};
|
||||
ctx.createSerializer();
|
||||
auto& bw = (*ctx.bw);
|
||||
for (auto i = 0; i < 10; ++i) {
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v1);
|
||||
bw.writeBytes<4>(data.v2);
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.endSession();
|
||||
}
|
||||
//create more sessions that can fit in 2 bytes
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
DataV2 res{};
|
||||
auto& br = (*ctx.br);
|
||||
for (auto i = 0; i < 10; ++i) {
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v1);
|
||||
br.readBytes<4>(res.v2);
|
||||
br.endSession();
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
}
|
||||
EXPECT_THAT(br.isCompletedSuccessfully(), Eq(true));
|
||||
}
|
||||
|
||||
TEST(SerializeGrowable, MultipleSessionsReadOlderVersionData) {
|
||||
SerializationContext ctx;
|
||||
DataV2 data{8454,987451};
|
||||
ctx.createSerializer();
|
||||
auto& bw = (*ctx.bw);
|
||||
for (auto i = 0; i < 10; ++i) {
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v1);
|
||||
bw.writeBytes<4>(data.v2);
|
||||
bw.endSession();
|
||||
}
|
||||
//create more sessions that can fit in 2 bytes
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
DataV3 res{4798,657891,985};
|
||||
auto& br = (*ctx.br);
|
||||
for (auto i = 0; i < 10; ++i) {
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v1);
|
||||
br.readBytes<4>(res.v2);
|
||||
br.readBytes<4>(res.v3);
|
||||
br.endSession();
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
EXPECT_THAT(res.v3, Eq(0));
|
||||
}
|
||||
EXPECT_THAT(ctx.br->isCompletedSuccessfully(), Eq(true));
|
||||
}
|
||||
|
||||
TEST(SerializeGrowable, MultipleNestedSessionsReadSameVersionData) {
|
||||
SerializationContext ctx;
|
||||
DataV2 data{8454,987451};
|
||||
ctx.createSerializer();
|
||||
auto& bw = (*ctx.bw);
|
||||
for (auto i = 0; i < 2; ++i) {
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v1);
|
||||
bw.writeBytes<4>(data.v2);
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v1);
|
||||
bw.writeBytes<4>(data.v2);
|
||||
bw.endSession();
|
||||
bw.endSession();
|
||||
}
|
||||
//create more sessions that can fit in 2 bytes
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
DataV2 res{};
|
||||
auto& br = (*ctx.br);
|
||||
for (auto i = 0; i < 2; ++i) {
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v1);
|
||||
br.readBytes<4>(res.v2);
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v1);
|
||||
br.readBytes<4>(res.v2);
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
br.endSession();
|
||||
br.endSession();
|
||||
}
|
||||
EXPECT_THAT(ctx.br->isCompletedSuccessfully(), Eq(true));
|
||||
}
|
||||
|
||||
TEST(SerializeGrowable, MultipleNestedSessionsReadOlderVersionData) {
|
||||
SerializationContext ctx;
|
||||
DataV2 data{8454,987451};
|
||||
ctx.createSerializer();
|
||||
auto& bw = (*ctx.bw);
|
||||
for (auto i = 0; i < 5; ++i) {
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v1);
|
||||
bw.endSession();
|
||||
bw.writeBytes<4>(data.v2);
|
||||
}
|
||||
|
||||
//create more sessions that can fit in 2 bytes
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
DataV3 res{};
|
||||
auto& br = (*ctx.br);
|
||||
for (auto i = 0; i < 5; ++i) {
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v1);
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
//new flow
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v3);
|
||||
EXPECT_THAT(res.v3, Eq(0));
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v3);
|
||||
EXPECT_THAT(res.v3, Eq(0));
|
||||
br.endSession();
|
||||
br.endSession();
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v3);
|
||||
EXPECT_THAT(res.v3, Eq(0));
|
||||
br.endSession();
|
||||
br.endSession();
|
||||
br.readBytes<4>(res.v2);
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
}
|
||||
EXPECT_THAT(ctx.br->isCompletedSuccessfully(), Eq(true));
|
||||
}
|
||||
|
||||
TEST(SerializeGrowable, MultipleNestedSessionsReadNewerVersionData1) {
|
||||
SerializationContext ctx;
|
||||
DataV3 data{8454,987451,54};
|
||||
ctx.createSerializer();
|
||||
auto& bw = (*ctx.bw);
|
||||
for (auto i = 0; i < 2; ++i) {
|
||||
bw.beginSession();
|
||||
{
|
||||
bw.writeBytes<4>(data.v1);
|
||||
bw.writeBytes<4>(data.v2);
|
||||
//new flow
|
||||
bw.beginSession();
|
||||
{
|
||||
bw.writeBytes<4>(data.v3);
|
||||
}
|
||||
bw.endSession();
|
||||
bw.beginSession();
|
||||
{
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.beginSession();
|
||||
{
|
||||
bw.beginSession();
|
||||
{
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.writeBytes<4>(data.v3);
|
||||
}
|
||||
bw.endSession();
|
||||
bw.writeBytes<4>(data.v3);
|
||||
}
|
||||
bw.endSession();
|
||||
}
|
||||
bw.endSession();
|
||||
bw.writeBytes<4>(data.v3);
|
||||
}
|
||||
bw.endSession();
|
||||
bw.writeBytes<4>(data.v2);
|
||||
}
|
||||
//create more sessions that can fit in 2 bytes
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
DataV2 res{};
|
||||
auto& br = (*ctx.br);
|
||||
for (auto i = 0; i < 2; ++i) {
|
||||
br.beginSession();
|
||||
{
|
||||
br.readBytes<4>(res.v1);
|
||||
br.readBytes<4>(res.v2);
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
}
|
||||
br.endSession();
|
||||
br.readBytes<4>(res.v2);
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
}
|
||||
EXPECT_THAT(ctx.br->isCompletedSuccessfully(), Eq(true));
|
||||
}
|
||||
|
||||
TEST(SerializeGrowable, MultipleNestedSessionsReadNewerVersionData2) {
|
||||
SerializationContext ctx;
|
||||
DataV3 data{8454,987451,54};
|
||||
ctx.createSerializer();
|
||||
auto& bw = (*ctx.bw);
|
||||
for (auto i = 0; i < 2; ++i) {
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v1);
|
||||
bw.writeBytes<4>(data.v2);
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v1);
|
||||
bw.writeBytes<4>(data.v2);
|
||||
|
||||
//new flow
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.endSession();
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.beginSession();
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.endSession();
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.endSession();
|
||||
bw.endSession();
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.endSession();
|
||||
bw.writeBytes<4>(data.v2);
|
||||
|
||||
//new flow
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.beginSession();
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.endSession();
|
||||
bw.writeBytes<4>(data.v3);
|
||||
bw.endSession();
|
||||
}
|
||||
//create more sessions that can fit in 2 bytes
|
||||
ctx.createDeserializer();//to flush data and create buffer reader
|
||||
DataV2 res{};
|
||||
auto& br = (*ctx.br);
|
||||
for (auto i = 0; i < 2; ++i) {
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v1);
|
||||
br.readBytes<4>(res.v2);
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
br.beginSession();
|
||||
br.readBytes<4>(res.v1);
|
||||
br.readBytes<4>(res.v2);
|
||||
EXPECT_THAT(res.v1, Eq(data.v1));
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
br.endSession();
|
||||
br.readBytes<4>(res.v2);
|
||||
EXPECT_THAT(res.v2, Eq(data.v2));
|
||||
br.endSession();
|
||||
}
|
||||
EXPECT_THAT(ctx.br->isCompletedSuccessfully(), Eq(true));
|
||||
}
|
||||
|
||||
@@ -24,13 +24,6 @@
|
||||
#include <gmock/gmock.h>
|
||||
#include "serialization_test_utils.h"
|
||||
|
||||
#include <bitsery/delta_serializer.h>
|
||||
#include <bitsery/delta_deserializer.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
|
||||
|
||||
using testing::Eq;
|
||||
using testing::StrEq;
|
||||
using testing::ContainerEq;
|
||||
@@ -73,8 +66,8 @@ SERIALIZE(Y)
|
||||
auto writeInt = [](auto& s, auto& v) { s.template value<sizeof(v)>(v); };
|
||||
s.template text<1>(o.s, 10000);
|
||||
s.template value<sizeof(o.y)>(o.y);
|
||||
s.array(o.arr, writeInt);
|
||||
s.array(o.carr, writeInt);
|
||||
s.container(o.arr, writeInt);
|
||||
s.container(o.carr, writeInt);
|
||||
s.container(o.vx, 10000, [](auto& s, auto& v) { s.object(v); });
|
||||
}
|
||||
|
||||
@@ -126,49 +119,4 @@ TEST(SerializeObject, GeneralConceptTest) {
|
||||
EXPECT_THAT(zres.x.s, StrEq(z.x.s));
|
||||
EXPECT_THAT(zres.x.x, Eq(z.x.x));
|
||||
|
||||
}
|
||||
|
||||
TEST(DeltaSerializer, GeneralConceptTest) {
|
||||
//std::string buf;
|
||||
Y y{};
|
||||
y.y = 3423;
|
||||
y.arr[0] = 111;
|
||||
y.arr[1] = 222;
|
||||
y.arr[2] = 333;
|
||||
y.carr[0] = 123;
|
||||
y.carr[1] = 456;
|
||||
y.carr[2] = 789;
|
||||
y.vx.push_back(X(234));
|
||||
y.vx.push_back(X(6245));
|
||||
y.vx.push_back(X(613461));
|
||||
y.s = "labal diena";
|
||||
y.vx[0].s = "very nice";
|
||||
y.vx[1].s = "very nice string, that is a little bit longer that previous";
|
||||
|
||||
Y yRead = y;
|
||||
Y yNew = y;
|
||||
yNew.y = 111111;
|
||||
yNew.arr[2] = 0xFFFFFFFF;
|
||||
yNew.carr[1] = 0xFFFFFFFF;
|
||||
yNew.s = "labas dienaABC";
|
||||
yNew.vx[0].s = "very opapa";
|
||||
yNew.vx[1].s = "bla";
|
||||
yNew.vx.push_back(X{ 3 });
|
||||
|
||||
bitsery::DefaultConfig::BufferType buf;
|
||||
bitsery::BufferWriter bw{ buf };
|
||||
bitsery::DeltaSerializer<bitsery::BufferWriter, Y> ser(bw, y, yNew);
|
||||
serialize(ser, yNew);
|
||||
bw.flush();
|
||||
|
||||
bitsery::BufferReader br{ bw.getWrittenRange() };
|
||||
bitsery::DeltaDeserializer<bitsery::BufferReader, Y> des(br, y, yRead);
|
||||
serialize(des, yRead);
|
||||
|
||||
EXPECT_THAT(yRead.y, Eq(yNew.y));
|
||||
EXPECT_THAT(yRead.vx, ContainerEq(yNew.vx));
|
||||
EXPECT_THAT(yRead.arr, ContainerEq(yNew.arr));
|
||||
EXPECT_THAT(yRead.carr, ContainerEq(yNew.carr));
|
||||
EXPECT_THAT(yRead.s, StrEq(yNew.s));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -152,3 +152,15 @@ TEST(SerializeRange, DoubleUsingBitsSizeConstraint2) {
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(7));
|
||||
EXPECT_THAT(res1, ::testing::DoubleNear(t1, (max - min) / (static_cast<bitsery::details::SAME_SIZE_UNSIGNED<double>>(1) << bits)));
|
||||
}
|
||||
|
||||
TEST(SerializeRange, WhenDataIsInvalidThenReturnMinimumRangeValue) {
|
||||
SerializationContext ctx;
|
||||
constexpr RangeSpec<int> r1{4, 10};//6 is max, but 3bits required
|
||||
int res1;
|
||||
uint8_t tmp{0xFF};//write all 1 so when reading 3 bits we get 7
|
||||
ctx.createSerializer().value1b(tmp);
|
||||
ctx.createDeserializer().range(res1, r1);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(1));
|
||||
EXPECT_THAT(res1, Eq(4));
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
//SOFTWARE.
|
||||
|
||||
|
||||
#ifndef BITSERY_SERIALIZERTESTS_H
|
||||
#define BITSERY_SERIALIZERTESTS_H
|
||||
#ifndef BITSERY_SERIALIZER_TEST_UTILS_H
|
||||
#define BITSERY_SERIALIZER_TEST_UTILS_H
|
||||
|
||||
#include <bitsery/bitsery.h>
|
||||
#include <memory>
|
||||
@@ -82,10 +82,11 @@ SERIALIZE(MyStruct2) {
|
||||
|
||||
|
||||
class SerializationContext {
|
||||
public:
|
||||
bitsery::DefaultConfig::BufferType buf{};
|
||||
std::unique_ptr<bitsery::BufferWriter> bw;
|
||||
std::unique_ptr<bitsery::BufferReader> br;
|
||||
public:
|
||||
|
||||
bitsery::Serializer<bitsery::BufferWriter> createSerializer() {
|
||||
bw = std::make_unique<bitsery::BufferWriter>(buf);
|
||||
return {*bw};
|
||||
@@ -113,4 +114,4 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
#endif //BITSERY_SERIALIZERTESTS_H
|
||||
#endif //BITSERY_SERIALIZER_TEST_UTILS_H
|
||||
|
||||
@@ -65,8 +65,8 @@ TEST(SerializeValues, ValueSizeOverload1Byte) {
|
||||
constexpr size_t TSIZE = sizeof(v);
|
||||
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().value1(v);
|
||||
ctx.createDeserializer().value1(res);
|
||||
ctx.createSerializer().value1b(v);
|
||||
ctx.createDeserializer().value1b(res);
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(TSIZE, Eq(ctx.getBufferSize()));
|
||||
@@ -78,8 +78,8 @@ TEST(SerializeValues, ValueSizeOverload2Byte) {
|
||||
constexpr size_t TSIZE = sizeof(v);
|
||||
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().value2(v);
|
||||
ctx.createDeserializer().value2(res);
|
||||
ctx.createSerializer().value2b(v);
|
||||
ctx.createDeserializer().value2b(res);
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(TSIZE, Eq(ctx.getBufferSize()));
|
||||
@@ -91,8 +91,8 @@ TEST(SerializeValues, ValueSizeOverload4Byte) {
|
||||
constexpr size_t TSIZE = sizeof(v);
|
||||
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().value4(v);
|
||||
ctx.createDeserializer().value4(res);
|
||||
ctx.createSerializer().value4b(v);
|
||||
ctx.createDeserializer().value4b(res);
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(TSIZE, Eq(ctx.getBufferSize()));
|
||||
@@ -104,8 +104,8 @@ TEST(SerializeValues, ValueSizeOverload8Byte) {
|
||||
constexpr size_t TSIZE = sizeof(v);
|
||||
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().value8(v);
|
||||
ctx.createDeserializer().value8(res);
|
||||
ctx.createSerializer().value8b(v);
|
||||
ctx.createDeserializer().value8b(res);
|
||||
|
||||
EXPECT_THAT(res, Eq(v));
|
||||
EXPECT_THAT(TSIZE, Eq(ctx.getBufferSize()));
|
||||
|
||||
Reference in New Issue
Block a user