mirror of
https://github.com/fraillt/bitsery.git
synced 2026-06-08 08:13:56 +00:00
buffer reading/writing improvements
This commit is contained in:
@@ -4,7 +4,11 @@
|
||||
### Features
|
||||
|
||||
* now all serializer/deserializer functions return void, to avoid undefined behaviour for functions parameters evaluation when using method chaining. There was no benefits apart from *nicer* syntax, but could have undefined behaviour when building complex serialization flows.
|
||||
* changed BufferWriter/Reader config, added *FixedBufferSize* bool parameter for *BufferWriter* for much better serializer performance (more than 50% improvement). Default is old behavour - using back_insert_iterator when writing.
|
||||
* changed BufferWriter/Reader behaviour,
|
||||
* after serialization, call *getWrittenRange* to get valid written range.
|
||||
* BufferReader only has constructors with iterators.
|
||||
* added *FixedBufferSize* config bool parameter for *BufferWriter* for better serializer performance (more than 50% improvement). Default is resizable buffer.
|
||||
* BufferWritter for resizable buffer now always resize to *capacity* to avoid using *back_insert_iterator* for better performance.
|
||||
* added **SERIALIZE_FRIEND** macro to be able to serialize private struct fields
|
||||
* user friendly static_assert when trying to serialize object, that doesn't have **serialize** function defined.
|
||||
* added **custom** function to override default behaviour for **object** serialization
|
||||
|
||||
@@ -18,7 +18,7 @@ All cross-platform requirements are enforced at compile time, so serialized data
|
||||
* Configurable endianess support.
|
||||
* Advanced serialization features like value ranges and entrophy encoding.
|
||||
* Easy to extend for types that requires different serialization and deserialization logic (e.g. pointers, or geometry compression).
|
||||
* Error checking at runtime on deserialization, and asserts on serialization errors.
|
||||
* No exceptions. Error checking at runtime for deserialization, and asserts on serialization.
|
||||
|
||||
## How to use it
|
||||
This documentation comprises these parts:
|
||||
|
||||
@@ -2,7 +2,7 @@ To get the most out of **Bitsery**, start with the [tutorial](tutorial/README.md
|
||||
Once you're familiar with the library consider the following reference material.
|
||||
|
||||
Library design:
|
||||
* [*valueN* instead of *value*](design/func_n.md)
|
||||
* [*valueN* instead of *value*](design/function_n.md)
|
||||
* [fundamental types](design/fundamental_types.md)
|
||||
* [serializer/deserializer functions overloads](design/function_overload.md)
|
||||
* [extending library functionality](design/extensions.md)
|
||||
@@ -29,11 +29,6 @@ Tips and tricks:
|
||||
|
||||
Advanced topics:
|
||||
|
||||
|
||||
|
||||
FAQ:
|
||||
* [Known limitations](limitations.md)
|
||||
|
||||
Other:
|
||||
* [Why Bitsery?](why-bitsery.md)
|
||||
* [Contributing](../CONTRIBUTING.md)
|
||||
|
||||
@@ -2,14 +2,13 @@ The grand plan for this tutorial is to learn how to serialize/deserialize any ob
|
||||
|
||||
|
||||
This tutorial will cover these main topics:
|
||||
* [Hello World](hello_world.md) how to serialize a simple struct.
|
||||
* [2 in 1](two_in_one.md) how to write one control flow for both, serialization and deserialization.
|
||||
* [Composer](composition.md) how to make your type serializable by default or override default flow.
|
||||
* [Squeeze Me!](compression.md) how to compress your data if you know what it stores.
|
||||
* [Anything is Possible](extensions.md) how to extend library for your custom container, compress geometry and more.
|
||||
* [Little or Big](endianness.md) how to change Endianness if you want best performance on PowerPC.
|
||||
* [Hello World](hello_world.md) serialize a simple struct.
|
||||
* [2 in 1](two_in_one.md) write one control flow for both: serialization and deserialization.
|
||||
* [Composer](composition.md) efficiently compose complex serialization flows.
|
||||
* [Squeeze Me!](compression.md) compress your data when you know what it stores.
|
||||
* [Anything is Possible](extensions.md) extend library for custom container, compress geometry and more.
|
||||
* [Little or Big](endianness.md) change endianness if you want best performance on PowerPC.
|
||||
|
||||
In order to successfully use the library you need c++14 compatible compiler. In theory you could also use c++11 compatible compiler, but c++14 generic lambdas really change the way you can work with this library, so all tutorial sections will asume that you use c++14 compatible compiler.
|
||||
|
||||
So without further ado lets start with [hello world](hello_world.md).
|
||||
|
||||
|
||||
@@ -34,9 +34,11 @@ namespace bitsery {
|
||||
struct BasicBufferReader {
|
||||
using BufferType = typename Config::BufferType;
|
||||
using ValueType = typename BufferType::value_type;
|
||||
using IteratorType = typename BufferType::iterator;
|
||||
using ScratchType = typename details::SCRATCH_TYPE<ValueType>::type;
|
||||
|
||||
BasicBufferReader(const ValueType *data, size_t size) : _pos{data}, _end{data + size} {
|
||||
BasicBufferReader(IteratorType begin, IteratorType end)
|
||||
:_pos{begin}, _end{end} {
|
||||
static_assert(std::is_unsigned<ValueType>(), "Config::BufferValueType must be unsigned");
|
||||
static_assert(std::is_unsigned<ScratchType>(), "Config::BufferScrathType must be unsigned");
|
||||
static_assert(sizeof(ValueType) * 2 == sizeof(ScratchType),
|
||||
@@ -44,11 +46,8 @@ namespace bitsery {
|
||||
static_assert(sizeof(ValueType) == 1, "currently only supported BufferValueType is 1 byte");
|
||||
}
|
||||
|
||||
BasicBufferReader(typename BufferType::iterator begin, typename BufferType::iterator end)
|
||||
: BasicBufferReader(std::addressof(*begin), std::distance(begin, end)) {}
|
||||
|
||||
explicit BasicBufferReader(const BufferType &buf) : BasicBufferReader(buf.data(), buf.size()) {
|
||||
}
|
||||
BasicBufferReader(BufferRange<IteratorType> range)
|
||||
:BasicBufferReader(range.begin(), range.end()) {}
|
||||
|
||||
BasicBufferReader(const BasicBufferReader &) = delete;
|
||||
|
||||
@@ -117,8 +116,8 @@ namespace bitsery {
|
||||
}
|
||||
|
||||
private:
|
||||
const ValueType *_pos;
|
||||
const ValueType *_end;
|
||||
IteratorType _pos;
|
||||
IteratorType _end;
|
||||
|
||||
template<typename T>
|
||||
bool directRead(T *v, size_t count) {
|
||||
|
||||
@@ -147,8 +147,8 @@ namespace bitsery {
|
||||
}
|
||||
}
|
||||
|
||||
size_t getWrittenBytesCount() const {
|
||||
return _bufferContext.getWrittenBytesCount();
|
||||
BufferRange<typename BufferType::iterator> getWrittenRange() const {
|
||||
return _bufferContext.getWrittenRange();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "details/buffer_common.h"
|
||||
#include <vector>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace bitsery {
|
||||
|
||||
struct DefaultConfig {
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
namespace bitsery {
|
||||
|
||||
@@ -38,6 +40,14 @@ namespace bitsery {
|
||||
BigEndian
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
struct BufferRange : std::pair<I, I> {
|
||||
using std::pair<I, I>::pair;
|
||||
I begin() const { return this->first; }
|
||||
I end() const { return this->second; }
|
||||
};
|
||||
|
||||
|
||||
namespace details {
|
||||
template<typename T>
|
||||
constexpr size_t BITS_SIZE = sizeof(T) << 3;
|
||||
@@ -126,46 +136,66 @@ namespace bitsery {
|
||||
|
||||
explicit WriteBufferContext(Buffer &buffer)
|
||||
: _buffer{buffer},
|
||||
_outIt{buffer.begin()} {
|
||||
_outIt{buffer.begin()},
|
||||
_end{buffer.end()}
|
||||
{
|
||||
}
|
||||
|
||||
void write(const ValueType *data, size_t size) {
|
||||
assert(std::distance(_outIt, _end) >= static_cast<typename Buffer::difference_type>(size));
|
||||
_outIt = std::copy_n(data, size, _outIt);
|
||||
}
|
||||
|
||||
size_t getWrittenBytesCount() const {
|
||||
return std::distance(_buffer.begin(), _outIt) * sizeof(ValueType);
|
||||
BufferRange<IteratorType> getWrittenRange() const {
|
||||
return BufferRange<IteratorType>{_buffer.begin(), _outIt};
|
||||
}
|
||||
|
||||
private:
|
||||
Buffer &_buffer;
|
||||
IteratorType _outIt;
|
||||
IteratorType _end;
|
||||
};
|
||||
|
||||
template<typename Buffer>
|
||||
class WriteBufferContext<Buffer, false> {
|
||||
public:
|
||||
using ValueType = typename Buffer::value_type;
|
||||
using IteratorType = std::back_insert_iterator<Buffer>;
|
||||
using IteratorType = typename Buffer::iterator;
|
||||
|
||||
explicit WriteBufferContext(Buffer &buffer)
|
||||
: _buffer{buffer},
|
||||
_outIt{std::back_insert_iterator<Buffer>(buffer)},
|
||||
_initialSize{buffer.size()} {
|
||||
: _buffer{buffer}
|
||||
{
|
||||
resizeToCapacity(0);
|
||||
}
|
||||
|
||||
void write(const ValueType *data, size_t size) {
|
||||
std::copy_n(data, size, _outIt);
|
||||
if (std::distance(_outIt, _end) >= static_cast<typename Buffer::difference_type>(size)) {
|
||||
_outIt = std::copy_n(data, size, _outIt);
|
||||
} else {
|
||||
//get current position before invalidating iterators
|
||||
auto pos = std::distance(_buffer.begin(), _outIt);
|
||||
//make dummy call to back insert iterator to resize buffer
|
||||
*(std::back_insert_iterator<Buffer>(_buffer)) = {};
|
||||
resizeToCapacity(pos);
|
||||
write(data, size);
|
||||
}
|
||||
}
|
||||
|
||||
size_t getWrittenBytesCount() const {
|
||||
return (std::distance(_buffer.begin(), _buffer.end()) - _initialSize) * sizeof(ValueType);
|
||||
BufferRange<IteratorType> getWrittenRange() const {
|
||||
return BufferRange<IteratorType>{_buffer.begin(), _outIt};
|
||||
}
|
||||
|
||||
private:
|
||||
void resizeToCapacity(typename Buffer::difference_type writePos) {
|
||||
if (_buffer.capacity() != _buffer.size()) {
|
||||
_buffer.resize(_buffer.capacity());
|
||||
}
|
||||
_end = _buffer.end();
|
||||
_outIt = std::next(_buffer.begin(), writePos);
|
||||
}
|
||||
Buffer &_buffer;
|
||||
IteratorType _outIt;
|
||||
size_t _initialSize;
|
||||
IteratorType _end;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
107
tests/buffer_reading.cpp
Normal 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
115
tests/buffer_writing.cpp
Normal 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());
|
||||
//}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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};
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user