forked from mousebird/libjson
-
Notifications
You must be signed in to change notification settings - Fork 1
/
libjson.h
336 lines (304 loc) · 12.8 KB
/
libjson.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#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