1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/zhoutk-zjson

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README_CN.md 21 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 07.03.2025 10:09 67ba5f0

ZJSON    English

Introduction

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.

Explanation of Project Name

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
  • Копирующий конструктор
  • Конструктор из initializer_list
  • Деструктор
  • Оператор =
  • Оператор []
  • Метод contains
  • Метод getValueType
  • Метод getAndRemove
  • Метод getAllKeys
  • Метод addSubitem (Добавление подобъекта к объекту JSON, быстрое добавление элемента в массив)
  • Метод toString (Генерация JSON-строки)
  • Методы toInt,toDouble,toBool (Преобразование типов значений)
  • Метод toVector (Преобразование типа массива)
  • Методы isError, isNull, isArray (Определение типа узла)
  • Метод parse (Конвертация из строки JSON в объект типа JSON)
  • Расширение объекта Extend JSON
  • Расширение массива Concat JSON
  • Метод push_front (Вставка в начало массива)
  • Метод push_back (Вставка в конец массива)
  • Метод insert (Вставка в массив)
  • Метод clear (Очистка)
  • Поддержка std::move
  • Удаление всех ключей key (Для объекта JSON повторяющиеся ключи допустимы)
  • Удаление элемента по индексу (Для массива)
  • Методы pop, pop_back, pop_front
  • Методы removeFirst, removeLast, remove (Для массива)
  • Метод slice
  • Методы takes, take
  • Профилирование производительности рекурсивной версии и сравнение
  • Преобразование алгоритма в нерекурсивный вид
  • Вторичное профилирование производительности и сравнение## Структура данных

Определение типов узлов JSON

(внутреннее использование, тип данных используется только внутри класса JSON)

enum Type {
    Error,                //Ошибка, поиск не дал результатов, это недействительный объект JSON
    False,                //Тип значения JSON — false
    True,                 //Тип значения JSON — true
    Null,                 //Тип значения JSON — null
    Number,              //Тип значения JSON — число, хранится в виде типа double
    String,               //Тип значения JSON — строка
    Object,               //Тип объекта JSON — это вложенный объект, только дочерние узлы требуют внимания
    Array                 //Тип объекта JSON — это вложенный массив, только дочерние узлы требуют внимания
};

Определение узлов 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;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp-&emsp;
```Json оператор [](const string& key) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&nbsp;&nbsp;// Поиск значения в объекте 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() &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&nbsp;&nbsp;// Преобразование значения в булево значение
- vector<Json> toVector() &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&nbsp;&nbsp;// Преобразование массива JSON в вектор
- bool extend(Json value) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Расширение объекта JSON добавлением нового значения
- bool concat(Json value) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Расширение массива
- bool push_front(Json value) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Вставка значения в начало массива
- bool push_back(Json value) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Вставка значения в конец массива
- bool insert(int index, Json value) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Вставка элемента в массив по индексу
- bool clear() &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Очистка массива
- void remove(const string &key) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Удаление ключа
- bool contains(const string& key) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Проверка наличия ключа
- string getValueType() &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Получение типа значения в виде строки
- Json getAndRemove(const string& key) &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Получение и удаление значения по ключу
- std::vector<std::string> getAllKeys() &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;// Получение всех ключей## Пример программы
Простой пример использования
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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/zhoutk-zjson.git
git@api.gitlife.ru:oschina-mirror/zhoutk-zjson.git
oschina-mirror
zhoutk-zjson
zhoutk-zjson
master