HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Basis of custom C++ serialization lib

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
libcustomserializationbasis

Problem

I know it's been done a million times already, but I couldn't find a serialization library to suit my needs. This is the very basis of what I came up with. I know the code is ugly and unstructured, so you don't have to tell me that.

My goal is to make a serialization/deserialization system that provides a minimal, optimally non-intrusive interface for all classes, but can also store data verbosely, including variable names and type names. I will also implement a linear search-like tool that allows you to quickly access only a certain variable inside a structure hierarchy without having to serialize your whole app.

I'm wondering if any of this can be done in a more simple way. I especially don't like that I need to hard-code the class name for my classes, but I couldn't find a more simple solution to do it in a compiler-independent way.

Serializer.h:

```
#ifndef jag_SERIALIZER_H_
#define jag_SERIALIZER_H_

#include "jag_config.h"

namespace jag {

namespace Serializer {

struct SerializedData {
SerializedData(const std::string& n, const std::string& val = "", const std::string& t = "") :
name(n), value(val), type_name(t) {
}

std::string name;
std::string value;
std::string type_name;

std::list collection_value;
};

template
struct Type {
static const std::string GetTypeName() {
return T::GetTypeName();
}
};

#define PRIMITIVE_TYPENAME(type) \
template<> \
struct Type { \
static const std::string GetTypeName() { \
return #type; \
} };

PRIMITIVE_TYPENAME(int)
PRIMITIVE_TYPENAME(float)
#undef PRIMITIVE_TYPENAME

#define COLLECTION_TYPENAME(type) \
template \
struct Type> { \
static const std::string GetTypeName() { \
return std::string(#type) + " of " + Type::GetTypeName(); \
} };

COLLECTION_TYPENAME(list)

#undef COLLECTION_TYPENAME

template
struct EnumeratedValue {
EnumeratedValue(T& val, co

Solution

The claim "As you can see I only had to add two functions - an enumerator and a typename function." will not generally be true for every type. Specifically, you'll also need to provide an appropriate operator<< for every type you'd like to use as a member in a serializable type.

When doing so, you'll also need to pay special attention to pointers and pointer-like things. Currently, if your program tries to use a deserialized pointer that was serialized by another instance of your program, things will likely blow up. You'll want to serialize the pointed-at thing as well. And you'll need to keep track of all those pointed-at things, so that multiple pointers can point to the same thing on both ends.

There are other types that will be problematic as well, such as mutexes. Basically, unless it employs pure value semantics, it's going to be hard to serialize reliably. Trying to handle all of this in the serializer is going to get really messy really quickly. So come up with some way for classes to say "Nuh-uh, I'm gonna do my own (de)serialization".

I also have some portability and maintainability concerns regarding the way you're storing type information. As the code currently stands, I'm not sure how you plan on identifying the correct type to instantiate when deserializing.

I'd also strongly recommend adding some protocol information at the start of any serialization stream. At the very least have a couple of magic bytes, so you can avoid blowing up when faced with something that's not actually a serialization stream. If you eventually want to support this code in the wild, I'd also suggest adding versioning to your protocol.

Context

StackExchange Code Review Q#11367, answer score: 2

Revisions (0)

No revisions yet.