Skip to content

CdecPGL/minimal-serializer

Repository files navigation

Release License CircleCI Build and Test Status

minimal-serializer

A C++ and C# binary serializer which serializes data without any extra data.

  • Minimal size without metadata
  • Extremely fast in C++ version!
  • Portable between C++ and C#
  • Portable between different machines
  • Serialized size is always same and predictable if type is same
  • Header only in C++ version

Comparison of binary serializers for C++ and C#.

Library C++ C# Minimal Size (No Metadata) Portable Supported Type
Minimal Serializer Yes Yes Yes Yes Fixed Size Types Only
Boost Serializer (Binary) Yes No No No Almost All Types
Cereal (Binary) Yes No Yes Yes Almost All Types
C# Built-in Serializer (BinaryFormatter) No Yes No No Almost All Types

Example

See Serializer Usage to know the usage of minimal-serializer.

C++

#include "minimal_serializer/serializer.hpp"

struct Data {
    uint32_t value;
    std::array<int64_t, 16> array;
    minimal_serializer::fixed_string<32> string; // Ensure encoding is UTF-8. We strongly recommend to use u8 literal. This type is deprecated when using C++20
    minimal_serializer::fixed_u8string<32> u8string; // (C++20) A string whose encoding is guaranteed to be UTF-8. Use this type instead of fixed_string in C++20

    // Intrusive definition of serialize targets
    using serialize_targets = minimal_serializer::serialize_target_container<&Data::value, &Data::array, &Data::string>, &Data::u8string>;
}

// Not intrusive definition is also available
namespace minimal_serializer {
    template<>
    struct serialize_targets<Data> {
        using type = minimal_serializer::serialize_target_container<&Data::value, &Data::array, &Data::string, &Data::u8string>;
    }
}

int main(){
    // Get serialized size. The size is calculated in compile time
    constexpr auto size = minimal_serializer::serialized_size_v<Data>;

    // Serialize to fixed size byte array
    Data data;
    auto byte_array = minimal_serializer::serialize(data);

    // Serialize to buffer
    std::vector<uint8_t> buffer1{...};
    minimal_serializer::serialize(data, buffer);

    // Serialize to buffer with offset
    std::vector<uint8_t> buffer2{...};
    minimal_serializer::serialize(data, buffer, 10);

    // Serialize to output stream
    std::ostream ostream{...};
    minimal_serializer::serialize(data, ostream);

    // Deserialize from fixed size byte array
    minimal_serializer::deserialize(data, byte_array);

    // Deserialize from buffer
    minimal_serializer::deserialize(data, buffer1);

    // Deserialize from buffer with offset
    minimal_serializer::deserialize(data, buffer2, 10);

    // Deserialize from input stream
    std::istream istream{...};
    minimal_serializer::deserialize(data, istream);

    // Get a flag representing the type is serializable, which is judged in compile time.
    constexpr auto is_serializable = minimal_serializer::is_serializable_v<Data>;

    // (C++20) A concept to constrain types to serializable with minimal serializer.
    template<minimal_serializer::serializable T>
    void func(T data) {
        // Awesome codes...
    }
}

C#

using System;

// By Serializable attribute, the struct and class become serializable with minimal-serializer
// Add [StructLayout(LayoutKind.Sequential)] if you want to serialize class
[Serializable]
class Data {
    public uint value;
    // To inform the size to serializer, FixedLength attribute is required
    public [FixedLength(16)] long[] array;
    public [FixedLength(32)] string string;
}

public class Main {
    public static void Main(){
        // Get serialized size. The size is always same is typpe is same
        var size = CdecPGL.MinimalSerializerSerializer.GetSerializedSize<Data>();
        // Serialize to byte[]
        var data = new Data();
        var byteArray = CdecPGL.MinimalSerializer.Serializer.Serialize(data);
        // Deserialize from byte[]
        data = CdecPGL.MinimalSerializer.Serializer.Deserialize(byteArray);
    }
}

Requirement

C++

  • A compiler which is compatible with C++17 (VS15.7, g++7 or clang5)
    • Concepts and the UTF-8 string type are supported in compilers which is compatible with C++20
  • Boost Library
    • Minimal Support: 1.67 or higher
    • Floating Point Number Type Support: 1.74 or higher
    • C++20 Support: 1.77 or higher
  • nameof C++ (this is included in this repository)

Tested Compilers

  • g++ 10.3.1
  • Clang 12.0.1
  • MSVC 14.30 (VS 17.0.2)

C#

  • .NET Framework or .NET Core which is compatible with .NET Standard 2.0

Install

C++

This is a header only library.

Copy minimal_serializer_cpp/include directory to your project.

C#

Copy all files in MinimalSerializerCSharp/Source directory to your project.

Run Tests

C++

Visual Studio

  1. Open minimal-serializer.sln with Visual Studio
  2. Build minimal_serializer_cpp_test project
  3. Run the tests with test runner of Visual Studio

CMake

  1. Install a compiler which is compatible with C++17
  2. Install Boost Library 1.69 or higher (It is convenient to use vcpkg in Windows to install the Boost Library)
  3. Install CMake 3.8 or higher
  4. Move to the root directory of minimal-serializer
  5. mkdir build
  6. cmake ..
  7. make install
  8. ctest

Instead of installing required packages, you can use docker container "cdec/minimal-serializer-dev" to build and run tests like below command.

docker run -v <A Path of Minimal Serialier Repogitory>:/minimal-serializer -itd cdec/minimal-serializer-dev:latest

cdec/minimal-serializer-dev is built from docker/dev/Dockerfile in this repository. You can build a docker image yourself with docker/dev/Dockerfile if you need.

C#

  1. Open minimal-serializer.sln with Visual Studio
  2. Build MinimalSerializerCSharpTest project
  3. Run the tests with test runner of Visual Studio

Contribution

Please submit issues (https://github.com/CdecPGL/minimal-serializer/issues) or create Pull Requests (https://github.com/CdecPGL/minimal-serializer/pulls) if you find bugs or want to propose new features.

You can create pull requests by below steps.

  1. Fork (https://github.com/CdecPGL/minimal-serializer/fork)
  2. Create a feature branch
  3. Commit your changes
  4. Rebase your local changes against the master branch
  5. Run tests and confirm that it passes
  6. Create new Pull Request

License

The code in this repository are licensed under the MIT License.

This repository includes following libraries from other repositories. The licenses of these repositories follow each respective repository:

About

A C++ and C# serializer which serializes data without any extra data.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages