/* * Copyright (c) 2020 YuQing <384681@qq.com> * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the Lesser GNU General Public License, version 3 * or later ("LGPL"), as published by the Free Software Foundation. * * 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. * * You should have received a copy of the Lesser GNU General Public License * along with this program. If not, see . */ //json_parser.h #ifndef _FC_JSON_PARSER_H #define _FC_JSON_PARSER_H #include #include #include #include #include "common_define.h" #include "shared_func.h" #define FC_JSON_TYPE_STRING 1 #define FC_JSON_TYPE_ARRAY 2 #define FC_JSON_TYPE_MAP 3 #define DEFINE_ARRAY_STRUCT(ELEMENT_TYPE, ARRAY_TYPE) \ typedef struct { \ ELEMENT_TYPE *elements; \ int count; \ \ /* for internal use */ \ int element_size; \ int alloc; \ } ARRAY_TYPE DEFINE_ARRAY_STRUCT(void, fc_common_array_t); DEFINE_ARRAY_STRUCT(string_t, fc_json_array_t); DEFINE_ARRAY_STRUCT(key_value_pair_t, fc_json_map_t); typedef struct { BufferInfo output; //for json encode string_t element; //string allocator use output buffer int init_buff_size; int error_no; int error_size; char error_holder[256]; string_t error_info; fc_json_array_t jarray; fc_json_map_t jmap; /* for internal use */ const char *str; //input string const char *p; //current const char *end; } fc_json_context_t; #ifdef __cplusplus extern "C" { #endif static inline void fc_init_common_array(fc_common_array_t *array, const int element_size) { array->elements = NULL; array->element_size = element_size; array->count = array->alloc = 0; } static inline void fc_init_json_array(fc_json_array_t *array) { fc_init_common_array((fc_common_array_t *)array, sizeof(string_t)); } static inline void fc_init_json_map(fc_json_map_t *array) { fc_init_common_array((fc_common_array_t *)array, sizeof(key_value_pair_t)); } static inline void fc_free_common_array(fc_common_array_t *array) { if (array->elements != NULL) { free(array->elements); array->elements = NULL; array->count = array->alloc = 0; } } static inline void fc_free_json_array(fc_json_array_t *array) { fc_free_common_array((fc_common_array_t *)array); } static inline void fc_free_json_map(fc_json_map_t *array) { fc_free_common_array((fc_common_array_t *)array); } static inline void fc_set_json_error_buffer(fc_json_context_t *ctx, char *error_info, const int error_size) { if (error_info != NULL && error_size > 0) { ctx->error_info.str = error_info; ctx->error_size = error_size; } else { ctx->error_info.str = ctx->error_holder; ctx->error_size = sizeof(ctx->error_holder); } ctx->error_info.len = 0; *ctx->error_info.str = '\0'; } static inline int fc_init_json_context_ex(fc_json_context_t *ctx, const int init_buff_size, char *error_info, const int error_size) { ctx->output.buff = NULL; ctx->output.alloc_size = ctx->output.length = 0; FC_SET_STRING_NULL(ctx->element); if (init_buff_size > 0) { ctx->init_buff_size = init_buff_size; } else { ctx->init_buff_size = 1024; } fc_init_json_array(&ctx->jarray); fc_init_json_map(&ctx->jmap); ctx->error_no = 0; fc_set_json_error_buffer(ctx, error_info, error_size); return 0; } static inline int fc_init_json_context(fc_json_context_t *ctx) { const int init_buff_size = 0; return fc_init_json_context_ex(ctx, init_buff_size, NULL, 0); } static inline void fc_destroy_json_context(fc_json_context_t *ctx) { fc_free_buffer(&ctx->output); fc_free_json_array(&ctx->jarray); fc_free_json_map(&ctx->jmap); } static inline int fc_json_parser_get_error_no(fc_json_context_t *ctx) { return ctx->error_no; } static inline const string_t *fc_json_parser_get_error_info( fc_json_context_t *ctx) { return &ctx->error_info; } int fc_detect_json_type(const string_t *input); int fc_encode_json_array_ex(fc_json_context_t *context, const string_t *elements, const int count, BufferInfo *buffer); int fc_encode_json_map_ex(fc_json_context_t *context, const key_value_pair_t *elements, const int count, BufferInfo *buffer); static inline const BufferInfo *fc_encode_json_array(fc_json_context_t *context, const string_t *elements, const int count) { if (fc_encode_json_array_ex(context, elements, count, &context->output) == 0) { return &context->output; } else { return NULL; } } static inline const BufferInfo *fc_encode_json_map(fc_json_context_t *context, const key_value_pair_t *elements, const int count) { if (fc_encode_json_map_ex(context, elements, count, &context->output) == 0) { return &context->output; } else { return NULL; } } const fc_json_array_t *fc_decode_json_array(fc_json_context_t *context, const string_t *input); const fc_json_map_t *fc_decode_json_map(fc_json_context_t *context, const string_t *input); #ifdef __cplusplus } #endif #endif