158 lines
2.8 KiB
Markdown
Executable File
158 lines
2.8 KiB
Markdown
Executable File
# Core_IO
|
|
|
|
IO foundational classes
|
|
|
|
IO classes which optimize super well, super fast, super memory efficient.
|
|
JSON is based on sajson which is nearly as fast as memcpy (which blows my mind).
|
|
|
|
## Building
|
|
|
|
IO is header only.
|
|
|
|
## How to use
|
|
|
|
### Declare your data
|
|
|
|
```
|
|
|
|
namespace my_namespace {
|
|
|
|
struct MyOtherData {
|
|
float f;
|
|
} ;
|
|
|
|
struct MyData {
|
|
char c;
|
|
int i;
|
|
std::string s;
|
|
MyOtherData o;
|
|
} ;
|
|
|
|
} // my_namespace
|
|
|
|
```
|
|
|
|
### Somewhere in the same namespace, declare the serializer:
|
|
|
|
```
|
|
|
|
namespace my_namespace {
|
|
|
|
template<typename IO>
|
|
void io_(IO &io, MyOtherData &v)
|
|
{
|
|
io.object(
|
|
"f", v.f
|
|
);
|
|
)
|
|
|
|
|
|
template<typename IO>
|
|
void io_(IO &io, MyData &v)
|
|
{
|
|
io.object(
|
|
"c", v.c,
|
|
"i", v.i,
|
|
"s", v.s,
|
|
"o", v.o
|
|
);
|
|
)
|
|
|
|
} // my_namespace
|
|
|
|
```
|
|
|
|
### To serialize and deserialize as json:
|
|
|
|
```
|
|
|
|
#include <tjp/core/json/in_sajson.h>
|
|
#include <tjp/core/json/out.h>
|
|
|
|
namespace any_namespace {
|
|
|
|
void somewhere ()
|
|
{
|
|
my_namespace::MyData myData;
|
|
auto serialized = tjp::core::io::json::serialize(myData);
|
|
auto deserialized = tjp::core::io::json::deserialize<my_namespace::MyData>(serialized);
|
|
}
|
|
|
|
} // any_namespace
|
|
|
|
```
|
|
|
|
### To serialize and deserialize as binary:
|
|
|
|
```
|
|
#include <tjp/core/bin/in.h>
|
|
#include <tjp/core/bin/out.h>
|
|
|
|
namespace any_namespace {
|
|
|
|
void somewhere ()
|
|
{
|
|
my_namespace::MyData myData;
|
|
auto serialized = tjp::core::io::bin::serialize(myData);
|
|
auto deserialized = tjp::core::io::bin::deserialize<my_namespace::MyData>(serialized);
|
|
}
|
|
|
|
} // any_namespace
|
|
|
|
```
|
|
|
|
### To do versioning
|
|
|
|
I use versioning, however I declared it outside the scope of the library.
|
|
|
|
The method I ended up using was to deserialize a version number at the beginning of a
|
|
deserialization and store in the IO class. Then when deserializing data which is versioned,
|
|
check the version number and dispatch to the appropriate function.
|
|
|
|
It ends up looking like this:
|
|
|
|
```
|
|
template<typename IO>
|
|
void io_(IO &io, TimeSpecification &v, serializer::Version<100> &&)
|
|
{
|
|
io.object(
|
|
"clock", v.clock,
|
|
"bounds", v.bounds
|
|
);
|
|
}
|
|
|
|
template<typename IO>
|
|
void io_(IO &io, TimeSpecification &v, serializer::Version<104> &&)
|
|
{
|
|
io.object(
|
|
"clock", v.clock,
|
|
"bounds", v.bounds,
|
|
"flags", v.flags
|
|
);
|
|
}
|
|
|
|
|
|
template<typename IO>
|
|
void io_(IO &io, TimeSpecification &v)
|
|
{
|
|
if (io.version.my_version_number < 104)
|
|
return io_(io, v, serializer::Version<104>{});
|
|
|
|
return io_(io, v, serializer::Version<104>{});
|
|
}
|
|
```
|
|
|
|
|
|
###
|
|
|
|
You can make your own serialization IO by implementing a new IO class
|
|
|
|
|
|
It's not trivial, but it's not hard.
|
|
|
|
Generally, I'll be putting in some time to clean up these IO classes in the end of 2025.
|
|
|
|
### Other examples
|
|
|
|
Look at `Core_IO/bin/_tests/IO_bin.cpp` for more examples on how to use this library.
|