A serialization library for C++ and C Sharp
Cereal is a header-only library based on TheCherno's serialization library for Java. It can be used to serialize almost any kind of data. It's really fast, lightweight and ideal for videogames and other programs where performance and resources are really valuable.
The library is really simple to use and fully customizable to fit all your needs. If you make any changes, please open a pull request. We'd love to see your changes!
This project began a while ago, when both @raresica1234 and I were developing our own game engines. We needed a way to serialize (that is, to store variables and data structures on files) and deserialize information such as game data, game settings, 3D files and much more.
The main inspiration came from @TheCherno's serialization library. We took the main idea and ported it to C++ with a few improvements.
The entire project was done in less than a week. After that, we started writing the wiki, writing some automated tests and working on some extra features.
To install this library, just download it and copy the contents of the Cereal/Cereal
folder to your include forlder. Then, you only need to include the file Cereal.h
in your source files.
Just copy the folder Cereal/Cereal
from this repository to the include folder of your project so that it contains Cereal.h
and the folder src
:
marcizhu@linux:~ $ git clone https://github.com/marcizhu/Cereal.git
Cloning into 'Cereal'...
remote: Counting objects: 1031, done.
remote: Compressing objects: 100% (38/38), done.
remote: Total 1031 (delta 17), reused 35 (delta 9), pack-reused 980
Receiving objects: 100% (1031/1031), 1.49 MiB | 678.00 KiB/s, done.
Resolving deltas: 100% (616/616), done.
marcizhu@linux:~ $ cd Cereal
marcizhu@linux:~/Cereal $ mv Cereal/Cereal ../myProject/includes/
marcizhu@linux:~/Cereal $ cd ../myProject/includes/
marcizhu@linux:~/myProject/includes $ ls
Cereal.h src/
To manually install the library, click on the green button in the top right and download this repository. After that, copy the folder Cereal/Cereal
to your include folder.
Using this library is pretty straightforward. Just include the file Cereal.h
in your source file:
#include <Cereal.h>
After that, all the API will be available inside the Cereal
namespace. You may include a using namespace Cereal;
at the top of your source file if you don't like having to type Cereal::
in front of every class.
The following snippet illustrates how to use this library to write some configuration to a file and read it back:
#include <Cereal.h> // Include the library
void writeDatabase()
{
Cereal::Buffer buffer(1024); // Create a buffer
Cereal::Database* db = new Cereal::Database("My program database"); // Create a database
Cereal::Object* config = new Cereal::Object("Configuration"); // Create an object to store configuration
// Adding fields to objects
config->addField(new Cereal::Field("windowSizeX", winSize.x)); // Create a field and add it to the object
config->addField(new Cereal::Field("windowSizeY", winSize.y));
config->addField(new Cereal::Field("user name", userName));
config->addField(new Cereal::Field("other value", 15.9f));
// Adding objects to databases
db->addObject(config); // Add object 'config' to the database
// Write the database to the buffer & then to a file
db->write(buffer);
buffer.writeFile("progDatabase.db");
// Free dynamic memory
delete db; // Databases will automatically delete all the objects, fields and arrays they contain
}
void readDatabase()
{
// Create an empty buffer and read the database file 'progDatabase.db'
Cereal::Buffer buf;
buf.readFile("progDatabase.db");
// Read database from buffer
Cereal::Database* db = new Cereal::Database; // Create an empty database
db->read(buf); // Read the buffer
// Getting an object from a database
Cereal::Object* config = otherDatabase->getObject("Configuration");
// Getting the configuration back
winSize.x = config->getField("windowSizeX")->getValue<int>(); // Get the data
winSize.y = config->getField("windowSizeY")->getValue<int>();
userName = config->getField("user name")->getValue<std::string>();
otherVal = config->getField("other value")->getValue<float>();
delete db;
}
For a brief description of each class, its capabilities and its use, please read the API section
Finally, to compile your file (say main.cpp
) with Cereal, just include the -I
modifier followed by the folder where the file Cereal.h
is located. Also include -std=c++11
to the compilation command. This is necessary because Cereal uses some C++11 features:
g++ main.cpp -Ipath/to/Cereal -std=c++11 -o output_file
To compile a file with Cereal using visual studio, just add the Cereal folder to the include path. This is done in Project Settings > Project paths > Include paths.
Once this is done, your project should compile without any problems!
This library is actively maintained. We are basically testing the library, improving its features and making sure everything works as intended. More than 8,000 assertions and 20 tests make sure this library is stable and that no new bugs are introduced.
This tests are executed after each push commit, and the status is displayed as a green tick or red mark next to each commit. You can see the details for each test case.
Right now, the library is ready to be used in any application. As far as we know, it is 100% bug free and fully cross-platform, compiling in Microsoft Windows Vista/7/8/8.1/10, Linux Debian/Ubuntu/Mint/Kali, and MacOS High Sierra.
This library contains different classes. Each class can be used to serialized a different kind of data:
- Cereal::Field: A field is the smallest serialization unit. It holds a name and a simple data type which can be any of the following:
bool
,char
,byte
,short
,int
,long long
,float
,double
andstd::string
. The name is used to access the field and distinguish it from other fields. It is used to store name-value pairs. - Cereal::Array: An array contains a name and a list of simple data types. Those types can be any of the previously mentioned, and this object can contain thousands, even millions of them.
- Cereal::Object: Each object contains a name (like all the other data structures) but it also stores up to 65536 fields and 65536 arrays. The fields and arrays contained by an object are not shared across all other objects, so a field or array name doesn't have to be unique across all objects, but it must be unique across all the fields and arrays in that object.
- Cereal::Database: A database is a collection of objects, each with its own fields and arrays. Databases also have a name, and that can be used if you want to store multiple databases in the same file. If you are only using one database per file, the name is not really that useful.
- Cereal::Header: Headers are optional, but really useful if you want to store more than one database per file. With headers you can have up to 255 databases in a single file! Headers do NOT have a name, and only contain a list of databases.
- Cereal::Buffer: Buffers are just a helper class that holds serialized data. All data is serialized to this buffer first (using the method
Database::write()
), then it can be written to a file usingBuffer::writeFile()
. Later, a file can be read usingBuffer::readFile()
and deserialized by calling the methodDatabase::read()
. Easy, right?
For more information, check out the GitHub wiki page
This project is currently maintained by:
Pull requests and suggestions are always accepted. If you have any question, feel free to open an issue and we will reply as soon as possible :)
For support and other questions, you can also send me an e-mail at [email protected].
Small note: If editing the README, please conform to the standard-readme specification.
This project is licensed under the GNU General Public License v3.0. Copyright © 2016-2018 The Cereal Team