Transitioning from Node.js to C++, we miss the convenience of working with JSON in JavaScript. We tried various libraries for C++, but their provided interfaces were either unfamiliar or overly complex, and the number of functions made usage less straightforward. We analyzed numerous libraries such as rapidjson, cJson, CJsonObject, drleq-cppjson, json11, and others. The data structure was inspired by cJOSN, while the parser was based on json11, for which we thank the authors of these projects. Ultimately, to ensure type-agnostic storage but still know the types, we chose std::variant
together with std::any
, supported starting from C++17. The library is designed as a single-header file that does not depend on any other libraries except the standard C++ library.
The project name is composed of the first letter of my name in pinyin (Z) and the word "json," resulting in the name zjson, which has no other meaning. I plan to create a series of projects starting with the letter Z, so I used this simple approach to naming.## Концепция дизайна
Простые интерфейсные функции, удобство использования, гибкая структура данных, максимальная поддержка цепного программирования. Используя шаблоны, удалось достичь минималистичного дизайна, методы для подэлементов JSON объекта требуют всего одну функцию — addSubitem
, которая автоматически распознает, является ли это значением или под-JSON объектом. Используется связный список (в честь cJSON) для хранения JSON объекта, обратите внимание на моё проектирование структуры данных, где голова списка и последующие узлы используют одинаковую структуру, что позволяет выполнять цепное программирование при работе с индексами ([]).
Проект в настоящее время завершён основной частью функциональности. Для получения более подробной информации смотрите список задач. Можно создавать объекты типа JSON, добавлять данные, извлекать значения или подобъекты по ключу (тип Object) или индексу (тип Array), генерировать JSON-строки и реализовать конвертацию из JSON-строки в объект типа JSON.Выполнены тесты на утечку памяти; деструктор работает правильно, при миллионах операций создания и удаления объектов заметного увеличения потребляемой памяти не было замечено.
Написано множество юнит-тестов, поддерживающих основные операционные системы Windows, Linux и macOS.
Список задач:- [x] Конструктор (Объект & Массив)
(внутреннее использование, тип данных используется только внутри класса JSON)
enum Type {
Error, //Ошибка, поиск не дал результатов, это недействительный объект JSON
False, //Тип значения JSON — false
True, //Тип значения JSON — true
Null, //Тип значения JSON — null
Number, //Тип значения JSON — число, хранится в виде типа double
String, //Тип значения JSON — строка
Object, //Тип объекта JSON — это вложенный объект, только дочерние узлы требуют внимания
Array //Тип объекта JSON — это вложенный массив, только дочерние узлы требуют внимания
};
class Json {
Json* brother; //Соответствует next в cJSON, действителен только для значений, указывает на параллельные данные, но может быть как значение, так и объект
Json* child; //Дочерний узел, действителен только для объектов
Type type; //Тип узла
std::variant<int, bool, double, std::string> data; //Данные узла
std::string name; //Ключ узла
}
```## Описание интерфейса
Открытый тип объекта JSON поддерживает только два типа объектов — Object и Array, соответствующие внутренним типам.
```cpp
enum class JsonType
{
Object = 6,
Array = 7
};
Список интерфейсов- Json(JsonType type = JsonType::Object)
Документация не содержит явных текстовых описаний или фрагментов, требующих перевода. Все предоставленные строки содержат только пробелы и табуляцию, что не требует перевода или изменения. Таким образом, исходный текст остается без изменений:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            &emsp- 
```Json оператор [](const string& key)         // Поиск значения в объекте JSON по ключу- template<typename T> bool addSubitem(T value); // Добавление подэлемента типа T в массив
- template<typename T> bool addSubitem(string name, T value); // Добавление подэлемента типа T с именем name в массив, имя игнорируется если this — это объект
- string toString(); // Преобразование объекта JSON в строку
- bool isError(); // Проверка на наличие ошибки в объекте JSON
- bool isNull(); // Проверка на null значение
- bool isObject(); // Проверка на объект JSON
- bool isArray(); // Проверка на массив JSON
- bool isNumber(); // Проверка на число, хранящееся как double
- bool isTrue(); // Проверка на true значение
- bool isFalse(); // Проверка на false значение
- int toInt(); // Преобразование значения в int
- float toFloat(); // Преобразование значения в float
- double toDouble(); // Преобразование значения в double- bool toBool()                  // Преобразование значения в булево значение
- vector<Json> toVector()             // Преобразование массива JSON в вектор
- bool extend(Json value)             // Расширение объекта JSON добавлением нового значения
- bool concat(Json value)             // Расширение массива
- bool push_front(Json value)             // Вставка значения в начало массива
- bool push_back(Json value)             // Вставка значения в конец массива
- bool insert(int index, Json value)            // Вставка элемента в массив по индексу
- bool clear()              // Очистка массива
- void remove(const string &key)           // Удаление ключа
- bool contains(const string& key)             // Проверка наличия ключа
- string getValueType()            // Получение типа значения в виде строки
- Json getAndRemove(const string& key)            // Получение и удаление значения по ключу
- std::vector<std::string> getAllKeys()            // Получение всех ключей## Пример программы
Простой пример использования
Json subObject{{"math", 99}, {"str", "строка."}}; // создание объекта Json с помощью initializer_list
//initializer_list способ создаёт объект Json, который может содержать вложенные данные
@Json mulitListObj{{"fkey", false},{"strkey","ffffff"},{"num2", 9.98}, {"okey", subObject}};
Json subArray(JsonType::Array); // Создание массива JSON с использованием initializer_list
subArray.add({12,13,14,15}); // Быстрое создание массива [12,13,14,15]
Json ajson(JsonType::Object); // Создание объекта JSON
std::string data = "kevin";
ajson.add("fail", false); // Добавление логического значения
ajson.add("name", data); // Добавление строки
ajson.add("school-en", "the 85th.");
ajson.add("age", 10); // Добавление целого числа
ajson.add("scores", 95.98); // Добавление вещественного числа
ajson.add("nullkey", nullptr); // Добавление null значения
Json sub; // Создание объекта JSON
sub.add("math", 99);
ajson.addValueJson("subJson", sub); // Добавление вложенного объекта JSON
Json subArray(JsonType::Array); // Создание массива JSON
subArray.add("I'm the first one."); // Добавление строки в массив
subArray.add("two", 2); // Добавление числа в массив
Json sub2;
sub2.add("sb2", 222);
subArray.addValueJson("subObj", sub2); // Добавление вложенного объекта JSON в массив
ajson.addValueJson("array", subArray); // Добавление массива JSON в основной объект std::cout << "ajson's string is : " << ajson.toString() << std::endl; // Вывод сериализованной строки объекта ajson, результат см. ниже```markdown
строка name = ajson["name"].toString(); # Извлечение строки с ключом "name", результат: kevin
целое число oper = ajson["sb2"].toInt(); # Извлечение целого числа из вложенной структуры с ключом "sb2", результат: 222
Json operArr = ajson["array"]; # Извлечение массива объектов с ключом "array"
строка first = ajson["array"][0].toString(); # Извлечение значения с индексом 0 из массива объектов с ключом "array", результат: Я первый.
Результат сериализации mulitListObj:
{
"fkey": false,
"strkey": "ffffff",
"num2": 9.98,
"okey": {
"math": 99,
"str": "строка."
}
}
Результат сериализации ajson:
{
"fail": false,
"name": "kevin",
"school-en": "the 85th.",
"age": 10,
"scores": 95.98,
"nullkey": null,
"subJson": {
"math": 99
},
"array": [
"Я первый.",
2,
{
"sb2": 222
}
]
}
Дополнительные примеры можно найти в файлах demo.cpp или тестовых случаях в директории tests.
https://gitee.com/zhoutk/zjson или https://github.com/zhoutk/zjson
Проект успешно компилируется и выполняется в vs2019, gcc7.5, clang12.0.
git clone https://github.com/zhoutk/zjson cd zjson cmake -Bbuild .
---Windows cd build && cmake --build .
---Linux & Mac cd build && make
запустите zjson или ctest
## Связанные проекты
Будут выпущены ряд проектов, связанных с сетью, следите за новостями...
> [zorm](https://gitee.com/zhoutk/zorm.git) (универсальное обертывание отношений баз данных)
https://gitee.com/zhoutk/zorm или https://github.com/zhoutk/zorm
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )