336 lines
13 KiB
C++
336 lines
13 KiB
C++
#ifndef LIBJSON_H
|
|
#define LIBJSON_H
|
|
|
|
#include "_internal/Source/JSONDefs.h" //for typedefs of functions, strings, and nodes
|
|
|
|
/*
|
|
This is the C interface to libjson.
|
|
|
|
This file also declares various things that are needed for
|
|
C++ programming
|
|
*/
|
|
|
|
#ifdef JSON_LIBRARY //compiling the library, hide the interface
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifdef JSON_NO_C_CONSTS
|
|
/* The interface has no consts in it, but ther must be const_cast internally */
|
|
#define json_const
|
|
#define TOCONST_CSTR(x) const_cast<const json_char *>(x)
|
|
#else
|
|
#define json_const const
|
|
#define TOCONST_CSTR(x) x
|
|
#endif
|
|
|
|
/*
|
|
stuff that's in namespace libjson
|
|
*/
|
|
void json_free(void * str);
|
|
void json_delete(JSONNODE * node);
|
|
#ifdef JSON_MEMORY_MANAGE
|
|
void json_free_all(void);
|
|
void json_delete_all(void);
|
|
#endif
|
|
#ifdef JSON_READ_PRIORITY
|
|
JSONNODE * json_parse(json_const json_char * json);
|
|
JSONNODE * json_parse_unformatted(json_const json_char * json);
|
|
#endif
|
|
json_char * json_strip_white_space(json_const json_char * json);
|
|
#ifdef JSON_VALIDATE
|
|
#ifdef JSON_DEPRECATED_FUNCTIONS
|
|
JSONNODE * json_deprecated(json_validate(json_const json_char * json), "json_validate is deprecated, use json_is_valid and json_parse instead");
|
|
#endif
|
|
json_bool_t json_is_valid(json_const json_char * json);
|
|
json_bool_t json_is_valid_unformatted(json_const json_char * json);
|
|
#endif
|
|
#if defined JSON_DEBUG && !defined JSON_STDERROR
|
|
/* When libjson errors, a callback allows the user to know what went wrong */
|
|
void json_register_debug_callback(json_error_callback_t callback);
|
|
#endif
|
|
#ifdef JSON_MUTEX_CALLBACKS
|
|
#ifdef JSON_MUTEX_MANAGE
|
|
void json_register_mutex_callbacks(json_mutex_callback_t lock, json_mutex_callback_t unlock, json_mutex_callback_t destroy, void * manager_lock);
|
|
#else
|
|
void json_register_mutex_callbacks(json_mutex_callback_t lock, json_mutex_callback_t unlock, void * manager_lock);
|
|
#endif
|
|
void json_set_global_mutex(void * mutex);
|
|
void json_set_mutex(JSONNODE * node, void * mutex);
|
|
void json_lock(JSONNODE * node, int threadid);
|
|
void json_unlock(JSONNODE * node, int threadid);
|
|
#endif
|
|
#ifdef JSON_MEMORY_CALLBACKS
|
|
void json_register_memory_callbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre);
|
|
#endif
|
|
|
|
#ifdef JSON_STREAM
|
|
JSONSTREAM * json_new_stream(json_stream_callback_t callback, json_stream_e_callback_t e_callback, void * identifier);
|
|
void json_stream_push(JSONSTREAM * stream, json_const json_char * addendum);
|
|
void json_delete_stream(JSONSTREAM * stream);
|
|
void json_stream_reset(JSONSTREAM * stream);
|
|
#endif
|
|
|
|
|
|
/*
|
|
stuff that's in class JSONNode
|
|
*/
|
|
/* ctors */
|
|
JSONNODE * json_new_a(json_const json_char * name, json_const json_char * value);
|
|
JSONNODE * json_new_i(json_const json_char * name, json_int_t value);
|
|
JSONNODE * json_new_f(json_const json_char * name, json_number value);
|
|
JSONNODE * json_new_b(json_const json_char * name, json_bool_t value);
|
|
JSONNODE * json_new(char type);
|
|
JSONNODE * json_copy(json_const JSONNODE * orig);
|
|
JSONNODE * json_duplicate(json_const JSONNODE * orig);
|
|
|
|
/* assignment */
|
|
void json_set_a(JSONNODE * node, json_const json_char * value);
|
|
void json_set_i(JSONNODE * node, json_int_t value);
|
|
void json_set_f(JSONNODE * node, json_number value);
|
|
void json_set_b(JSONNODE * node, json_bool_t value);
|
|
void json_set_n(JSONNODE * node, json_const JSONNODE * orig);
|
|
|
|
/* inspectors */
|
|
char json_type(json_const JSONNODE * node);
|
|
json_index_t json_size(json_const JSONNODE * node);
|
|
json_bool_t json_empty(json_const JSONNODE * node);
|
|
json_char * json_name(json_const JSONNODE * node);
|
|
#ifdef JSON_COMMENTS
|
|
json_char * json_get_comment(json_const JSONNODE * node);
|
|
#endif
|
|
json_char * json_as_string(json_const JSONNODE * node);
|
|
json_int_t json_as_int(json_const JSONNODE * node);
|
|
json_number json_as_float(json_const JSONNODE * node);
|
|
json_bool_t json_as_bool(json_const JSONNODE * node);
|
|
#ifdef JSON_CASTABLE
|
|
JSONNODE * json_as_node(json_const JSONNODE * node);
|
|
JSONNODE * json_as_array(json_const JSONNODE * node);
|
|
#endif
|
|
#ifdef JSON_BINARY
|
|
void * json_as_binary(json_const JSONNODE * node, unsigned long * size);
|
|
#endif
|
|
#ifdef JSON_WRITE_PRIORITY
|
|
json_char * json_write(json_const JSONNODE * node);
|
|
json_char * json_write_formatted(json_const JSONNODE * node);
|
|
#endif
|
|
|
|
/* modifiers */
|
|
void json_set_name(JSONNODE * node, json_const json_char * name);
|
|
#ifdef JSON_COMMENTS
|
|
void json_set_comment(JSONNODE * node, json_const json_char * comment);
|
|
#endif
|
|
void json_clear(JSONNODE * node);
|
|
void json_nullify(JSONNODE * node);
|
|
void json_swap(JSONNODE * node, JSONNODE * node2);
|
|
void json_merge(JSONNODE * node, JSONNODE * node2);
|
|
#if !defined (JSON_PREPARSE) && defined(JSON_READ_PRIORITY)
|
|
void json_preparse(JSONNODE * node);
|
|
#endif
|
|
#ifdef JSON_BINARY
|
|
void json_set_binary(JSONNODE * node, json_const void * data, unsigned long length);
|
|
#endif
|
|
#ifdef JSON_EXPOSE_BASE64
|
|
json_char * json_encode64(json_const void * binary, json_index_t bytes);
|
|
void * json_decode64(json_const json_char * text, unsigned long * size);
|
|
#endif
|
|
#ifdef JSON_CASTABLE
|
|
void json_cast(JSONNODE * node, char type);
|
|
#endif
|
|
|
|
/* children access */
|
|
void json_reserve(JSONNODE * node, json_index_t siz);
|
|
JSONNODE * json_at(JSONNODE * node, json_index_t pos);
|
|
JSONNODE * json_get(JSONNODE * node, json_const json_char * name);
|
|
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
|
|
JSONNODE * json_get_nocase(JSONNODE * node, json_const json_char * name);
|
|
JSONNODE * json_pop_back_nocase(JSONNODE * node, json_const json_char * name);
|
|
#endif
|
|
void json_push_back(JSONNODE * node, JSONNODE * node2);
|
|
JSONNODE * json_pop_back_at(JSONNODE * node, json_index_t pos);
|
|
JSONNODE * json_pop_back(JSONNODE * node, json_const json_char * name);
|
|
#ifdef JSON_ITERATORS
|
|
JSONNODE_ITERATOR json_find(JSONNODE * node, json_const json_char * name);
|
|
#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS
|
|
JSONNODE_ITERATOR json_find_nocase(JSONNODE * node, json_const json_char * name);
|
|
#endif
|
|
JSONNODE_ITERATOR json_erase(JSONNODE * node, JSONNODE_ITERATOR it);
|
|
JSONNODE_ITERATOR json_erase_multi(JSONNODE * node, JSONNODE_ITERATOR start, JSONNODE_ITERATOR end);
|
|
JSONNODE_ITERATOR json_insert(JSONNODE * node, JSONNODE_ITERATOR it, JSONNODE * node2);
|
|
JSONNODE_ITERATOR json_insert_multi(JSONNODE * node, JSONNODE_ITERATOR it, JSONNODE_ITERATOR start, JSONNODE_ITERATOR end);
|
|
|
|
/* iterator functions */
|
|
JSONNODE_ITERATOR json_begin(JSONNODE * node);
|
|
JSONNODE_ITERATOR json_end(JSONNODE * node);
|
|
#endif
|
|
|
|
/* comparison */
|
|
json_bool_t json_equal(JSONNODE * node, JSONNODE * node2);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#else
|
|
#ifndef __cplusplus
|
|
#error Turning off JSON_LIBRARY requires C++
|
|
#endif
|
|
#include "_internal/Source/JSONNode.h" //not used in this file, but libjson.h should be the only file required to use it embedded
|
|
#include "_internal/Source/JSONWorker.h"
|
|
#include "_internal/Source/JSONValidator.h"
|
|
#include "_internal/Source/JSONStream.h"
|
|
#include "_internal/Source/JSONPreparse.h"
|
|
#ifdef JSON_EXPOSE_BASE64
|
|
#include "_internal/Source/JSON_Base64.h"
|
|
#endif
|
|
#ifndef JSON_NO_EXCEPTIONS
|
|
#include <stdexcept> //some methods throw exceptions
|
|
#endif
|
|
|
|
#include <cwchar> /* need wide characters */
|
|
#include <string>
|
|
|
|
namespace libjson {
|
|
#ifdef JSON_EXPOSE_BASE64
|
|
inline static json_string encode64(const unsigned char * binary, size_t bytes) json_nothrow {
|
|
return JSONBase64::json_encode64(binary, bytes);
|
|
}
|
|
|
|
inline static std::string decode64(const json_string & encoded) json_nothrow {
|
|
return JSONBase64::json_decode64(encoded);
|
|
}
|
|
#endif
|
|
|
|
//useful if you have json that you don't want to parse, just want to strip to cut down on space
|
|
inline static json_string strip_white_space(const json_string & json) json_nothrow {
|
|
return JSONWorker::RemoveWhiteSpaceAndComments(json, false);
|
|
}
|
|
|
|
#ifndef JSON_STRING_HEADER
|
|
inline static std::string to_std_string(const json_string & str){
|
|
#if defined(JSON_UNICODE) ||defined(JSON_MEMORY_CALLBACKS) || defined(JSON_MEMORY_POOL)
|
|
return std::string(str.begin(), str.end());
|
|
#else
|
|
return str;
|
|
#endif
|
|
}
|
|
inline static std::wstring to_std_wstring(const json_string & str){
|
|
#if (!defined(JSON_UNICODE)) || defined(JSON_MEMORY_CALLBACKS) || defined(JSON_MEMORY_POOL)
|
|
return std::wstring(str.begin(), str.end());
|
|
#else
|
|
return str;
|
|
#endif
|
|
}
|
|
|
|
inline static json_string to_json_string(const std::string & str){
|
|
#if defined(JSON_UNICODE) ||defined(JSON_MEMORY_CALLBACKS) || defined(JSON_MEMORY_POOL)
|
|
return json_string(str.begin(), str.end());
|
|
#else
|
|
return str;
|
|
#endif
|
|
}
|
|
inline static json_string to_json_string(const std::wstring & str){
|
|
#if (!defined(JSON_UNICODE)) || defined(JSON_MEMORY_CALLBACKS) || defined(JSON_MEMORY_POOL)
|
|
return json_string(str.begin(), str.end());
|
|
#else
|
|
return str;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef JSON_READ_PRIORITY
|
|
//if json is invalid, it throws a std::invalid_argument exception
|
|
inline static JSONNode parse(const json_string & json) json_throws(std::invalid_argument) {
|
|
#ifdef JSON_PREPARSE
|
|
size_t len;
|
|
json_auto<json_char> buffer(JSONWorker::RemoveWhiteSpace(json, len, false));
|
|
return JSONPreparse::isValidRoot(buffer.ptr);
|
|
#else
|
|
return JSONWorker::parse(json);
|
|
#endif
|
|
}
|
|
|
|
inline static JSONNode parse_unformatted(const json_string & json) json_throws(std::invalid_argument) {
|
|
#ifdef JSON_PREPARSE
|
|
return JSONPreparse::isValidRoot(json);
|
|
#else
|
|
return JSONWorker::parse_unformatted(json);
|
|
#endif
|
|
}
|
|
|
|
#ifdef JSON_VALIDATE
|
|
inline static bool is_valid(const json_string & json) json_nothrow {
|
|
#ifdef JSON_SECURITY_MAX_STRING_LENGTH
|
|
if (json_unlikely(json.length() > JSON_SECURITY_MAX_STRING_LENGTH)){
|
|
JSON_FAIL(JSON_TEXT("Exceeding JSON_SECURITY_MAX_STRING_LENGTH"));
|
|
return false;
|
|
}
|
|
#endif
|
|
json_auto<json_char> s;
|
|
s.set(JSONWorker::RemoveWhiteSpaceAndCommentsC(json, false));
|
|
return JSONValidator::isValidRoot(s.ptr);
|
|
}
|
|
|
|
inline static bool is_valid_unformatted(const json_string & json) json_nothrow {
|
|
#ifdef JSON_SECURITY_MAX_STRING_LENGTH
|
|
if (json_unlikely(json.length() > JSON_SECURITY_MAX_STRING_LENGTH)){
|
|
JSON_FAIL(JSON_TEXT("Exceeding JSON_SECURITY_MAX_STRING_LENGTH"));
|
|
return false;
|
|
}
|
|
#endif
|
|
return JSONValidator::isValidRoot(json.c_str());
|
|
}
|
|
#ifdef JSON_DEPRECATED_FUNCTIONS
|
|
#ifdef JSON_NO_EXCEPTIONS
|
|
#error, JSON_DEPRECATED_FUNCTIONS requires JSON_NO_EXCEPTIONS be off
|
|
#endif
|
|
//if json is invalid, it throws a std::invalid_argument exception (differs from parse because this checks the entire tree)
|
|
inline static JSONNode json_deprecated(validate(const json_string & json), "libjson::validate is deprecated, use libjson::is_valid and libjson::parse instead");
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
//When libjson errors, a callback allows the user to know what went wrong
|
|
#if defined JSON_DEBUG && !defined JSON_STDERROR
|
|
inline static void register_debug_callback(json_error_callback_t callback) json_nothrow {
|
|
JSONDebug::register_callback(callback);
|
|
}
|
|
#endif
|
|
|
|
#ifdef JSON_MUTEX_CALLBACKS
|
|
#ifdef JSON_MUTEX_MANAGE
|
|
inline static void register_mutex_callbacks(json_mutex_callback_t lock, json_mutex_callback_t unlock, json_mutex_callback_t destroy, void * manager_lock) json_nothrow {
|
|
JSONNode::register_mutex_callbacks(lock, unlock, manager_lock);
|
|
JSONNode::register_mutex_destructor(destroy);
|
|
}
|
|
#else
|
|
inline static void register_mutex_callbacks(json_mutex_callback_t lock, json_mutex_callback_t unlock, void * manager_lock) json_nothrow {
|
|
JSONNode::register_mutex_callbacks(lock, unlock, manager_lock);
|
|
}
|
|
#endif
|
|
|
|
inline static void set_global_mutex(void * mutex) json_nothrow {
|
|
JSONNode::set_global_mutex(mutex);
|
|
}
|
|
#endif
|
|
|
|
#ifdef JSON_MEMORY_CALLBACKS
|
|
inline static void register_memory_callbacks(json_malloc_t mal, json_realloc_t real, json_free_t fre) json_nothrow {
|
|
JSONMemory::registerMemoryCallbacks(mal, real, fre);
|
|
}
|
|
#endif
|
|
|
|
}
|
|
#ifdef JSON_VALIDATE
|
|
#ifdef JSON_DEPRECATED_FUNCTIONS
|
|
//if json is invalid, it throws a std::invalid_argument exception (differs from parse because this checks the entire tree)
|
|
inline static JSONNode libjson::validate(const json_string & json) {
|
|
if (json_likely(is_valid(json))){
|
|
return parse(json);
|
|
}
|
|
throw std::invalid_argument("");
|
|
}
|
|
#endif
|
|
#endif
|
|
#endif //JSON_LIBRARY
|
|
|
|
#endif //LIBJSON_H
|