buffer reading/writing improvements

This commit is contained in:
fraillt
2017-09-01 16:23:52 +03:00
parent fe2bccf28f
commit 241f1f2940
15 changed files with 424 additions and 357 deletions

View File

@@ -1,272 +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 <bitsery/buffer_writer.h>
#include <bitsery/buffer_reader.h>
#include <list>
#include <bitset>
using testing::Eq;
using testing::ContainerEq;
using bitsery::BufferWriter;
using bitsery::BufferReader;
using Buffer = bitsery::DefaultConfig::BufferType;
struct IntegralTypes {
int64_t a;
uint32_t b;
int16_t c;
uint8_t d;
int8_t e;
int8_t f[2];
};
IntegralTypes getInitializedIntegralTypes() {
IntegralTypes data;
data.a = -4894541654564;
data.b = 94545646;
data.c = -8778;
data.d = 200;
data.e = -98;
data.f[0] = 43;
data.f[1] = -45;
return data;
}
void writeIntegralTypesToBuffer(BufferWriter& bw, const IntegralTypes& data) {
bw.writeBytes<4>(data.b);
bw.writeBytes<1>(data.f[0]);
bw.writeBytes<2>(data.c);
bw.writeBytes<1>(data.d);
bw.writeBytes<8>(data.a);
bw.writeBytes<1>(data.e);
bw.writeBytes<1>(data.f[1]);
}
TEST(BufferBytesOperations, WriteAndReadBytes) {
//setup data
auto data =getInitializedIntegralTypes();
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
writeIntegralTypesToBuffer(bw, data);
EXPECT_THAT(std::distance(buf.begin(), buf.end()), Eq(18));
//read from buffer
BufferReader br{buf};
IntegralTypes res{};
EXPECT_THAT(br.readBytes<4>(res.b), Eq(true));
EXPECT_THAT(br.readBytes<1>(res.f[0]), 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.readBytes<1>(res.f[1]), Eq(true));
//assert results
EXPECT_THAT(data.a, Eq(res.a));
EXPECT_THAT(data.b, Eq(res.b));
EXPECT_THAT(data.c, Eq(res.c));
EXPECT_THAT(data.d, Eq(res.d));
EXPECT_THAT(data.e, Eq(res.e));
EXPECT_THAT(data.f, ContainerEq(res.f));
}
TEST(BufferBytesOperations, BufferReaderUsingDataPlusSizeCtor) {
//setup data
auto data =getInitializedIntegralTypes();
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
writeIntegralTypesToBuffer(bw, data);
EXPECT_THAT(std::distance(buf.begin(), buf.end()), Eq(18));
//read from buffer
BufferReader br{buf.data(), buf.size()};
IntegralTypes res{};
EXPECT_THAT(br.readBytes<4>(res.b), Eq(true));
EXPECT_THAT(br.readBytes<1>(res.f[0]), 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.readBytes<1>(res.f[1]), Eq(true));
//assert results
EXPECT_THAT(data.a, Eq(res.a));
EXPECT_THAT(data.b, Eq(res.b));
EXPECT_THAT(data.c, Eq(res.c));
EXPECT_THAT(data.d, Eq(res.d));
EXPECT_THAT(data.e, Eq(res.e));
EXPECT_THAT(data.f, ContainerEq(res.f));
}
TEST(BufferBytesOperations, BufferReaderUsingIteratorsCtor) {
//setup data
auto data =getInitializedIntegralTypes();
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
writeIntegralTypesToBuffer(bw, data);
ASSERT_THAT(std::distance(buf.begin(), buf.end()), Eq(18));
//read from buffer
BufferReader br{buf.begin(), buf.end()};
IntegralTypes res{};
EXPECT_THAT(br.readBytes<4>(res.b), Eq(true));
EXPECT_THAT(br.readBytes<1>(res.f[0]), 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.readBytes<1>(res.f[1]), Eq(true));
//assert results
EXPECT_THAT(data.a, Eq(res.a));
EXPECT_THAT(data.b, Eq(res.b));
EXPECT_THAT(data.c, Eq(res.c));
EXPECT_THAT(data.d, Eq(res.d));
EXPECT_THAT(data.e, Eq(res.e));
EXPECT_THAT(data.f, ContainerEq(res.f));
}
TEST(BufferBytesOperations, ReadReturnsFalseIfNotEnoughBufferSize) {
//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);
//read from buffer
BufferReader br{buf};
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));
}
TEST(BufferBytesOperations, ReadIsCompletedWhenAllBytesAreRead) {
//setup data
IntegralTypes data;
data.b = 94545646;
data.c = -8778;
data.d = 200;
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
bw.writeBytes<4>(data.b);
bw.writeBytes<2>(data.c);
bw.writeBytes<1>(data.d);
//read from buffer
BufferReader br{buf};
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));
BufferReader br1{buf};
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));
}
TEST(BufferBytesOperations, ReadWriteBufferFncCanAcceptSignedData) {
//setup data
constexpr size_t DATA_SIZE = 3;
int16_t src[DATA_SIZE] {54,-4877,30067};
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
bw.writeBuffer<2>(src, DATA_SIZE);
bw.flush();
//read from buffer
BufferReader br1{buf};
int16_t dst[DATA_SIZE]{};
EXPECT_THAT(br1.readBuffer<2>(dst, DATA_SIZE), Eq(true));
EXPECT_THAT(dst, ContainerEq(src));
//read more than available
BufferReader br2{buf};
int16_t dstMore[DATA_SIZE+1]{};
EXPECT_THAT(br2.readBuffer<2>(dstMore, DATA_SIZE+1), Eq(false));
}
TEST(BufferBytesOperations, ReadWriteBufferCanWorkOnUnalignedData) {
//setup data
constexpr size_t DATA_SIZE = 3;
int16_t src[DATA_SIZE] {54,-4877,30067};
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
bw.writeBits(15u, 4);
bw.writeBuffer<2>(src, DATA_SIZE);
bw.writeBits(12u, 4);
bw.flush();
EXPECT_THAT(buf.size(), Eq(sizeof(src) + 1));
//read from buffer
BufferReader br1{buf};
int16_t dst[DATA_SIZE]{};
uint8_t tmp{};
br1.readBits(tmp, 4);
EXPECT_THAT(tmp, Eq(15));
EXPECT_THAT(br1.readBuffer<2>(dst, DATA_SIZE), Eq(true));
EXPECT_THAT(dst, ContainerEq(src));
br1.readBits(tmp, 4);
EXPECT_THAT(tmp, Eq(12));
//read more than available
BufferReader br2{buf};
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));
}

View File

@@ -80,7 +80,7 @@ TEST(BufferEndianness, WhenWriteBytesThenBytesAreSwapped) {
bw.writeBytes<1>(src.e);
bw.flush();
//read from buffer using inverse endianness config
bitsery::BasicBufferReader<InverseEndiannessConfig> br{buf};
bitsery::BasicBufferReader<InverseEndiannessConfig> br{bw.getWrittenRange()};
IntegralTypes res{};
br.readBytes<8>(res.a);
br.readBytes<4>(res.b);
@@ -106,7 +106,7 @@ TEST(BufferEndianness, WhenWriteBuffer1ByteValuesThenEndiannessIsIgnored) {
bw.writeBuffer<1>(src, SIZE);
bw.flush();
//read from buffer using inverse endianness config
bitsery::BasicBufferReader<InverseEndiannessConfig> br{buf};
bitsery::BasicBufferReader<InverseEndiannessConfig> br{bw.getWrittenRange()};
br.readBuffer<1>(res, SIZE);
//result is identical, because we write separate values, of size 1byte, that requires no swapping
//check results
@@ -125,7 +125,7 @@ TEST(BufferEndianness, WhenWriteBufferMoreThan1ByteValuesThenValuesAreSwapped) {
bw.writeBuffer<2>(src, SIZE);
bw.flush();
//read from buffer using inverse endianness config
bitsery::BasicBufferReader<InverseEndiannessConfig> br{buf};
bitsery::BasicBufferReader<InverseEndiannessConfig> br{bw.getWrittenRange()};
br.readBuffer<2>(res, SIZE);
//result is identical, because we write separate values, of size 1byte, that requires no swapping
//check results
@@ -169,7 +169,7 @@ TEST(BufferEndianness, WhenBufferValueTypeIs1ByteThenBitOperationsIsNotAffectedB
bw.writeBits(src.d, dBITS);
bw.flush();
//read from buffer using inverse endianness config
bitsery::BasicBufferReader<InverseEndiannessConfig> br{buf};
bitsery::BasicBufferReader<InverseEndiannessConfig> br{bw.getWrittenRange()};
IntegralUnsignedTypes res{};
br.readBits(res.a, aBITS);
br.readBits(res.b, bBITS);

View File

@@ -45,7 +45,9 @@ constexpr size_t getBits(T v) {
return bitsery::details::calcRequiredBits<T>({}, v);
};
TEST(BufferBitsOperations, WriteAndReadBits) {
// *** bits operations
TEST(BufferBitsAndBytesOperations, WriteAndReadBits) {
//setup data
constexpr IntegralUnsignedTypes data{
485454,//bits 19
@@ -71,10 +73,11 @@ TEST(BufferBitsOperations, WriteAndReadBits) {
bw.writeBits(data.d, dBITS);
bw.writeBits(data.e, eBITS);
bw.flush();
auto range = bw.getWrittenRange();
auto bytesCount = ((aBITS + bBITS + cBITS + dBITS + eBITS) / 8) +1 ;
EXPECT_THAT(std::distance(buf.begin(), buf.end()), Eq(bytesCount));
EXPECT_THAT(std::distance(range.begin(), range.end()), Eq(bytesCount));
//read from buffer
BufferReader br{buf};
BufferReader br{range};
IntegralUnsignedTypes res;
br.readBits(res.a, aBITS);
@@ -91,19 +94,7 @@ TEST(BufferBitsOperations, WriteAndReadBits) {
}
TEST(BufferBitsOperations, WhenFinishedFlushWriter) {
Buffer buf;
BufferWriter bw{buf};
bw.writeBits(3u, 2);
EXPECT_THAT(std::distance(buf.begin(), buf.end()), Eq(0));
bw.flush();
EXPECT_THAT(std::distance(buf.begin(), buf.end()), Eq(1));
}
TEST(BufferBitsOperations, BufferSizeIsCountedPerByteNotPerBit) {
TEST(BufferBitsAndBytesOperations, BufferSizeIsCountedPerByteNotPerBit) {
//setup data
//create and write to buffer
@@ -112,10 +103,11 @@ TEST(BufferBitsOperations, BufferSizeIsCountedPerByteNotPerBit) {
bw.writeBits(7u,3);
bw.flush();
EXPECT_THAT(std::distance(buf.begin(), buf.end()), Eq(1));
auto range = bw.getWrittenRange();
EXPECT_THAT(std::distance(range.begin(), range.end()), Eq(1));
//read from buffer
BufferReader br{buf};
BufferReader br{range};
uint16_t tmp;
EXPECT_THAT(br.readBits(tmp,4), Eq(true));
EXPECT_THAT(br.readBits(tmp,2), Eq(true));
@@ -123,16 +115,16 @@ TEST(BufferBitsOperations, BufferSizeIsCountedPerByteNotPerBit) {
EXPECT_THAT(br.readBits(tmp,2), Eq(false));
//part of next byte
BufferReader br1{buf};
BufferReader br1{range};
EXPECT_THAT(br1.readBits(tmp,2), Eq(true));
EXPECT_THAT(br1.readBits(tmp,7), Eq(false));
//bigger than byte
BufferReader br2{buf};
BufferReader br2{range};
EXPECT_THAT(br2.readBits(tmp,9), Eq(false));
}
TEST(BufferBitsOperations, ConsecutiveCallsToAlignHasNoEffect) {
TEST(BufferBitsAndBytesOperations, ConsecutiveCallsToAlignHasNoEffect) {
Buffer buf;
BufferWriter bw{buf};
@@ -148,7 +140,7 @@ TEST(BufferBitsOperations, ConsecutiveCallsToAlignHasNoEffect) {
bw.flush();
unsigned char tmp;
BufferReader br{buf};
BufferReader br{bw.getWrittenRange()};
EXPECT_THAT(br.readBits(tmp,2), Eq(true));
EXPECT_THAT(tmp, Eq(3u));
EXPECT_THAT(br.align(), Eq(true));
@@ -163,24 +155,7 @@ TEST(BufferBitsOperations, ConsecutiveCallsToAlignHasNoEffect) {
EXPECT_THAT(tmp, Eq(15u));
}
TEST(BufferBitsOperations, WhenAlignedFlushHasNoEffect) {
//setup data
//create and write to buffer
Buffer buf;
BufferWriter bw{buf};
bw.writeBits(3u, 2);
bw.align();
EXPECT_THAT(std::distance(buf.begin(), buf.end()), Eq(1));
bw.flush();
EXPECT_THAT(std::distance(buf.begin(), buf.end()), Eq(1));
}
TEST(BufferBitsOperations, AlignMustWriteZerosBits) {
TEST(BufferBitsAndBytesOperations, AlignWritesZerosBits) {
//setup data
//create and write to buffer
@@ -190,16 +165,128 @@ TEST(BufferBitsOperations, AlignMustWriteZerosBits) {
//write 2 bits and align
bw.writeBits(3u, 2);
bw.align();
bw.flush();
unsigned char tmp;
BufferReader br1{buf};
BufferReader br1{bw.getWrittenRange()};
br1.readBits(tmp,2);
//read aligned bits
EXPECT_THAT(br1.readBits(tmp,6), Eq(true));
EXPECT_THAT(tmp, Eq(0));
BufferReader br2{buf};
BufferReader br2{bw.getWrittenRange()};
//read 2 bits
br2.readBits(tmp,2);
EXPECT_THAT(br2.align(), Eq(true));
}
// *** bytes operations
struct IntegralTypes {
int64_t a;
uint32_t b;
int16_t c;
uint8_t d;
int8_t e;
int8_t f[2];
};
TEST(BufferBitsAndBytesOperations, WriteAndReadBytes) {
//setup data
IntegralTypes data;
data.a = -4894541654564;
data.b = 94545646;
data.c = -8778;
data.d = 200;
data.e = -98;
data.f[0] = 43;
data.f[1] = -45;
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
bw.writeBytes<4>(data.b);
bw.writeBytes<2>(data.c);
bw.writeBytes<1>(data.d);
bw.writeBytes<8>(data.a);
bw.writeBytes<1>(data.e);
bw.writeBuffer<1>(data.f, 2);
bw.flush();
auto range = bw.getWrittenRange();
EXPECT_THAT(std::distance(range.begin(), range.end()), Eq(18));
//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));
//assert results
EXPECT_THAT(data.a, Eq(res.a));
EXPECT_THAT(data.b, Eq(res.b));
EXPECT_THAT(data.c, Eq(res.c));
EXPECT_THAT(data.d, Eq(res.d));
EXPECT_THAT(data.e, Eq(res.e));
EXPECT_THAT(data.f, ContainerEq(res.f));
}
TEST(BufferBitsAndBytesOperations, ReadWriteBufferFncCanAcceptSignedData) {
//setup data
constexpr size_t DATA_SIZE = 3;
int16_t src[DATA_SIZE] {54,-4877,30067};
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
bw.writeBuffer<2>(src, DATA_SIZE);
bw.flush();
//read from buffer
BufferReader br1{bw.getWrittenRange()};
int16_t dst[DATA_SIZE]{};
EXPECT_THAT(br1.readBuffer<2>(dst, DATA_SIZE), Eq(true));
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) {
//setup data
constexpr size_t DATA_SIZE = 3;
int16_t src[DATA_SIZE] {54,-4877,30067};
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
bw.writeBits(15u, 4);
bw.writeBuffer<2>(src, DATA_SIZE);
bw.writeBits(12u, 4);
bw.flush();
auto range = bw.getWrittenRange();
EXPECT_THAT(std::distance(range.begin(), range.end()), Eq(sizeof(src) + 1));
//read from buffer
BufferReader br1{range};
int16_t dst[DATA_SIZE]{};
uint8_t tmp{};
br1.readBits(tmp, 4);
EXPECT_THAT(tmp, Eq(15));
EXPECT_THAT(br1.readBuffer<2>(dst, DATA_SIZE), Eq(true));
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));
}

107
tests/buffer_reading.cpp Normal file
View File

@@ -0,0 +1,107 @@
//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 <bitsery/buffer_writer.h>
#include <bitsery/buffer_reader.h>
#include <list>
#include <bitset>
using testing::Eq;
using testing::ContainerEq;
using bitsery::BufferWriter;
using bitsery::BufferReader;
using Buffer = bitsery::DefaultConfig::BufferType;
struct IntegralTypes {
int64_t a;
uint32_t b;
int16_t c;
uint8_t d;
int8_t e;
int8_t f[2];
};
TEST(BufferReading, ReadReturnsFalseIfNotEnoughBufferSize) {
//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()};
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));
}
TEST(BufferReading, ReadIsCompletedWhenAllBytesAreRead) {
//setup data
IntegralTypes data;
data.b = 94545646;
data.c = -8778;
data.d = 200;
//create and write to buffer
Buffer buf{};
BufferWriter bw{buf};
bw.writeBytes<4>(data.b);
bw.writeBytes<2>(data.c);
bw.writeBytes<1>(data.d);
bw.flush();
//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));
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));
}

115
tests/buffer_writing.cpp Normal file
View File

@@ -0,0 +1,115 @@
//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 <bitsery/buffer_writer.h>
#include <bitsery/buffer_reader.h>
#include <bitsery/details/serialization_common.h>
using testing::Eq;
using testing::ContainerEq;
using bitsery::EndiannessType;
using bitsery::DefaultConfig;
using Buffer = bitsery::DefaultConfig::BufferType;
struct FixedBufferConfig {
static constexpr bitsery::EndiannessType NetworkEndianness = DefaultConfig::NetworkEndianness;
static constexpr bool FixedBufferSize = true;
using BufferType = std::array<uint8_t, 100>;
};
struct NonFixedBufferConfig: public DefaultConfig {
};
template <typename Config>
class BufferWriting:public testing::Test {
public:
using type = Config;
};
using BufferWritingConfigs = ::testing::Types<
NonFixedBufferConfig,
FixedBufferConfig>;
TYPED_TEST_CASE(BufferWriting, BufferWritingConfigs);
static constexpr size_t DATA_SIZE = 14u;
template <typename BW>
void writeData(BW& bw) {
uint16_t tmp1{45}, tmp2{6543}, tmp3{46533};
uint32_t tmp4{8979445}, tmp5{7987564};
bw.template writeBytes<2>(tmp1);
bw.template writeBytes<2>(tmp2);
bw.template writeBytes<2>(tmp3);
bw.template writeBytes<4>(tmp4);
bw.template writeBytes<4>(tmp5);
}
TYPED_TEST(BufferWriting, GetWrittenRangeReturnsIterators) {
using Config = typename TestFixture::type;
using Buffer = typename Config::BufferType;
Buffer buf{};
bitsery::BasicBufferWriter<Config> bw{buf};
writeData(bw);
bw.flush();
auto range = bw.getWrittenRange();
EXPECT_THAT(std::distance(range.begin(), range.end()), DATA_SIZE);
}
TYPED_TEST(BufferWriting, WhenWritingBitsThenFlushWriter) {
Buffer buf;
bitsery::BufferWriter bw{buf};
bw.writeBits(3u, 2);
auto range1 = bw.getWrittenRange();
bw.flush();
auto range2 = bw.getWrittenRange();
EXPECT_THAT(std::distance(range1.begin(), range1.end()), Eq(0));
EXPECT_THAT(std::distance(range2.begin(), range2.end()), Eq(1));
}
TYPED_TEST(BufferWriting, WhenDataAlignedThenFlushHasNoEffect) {
using Config = typename TestFixture::type;
using Buffer = typename Config::BufferType;
Buffer buf{};
bitsery::BasicBufferWriter<Config> bw{buf};
bw.writeBits(3u, 2);
bw.align();
auto range1 = bw.getWrittenRange();
bw.flush();
auto range2 = bw.getWrittenRange();
EXPECT_THAT(std::distance(range1.begin(), range1.end()), Eq(1));
EXPECT_THAT(std::distance(range2.begin(), range2.end()), Eq(1));
}
//TEST(BufferWritingFixedBuffer, ) {
// FixedBufferConfig::BufferType buf{};
// bitsery::BasicBufferWriter<FixedBufferConfig> bw{buf};
// writeData(bw);
// bw.flush();
// auto r = bw.getWrittenRange();
// EXPECT_THAT(buf.begin(), r.begin());
//}

View File

@@ -161,7 +161,7 @@ TEST(DeltaSerializer, GeneralConceptTest) {
serialize(ser, yNew);
bw.flush();
bitsery::BufferReader br{ buf };
bitsery::BufferReader br{ bw.getWrittenRange() };
bitsery::DeltaDeserializer<bitsery::BufferReader, Y> des(br, y, yRead);
serialize(des, yRead);

View File

@@ -92,7 +92,8 @@ public:
};
size_t getBufferSize() const {
return buf.size();
auto range = bw->getWrittenRange();
return std::distance(range.begin(), range.end());
}
//since all containers .size() method returns size_t, it cannot be directly serialized, because size_t is platform dependant
@@ -107,7 +108,7 @@ public:
bitsery::Deserializer<bitsery::BufferReader> createDeserializer() {
bw->flush();
br = std::make_unique<bitsery::BufferReader>(buf);
br = std::make_unique<bitsery::BufferReader>(bw->getWrittenRange());
return {*br};
};
};