/** rjp Copyright (C) 2018-2020 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef RJP_H_INCLUDED #define RJP_H_INCLUDED #ifdef __cplusplus extern "C"{ #endif #ifndef __STDC_VERSION__ # ifdef __cplusplus # if __cplusplus >= 201402L # define DEPRECATED(str) [[deprecated(str)]] # elif defined(__GNUC__) || defined(__clang__) # define DEPRECATED(str) __attribute__((deprecated(str))) # else # define DEPRECATED(str) # endif # else # define DEPRECATED(str) # endif #else # if __STDC_VERSION__ > 201710L # define DEPRECATED(str) [[deprecated(str)]] # elif defined(__GNUC__) || defined(__clang__) # define DEPRECATED(str) __attribute__((deprecated(str))) # else # define DEPRECATED(str) # endif #endif #ifndef RJP_int # include # define RJP_int int_fast64_t #endif #ifndef RJP_index # include # define RJP_index size_t #endif #ifndef RJP_float # define RJP_float double #endif #ifndef RJP_bool # define RJP_bool char #endif //used with rjp_to_json typedef enum RJP_format_flag{ RJP_FORMAT_NONE = 0, RJP_FORMAT_PRETTY = 1 }RJP_format_flag; //used with rjp_parse typedef enum RJP_parse_flag{ RJP_PARSE_NONE = 0, RJP_PARSE_ALLOW_COMMENTS = 1, RJP_PARSE_ALLOW_TRAILING_COMMA = 2, RJP_PARSE_ALL_EXT = RJP_PARSE_ALLOW_COMMENTS | RJP_PARSE_ALLOW_TRAILING_COMMA }RJP_parse_flag; //type of data typedef enum RJP_data_type{ rjp_json_object = 1, rjp_json_ordered_object = 3, rjp_json_string = 2, rjp_json_integer = 4, rjp_json_dfloat = 8, rjp_json_boolean = 16, rjp_json_array = 32, rjp_json_null = 64 }RJP_data_type; typedef struct RJP_value RJP_value; //Hold a C string and the length excluding NULL terminator typedef struct RJP_string{ char* value; RJP_index length; }RJP_string; //Forward declarations struct RJP_object_iterator_impl; typedef struct RJP_object_iterator{ union{ struct RJP_object_iterator_impl* it; RJP_value* current; }; RJP_data_type type; }RJP_object_iterator; typedef struct RJP_array_iterator{ RJP_value* current; }RJP_array_iterator; typedef struct RJP_parse_callback{ int(*read)(char*,int,void*); void* data; }RJP_parse_callback; /***************** NON OBJECT OPERATIONS *******************/ //Allocate heap space for rjp to use. Use if the memory is to be freed by rjp void* rjp_alloc(RJP_index nbytes); //Allocate heap space for rjp and initialize to 0. void* rjp_calloc(RJP_index num, RJP_index nbytes); //Resize heap allocated space for rjp void* rjp_realloc(void* ptr, RJP_index nbytes); //Free memory allocated by rjp_alloc or rjp_calloc void rjp_free(void* dest); //copy input string and add json escape sequences RJP_index rjp_escape_strcpy(char* dest, const char* src); //length of string including escape sequences RJP_index rjp_escape_strlen(const char* str); RJP_string rjp_escape(const char* src); /***************** GENERIC OPERATIONS *******************/ //Convert C string consisting of json data into RJP's format RJP_value* rjp_parse(const char* str, int flags); //Read json data in using a user supplied callback and convert it to RJP's format RJP_value* rjp_parse_cback(int flags, RJP_parse_callback* cbacks); char* rjp_to_json(const RJP_value* root, int pretty); //Initialize a root RJP_value to copy of value RJP_value* rjp_new_null(void); RJP_value* rjp_new_int(RJP_int val); RJP_value* rjp_new_float(RJP_float val); RJP_value* rjp_new_bool(RJP_bool val); RJP_value* rjp_new_string_copy(const char* val, RJP_index length); RJP_value* rjp_new_string(char* val, RJP_index length); RJP_value* rjp_new_object(void); RJP_value* rjp_new_ordered_object(void); RJP_value* rjp_new_array(void); //Deallocate RJP_value void rjp_free_value(RJP_value* root); //Deep copy RJP_value //When dest is not null, cleanup and then fill the object pointed to by dest. Otherwise allocate a new value. RJP_value* rjp_copy_value(RJP_value* dest, const RJP_value* src); RJP_value* rjp_move_value(RJP_value* dest, RJP_value* src); //set existing value //initialize a RJP_value to the requested type and value RJP_value* rjp_set_null(RJP_value* v); RJP_value* rjp_set_int(RJP_value* v, RJP_int val); RJP_value* rjp_set_float(RJP_value* v, RJP_float val); RJP_value* rjp_set_bool(RJP_value* v, RJP_bool val); RJP_value* rjp_set_string_copy(RJP_value* v, const char* val, RJP_index length); RJP_value* rjp_set_string(RJP_value* v, char* val, RJP_index length); RJP_value* rjp_set_object(RJP_value* v); RJP_value* rjp_set_ordered_object(RJP_value* v); RJP_value* rjp_set_array(RJP_value* v); RJP_float rjp_get_float(const RJP_value* value); RJP_int rjp_get_int(const RJP_value* value); RJP_bool rjp_get_bool(const RJP_value* value); RJP_string* rjp_get_string(RJP_value* value); const RJP_string* rjp_get_cstring(const RJP_value* value); /***************** OBJECT/ARRAY SHARED OPERATIONS *******************/ RJP_value* rjp_value_parent(const RJP_value* element); //Return type of value RJP_data_type rjp_value_type(const RJP_value* value); /***************** OBJECT OPERATIONS *******************/ //add a member to a json object, allocating a copy of the key RJP_value* rjp_add_member_key_copy(RJP_value* dest, const char* key, RJP_index keylen); //add a member to a json object without allocation. key must be allocated using rjp_alloc/rjp_calloc RJP_value* rjp_add_member(RJP_value* dest, char* key, RJP_index keylen); //Remove member without freeing RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key); RJP_value* rjp_remove_member(RJP_value* obj, RJP_value* member); //Remove and free member void rjp_free_member_by_key(RJP_value* obj, const char* key); void rjp_free_member(RJP_value* obj, RJP_value* member); //set existing object member's key without allocation. key must be allocated using rjp_alloc/rjp_calloc void rjp_set_key(RJP_value* dest, char* key, RJP_index keylen); //set existing object member's key void rjp_set_key_copy(RJP_value* dest, const char* key, RJP_index keylen); //Return number of members in the object RJP_index rjp_num_members(const RJP_value* object); //Return the object member's key const RJP_string* rjp_member_key(const RJP_value* member); //Search for an object member with given key RJP_value* rjp_search_member(const RJP_value* object, const char* search); RJP_value* rjp_object_to_ordered(RJP_value* object); RJP_value* rjp_object_to_unordered(RJP_value* object); /***************** OBJECT ITERATOR OPERATIONS *******************/ //Access first member of a json object void rjp_init_object_iterator(RJP_object_iterator* iter, const RJP_value* object); void rjp_delete_object_iterator(RJP_object_iterator* it); RJP_value* rjp_object_iterator_current(const RJP_object_iterator* it); RJP_value* rjp_object_iterator_next(RJP_object_iterator* it); RJP_value* rjp_object_iterator_peek(const RJP_object_iterator* it); /***************** ARRAY OPERATIONS *******************/ //add an element to a json array RJP_value* rjp_add_element(RJP_value* dest); RJP_value* rjp_remove_element(RJP_value* arr, RJP_value* elem); void rjp_free_element(RJP_value* arr, RJP_value* elem); RJP_index rjp_num_elements(const RJP_value* arr); /***************** ARRAY ITERATOR OPERATIONS *******************/ void rjp_init_array_iterator(RJP_array_iterator* iter, const RJP_value* array); void rjp_delete_array_iterator(RJP_array_iterator* iter); RJP_value* rjp_array_iterator_current(const RJP_array_iterator* it); RJP_value* rjp_array_iterator_next(RJP_array_iterator* it); RJP_value* rjp_array_iterator_peek(const RJP_array_iterator* it); #ifdef __cplusplus } #endif #undef DEPRECATED #endif