206 lines
6.7 KiB
C
206 lines
6.7 KiB
C
/**
|
|
rjp
|
|
Copyright (C) 2018-2019 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef RJP_H
|
|
#define RJP_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"{
|
|
#endif
|
|
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
#define DEPRECATED(str) __attribute__((deprecated(str)))
|
|
#else
|
|
#define DEPRECATED(str)
|
|
#endif
|
|
|
|
#ifndef RJP_int
|
|
#include <stdint.h>
|
|
#define RJP_int int_fast64_t
|
|
#endif
|
|
#ifndef RJP_index
|
|
#include <stddef.h>
|
|
#define RJP_index size_t
|
|
#endif
|
|
#ifndef RJP_float
|
|
#include <stdint.h>
|
|
#define RJP_float double
|
|
#endif
|
|
|
|
//used with rjp_to_json
|
|
#define RJP_FORMAT_NONE 0
|
|
#define RJP_FORMAT_PRETTY 1
|
|
|
|
//type of data
|
|
typedef enum RJP_data_type{
|
|
rjp_json_object = 0,
|
|
rjp_json_string,
|
|
rjp_json_integer,
|
|
rjp_json_dfloat,
|
|
rjp_json_boolean,
|
|
rjp_json_array,
|
|
rjp_json_null
|
|
}RJP_data_type;
|
|
|
|
|
|
//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{
|
|
struct RJP_object_iterator_impl* it;
|
|
}RJP_object_iterator;
|
|
|
|
struct RJP_array_iterator_impl;
|
|
typedef struct RJP_array_iterator{
|
|
struct RJP_array_iterator_impl* it;
|
|
}RJP_array_iterator;
|
|
|
|
typedef struct RJP_value RJP_value;
|
|
|
|
typedef struct RJP_vinit{
|
|
union{
|
|
RJP_int integer;
|
|
RJP_float dfloat;
|
|
char boolean;
|
|
struct RJP_string string;
|
|
};
|
|
enum RJP_data_type type;
|
|
}RJP_vinit;
|
|
|
|
/*
|
|
Generic operations
|
|
*/
|
|
//Convert C string consisting of json data into RJP's format
|
|
RJP_value* rjp_parse(const char* str);
|
|
//RJP_value* rjp_parse_chunked(const char* str, RJP_value* prev_chunk);
|
|
|
|
//Initialize a root RJP_value to NULL
|
|
RJP_value* rjp_new_value(void);
|
|
//Initialize a root RJP_value to copy of value
|
|
RJP_value* rjp_new_value_as(RJP_vinit* val);
|
|
//Free an RJP_value and all members/elements
|
|
void rjp_free_value(RJP_value* root);
|
|
//Deep copy RJP_value
|
|
void rjp_copy_value(RJP_value* dest, const RJP_value* src);
|
|
//set existing value
|
|
void rjp_set_value(RJP_value* dest, RJP_vinit* val);
|
|
//initialize a RJP_value to the requested type and value
|
|
RJP_vinit rjp_integer(RJP_int i);
|
|
RJP_vinit rjp_boolean(char b);
|
|
RJP_vinit rjp_dfloat(RJP_float d);
|
|
RJP_vinit rjp_string(char* c, RJP_index len);
|
|
RJP_vinit rjp_null(void);
|
|
RJP_vinit rjp_object(void);
|
|
RJP_vinit rjp_array(void);
|
|
//Return handle to parent of given value
|
|
RJP_value* rjp_value_parent(const RJP_value* element);
|
|
//Return type of value
|
|
RJP_data_type rjp_value_type(const RJP_value* value);
|
|
//value accessors
|
|
RJP_float rjp_value_dfloat(const RJP_value* value);
|
|
RJP_int rjp_value_integer(const RJP_value* value);
|
|
char rjp_value_boolean(const RJP_value* value);
|
|
char* rjp_value_string(RJP_value* value);
|
|
const char* rjp_value_cstring(const RJP_value* value);
|
|
RJP_index rjp_value_string_length(const RJP_value* value);
|
|
//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);
|
|
|
|
//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);
|
|
|
|
|
|
/*
|
|
Object operations
|
|
*/
|
|
//add a member to a json object, allocating a copy of the key
|
|
RJP_value* rjp_new_member(RJP_value* dest, const char* key, RJP_index keylen, RJP_vinit* value);
|
|
RJP_value* rjp_add_member(RJP_value* dest, const char* key, RJP_index keylen, RJP_value* value);
|
|
//add a member to a json object without allocation. key must be allocated using rjp_alloc/rjp_calloc
|
|
RJP_value* rjp_new_member_no_alloc(RJP_value* dest, char* key, RJP_index keylen, RJP_vinit* value);
|
|
RJP_value* rjp_add_member_no_alloc(RJP_value* dest, char* key, RJP_index keylen, RJP_value* value);
|
|
RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key);
|
|
RJP_value* rjp_remove_member(RJP_value* obj, RJP_value* member);
|
|
//add an element to a json array
|
|
RJP_value* rjp_add_element(RJP_value* dest, RJP_value* value);
|
|
RJP_value* rjp_new_element(RJP_value* dest, RJP_vinit* value);
|
|
//set existing object member's key
|
|
void rjp_set_key(RJP_value* dest, const char* key, RJP_index keylen);
|
|
//set existing object member's key without allocation. key must be allocated using rjp_alloc/rjp_calloc
|
|
void rjp_set_key_no_alloc(RJP_value* dest, char* key, RJP_index keylen);
|
|
//Access first member of a json object
|
|
RJP_value* rjp_get_member(RJP_object_iterator* object);
|
|
void rjp_init_object_iterator(RJP_object_iterator* it, const RJP_value* object);
|
|
RJP_value* rjp_object_iterator_current(RJP_object_iterator* it);
|
|
RJP_value* rjp_object_iterator_next(RJP_object_iterator* it);
|
|
RJP_value* rjp_object_iterator_peek(RJP_object_iterator* it);
|
|
void rjp_delete_object_iterator(RJP_object_iterator* it);
|
|
//Return number of members in the object
|
|
RJP_index rjp_num_members(const RJP_value* object);
|
|
//Return the object member's key name
|
|
char* rjp_member_name(const RJP_value* member);
|
|
//Return the object member's key name length excluding null terminator
|
|
RJP_index rjp_member_name_length(const RJP_value* member);
|
|
//Search for an object member with given key
|
|
RJP_value* rjp_search_member(const RJP_value* object, const char* search);
|
|
//Search for first occurance of multiple keys. Returns first occurance of each.
|
|
//Assumes dest is large enough to hold maximum num items.
|
|
RJP_index rjp_search_members(const RJP_value* object, RJP_index num, const char* const* searches, RJP_value** dest);
|
|
|
|
|
|
/*
|
|
Array operations
|
|
*/
|
|
//Access first element of a json array
|
|
RJP_value* rjp_get_element(const RJP_value* array);
|
|
//Access next element of a json array given the previous element
|
|
RJP_value* rjp_next_element(const RJP_value* element);
|
|
//Return number of elements in the array
|
|
RJP_index rjp_num_elements(const RJP_value* array);
|
|
|
|
|
|
/*
|
|
Output operations
|
|
*/
|
|
//Convert RJP_object to json string
|
|
RJP_index rjp_dump_object(const RJP_value* root, char* dest);
|
|
//Convert RJP_array to json string
|
|
RJP_index rjp_dump_array(const RJP_value* arr, char* dest);
|
|
//Convert root rjp value into json string
|
|
char* rjp_to_json(const RJP_value* root, int pretty);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#undef DEPRECATED
|
|
|
|
#endif
|