• This repository has been archived on 04/Mar/2023
  • Stars
    star
    143
  • Rank 257,007 (Top 6 %)
  • Language
    C++
  • License
    BSD 3-Clause "New...
  • Created almost 8 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A library to perform generic seralization and deserialization of QObjects from and to JSON and CBOR

QtJsonSerializer

A library to perform generic seralization and deserialization of QObjects from and to JSON and CBOR.

With this small library, you are able to serialize any C++ datatype to JSON or CBOR and back. This is done with help of Qt's meta system.

Github Actions status Codacy Badge AUR

The library was recently update to 4.0.0. Have a look at the Porting section to learn how to migrate your project from 3.* to 4.0.0. Don't be afraid, as for most existing projects, only class names will have changed.

Features

  • Serialize QObjects, Q_GADGETS, lists, maps, etc. to JSON/CBOR, in a generic matter
  • ... and of course deserialize JSON/CBOR back as well
  • De/serialize any QVariant - as long as it contains only basic types or one of the above
    • Works even with QJsonValue/Array/Object as properties
  • Serializes Q_PROPERTY elements
  • Enum de/serialization as integer or as string
  • Deserialization: Additional JSON/CBOR-values will be stored as dynamic properties for QObjects
  • Supports polymorphism
  • Fully Unit-Tested
  • Thread-Safe
  • Easily extensible

Download/Installation

There are multiple ways to install the Qt module, sorted by preference:

  1. Package Managers: The library is available via:
  2. Simply add my repository to your Qt MaintenanceTool (Image-based How-To here: Add custom repository):
    1. Start the MaintenanceTool from the commandline using /path/to/MaintenanceTool --addRepository <url> with one of the following urls (Alternatively you can add it via the GUI, as stated in the previously linked GUI):
    2. A new entry appears under all supported Qt Versions (e.g. Qt > Qt 5.13 > Skycoder42 Qt modules)
    3. You can install either all of my modules, or select the one you need: Qt JsonSerializer
    4. Continue the setup and thats it! you can now use the module for all of your installed Kits for that Qt
  3. Download the compiled modules from the release page. Note: You will have to add the correct ones yourself and may need to adjust some paths to fit your installation!
  4. Build it yourself! Note: This requires perl to be installed. If you don't have/need cmake, you can ignore the related warnings. To automatically build and install to your Qt installation, perform the following steps:
    • Download the sources. Either use git clone or download from the releases. If you choose the second option, you have to manually create a folder named .git in the projects root directory, otherwise the build will fail.
    • qmake
    • make (If you want the tests/examples/etc. run make all)
    • Optional steps:
      • make doxygen to generate the documentation
      • make -j1 run-tests to build and run all tests
    • make install

Building without converter registration

By default, a bunch of list, map, etc. converters are registered for standard Qt types via the qtJsonSerializerRegisterTypes method. This however needs many generated functions and will increase the size of the generated binary drasticly. If you don't need those converters, run qmake CONFIG+=no_register_json_converters instead of a parameterless qmake. The mentioned function will then be generated as noop method and no converters are registerd.

Please be aware that in this mode it is not possible to serialize e.g. QList<int> unless you manually register the corresponding converters via QtJsonSerializer::JsonSerializer::registerListConverters<int>();!

Usage

The serializer is provided as a Qt module. Thus, all you have to do is install the module, and then, in your project, add QT += jsonserializer to your .pro file! The following chapters show an example and explain a few important details regarding the functionality and limits of the implementation.

Example

Both serialization and desertialization are rather simple. Create an object, and then use the serializer as follows:

The following is an example for a serializable object. Note: The usage of MEMBER Properties is not required, and simply done to make this example more readable.

class TestObject : public QObject
{
	Q_OBJECT

	Q_PROPERTY(QString stringProperty MEMBER stringProperty)
	Q_PROPERTY(QList<int> simpleList MEMBER simpleList)
	Q_PROPERTY(QMap<QString, double> simpleMap MEMBER simpleMap);  // add the semicolon or use a typedef to surpress most errors of the clang code model
	Q_PROPERTY(TestObject* childObject MEMBER childObject)

public:
	Q_INVOKABLE TestObject(QObject *parent = nullptr);

	QString stringProperty;
	QList<int> simpleList;
	QMap<QString, double> simpleMap;
	TestObject* childObject;
}

You can serialize (and deserialize) the object with:

auto serializer = new QJsonSerializer(this);

try {
	//serialize
	auto object = new TestObject();
	object->stringProperty = "test";
	object->simpleList = {1, 2, 3};
	object->simpleMap = {
		{"pi", 3.14},
		{"e", 2.71}
	};
	object->childObject = new TestObject(object);
	auto json = serializer->serialize(object);
	qDebug() << json;
	delete object;

	//deserialize
	object = serializer->deserialize<TestObject>(json);//optional: specify the parent
	qDebug() << object->stringProperty
			 << object->simpleList
			 << object->simpleMap
			 << object->childObject;
	delete object;
} catch(QJsonSerializerException &e) {
	qDebug() << e.what();
}

For the serialization, the created json would look like this:

{
	"stringProperty": "test",
	"simpleList": [1, 2, 3],
	"simpleMap": {
		"pi": 3.14,
		"e": 2.71
	},
	"childObject": {
		"stringProperty": "",
		"simpleList": [],
		"simpleMap": {},
		"childObject": null
	}
}

Important Usage Hints

In order for the serializer to properly work, there are a few things you have to know and do:

  1. Only Q_PROPERTY properties of objects/gadgets will be serialized, and of those only properties that are marked to be stored (see The Property System, STORED attribute)
  2. For the deserialization of QObjects, they need an invokable constructor, that takes only a parent: Q_INVOKABLE MyClass(QObject*);
  3. The following types are explicitly supported:
    • QObject* and deriving classes
    • Classes/structs marked with Q_GADGET (as value or plain pointer only!)
    • QList<T>, QLinkedList<T>, QVector<T>, QStack<T>, QQueue<T>, QSet<T>, with T beeing any type that is serializable as well
    • QMap<QString, T>, QHash<QString, T>, QMultiMap<QString, T>, QMultiHash<QString, T>, with T beeing any type that is serializable as well (string as key type is required)
    • Simple types, that are supported by QJsonValue (See QJsonValue::fromVariant and QJsonValue::toVariant)
    • Q_ENUM and Q_FLAG types, as integer or as string
      • The string de/serialization of Q_ENUM and Q_FLAG types only works if used as a Q_PROPERTY. Integer will always work.
    • QJson... types
    • QPair<T1, T2> and std::pair<T1, T2>, of any types that are serializable as well
    • std::tuple<TArgs...>, of any types that are serializable as well
    • std::optional<T>, of any type that is serializable as well
    • std::variant<TArgs...>, of any types that are serializable as well
    • std::chrono::*, for the basic times (hours, minutes, seconds, milliseconds, microseconds, nanoseconds)
    • Standard QtCore types (QByteArray, QUrl, QVersionNumber, QUuid, QPoint, QSize, QLine, QRect, QLocale, QRegularExpression, ...)
      • QByteArray is represented by a base64 encoded string
    • Any type you add yourself by extending the serializer (See QJsonTypeConverter documentation)
  4. While simple types (i.e. QList<int>) are supported out of the box, for custom types (like QList<TestObject*>) you will have to register converters. This goes for
    • List-, Set- and Map-Types: use SerializerBase::registerBasicConverters<T>()
    • List-Types only: use SerializerBase::registerListConverters<T>()
    • Set-Types only: use SerializerBase::registerSetConverters<T>()
    • Map-Types only: use SerializerBase::registerMapConverters<T>()
      • Maps and hashes can be registered seperately using a template parameter, if you only need one of those
    • QPair and std::pair: use SerializerBase::registerPairConverters<T1, T2>()
    • std::tuple: use SerializerBase::registerTupleConverters<TArgs...>()
    • std::optional: use SerializerBase::registerOptionalConverters<T>()
    • std::variant: use SerializerBase::registerVariantConverters<TArgs...>()
    • QSharedPointer/QPointer: use SerializerBase::registerPointerConverters<T>()
  5. Polymorphic QObjects are supported. This is done by the serializer via adding a special @@class json property. To make a class polymorphic you can:
    • Add Q_JSON_POLYMORPHIC(true) (or Q_CLASSINFO("polymorphic", "true")) to its definition
    • Globally force polyphormism (See QJsonSerializer::polymorphing in the doc)
    • Set a dynamic property: setProperty("__qt_json_serializer_polymorphic", true);
  6. By default, the objectName property of QObjects is not serialized (See keepObjectName)
  7. By default, the JSON null can only be converted to QObjects. For other types the conversion fails (See allowDefaultNull)

Support for alternative Containers

While the default Qt containers, like QList, QVector and QMap are all supported by default, custom containers need to be registered. For this, two steps need to happen:

  • For sequential containers:
    1. Register the container via Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE
    2. Make it available for a certain type via QtJsonSerializer::SequentialWriter::registerWriter<Container, Type>()
  • For associative containers:
    1. Register the container via Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE
    2. Make it available for a certain type via QtJsonSerializer::AssociativeWriter::registerWriter<Container, Key, Value>()

Documentation

The documentation is available on github pages. It was created using doxygen. The HTML-documentation and Qt-Help files are shipped together with the module for both the custom repository and the package on the release page. Please note that doxygen docs do not perfectly integrate with QtCreator/QtAssistant.

Porting

Most changes to the library have been of additive nature. The following list summarizes the most important changes:

  • Support for CBOR de/serialization
  • Support for generic sequential and associative containers
  • Improved type safety via extraxtors
  • More converters (including bitarrays, smart pointers and enums)
  • All types have been renamed and moved into the QtJsonSerializer namespace

The next sections will talk about specific changes and how to adjust your project. Also, if you have any questions or need help porting your project, I am always happy to help. Just create a new Issue asking for help, and it shall be given.

Rename refactoring

One big part of the 4.0.0 release was to move all types into a namespace and get rid of the QJson prefix. The following table shows how types have been renamed. If you do not want to change all usages in your code, simply use using declarations for the types, i.e. using QJsonSerializer = QtJsonSerializer::JsonSerializer;.

Old name New name
QJsonSerializerException QtJsonSerializer::Exception
QJsonDeserializationException QtJsonSerializer::DeserializationException
QJsonSerializationException QtJsonSerializer::SerializationException
QJsonSerializer QtJsonSerializer::JsonSerializer (split into that class and the base class QtJsonSerializer::SerializerBase)
QJsonTypeConverter QtJsonSerializer::TypeConverter

Changes in type registrations

With the new system, typedefs are no longer a problem, as now, an advanced type registration system is used to get types instead of parsing class names. Thus, all related methods have been removed. Furthermore, the old system of converting various datatypes from and to a non-generic QVariant representation via QMetaType has been superseeded by the QtJsonSerializer::TypeExtracor system. For most usecases this changes nothing, as the QtJsonSerializer::SerializerBase::register* methods still exist. However, if you made use of the old system in custom converters, you should consider migrating to using either the QtJsonSerializer::MetaWriter mechanism for containers, or the QtJsonSerializer::TypeExtracor for other types. Check the documentation on how to use these classes.

Support for more containers

One additional advantage of the new system is, that now theoretically any sequential or associative container can be supported by the serializer without the need of a custom converter. Alls that is needed is a simple registration of a custom container class within the QtJsonSerializer::MetaWriter classes as well as the type declaration (See Support for alternative Containers). The following shows a simple example for std::vector

Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::vector)
// ...
QtJsonSerializer::SequentialWriter::registerWriter<std::vector, int>();
QtJsonSerializer::SequentialWriter::registerWriter<std::vector, double>();
QtJsonSerializer::SequentialWriter::registerWriter<std::vector, QString>();
// ...

CBOR support

The biggest feature however is support for de/serialization of CBOR data. Usage is the same as for JSON, simply use QtJsonSerializer::CborSerializer instead of the QtJsonSerializer::JsonSerializer class. Nothing more to say here - simply try it out!

Changes for TypeConverters

If you previously had your own QJsonTypeConverter (now called QtJsonSerializer::TypeConverter), the changes are slightly more complex. The primary change was, that all these converter now operate on CBOR data, not JSON, as CBOR can be easily converted to JSON, but not the other way around. Check the QtJsonSerializer::TypeConverter documentation for more details on how to use these new converters.

More Repositories

1

QtAutoUpdater

A Qt library to automatically check for updates and install them
C++
753
star
2

QHotkey

A global shortcut/hotkey for Desktop Qt-Applications
C++
549
star
3

QtMvvm

A mvvm oriented library for Qt, to create Projects for Widgets and Quick in parallel
C++
332
star
4

QtService

A platform independent library to easily create system services and use some of their features
C++
154
star
5

QtApng

An apng image plugin for Qt to support animated PNGs
C++
102
star
6

QtRestClient

A library for generic JSON-based REST-APIs, with a mechanism to map JSON to Qt objects
C++
88
star
7

QtDataSync

A simple offline-first synchronisation framework, to synchronize data of Qt applications between devices
C++
87
star
8

QtIFW-Advanced-Setup

Create "Qt Installer Framework" installers from your project via qmake
JavaScript
58
star
9

QTaskbarControl

A class to create a taskbar/launcher progress and more, for all desktop platforms
C++
43
star
10

libsodium_dart_bindings

Dart bindings for libsodium, supporting both the VM and JS without flutter dependencies.
Dart
28
star
11

AndroidUtils

Utils for easy c++ and qml integration of common android features
C++
23
star
12

repkg

A tool to manage rebuilding of AUR packages based on their dependencies
C++
19
star
13

QAutoStart

A class to easily register your application as autostart application
C++
19
star
14

qdep

A very basic yet simple to use dependency management tool for qmake based projects
Python
18
star
15

qpmx

A frontend for qpm, to provide source and build caching
C++
16
star
16

QSslServer

An extension of QTcpServer to support ssl. The counterpart to QSslSocket
C++
16
star
17

QuickExtras

Additional Stuff for Qt Quick Controls 2, to make it work event better
QML
14
star
18

KeepassTransfer

A collection of tools to securely transfer passwords to your browser
C++
14
star
19

firebase_auth_rest

A platform independent Dart/Flutter Wrapper for the Firebase Authentication API based on REST
Dart
14
star
20

QSingleInstance

A simple single instance application for Qt
C++
13
star
21

QPluginFactory

A factory class to easily load generic plugins
C++
12
star
22

QPathEdit

A Qt-Widget to get local file and folder-paths in an optimized and simple way
C++
12
star
23

QTinyAes

A Qt-Wrapper for the AES-implementation kokke/tiny-AES128-C
C++
11
star
24

QSettingsDialog

Has been replaced by https://github.com/Skycoder42/QtMvvm
C++
11
star
25

qsshfs

A gui wrapper around sshfs
C++
10
star
26

QtUtils

A collection of various Qt-Classes, branch-sorted
C++
10
star
27

QObjectListModel

A Collection of classes to easily create models with QObject and Q_GADGET classes for widgets and quick
C++
10
star
28

qt-json

A basic package for simple json serialization between json and qt classes
C++
10
star
29

QtBackgroundProcess

A Library to create background applications with simple, automated foreground control
C++
10
star
30

dolphin-seafile-plugin

A plugin for dolphin to show the seafile synchronization status
C++
9
star
31

QConsole

A non-blocking Qt Style console class to easily handle stdin/out/err
C++
9
star
32

dart_pre_commit

A small collection of pre commit hooks to format and lint dart code
Dart
9
star
33

QtModules

A collection of ci and deployment scripts to create and deploy Qt modules with travis/appveyor
Python
8
star
34

Syrem

A simple reminder application for desktop and mobile, with synchronized reminders
C++
8
star
35

action-setup-qt

A Github workflow action to install Qt from their online installer
JavaScript
7
star
36

QUrlValidator

A class that provides a QValidator to validate urls
C++
6
star
37

QSettingsGenerator

A qmake extension to generate a C++ settings wrapper for easier, stringless access
Python
5
star
38

keepassxc-client-library

A C++ library to access the browser-plugin-API of KeePassXC to retrieve or create entries.
C++
5
star
39

DialogMaster

A utility to create optimized dialogs with Qt
C++
4
star
40

QCliParser

An extension of QCommandlineParser to make context based CLIs easier
C++
4
star
41

QtRemoteObjectsSslBackend

A backend for QtRemoteObjects to connect via an encrypted SSL connection
C++
4
star
42

cryptopp-qt

A collection of pro/pri files to build and integrate Crypto++ via qmake
QMake
4
star
43

IconThemeBrowser

A small application to browse Qt icon themes
C++
4
star
44

QCtrlSignals

A library to catch and handle windows and unix signals, in a cross platform manner
C++
4
star
45

AndroidContentDevice

A QIODevice implementation to be able to open "content://" urls on android
C++
4
star
46

etebase-dart

Dart/Flutter bindings for libetebase
Dart
3
star
47

QGenericTree

A generic tree data structure for Qt
C++
3
star
48

QIpcPointer

A smart pointer for Qt to create any type on managed shared memory
C++
3
star
49

ApngProject

A collection of projects, all around making apng available in Qt
C++
3
star
50

AniRem

A tool to passivly check for updates on seasons, for proxer.me
C++
3
star
51

flutter_data_extensions

A collection of packages that extend functionally of flutter_data. Namely firebase, encryption and sync.
Dart
3
star
52

openssl-android

qdep package to compile openssl for android and add it to your app
Prolog
3
star
53

qtrng

Qt Random number generator wrapper around "secure" os RNGS
C++
2
star
54

QPipeDevice

A collection of QIODevice classes used for "piping" things between devices
C++
2
star
55

QtProFileParser

A small library to parse Qt Project Files and provide easy handling of those
C++
2
star
56

PWatcher

C++
1
star
57

ClipboardSync

A small tool for clipboard synchronization
C++
1
star
58

action-dart-release

An action to create a github release from a dart package
TypeScript
1
star
59

action-deploy-qt

A Github workflow action to upload qt modules to a server via sshfs
JavaScript
1
star
60

UniInsert

An application to easily insert unicode characters EVERYWHERE
C++
1
star
61

qt-rest

A basic package for simple, generic, builder-based asynchronous rest calls
C++
1
star
62

MangaConvert

Download and convert mangas from single images to pdf
C++
1
star
63

Conflip

A tool to synchronize settings/configurations across multiple machines
C++
1
star
64

deployment

Meta-Repo containing various scripts and files fo generic deployment
QMake
1
star
65

improved-initiative-interceptor

Dart
1
star
66

settings_builder

A dart builder that generates automatic accessors for reading and writing shared preferences.
Dart
1
star
67

dart_test_tools

Additional tools and helpers for writing dart unit tests
Dart
1
star
68

image_galery

Dart
1
star
69

QtMvvmQuick

Has been replaced by https://github.com/Skycoder42/QtMvvm
C++
1
star
70

paxchange

Simple dart script to passively synchronize installed pacman packages between systems
Dart
1
star
71

QtModules-LTS

Build-Repo to build my Qt modules as LTS independent of the primary modules
Shell
1
star
72

QColorEdit

A simple widget to inline-edit colors
C++
1
star
73

QtMvvmWidgets

Has been replaced by https://github.com/Skycoder42/QtMvvm
C++
1
star
74

QtMvvmSettingsWidgets

Has been replaced by https://github.com/Skycoder42/QtMvvm
C++
1
star
75

QtMvvmCore

Has been replaced by https://github.com/Skycoder42/QtMvvm
C++
1
star
76

QExceptionStream

A wrapper around QDebug that allows you to create exception messages like you would write to QDebug
C++
1
star
77

QXmlCodeGen

A simple python script to generate C++ bindings from an XML Schema definition, with support for bootstrapped Qt
Python
1
star
78

aha-dart

Dart client for the AVM Home Automation HTTP Interface + Login
Dart
1
star