-
Notifications
You must be signed in to change notification settings - Fork 6
/
jfes.h
389 lines (289 loc) · 14.2 KB
/
jfes.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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
/**
\file jfes.h
\author Eremin Dmitry (http://github.com/NeonMercury)
\date October, 2015
\brief Json For Embedded Systems library headers.
*/
#ifndef JFES_H_INCLUDE_GUARD
#define JFES_H_INCLUDE_GUARD
/** Strict JSON mode. **/
//#define JFES_STRICT
/** Maximal tokens count */
#define JFES_MAX_TOKENS_COUNT 8192
/** NULL define for the jfes library. */
#ifndef JFES_NULL
#define JFES_NULL ((void*)0)
#endif
/** size_t type for the jfes library. */
typedef unsigned int jfes_size_t;
/** JFES return statuses. */
typedef enum jfes_status {
jfes_unknown = 0x00, /**< Unknown status */
jfes_success = 0x01, /**< Last operation finished sucessfully. */
jfes_invalid_arguments = 0x02, /**< Invalid arguments were passed to the function. */
jfes_no_memory = 0x03, /**< Not enough tokens were provided. */
jfes_invalid_input = 0x04, /**< Invalid character in JSON string. */
jfes_error_part = 0x05, /**< The string is not a full JSON packet. More bytes expected. */
jfes_unknown_type = 0x06, /**< Unknown token type. */
jfes_not_found = 0x07, /**< Something was not found. */
} jfes_status_t;
/** Memory allocator function type. */
typedef void *(*jfes_malloc_t)(jfes_size_t);
/** Memory deallocator function type. */
typedef void (*jfes_free_t)(void*);
/** JFES string type. */
typedef struct jfes_string {
char *data; /**< String bytes. */
jfes_size_t size; /**< Allocated bytes count. */
} jfes_string_t;
/** JFES token types */
typedef enum jfes_token_type {
jfes_type_undefined = 0x00, /**< Undefined token type. */
jfes_type_null = 0x01, /**< Null token type. */
jfes_type_boolean = 0x02, /**< Boolean token type. */
jfes_type_integer = 0x03, /**< Integer token type. */
jfes_type_double = 0x04, /**< Double token type. */
jfes_type_string = 0x05, /**< String token type. */
jfes_type_array = 0x06, /**< Array token type. */
jfes_type_object = 0x07, /**< Object token type. */
} jfes_token_type_t;
/** Json value type is the same as token type. */
typedef jfes_token_type_t jfes_value_type_t;
/** JFES token structure. */
typedef struct jfes_token {
jfes_token_type_t type; /**< Token type. */
int start; /**< Token start position. */
int end; /**< Token end position. */
jfes_size_t size; /**< Token children count. */
} jfes_token_t;
/** JFES config structure. */
typedef struct jfes_config {
jfes_malloc_t jfes_malloc; /**< Memory allocation function. */
jfes_free_t jfes_free; /**< Memory deallocation function. */
} jfes_config_t;
/** JFES tokens data structure. */
typedef struct jfes_tokens_data {
const jfes_config_t *config; /**< JFES configuration. */
const char *json_data; /**< JSON string. */
jfes_size_t json_data_length; /**< JSON string length. */
jfes_token_t *tokens; /**< String parsing result in tokens. */
jfes_size_t tokens_count; /**< Tokens count. */
jfes_size_t current_token; /**< Index of current token. */
} jfes_tokens_data_t;
/** JFES parser structure. */
typedef struct jfes_parser {
jfes_size_t pos; /**< Current offset in json string. */
jfes_size_t next_token; /**< Next token to allocate. */
int superior_token; /**< Superior token node. */
const jfes_config_t *config; /**< Pointer to jfes config. */
} jfes_parser_t;
/** JSON value structure. */
typedef struct jfes_value jfes_value_t;
/** JFES `key -> value` mapping structure. */
typedef struct jfes_object_map {
jfes_string_t key; /**< Object key. */
jfes_value_t *value; /**< Oject value. */
} jfes_object_map_t;
/** JSON array structure. */
typedef struct jfes_array {
jfes_value_t **items; /**< JSON items in array. */
jfes_size_t count; /**< Items count in array. */
} jfes_array_t;
/** JSON object structure. */
typedef struct jfes_object {
jfes_object_map_t **items; /**< JSON items in object. */
jfes_size_t count; /**< Items count in object. */
} jfes_object_t;
/** JFES value data union. */
typedef union jfes_value_data {
int bool_val; /**< Boolean JSON value. */
int int_val; /**< Integer JSON value. */
double double_val; /**< Double JSON value. */
jfes_string_t string_val; /**< String JSON value. */
jfes_array_t *array_val; /**< Array JSON value. */
jfes_object_t *object_val; /**< Object JSON value. */
} jfes_value_data_t;
/** JSON value structure. */
struct jfes_value {
jfes_value_type_t type; /**< JSON value type. */
jfes_value_data_t data; /**< Value data. */
};
/**
JFES status analizer function.
\param[in] status Status variable.
\return Zero status is not jfes_success. Otherwise anything else.
*/
int jfes_status_is_good(jfes_status_t status);
/**
JFES status analizer function.
\param[in] status Status variable.
\return Zero if status is jfes_success. Otherwise anything else.
*/
int jfes_status_is_bad(jfes_status_t status);
/**
JFES parser initialization.
\param[out] parser Pointer to the jfes_parser_t object.
\param[in] config JFES configuration.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_init_parser(jfes_parser_t *parser, const jfes_config_t *config);
/**
Resets all parser fields, except memory allocation functions.
\param[out] parser Pointer to the jfes_parser_t object.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_reset_parser(jfes_parser_t *parser);
/**
Runs JSON parser. It parses a JSON data string into an
array of tokens, each describing a single JSON object.
\param[in] parser Pointer to the jfes_parser_t object.
\param[in] json JSON data string.
\param[in] length JSON data length.
\param[out] tokens Tokens array to fill.
\param[in, out] max_tokens_count Maximal count of tokens in tokens array.
Will contain tokens count.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_parse_tokens(jfes_parser_t *parser, const char *json,
jfes_size_t length, jfes_token_t *tokens, jfes_size_t *max_tokens_count);
/**
Runs JSON parser and fills jfes_value_t object.
\param[in] config JFES configuration.
\param[in] json JSON data string.
\param[in] length JSON data length.
\param[out] value Output value.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_parse_to_value(const jfes_config_t *config, const char *json,
jfes_size_t length, jfes_value_t *value);
/**
Frees all resources captured by the object.
\param[in] config JFES configuration.
\param[in,out] value Object to free.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_free_value(const jfes_config_t *config, jfes_value_t *value);
/**
Allocates a new null value.
\param[in] config JFES configuration.
\return Allocated JFES value or JFES_NULL if something went wrong.
*/
jfes_value_t *jfes_create_null_value(const jfes_config_t *config);
/**
Allocates a new boolean value.
\param[in] config JFES configuration.
\param[in] value Value to pass it to the object.
\return Allocated JFES value or JFES_NULL if something went wrong.
*/
jfes_value_t *jfes_create_boolean_value(const jfes_config_t *config, int value);
/**
Allocates a new integer value.
\param[in] config JFES configuration.
\param[in] value Value to pass it to the object.
\return Allocated JFES value or JFES_NULL if something went wrong.
*/
jfes_value_t *jfes_create_integer_value(const jfes_config_t *config, int value);
/**
Allocates a new double value.
\param[in] config JFES configuration.
\param[in] value Value to pass it to the object.
\return Allocated JFES value or JFES_NULL if something went wrong.
*/
jfes_value_t *jfes_create_double_value(const jfes_config_t *config, double value);
/**
Allocates a new string value.
\param[in] config JFES configuration.
\param[in] value Value to pass it to the object.
\param[in] length Optional. String length. You can pass 0
if the string is zero-terminated.
\return Allocated JFES value or JFES_NULL if something went wrong.
*/
jfes_value_t *jfes_create_string_value(const jfes_config_t *config, const char *value, jfes_size_t length);
/**
Allocates a new array value.
\param[in] config JFES configuration.
\return Allocated JFES value or JFES_NULL if something went wrong.
*/
jfes_value_t *jfes_create_array_value(const jfes_config_t *config);
/**
Allocates a new object value.
\param[in] config JFES configuration.
\return Allocated JFES value or JFES_NULL if something went wrong.
*/
jfes_value_t *jfes_create_object_value(const jfes_config_t *config);
/**
Finds child value if given parent value is object.
\param[in] value Parent object value.
\param[in] key Child key.
\param[in] key_length Optional. Child key length. You can pass 0
if the key string is zero-terminated.
\return Child value by the given key or JFES_NULL if nothing was found.
*/
jfes_value_t *jfes_get_child(const jfes_value_t *value, const char *key, jfes_size_t key_length);
/**
Finds child value if given parent value is object.
\param[in] value Parent object value.
\param[in] key Child key.
\param[in] key_length Optional. Child key length. You can pass 0
if the key string is zero-terminated.
\return Mapped child value with the given key or JFES_NULL if nothing was found.
*/
jfes_object_map_t *jfes_get_mapped_child(const jfes_value_t *value, const char *key, jfes_size_t key_length);
/**
Adds a new item to the given array value.
\param[in] config JFES configuration.
\param[in] value Array value.
\param[in] item Item to add. Must be allocated on heap.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_place_to_array(const jfes_config_t *config, const jfes_value_t *value, jfes_value_t *item);
/**
Adds a new item to the given array value in the given place.
\param[in] config JFES configuration.
\param[in] value Array value.
\param[in] item Item to add. Must be allocated on heap.
\param[in] place_at Index to place.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_place_to_array_at(const jfes_config_t *config, const jfes_value_t *value, jfes_value_t *item, jfes_size_t place_at);
/**
Removes an item with the given index from the array.
\param[in] config JFES configuration.
\param[in] value Array value.
\param[in] index Index to remove.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_remove_from_array(const jfes_config_t *config, const jfes_value_t *value, jfes_size_t index);
/**
Adds a new item to the given object.
\param[in] config JFES configuration.
\param[in] value Array value.
\param[in] item Item to add. Must be allocated on heap.
\param[in] key Child key.
\param[in] key_length Optional. Child key length. You can pass 0
if the key string is zero-terminated.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_set_object_property(const jfes_config_t *config, const jfes_value_t *value,
jfes_value_t *item, const char *key, jfes_size_t key_length);
/**
Removes a child object with the given key.
\param[in] config JFES configuration.
\param[in] value Array value.
\param[in] key Child key.
\param[in] key_length Optional. Child key length. You can pass 0
if the key string is zero-terminated.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_remove_object_property(const jfes_config_t *config, const jfes_value_t *value,
const char *key, jfes_size_t key_length);
/**
Dumps JFES value to the memory.
\param[in] value JFES value to dump.
\param[out] data Allocated memory to store.
\param[in, out] max_size Maximal size of data. Will store data length.
\param[in] beautiful Beautiful JSON.
\return jfes_success if everything is OK.
*/
jfes_status_t jfes_value_to_string(const jfes_value_t *value, char *data, jfes_size_t *max_size, int beautiful);
#endif