ESP-IDF json_generator Печать
Добавил(а) microsin   

Перевод документации API библиотеки json_generator [4], содержимое файла json_generator.h:

/*
* JSON String Generator
*
* Этот модуль может использоваться для создания строк JSON с функционалом
* слива (flush out) данных, если буфер назначения переполнен.
* Все запятые и двоеточия по мере необходимости добавляются автоматически.
*
*/
#ifndef _JSON_GENERATOR_H
#define _JSON_GENERATOR_H

#include < stdint.h>
#include < stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/** Точность представления чисел с плавающей запятой, т. е. количество цифр
после десятичной точки */
#ifndef JSON_FLOAT_PRECISION
#define JSON_FLOAT_PRECISION 5
#endif

/** Прототип callback-функции слива буфера строки JSON
*
* Эта функция должна быть передана в json_gen_str_start(), и она будет
* вызвана из модуля JSON generator, когда буфер заполнится, или
* при вызове json_gen_str_end().
*
* \param[in] buf Указатель на NULL-terminated строку JSON
* \param[in] priv Приватные данные для передачи в flush callback.
* значение будет то же самое, что передано в json_gen_str_start()
*/
typedef void (*json_gen_flush_cb_t) (char *buf, void *priv);

/** Структура JSON String
*
* Не устанавливайте и не изменяйте в ней никакие элементы.
* Просто определите эту структуру и передайте указатель на неё в API-функции,
* описанные далее.
*/
typedef struct {
/** Указатель на буфер JSON, предоставленный вызывающей функцией */
char *buf;
/** Размер буфера buf */
int buf_size;
/** (Не обязательный параметр) callback-функция, которая будет вызвана,
когда буфер переполнится */
json_gen_flush_cb_t flush_cb;
/** (Не обязательный параметр) приватные данные для передачи в callback-функцию */
void *priv;
/** (Только для внутреннего использования) */
bool comma_req;
/** (Только для внутреннего использования) */
char *free_ptr;
/** Общая длина */
int total_len; } json_gen_str_t;

/** Начало формирования строки JSON
*
* Это первая вызываемая функция для создания строки JSON. Она инициализирует
* внутренние структуры данных. После того, как генерация строки JSON закончилась,
* должна быть вызвана функция json_gen_str_end().
*
* \param[out] jstr Указатель на выделенную структуру \ref json_gen_str_t.
* Она будет внутренне инициализирована, и должна передаваться во все последующие
* вызовы функций.
* \param[out] buf Указатель на выделенный буфер, в который будет записываться
* строка JSON. * \param[in] buf_size Размер буфера
* \param[in] flush_cb Указатель на функцию слива типа \ref json_gen_flush_cb_t,
* которая будет вовлечена либо когда буфер заполнится, либо когда будет
* вызвана json_gen_str_end(). Этот параметр может быть NULL.
* \param[in] priv Приватные данные для передачи в callback-функцию слива.
* Может быть чем-то наподобие идентификатора сессии или порта (например socket).
* Этот параметр может быть NULL.
*/
void json_gen_str_start(json_gen_str_t *jstr, char *buf, int buf_size,
json_gen_flush_cb_t flush_cb, void *priv);
/** Завершение строки JSON string
*
* Эта функция должна быть последней вызываемой функцией, когда вся строка JSON
* была сгенерирована.
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
*
* \return Общая длина созданной строки, включая завершающий байт NULL-терминатора.
*/
int json_gen_str_end(json_gen_str_t *jstr);

/** Начало объекта JSON
*
* Начинает формирование объекта JSON добавлением '{'
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_start_object(json_gen_str_t *jstr);

/** Завершение JSON объекта
*
* Завершает объект JSON добавлением '}'
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_end_object(json_gen_str_t *jstr);

/** Начало формирования массива JSON
*
* Начнет JSON-массив добавлением '['
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_start_array(json_gen_str_t *jstr);

/** Завершение формирования массива JSON
*
* Завершит JSON-массив добавлением ']'
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_end_array(json_gen_str_t *jstr);

/** Вставит именованный JSON-объект
*
* Добавляет JSON-объект наподобие "name":{
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] name Имя объекта
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_push_object(json_gen_str_t *jstr, const char *name);

/** Выход из формирования именованного JSON-объекта
*
* Завершает JSON-объект добавлением '}'. Это в основном то же самое,
* что и вызов json_gen_end_object(), но было добавлено как комплементарная функция
* для json_gen_push_object().
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_pop_object(json_gen_str_t *jstr);

/** Вставит объект JSON-строки
*
* Это добавляет в имеющийся объект JSON полный предварительно отформатированный
* объект JSON-строки.
*
* Например json_gen_push_object_str(jstr, "mytext", "{\"a\":1,\"b\":2}");
* Это добавит "mytext":{"a":1,"b":2}
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] name Имя для объекта JSON-строки
* \param[in] object_str Предварительно отформатированный объект JSON-строки
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_push_object_str(json_gen_str_t *jstr, const char *name, const char *object_str);

/** Начало вставки именованного JSON-массива
*
* Добавит массив JSON наподобие "name":[
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start(). * \param[in] name массива
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_push_array(json_gen_str_t *jstr, const char *name);

/** Выход из формирования именованного JSON-массива
*
* Завершит массив JSON добавлением ']'. Это в основном то же самое, что и
* вызов json_gen_end_array(), но было добавлено как комплементарная функция
* для json_gen_push_array()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/int json_gen_pop_array(json_gen_str_t *jstr);

/** Вставит строку JSON-массива
*
* Добавит в существующий объект JSON предварительно полностью сформированную
* строку JSON-массива.
*
* Например json_gen_push_object_str(jstr, "myarray", "[1,2,3]");
* Это добавит "myarray":[1,2,3]
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] name Имя для строки JSON-массива
* \param[in] array_str Предварительно сформированная строка JSON-массива
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_push_array_str(json_gen_str_t *jstr, const char *name, const char *array_str);

/** Добавит элемент boolean в объект JSON
*
* Например "bool_val":true
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_object()/json_gen_push_object()
* и json_gen_end_object()/json_gen_pop_object()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] name Имя элемента
* \param[in] val Двоичное значение элемента
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_obj_set_bool(json_gen_str_t *jstr, const char *name, bool val);

/** Добавит целочисленный элемент в JSON-объект
*
* Например "int_val":28
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_object()/json_gen_push_object()
* и json_gen_end_object()/json_gen_pop_object()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] name Имя элемента
* \param[in] val Целочисленное значение элемента
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_obj_set_int(json_gen_str_t *jstr, const char *name, int val);

/** Добавит float-элемент в JSON-объект
*
* Например "float_val":23.8
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_object()/json_gen_push_object()
* и json_gen_end_object()/json_gen_pop_object()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] name Имя элемента
* \param[in] val Значение с плавающей точкой элемента
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_obj_set_float(json_gen_str_t *jstr, const char *name, float val);

/** Добавит элемент строки к JSON-объекту
*
* Например "string_val":"my_string"
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_object()/json_gen_push_object()
* и json_gen_end_object()/json_gen_pop_object()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] name Имя элемента
* \param[in] val Значение NULL-терминированной строки элемента
* * \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_obj_set_string(json_gen_str_t *jstr, const char *name, const char *val);

/** Добавит элемент NULL к JSON-объекту
*
* Например "null_val":null
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_object()/json_gen_push_object()
* и json_gen_end_object()/json_gen_pop_object()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] name Имя элемента
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_obj_set_null(json_gen_str_t *jstr, const char *name);

/** Добавит двоичный элемент в массив
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_array()/json_gen_push_array()
* и json_gen_end_array()/json_gen_pop_array()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] val Двоичное значение элемента
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_arr_set_bool(json_gen_str_t *jstr, bool val);

/** Добавит целочисленный элемент в массив
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_array()/json_gen_push_array()
* и json_gen_end_array()/json_gen_pop_array()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start(). * \param[in] val Целочисленное значение элемента
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_arr_set_int(json_gen_str_t *jstr, int val);

/** Добавит float элемент в массив
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_array()/json_gen_push_array()
* и json_gen_end_array()/json_gen_pop_array()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] val Значение элемента с плавающей точкой
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_arr_set_float(json_gen_str_t *jstr, float val);

/** Добавит элемент строки в массив
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_array()/json_gen_push_array()
* и json_gen_end_array()/json_gen_pop_array()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] val Значение NULL-терминированной строки элемента
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_arr_set_string(json_gen_str_t *jstr, const char *val);

/** Добавит NULL элемент в массив
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_array()/json_gen_push_array()
* и json_gen_end_array()/json_gen_pop_array()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_arr_set_null(json_gen_str_t *jstr);

/** Начнет добавления большой строки в объект JSON
*
* Начнет, но не закончит добавление строки в объект (т. е. не будут добавлены
* завершающие кавычки. Это полезно для больших строк. Пример: "string_val":"my_string.
* Для добавления к такой строке должна быть вызвана json_gen_add_to_long_string(),
* и для завершения должна быть вызвана json_gen_end_long_string() (добавит
* завершающие кавычки).
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_object()/json_gen_push_object()
* и json_gen_end_object()/json_gen_pop_object()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] name Имя элемента
* \param[in] val Начальная часть NULL-терминированного значения строки.
* Это также может быть NULL.
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_obj_start_long_string(json_gen_str_t *jstr, const char *name, const char *val);

/** Начнет большую строку в массиве
*
* Это начнет формирование строки в массиве, но не завершит её (т. е. не будут добавлены
* завершающие кавычки. Это полезно для больших строк.
* Для добавления к такой строке должна быть вызвана json_gen_add_to_long_string(),
* и для её завершения должна быть вызвана json_gen_end_long_string() (это добавит
* завершающие кавычки).
*
* \note Эта функция должна быть вызвана между комплементарными функциями
* json_gen_start_array()/json_gen_push_array()
* и json_gen_end_array()/json_gen_pop_array()
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] val Начальная часть NULL-терминированного значения строки.
* Это также может быть NULL.
* * \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_arr_start_long_string(json_gen_str_t *jstr, const char *val);

/** Добавит порцию к большой JSON-строке
*
* Расширит значение строки, инициализированной json_gen_obj_start_long_string() или
* json_gen_arr_start_long_string(). После того, как вся строка сформирована, она
* должна быть завершена вызовом json_gen_end_long_string().
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
* \param[in] val NULL-терминированная расширяющая часть строки.
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные.
*/
int json_gen_add_to_long_string(json_gen_str_t *jstr, const char *val);

/** Завершит длинную строку JSON
*
* Завершит строку, инициализированную json_gen_obj_start_long_string() или
* json_gen_arr_start_long_string(), путем добавления завершающих кавычек.
*
* \param[in] jstr Указатель на структуру \ref json_gen_str_t, инициализированную
* вызовом json_gen_str_start().
*
* \return 0 при успехе
* \return -1 если в буфере закончилось место (это возможно только если не была передана
* callback-функция слива в json_gen_str_start(). Иначе буфер будет слит и после этого
* в буфер будут добавлены новые данные. */
int json_gen_end_long_string(json_gen_str_t *jstr);

#ifdef __cplusplus }
#endif
#endif

Пример использования (взято из репозитория [2]):

/*
* Copyright 2020 Piyush Shah < shahpiyushv@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include < stdio.h>
#include < string.h>
#include < json_generator.h>

static const char expected_str[] = "{\"first_bool\":true,\"first_int\":30,"\
"\"first_int64\":-102030405060708090,\"float_val\":54.16430,"\
"\"my_str\":\"new_name\",\"null_obj\":null,\"arr\":[[\"arr_string\","\
"false,45.12000,null,25,908070605040302010,{\"arr_obj_str\":\"sample\""\
"}]],\"my_obj\":{\"only_val\":5}}";

typedef struct {
char buf[256];
size_t offset; } json_gen_test_result_t;

static void flush_str(char *buf, void *priv) {
json_gen_test_result_t *result = (json_gen_test_result_t *)priv;
if (result) {
if (strlen(buf) > sizeof(result->buf) - result->offset) {
printf("Result Buffer too small\r\n");
return;
}
memcpy(result->buf + result->offset, buf, strlen(buf));
result->offset += strlen(buf);
} }

/* Создание JSON
{
"first_bool": true,
"first_int": 30,
"first_int64": -102030405060708090,
"float_val": 54.1643,
"my_str": "new_name",
"null_obj": null,
"arr": [
["arr_string", false, 45.2, null, 25, 908070605040302010, {
"arr_obj_str": "sample"
}]
],
"my_obj": {
"only_val": 5
}
}
*/

static int json_gen_perform_test(json_gen_test_result_t *result, const char *expected) {
char buf[20];
memset(result, 0, sizeof(json_gen_test_result_t));
json_gen_str_t jstr;
json_gen_str_start(&jstr, buf, sizeof(buf), flush_str, result);
json_gen_start_object(&jstr);
json_gen_obj_set_bool(&jstr, "first_bool", true);
json_gen_obj_set_int(&jstr, "first_int", 30);
json_gen_obj_set_int64(&jstr, "first_int64", -102030405060708090);
json_gen_obj_set_float(&jstr, "float_val", 54.1643);
json_gen_obj_set_string(&jstr, "my_str", "new_name");
json_gen_obj_set_null(&jstr, "null_obj");
json_gen_push_array(&jstr, "arr");
json_gen_start_array(&jstr);
json_gen_arr_set_string(&jstr, "arr_string");
json_gen_arr_set_bool(&jstr, false);
json_gen_arr_set_float(&jstr, 45.12);
json_gen_arr_set_null(&jstr);
json_gen_arr_set_int(&jstr, 25);
json_gen_arr_set_int64(&jstr, 908070605040302010);
json_gen_start_object(&jstr);
json_gen_obj_set_string(&jstr, "arr_obj_str", "sample");
json_gen_end_object(&jstr);
json_gen_end_array(&jstr);
json_gen_pop_array(&jstr);
json_gen_push_object(&jstr, "my_obj");
json_gen_obj_set_int(&jstr, "only_val", 5);
json_gen_pop_object(&jstr);
json_gen_end_object(&jstr);
json_gen_str_end(&jstr);
if (strcmp(expected, result->buf) == 0) {
return 0;
} else {
return -1;
} }

int main(int argc, char **argv) {
json_gen_test_result_t result;

printf("Creating JSON string [may require Line wrap enabled on console]\r\n");
int ret = json_gen_perform_test(&result, expected_str);
printf("Expected: %s\r\n", expected_str); printf("Generated: %s\r\n", result.buf);
if (ret == 0) {
printf("Test Passed!\r\n");
} else {
printf("Test Failed!\r\n");
}
return ret; }

[Ссылки]

1. espressif/json_generator site:espressif.com.
2. JSON Generator.