Files
pip/libs/main/serialization/pijson.h
2026-03-12 14:46:57 +03:00

259 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! \~\file pijson.h
//! \~\ingroup Serialization
//! \~\brief
//! \~english JSON tree node type
//! \~russian Тип узла дерева JSON
/*
PIP - Platform Independent Primitives
JSON class
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIJSON_H
#define PIJSON_H
#include "pivariant.h"
//! \~\ingroup Serialization
//! \~\brief
//! \~english JSON tree node.
//! \~russian Узел дерева JSON.
//! \~\details
//! \~english %PIJSON class provides a tree structure for JSON data representation.
//! Each element can be a value (with name), an array, or an object.
//! \~russian Класс %PIJSON предоставляет древовидную структуру для представления данных JSON.
//! Каждый элемент может быть значением (с именем), массивом или объектом.
class PIP_EXPORT PIJSON {
friend PICout operator<<(PICout s, const PIJSON & v);
public:
//! \~english Type of JSON node.
//! \~russian Тип узла JSON.
enum Type {
Invalid /*! \~english Invalid type \~russian Недействительный тип */,
Null /*! \~english Without value, null \~russian Без значения, null */,
Boolean /*! \~english Boolean, \b true or \b false \~russian Логическое, \b true или \b false */,
Number /*! \~english Integer or floating-point number \~russian Целое либо число с плавающей точкой */,
String /*! \~english Text \~russian Текст */,
Object /*! \~english Object, {} \~russian Объект, {} */,
Array /*! \~english Array, [] \~russian Массив, [] */
};
//! \~english Formatting mode for JSON text output.
//! \~russian Режим форматирования JSON-текста.
enum PrintType {
Compact /*! \~english Without spaces, minimum size \~russian Без пробелов, минимальный размер */,
Tree /*! \~english With spaces and new-lines, human-readable \~russian С пробелами и новыми строками, читаемый человеком */
};
//! \~english Constructs invalid %PIJSON.
//! \~russian Создает недействительный %PIJSON.
PIJSON() {}
//! \~english Copy constructor.
//! \~russian Конструктор копирования.
PIJSON(const PIJSON & o) = default;
//! \~english Returns node name, or empty string for unnamed nodes.
//! \~russian Возвращает имя узла, либо пустую строку для безымянных узлов.
const PIString & name() const { return c_name; }
//! \~english Returns array children, or an empty array when the node is not \a PIJSON::Array.
//! \~russian Возвращает дочерние элементы массива, либо пустой массив, если узел не имеет тип \a PIJSON::Array.
const PIVector<PIJSON> & array() const;
//! \~english Returns object members, or an empty map when the node is not \a PIJSON::Object.
//! \~russian Возвращает поля объекта, либо пустой словарь, если узел не имеет тип \a PIJSON::Object.
const PIMap<PIString, PIJSON> & object() const;
//! \~english Returns scalar node value.
//! \~russian Возвращает скалярное значение узла.
const PIVariant & value() const { return c_value; }
//! \~english Returns scalar value as bool.
//! \~russian Возвращает скалярное значение как логическое.
bool toBool() const { return c_value.toBool(); }
//! \~english Returns scalar value as integer.
//! \~russian Возвращает скалярное значение как целое число.
int toInt() const { return c_value.toInt(); }
//! \~english Returns scalar value as floating-point number.
//! \~russian Возвращает скалярное значение как число с плавающей точкой.
double toDouble() const { return c_value.toDouble(); }
//! \~english Returns scalar value as string.
//! \~russian Возвращает скалярное значение как строку.
PIString toString() const { return c_value.toString(); }
//! \~english Returns node type.
//! \~russian Возвращает тип узла.
Type type() const { return c_type; }
//! \~english Returns whether the node is valid.
//! \~russian Возвращает, является ли узел действительным.
bool isValid() const { return c_type != Invalid; }
//! \~english Returns whether the node is \a PIJSON::Object.
//! \~russian Возвращает, является ли узел \a PIJSON::Object.
bool isObject() const { return c_type == Object; }
//! \~english Returns whether the node is \a PIJSON::Array.
//! \~russian Возвращает, является ли узел \a PIJSON::Array.
bool isArray() const { return c_type == Array; }
//! \~english Sets scalar value and updates node type for bool, numeric and string variants.
//! \~russian Устанавливает скалярное значение и обновляет тип узла для логических, числовых и строковых вариантов.
void setValue(const PIVariant & v);
//! \~english Clears node content and sets type to \a PIJSON::Invalid.
//! \~russian Очищает содержимое узла и устанавливает тип \a PIJSON::Invalid.
void clear();
//! \~english Returns array length or object member count. Other node types return 0.
//! \~russian Возвращает длину массива или число полей объекта. Для остальных типов возвращает 0.
int size() const;
//! \~english Returns whether an object node contains key \a key.
//! \~russian Возвращает, содержит ли узел-объект ключ \a key.
bool contains(const PIString & key) const;
//! \~english Converts node to array and resizes it. New entries become empty strings.
//! \~russian Преобразует узел в массив и изменяет его размер. Новые элементы становятся пустыми строками.
void resize(int new_size);
//! \~english Synonym of \a setValue().
//! \~russian Аналог \a setValue().
PIJSON & operator=(const PIVariant & v) {
setValue(v);
return *this;
}
//! \~english Copy assignment operator.
//! \~russian Оператор копирующего присваивания.
PIJSON & operator=(const PIJSON & v);
//! \~english Returns array element by index, or invalid %PIJSON when the node is not an array.
//! \~russian Возвращает элемент массива по индексу, либо недействительный %PIJSON, если узел не является массивом.
const PIJSON & operator[](int index) const;
//! \~english Converts node to array, grows it when needed and returns element by index.
//! \~russian Преобразует узел в массив, при необходимости увеличивает его и возвращает элемент по индексу.
PIJSON & operator[](int index);
//! \~english Converts node to array and appends another JSON node.
//! \~russian Преобразует узел в массив и добавляет другой узел JSON.
PIJSON & operator<<(const PIJSON & element);
//! \~english Converts node to array and appends a scalar value.
//! \~russian Преобразует узел в массив и добавляет скалярное значение.
PIJSON & operator<<(const PIVariant & value);
//! \~english Returns object member by key, or invalid %PIJSON when the node is not an object or the key is absent.
//! \~russian Возвращает поле объекта по ключу, либо недействительный %PIJSON, если узел не является объектом или ключ отсутствует.
PIJSON operator[](const PIString & key) const;
//! \~english Converts node to object and returns member by key, creating it when needed.
//! \~russian Преобразует узел в объект и возвращает поле по ключу, создавая его при необходимости.
PIJSON & operator[](const PIString & key);
//! \~english Convenience overload for UTF-8 key access.
//! \~russian Вспомогательная перегрузка для доступа по UTF-8 ключу.
PIJSON operator[](const char * key) const { return (*this)[PIString::fromUTF8(key)]; }
//! \~english Convenience overload for UTF-8 key access.
//! \~russian Вспомогательная перегрузка для доступа по UTF-8 ключу.
PIJSON & operator[](const char * key) { return (*this)[PIString::fromUTF8(key)]; }
//! \~english Returns JSON text representation of the node tree.
//! \~russian Возвращает JSON-текст для дерева узлов.
PIString toJSON(PrintType print_type = Compact, bool mask_unicode = true) const;
//! \~english Parses JSON text and returns the root node.
//! \~russian Разбирает JSON-текст и возвращает корневой узел.
static PIJSON fromJSON(PIString str);
//! \~english Creates an object node initialized from variant fields.
//! \~russian Создает узел-объект, инициализированный из полей вариативного словаря.
static PIJSON newObject(const PIVariantMap & fields = {});
//! \~english Creates an array node initialized from variant elements.
//! \~russian Создает узел-массив, инициализированный из вариативных элементов.
static PIJSON newArray(const PIVariantVector & fields = {});
//! \~english Creates a string node.
//! \~russian Создает строковый узел.
static PIJSON newString(const PIString & v = PIString());
//! \~english Serializes value \a v with the overload set from \a pijsonserialization.h.
//! \~russian Сериализует значение \a v через набор перегрузок из \a pijsonserialization.h.
template<typename T>
static PIJSON serialize(const T & v);
//! \~english Deserializes value of type \c T with the overload set from \a pijsonserialization.h.
//! \~russian Десериализует значение типа \c T через набор перегрузок из \a pijsonserialization.h.
template<typename T>
static T deserialize(const PIJSON & json);
private:
static PIJSON & nullEntry();
static PIString parseName(PIString & s);
static PIJSON parseValue(PIString & s);
static PIJSON parseObject(PIString s);
static PIJSON parseArray(PIString s);
static PIString stringMask(const PIString & s, bool mask_unicode);
static PIString stringUnmask(const PIString & s);
static void
print(PIString & s, const PIJSON & v, PIString tab, bool spaces, bool transform = false, bool comma = false, bool mask_unicode = true);
PIString c_name;
PIVariant c_value;
PIVector<PIJSON> c_array;
PIMap<PIString, PIJSON> c_object;
Type c_type = Invalid;
};
//! \relatesalso PICout
//! \~english Output operator to \a PICout.
//! \~russian Оператор вывода в \a PICout.
inline PICout operator<<(PICout s, const PIJSON & v) {
s.space();
s.saveAndSetControls(0);
PIString str;
PIJSON::print(str, v, "", true);
s << str;
s.restoreControls();
return s;
}
#endif // PIJSON_H