-
Notifications
You must be signed in to change notification settings - Fork 1
/
json-actor.h
241 lines (214 loc) · 7.14 KB
/
json-actor.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
#ifndef JSON_ACTOR_H
#define JSON_ACTOR_H
#include <stdarg.h>
#include "ntl.h"
/*
*
* json actor (injector or extractor) specification grammar
*
* <injector> := <composite-value> <availability>?
* | <access-path-value-list> <availability>?
*
* <extractor> := <composite-value> <availability>?
* | <access-path-value-list> <availability>?
*
* <access-path> := (<key>) | (<key>) <access-path>
*
* <value> := true | false | null | <int> | <float> | <string-literal>
* | <composite-value> | <action>
*
* <action> := d | ld | lld | f | lf | b | <size-specifier>s
* | F | F_nullable | T | L
*
* <access-path-value> := <access-path> : <value>
*
* <access-path-value-list> := <access-path-value>
* | <access-path-value> <access-path-value-list>
*
* <composite-value> := { <access-path-value-list> } | [ <value> ]
*
* <availability> := <size-specifier>@
*
* <size-specifier> := <integer> | .* | ? | epsilon
*
*
* <builtin-action> := d | ld | lld | f | lf | b | <size-specifier>s
*
* d: corresponds to %d, it will inject to json as an int or extract data
* from a json value as an int
*
* ld: corresponds to %ld
* lld: corresponds to %lld
*
* f: corresponds to %f
* lf: corresponds to %lf
*
* b: corresponds to %b
*
* s: corresponds to %s, and it can be decorated with .* and ?
* .*s: corresponds to %.*s
*
* ?s: has not its counter part in printf format string, it tells the
* extract function to allocate sufficient memory for
* the extraction
*
* T: only works for extractor, it will return the memory section that stores
* a json value
*
* L: only works for extractor, it will return the memory sections that store
* each value of a json array
*
*
* examples:
*
*
* json_extract(pos, size, "{ (key) : d, (key) : .*s }", &i, &s)
*
* sized_buffer ** list;
* json_extract(pos, size, "[ L ]", &list);
*
*
* json_inject(pos, size, "{ (key) : d, (key) : |abc| }", i);
*
*
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct json_raw_value {
/*struct sized_buffer buffer; */
int type;
};
/*
* This function will inject variadic parameters into an json
* according to the specification `injector`
*
*
* `pos` pointers to the memory address to stop the injected json
* `size` is the size of the memory block that can be used to store the json
*
* `injector` specifies how the variadic parameters should be placed in
* the injected json.
*
* `injector` is defined by the above BNF grammar
*
*
* example:
* json_inject(pos, size, "(key1) : d, (key2) : |abc|", &i);
*
*
* the result is a json stored at pos
*
* { "key1": 10, "key2": "abc" }
*
* all variadic parameters of actions should be address
*
*/
extern size_t json_inject(char *pos, size_t size, char *injector, ...);
/*
* this function will allocate a sufficient memory block and then call
* json_inject to inject json to the memory block
*/
extern size_t json_ainject(char **buf_p, char *injector, ...);
/*
*
*/
extern size_t json_vinject(char *pos, size_t size, char *injector, va_list ap);
extern size_t json_extract(char *json, size_t size, char *extractor, ...);
extern size_t json_vextract(char *json,
size_t size,
char *extractor,
va_list ap);
extern char *json_string_escape(size_t *new_size, char *str, size_t old_size);
extern int json_string_unescape(char **new_str,
size_t *new_size,
char *str,
size_t old_size);
extern size_t query_inject(char *query, size_t size, char *injector, ...);
extern char *url_encode(char *str);
extern char *url_decode(char *str);
/*
* the line and column in a text file
* it will be used to generate more human
* readable locations.
*/
struct line_and_column {
int line;
int column;
};
extern void addr_to_lnc(char *json,
size_t size,
char *addr,
struct line_and_column *ln);
void json_actor_strong_type(int b);
extern size_t extract_ntl_from_json(char *buf,
size_t len,
struct ntl_deserializer *ntl_deserializer);
extern size_t extract_ntl_from_json2(
char *buf, size_t len, struct ntl_deserializer *ntl_deserializer);
extern int json_to_sized_buffer_ntl(char *json,
size_t size,
NTL_T(struct sized_buffer) * p);
/* All of the possible json datatypes */
enum json_type {
/* DATATYPE FLAGS */
JSON_UNDEFINED = 0,
JSON_NULL = 1 << 0,
JSON_BOOLEAN = 1 << 1,
JSON_NUMBER = 1 << 2,
JSON_STRING = 1 << 3,
JSON_OBJECT = 1 << 4,
JSON_ARRAY = 1 << 5,
/* SUPERSET FLAGS */
JSON_ANY = JSON_NULL | JSON_BOOLEAN | JSON_NUMBER | JSON_STRING | JSON_OBJECT
| JSON_ARRAY
};
/* forwarding, definition at json-parser.c */
typedef struct json_item_s json_item_t;
/* JSON INIT */
json_item_t *json_object(const char *key);
json_item_t *json_array(const char *key);
json_item_t *json_null(const char *key);
json_item_t *json_boolean(const char *key, int boolean);
json_item_t *json_number(const char *key, double number);
json_item_t *json_string(const char *key, char *string);
/* JSON DESTRUCTORS
* clean up json item and global allocated keys */
void json_cleanup(json_item_t *item);
/* JSON DECODING
* parse buffer and returns a json item */
json_item_t *json_parse(char *buffer, size_t len);
/* JSON ENCODING */
struct sized_buffer json_stringify(json_item_t *root, enum json_type type);
/* JSON UTILITIES */
long json_size(const json_item_t *item);
json_item_t *json_append(json_item_t *item, json_item_t *new_branch);
json_item_t *json_iter_next(json_item_t *item);
json_item_t *json_clone(json_item_t *item);
char *json_typeof(const json_item_t *item);
char *json_strdup(const json_item_t *item);
int json_typecmp(const json_item_t *item, const enum json_type type);
int json_keycmp(const json_item_t *item, const char *key);
int json_numcmp(const json_item_t *item, const double number);
/* JSON GETTERS */
json_item_t *json_get_root(json_item_t *item);
json_item_t *json_get_child(json_item_t *item, const char *key);
json_item_t *json_get_sibling(const json_item_t *item, const char *key);
json_item_t *json_get_sibling_byindex(const json_item_t *item,
const long relative_index);
json_item_t *json_get_parent(const json_item_t *item);
json_item_t *json_get_byindex(const json_item_t *item, const long index);
long json_get_index(const json_item_t *item, const char *key);
enum json_type json_get_type(const json_item_t *item);
char *json_get_key(const json_item_t *item);
int json_get_boolean(const json_item_t *item);
char *json_get_string(const json_item_t *item, size_t *len);
double json_get_number(const json_item_t *item);
/* JSON SETTERS */
json_item_t *json_set_boolean(json_item_t *item, int boolean);
json_item_t *json_set_string(json_item_t *item, char *string);
json_item_t *json_set_number(json_item_t *item, double number);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /*JSON_ACTOR_H */