mirror of
https://github.com/fraillt/bitsery.git
synced 2026-06-08 08:13:56 +00:00
simplified usage by merging adapter writer/reader with input/output
adapter and ability to disable checks on deserialization
This commit is contained in:
committed by
Mindaugas Vinkelis
parent
1822796f2e
commit
105aa5f9e5
@@ -68,9 +68,9 @@ using Context = std::tuple<int, std::pair<uint32_t, uint32_t>>;
|
||||
//use fixed-size buffer
|
||||
using Buffer = std::vector<uint8_t>;
|
||||
using namespace bitsery;
|
||||
// define Writer and Reader types,
|
||||
using Writer = AdapterWriter<OutputBufferAdapter<Buffer>, DefaultConfig, Context>;
|
||||
using Reader = AdapterReader<InputBufferAdapter<Buffer>, DefaultConfig, Context>;
|
||||
// define adapter types,
|
||||
using OutputAdapter = OutputBufferAdapter<Buffer>;
|
||||
using InputAdapter = InputBufferAdapter<Buffer>;
|
||||
|
||||
int main() {
|
||||
|
||||
@@ -90,18 +90,10 @@ int main() {
|
||||
|
||||
//create buffer to store data to
|
||||
Buffer buffer{};
|
||||
//create adapter writer with context
|
||||
//context is passed by reference without taking ownership
|
||||
Writer writer{buffer, ctx};
|
||||
//serialize data
|
||||
BasicSerializer<Writer> ser{writer};
|
||||
ser.object(data);
|
||||
writer.flush();
|
||||
auto writtenSize = quickSerialization(ctx, OutputAdapter{buffer}, data);
|
||||
|
||||
MyTypes::GameState res{};
|
||||
Reader reader {{buffer.begin(), writer.writtenBytesCount()}, ctx};
|
||||
BasicDeserializer<Reader> des {reader };
|
||||
des.object(res);
|
||||
auto state = quickDeserialization(ctx, InputAdapter{buffer.begin(), writtenSize}, res);
|
||||
|
||||
assert(reader.error() == ReaderError::NoError && reader.isCompletedSuccessfully());
|
||||
assert(state.first == ReaderError::NoError && state.second);
|
||||
}
|
||||
|
||||
@@ -21,9 +21,6 @@ void serialize(S& s, MyStruct& o) {
|
||||
|
||||
using namespace bitsery;
|
||||
|
||||
//buffered stream adapter allows for faster writes
|
||||
using Writer = AdapterWriter<OutputBufferedStreamAdapter, DefaultConfig>;
|
||||
|
||||
int main() {
|
||||
//set some random data
|
||||
MyStruct data{8941, MyEnum::V2, 0.045};
|
||||
@@ -38,11 +35,10 @@ int main() {
|
||||
}
|
||||
|
||||
//we cannot use quick serialization function, because streams cannot use writtenBytesCount method
|
||||
Writer writer{s};
|
||||
BasicSerializer<Writer> ser{writer};
|
||||
BasicSerializer<OutputBufferedStreamAdapter> ser{s};
|
||||
ser.object(data);
|
||||
//flush to writer
|
||||
writer.flush();
|
||||
ser.adapter().flush();
|
||||
s.close();
|
||||
//reopen for reading
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ using namespace bitsery;
|
||||
|
||||
//some helper types
|
||||
using Buffer = std::vector<uint8_t>;
|
||||
using Writer = AdapterWriter<OutputBufferAdapter<Buffer>, DefaultConfig, ext::InheritanceContext>;
|
||||
using Reader = AdapterReader<InputBufferAdapter<Buffer>, DefaultConfig, ext::InheritanceContext>;
|
||||
using Writer = OutputBufferAdapter<Buffer>;
|
||||
using Reader = InputBufferAdapter<Buffer>;
|
||||
|
||||
int main() {
|
||||
|
||||
@@ -96,19 +96,12 @@ int main() {
|
||||
Buffer buf{};
|
||||
|
||||
ext::InheritanceContext ctx1;
|
||||
Writer writer{buf, ctx1};
|
||||
BasicSerializer<Writer> ser{writer};
|
||||
ser.object(data);
|
||||
writer.flush();
|
||||
|
||||
auto writtenSize = quickSerialization(ctx1, Writer{buf}, data);
|
||||
assert(writtenSize == 4);//base is serialized once, because it is inherited virtually
|
||||
|
||||
MultipleInheritance res{0};
|
||||
ext::InheritanceContext ctx2;
|
||||
Reader reader{{buf.begin(), writer.writtenBytesCount()}, ctx2};
|
||||
BasicDeserializer<Reader> des{reader};
|
||||
des.object(res);
|
||||
assert(reader.error() == ReaderError::NoError && reader.isCompletedSuccessfully());
|
||||
|
||||
auto state = quickDeserialization(ctx2, Reader{buf.begin(), writtenSize}, res);
|
||||
assert(state.first == ReaderError::NoError && state.second);
|
||||
assert(data.x == res.x && data.y1 == res.y1 && data.getY2() == res.getY2() && data.z == res.z);
|
||||
assert(writer.writtenBytesCount() == 4);//base is serialized once, because it is inherited virtually
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ using namespace bitsery;
|
||||
|
||||
//some helper types
|
||||
using Buffer = std::vector<uint8_t>;
|
||||
using Writer = AdapterWriter<OutputBufferAdapter<Buffer>, DefaultConfig>;
|
||||
using Reader = AdapterReader<InputBufferAdapter<Buffer>, DefaultConfig>;
|
||||
using Writer = OutputBufferAdapter<Buffer>;
|
||||
using Reader = InputBufferAdapter<Buffer>;
|
||||
|
||||
int main() {
|
||||
|
||||
@@ -44,23 +44,21 @@ int main() {
|
||||
data.emplace_back(145.4f, 84.48f);
|
||||
std::vector<MyData> res{};
|
||||
|
||||
//we cant use quick (de)serialization helper methods, because we ant to serialize container directly
|
||||
//create buffer
|
||||
Buffer buffer{};
|
||||
|
||||
//we cant use quick (de)serialization helper methods, because we ant to serialize container directly
|
||||
//create writer and serialize container
|
||||
Writer writer{buffer};
|
||||
BasicSerializer<Writer> ser{writer};
|
||||
BasicSerializer<Writer> ser{buffer};
|
||||
ser.container(data, 10);
|
||||
writer.flush();
|
||||
ser.adapter().flush();
|
||||
|
||||
//create reader and deserialize container
|
||||
Reader reader{{buffer.begin(), writer.writtenBytesCount()}};
|
||||
BasicDeserializer<Reader> des{reader};
|
||||
BasicDeserializer<Reader> des{buffer.begin(), ser.adapter().writtenBytesCount()};
|
||||
des.container(res, 10);
|
||||
|
||||
//check if everything went ok
|
||||
assert(reader.error() == ReaderError::NoError && reader.isCompletedSuccessfully());
|
||||
assert(des.adapter().error() == ReaderError::NoError && des.adapter().isCompletedSuccessfully());
|
||||
assert(res == data);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,16 +82,14 @@ using namespace bitsery;
|
||||
|
||||
//some helper types
|
||||
using Buffer = std::vector<uint8_t>;
|
||||
using OutputAdapter = OutputBufferAdapter<Buffer>;
|
||||
using InputAdapter = InputBufferAdapter<Buffer>;
|
||||
using Writer = OutputBufferAdapter<Buffer>;
|
||||
using Reader = InputBufferAdapter<Buffer>;
|
||||
|
||||
//we will need PointerLinkingContext to work with pointers
|
||||
//if we would require additional context for our own custom flow, we can define it as tuple like this:
|
||||
// std::tuple<MyContext,ext::PointerLinkingContext>
|
||||
//and other code will work as expected as long as it cast to proper type.
|
||||
//see context_usage.cpp for usage example
|
||||
using Writer = AdapterWriter<OutputBufferAdapter<Buffer>, DefaultConfig, ext::PointerLinkingContext>;
|
||||
using Reader = AdapterReader<InputBufferAdapter<Buffer>, DefaultConfig, ext::PointerLinkingContext>;
|
||||
|
||||
int main() {
|
||||
//set some random data
|
||||
@@ -114,15 +112,10 @@ int main() {
|
||||
//create buffer to store data
|
||||
Buffer buffer{};
|
||||
size_t writtenSize{};
|
||||
//in order to use pointers, we need to pass pointer linking context to writer/reader
|
||||
//in order to use pointers, we need to pass pointer linking context serializer/deserializer
|
||||
{
|
||||
ext::PointerLinkingContext ctx{};
|
||||
Writer writer{buffer, ctx};
|
||||
BasicSerializer<Writer> ser{writer};
|
||||
//serialize our data
|
||||
ser.object(data);
|
||||
writer.flush();
|
||||
writtenSize = writer.writtenBytesCount();
|
||||
writtenSize = quickSerialization(ctx, Writer{buffer}, data);
|
||||
|
||||
//make sure that pointer linking context is valid
|
||||
//this ensures that all non-owning pointers points to data that has been serialized,
|
||||
@@ -133,13 +126,9 @@ int main() {
|
||||
Test1Data res{};
|
||||
{
|
||||
ext::PointerLinkingContext ctx{};
|
||||
//pass lining context to reader
|
||||
Reader reader{{buffer.begin(), writtenSize}, ctx};
|
||||
BasicDeserializer<Reader> des{reader};
|
||||
//deserialize our data
|
||||
des.object(res);
|
||||
auto state = quickDeserialization(ctx, Reader{buffer.begin(), writtenSize}, res);
|
||||
//check if everything went find
|
||||
assert(reader.error() == ReaderError::NoError && reader.isCompletedSuccessfully());
|
||||
assert(state.first == ReaderError::NoError && state.second);
|
||||
//also check for dangling pointers, after deserialization
|
||||
assert(ctx.isValid());
|
||||
}
|
||||
|
||||
@@ -187,8 +187,8 @@ using namespace bitsery;
|
||||
|
||||
//some helper types
|
||||
using Buffer = std::vector<uint8_t>;
|
||||
using OutputAdapter = OutputBufferAdapter<Buffer>;
|
||||
using InputAdapter = InputBufferAdapter<Buffer>;
|
||||
using Writer = OutputBufferAdapter<Buffer>;
|
||||
using Reader = InputBufferAdapter<Buffer>;
|
||||
|
||||
//we need to define few things in order to work with polymorphism
|
||||
//1) we need pointer linking context to work with pointers
|
||||
@@ -196,10 +196,8 @@ using InputAdapter = InputBufferAdapter<Buffer>;
|
||||
using TContext = std::tuple<ext::PointerLinkingContext, ext::PolymorphicContext<ext::StandardRTTI>>;
|
||||
//NOTE:
|
||||
// RTTI can be customizable, if you can't use dynamic_cast and typeid, and have 'custom' solution
|
||||
|
||||
using Writer = AdapterWriter<OutputBufferAdapter<Buffer>, DefaultConfig, TContext>;
|
||||
using Reader = AdapterReader<InputBufferAdapter<Buffer>, DefaultConfig, TContext>;
|
||||
|
||||
using Serializer = BasicSerializer<Writer, TContext>;
|
||||
using Deserializer = BasicDeserializer<Reader, TContext>;
|
||||
|
||||
//checks if deserialized data is equal
|
||||
void assertSameShapes(const SomeShapes &data, const SomeShapes &res) {
|
||||
@@ -232,6 +230,7 @@ int main() {
|
||||
//create buffer to store data
|
||||
Buffer buffer{};
|
||||
size_t writtenSize{};
|
||||
// we will not use quickSerialization/Deserialization functions to show, that we need to register polymorphic classes, explicitly
|
||||
{
|
||||
|
||||
//STEP 2
|
||||
@@ -239,13 +238,12 @@ int main() {
|
||||
// bind it with base polymorphic types, it will go through all reachable classes that is defined in first step.
|
||||
// NOTE: you dont need to add Rectangle to reach for RoundedRectangle
|
||||
TContext ctx{};
|
||||
std::get<1>(ctx).registerBasesList<BasicSerializer<Writer>>(MyPolymorphicClassesForRegistering{});
|
||||
std::get<1>(ctx).registerBasesList<Serializer>(MyPolymorphicClassesForRegistering{});
|
||||
//create writer and serialize
|
||||
Writer writer{buffer, ctx};
|
||||
BasicSerializer<Writer> ser{writer};
|
||||
Serializer ser{ctx, buffer};
|
||||
ser.object(data);
|
||||
writer.flush();
|
||||
writtenSize = writer.writtenBytesCount();
|
||||
ser.adapter().flush();
|
||||
writtenSize = ser.adapter().writtenBytesCount();
|
||||
|
||||
//make sure that pointer linking context is valid
|
||||
//this ensures that all non-owning pointers points to data that has been serialized,
|
||||
@@ -255,13 +253,11 @@ int main() {
|
||||
SomeShapes res{};
|
||||
{
|
||||
TContext ctx{};
|
||||
std::get<1>(ctx).registerBasesList<BasicDeserializer<Reader>>(MyPolymorphicClassesForRegistering{});
|
||||
//serialize our data
|
||||
Reader reader {{buffer.begin(), writtenSize}, ctx};
|
||||
BasicDeserializer<Reader> des{reader};
|
||||
std::get<1>(ctx).registerBasesList<Deserializer>(MyPolymorphicClassesForRegistering{});
|
||||
//deserialize our data
|
||||
Deserializer des{ctx, buffer.begin(), writtenSize};
|
||||
des.object(res);
|
||||
//check if everything went find
|
||||
assert(reader.error() == ReaderError::NoError && reader.isCompletedSuccessfully());
|
||||
assert(des.adapter().error() == ReaderError::NoError && des.adapter().isCompletedSuccessfully());
|
||||
//also check for dangling pointers, after deserialization
|
||||
assert(std::get<0>(ctx).isValid());
|
||||
// clear shared state from pointer linking context,
|
||||
|
||||
Reference in New Issue
Block a user