iodine 0.7.59 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.clang-format +15 -0
- data/.rspec +1 -0
- data/.yardopts +1 -3
- data/CHANGELOG.md +132 -12
- data/Gemfile +5 -7
- data/LICENSE.txt +1 -1
- data/README.md +147 -671
- data/Rakefile +9 -16
- data/examples/chatroom.nru +9 -0
- data/examples/client +74 -0
- data/examples/config-hello.nru +9 -0
- data/examples/config-hello.ru +11 -0
- data/examples/config-hijack.ru +13 -0
- data/examples/config-shootout.ru +43 -0
- data/examples/config.nru +120 -0
- data/examples/config.rb +37 -0
- data/examples/config.ru +42 -53
- data/examples/fake +24 -0
- data/examples/hello_neorack +137 -0
- data/examples/routes.nru +29 -0
- data/examples/routes.ru +42 -0
- data/exe/iodine +218 -258
- data/ext/iodine/extconf.rb +27 -100
- data/ext/iodine/fio-stl.h +128336 -0
- data/ext/iodine/fio-stl.md +26396 -0
- data/ext/iodine/iodine.c +213 -1393
- data/ext/iodine/iodine.h +250 -55
- data/ext/iodine/iodine_arg_helper.h +329 -0
- data/ext/iodine/iodine_caller.h +234 -25
- data/ext/iodine/iodine_cli.h +434 -0
- data/ext/iodine/iodine_compression.h +312 -0
- data/ext/iodine/iodine_connection.h +3484 -34
- data/ext/iodine/iodine_core.h +363 -0
- data/ext/iodine/iodine_crypto.h +1441 -0
- data/ext/iodine/iodine_defer.h +225 -4
- data/ext/iodine/iodine_json.h +738 -4
- data/ext/iodine/iodine_listener.h +263 -0
- data/ext/iodine/iodine_log.h +297 -0
- data/ext/iodine/iodine_minimap.h +543 -0
- data/ext/iodine/iodine_mustache.h +461 -4
- data/ext/iodine/iodine_pubsub_eng.h +729 -0
- data/ext/iodine/iodine_pubsub_history.h +547 -0
- data/ext/iodine/iodine_pubsub_msg.h +228 -0
- data/ext/iodine/iodine_redis.h +322 -0
- data/ext/iodine/iodine_store.h +418 -16
- data/ext/iodine/iodine_threads.h +279 -0
- data/ext/iodine/iodine_tls.h +515 -6
- data/ext/iodine/iodine_utils.h +923 -0
- data/iodine.gemspec +37 -42
- data/lib/iodine/benchmark.rb +1690 -0
- data/lib/iodine/documentation.rb +3085 -0
- data/lib/iodine/version.rb +17 -1
- data/lib/iodine.rb +54 -255
- data/logo.svg +36 -0
- data/mustache.md +55 -0
- data/sig/iodine.rbs +4 -0
- metadata +58 -184
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
- data/.github/workflows/ruby.yml +0 -42
- data/.gitignore +0 -20
- data/LIMITS.md +0 -41
- data/SPEC-PubSub-Draft.md +0 -159
- data/SPEC-WebSocket-Draft.md +0 -239
- data/bin/console +0 -22
- data/bin/info.md +0 -353
- data/bin/mustache_bench.rb +0 -100
- data/bin/poc/Gemfile.lock +0 -23
- data/bin/poc/README.md +0 -37
- data/bin/poc/config.ru +0 -66
- data/bin/poc/gemfile +0 -1
- data/bin/poc/www/index.html +0 -57
- data/examples/async_task.ru +0 -92
- data/examples/bates/README.md +0 -3
- data/examples/bates/config.ru +0 -342
- data/examples/bates/david+bold.pdf +0 -0
- data/examples/bates/public/drop-pdf.png +0 -0
- data/examples/bates/public/index.html +0 -600
- data/examples/echo.ru +0 -59
- data/examples/etag.ru +0 -16
- data/examples/hello.ru +0 -29
- data/examples/pubsub_engine.ru +0 -81
- data/examples/rack3.ru +0 -12
- data/examples/redis.ru +0 -70
- data/examples/shootout.ru +0 -73
- data/examples/sub-protocols.ru +0 -90
- data/examples/tcp_client.rb +0 -66
- data/examples/x-sendfile.ru +0 -14
- data/ext/iodine/fio.c +0 -11995
- data/ext/iodine/fio.h +0 -6371
- data/ext/iodine/fio_cli.c +0 -431
- data/ext/iodine/fio_cli.h +0 -189
- data/ext/iodine/fio_json_parser.h +0 -688
- data/ext/iodine/fio_siphash.c +0 -157
- data/ext/iodine/fio_siphash.h +0 -37
- data/ext/iodine/fio_tls.h +0 -129
- data/ext/iodine/fio_tls_missing.c +0 -649
- data/ext/iodine/fio_tls_openssl.c +0 -1106
- data/ext/iodine/fio_tmpfile.h +0 -50
- data/ext/iodine/fiobj.h +0 -44
- data/ext/iodine/fiobj4fio.h +0 -21
- data/ext/iodine/fiobj_ary.c +0 -333
- data/ext/iodine/fiobj_ary.h +0 -139
- data/ext/iodine/fiobj_data.c +0 -1187
- data/ext/iodine/fiobj_data.h +0 -167
- data/ext/iodine/fiobj_hash.c +0 -409
- data/ext/iodine/fiobj_hash.h +0 -176
- data/ext/iodine/fiobj_json.c +0 -622
- data/ext/iodine/fiobj_json.h +0 -68
- data/ext/iodine/fiobj_mem.h +0 -71
- data/ext/iodine/fiobj_mustache.c +0 -317
- data/ext/iodine/fiobj_mustache.h +0 -62
- data/ext/iodine/fiobj_numbers.c +0 -344
- data/ext/iodine/fiobj_numbers.h +0 -127
- data/ext/iodine/fiobj_str.c +0 -433
- data/ext/iodine/fiobj_str.h +0 -172
- data/ext/iodine/fiobject.c +0 -620
- data/ext/iodine/fiobject.h +0 -655
- data/ext/iodine/hpack.h +0 -1923
- data/ext/iodine/http.c +0 -2743
- data/ext/iodine/http.h +0 -1002
- data/ext/iodine/http1.c +0 -910
- data/ext/iodine/http1.h +0 -29
- data/ext/iodine/http1_parser.h +0 -878
- data/ext/iodine/http_internal.c +0 -1279
- data/ext/iodine/http_internal.h +0 -237
- data/ext/iodine/http_mime_parser.h +0 -350
- data/ext/iodine/iodine_caller.c +0 -230
- data/ext/iodine/iodine_connection.c +0 -941
- data/ext/iodine/iodine_defer.c +0 -420
- data/ext/iodine/iodine_fiobj2rb.h +0 -120
- data/ext/iodine/iodine_helpers.c +0 -282
- data/ext/iodine/iodine_helpers.h +0 -12
- data/ext/iodine/iodine_http.c +0 -1181
- data/ext/iodine/iodine_http.h +0 -23
- data/ext/iodine/iodine_json.c +0 -302
- data/ext/iodine/iodine_mustache.c +0 -567
- data/ext/iodine/iodine_pubsub.c +0 -580
- data/ext/iodine/iodine_pubsub.h +0 -26
- data/ext/iodine/iodine_rack_io.c +0 -273
- data/ext/iodine/iodine_rack_io.h +0 -20
- data/ext/iodine/iodine_store.c +0 -146
- data/ext/iodine/iodine_tcp.c +0 -346
- data/ext/iodine/iodine_tcp.h +0 -13
- data/ext/iodine/iodine_tls.c +0 -261
- data/ext/iodine/mustache_parser.h +0 -1546
- data/ext/iodine/redis_engine.c +0 -957
- data/ext/iodine/redis_engine.h +0 -79
- data/ext/iodine/resp_parser.h +0 -317
- data/ext/iodine/websocket_parser.h +0 -506
- data/ext/iodine/websockets.c +0 -743
- data/ext/iodine/websockets.h +0 -185
- data/lib/iodine/connection.rb +0 -61
- data/lib/iodine/json.rb +0 -42
- data/lib/iodine/mustache.rb +0 -113
- data/lib/iodine/pubsub.rb +0 -55
- data/lib/iodine/rack_utils.rb +0 -43
- data/lib/iodine/tls.rb +0 -16
- data/lib/rack/handler/iodine.rb +0 -33
- data/logo.png +0 -0
data/ext/iodine/fiobj_json.c
DELETED
|
@@ -1,622 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright: Boaz Segev, 2017-2019
|
|
3
|
-
License: MIT
|
|
4
|
-
*/
|
|
5
|
-
#include <fiobj_json.h>
|
|
6
|
-
#define FIO_ARY_NAME fio_json_stack
|
|
7
|
-
#define FIO_ARY_TYPE FIOBJ
|
|
8
|
-
#include <fio.h>
|
|
9
|
-
|
|
10
|
-
#include <fio_json_parser.h>
|
|
11
|
-
|
|
12
|
-
#include <assert.h>
|
|
13
|
-
#include <ctype.h>
|
|
14
|
-
#include <math.h>
|
|
15
|
-
#include <stdlib.h>
|
|
16
|
-
#include <string.h>
|
|
17
|
-
|
|
18
|
-
/* *****************************************************************************
|
|
19
|
-
JSON API
|
|
20
|
-
***************************************************************************** */
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Parses JSON, setting `pobj` to point to the new Object.
|
|
24
|
-
*
|
|
25
|
-
* Returns the number of bytes consumed. On Error, 0 is returned and no data is
|
|
26
|
-
* consumed.
|
|
27
|
-
*/
|
|
28
|
-
size_t fiobj_json2obj(FIOBJ *pobj, const void *data, size_t len);
|
|
29
|
-
/* Formats an object into a JSON string. Remember to `fiobj_free`. */
|
|
30
|
-
FIOBJ fiobj_obj2json(FIOBJ, uint8_t);
|
|
31
|
-
|
|
32
|
-
/* *****************************************************************************
|
|
33
|
-
FIOBJ Parser
|
|
34
|
-
***************************************************************************** */
|
|
35
|
-
|
|
36
|
-
typedef struct {
|
|
37
|
-
json_parser_s p;
|
|
38
|
-
FIOBJ key;
|
|
39
|
-
FIOBJ top;
|
|
40
|
-
FIOBJ target;
|
|
41
|
-
fio_json_stack_s stack;
|
|
42
|
-
uint8_t is_hash;
|
|
43
|
-
} fiobj_json_parser_s;
|
|
44
|
-
|
|
45
|
-
/* *****************************************************************************
|
|
46
|
-
FIOBJ Callacks
|
|
47
|
-
***************************************************************************** */
|
|
48
|
-
|
|
49
|
-
static inline void fiobj_json_add2parser(fiobj_json_parser_s *p, FIOBJ o) {
|
|
50
|
-
if (p->top) {
|
|
51
|
-
if (p->is_hash) {
|
|
52
|
-
if (p->key) {
|
|
53
|
-
fiobj_hash_set(p->top, p->key, o);
|
|
54
|
-
fiobj_free(p->key);
|
|
55
|
-
p->key = FIOBJ_INVALID;
|
|
56
|
-
} else {
|
|
57
|
-
p->key = o;
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
fiobj_ary_push(p->top, o);
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
p->top = o;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** a NULL object was detected */
|
|
68
|
-
static void fio_json_on_null(json_parser_s *p) {
|
|
69
|
-
fiobj_json_add2parser((fiobj_json_parser_s *)p, fiobj_null());
|
|
70
|
-
}
|
|
71
|
-
/** a TRUE object was detected */
|
|
72
|
-
static void fio_json_on_true(json_parser_s *p) {
|
|
73
|
-
fiobj_json_add2parser((fiobj_json_parser_s *)p, fiobj_true());
|
|
74
|
-
}
|
|
75
|
-
/** a FALSE object was detected */
|
|
76
|
-
static void fio_json_on_false(json_parser_s *p) {
|
|
77
|
-
fiobj_json_add2parser((fiobj_json_parser_s *)p, fiobj_false());
|
|
78
|
-
}
|
|
79
|
-
/** a Numberl was detected (long long). */
|
|
80
|
-
static void fio_json_on_number(json_parser_s *p, long long i) {
|
|
81
|
-
fiobj_json_add2parser((fiobj_json_parser_s *)p, fiobj_num_new(i));
|
|
82
|
-
}
|
|
83
|
-
/** a Float was detected (double). */
|
|
84
|
-
static void fio_json_on_float(json_parser_s *p, double f) {
|
|
85
|
-
fiobj_json_add2parser((fiobj_json_parser_s *)p, fiobj_float_new(f));
|
|
86
|
-
}
|
|
87
|
-
/** a String was detected (int / float). update `pos` to point at ending */
|
|
88
|
-
static void fio_json_on_string(json_parser_s *p, void *start, size_t length) {
|
|
89
|
-
FIOBJ str = fiobj_str_buf(length);
|
|
90
|
-
fiobj_str_resize(
|
|
91
|
-
str, fio_json_unescape_str(fiobj_obj2cstr(str).data, start, length));
|
|
92
|
-
fiobj_json_add2parser((fiobj_json_parser_s *)p, str);
|
|
93
|
-
}
|
|
94
|
-
/** a dictionary object was detected */
|
|
95
|
-
static int fio_json_on_start_object(json_parser_s *p) {
|
|
96
|
-
fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
|
|
97
|
-
if (pr->target) {
|
|
98
|
-
/* push NULL, don't free the objects */
|
|
99
|
-
fio_json_stack_push(&pr->stack, pr->top);
|
|
100
|
-
pr->top = pr->target;
|
|
101
|
-
pr->target = FIOBJ_INVALID;
|
|
102
|
-
} else {
|
|
103
|
-
FIOBJ hash = fiobj_hash_new();
|
|
104
|
-
fiobj_json_add2parser(pr, hash);
|
|
105
|
-
fio_json_stack_push(&pr->stack, pr->top);
|
|
106
|
-
pr->top = hash;
|
|
107
|
-
}
|
|
108
|
-
pr->is_hash = 1;
|
|
109
|
-
return 0;
|
|
110
|
-
}
|
|
111
|
-
/** a dictionary object closure detected */
|
|
112
|
-
static void fio_json_on_end_object(json_parser_s *p) {
|
|
113
|
-
fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
|
|
114
|
-
if (pr->key) {
|
|
115
|
-
FIO_LOG_WARNING("(JSON parsing) malformed JSON, "
|
|
116
|
-
"ignoring dangling Hash key.");
|
|
117
|
-
fiobj_free(pr->key);
|
|
118
|
-
pr->key = FIOBJ_INVALID;
|
|
119
|
-
}
|
|
120
|
-
pr->top = FIOBJ_INVALID;
|
|
121
|
-
fio_json_stack_pop(&pr->stack, &pr->top);
|
|
122
|
-
pr->is_hash = FIOBJ_TYPE_IS(pr->top, FIOBJ_T_HASH);
|
|
123
|
-
}
|
|
124
|
-
/** an array object was detected */
|
|
125
|
-
static int fio_json_on_start_array(json_parser_s *p) {
|
|
126
|
-
fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
|
|
127
|
-
if (pr->target)
|
|
128
|
-
return -1;
|
|
129
|
-
FIOBJ ary = fiobj_ary_new();
|
|
130
|
-
fiobj_json_add2parser(pr, ary);
|
|
131
|
-
fio_json_stack_push(&pr->stack, pr->top);
|
|
132
|
-
pr->top = ary;
|
|
133
|
-
pr->is_hash = 0;
|
|
134
|
-
return 0;
|
|
135
|
-
}
|
|
136
|
-
/** an array closure was detected */
|
|
137
|
-
static void fio_json_on_end_array(json_parser_s *p) {
|
|
138
|
-
fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
|
|
139
|
-
pr->top = FIOBJ_INVALID;
|
|
140
|
-
fio_json_stack_pop(&pr->stack, &pr->top);
|
|
141
|
-
pr->is_hash = FIOBJ_TYPE_IS(pr->top, FIOBJ_T_HASH);
|
|
142
|
-
}
|
|
143
|
-
/** the JSON parsing is complete */
|
|
144
|
-
static void fio_json_on_json(json_parser_s *p) {
|
|
145
|
-
// fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
|
|
146
|
-
// FIO_ARY_FOR(&pr->stack, pos) { fiobj_free((FIOBJ)pos.obj); }
|
|
147
|
-
// fio_json_stack_free(&pr->stack);
|
|
148
|
-
(void)p; /* nothing special... right? */
|
|
149
|
-
}
|
|
150
|
-
/** the JSON parsing is complete */
|
|
151
|
-
static void fio_json_on_error(json_parser_s *p) {
|
|
152
|
-
fiobj_json_parser_s *pr = (fiobj_json_parser_s *)p;
|
|
153
|
-
#if DEBUG
|
|
154
|
-
FIO_LOG_DEBUG("JSON on error called.");
|
|
155
|
-
#endif
|
|
156
|
-
fiobj_free((FIOBJ)fio_json_stack_get(&pr->stack, 0));
|
|
157
|
-
fiobj_free(pr->key);
|
|
158
|
-
fio_json_stack_free(&pr->stack);
|
|
159
|
-
*pr = (fiobj_json_parser_s){.top = FIOBJ_INVALID};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/* *****************************************************************************
|
|
163
|
-
JSON formatting
|
|
164
|
-
***************************************************************************** */
|
|
165
|
-
|
|
166
|
-
/** Writes a JSON friendly version of the src String */
|
|
167
|
-
static void write_safe_str(FIOBJ dest, const FIOBJ str) {
|
|
168
|
-
fio_str_info_s s = fiobj_obj2cstr(str);
|
|
169
|
-
fio_str_info_s t = fiobj_obj2cstr(dest);
|
|
170
|
-
t.data[t.len] = '"';
|
|
171
|
-
t.len++;
|
|
172
|
-
fiobj_str_resize(dest, t.len);
|
|
173
|
-
t = fiobj_obj2cstr(dest);
|
|
174
|
-
const uint8_t *restrict src = (const uint8_t *)s.data;
|
|
175
|
-
size_t len = s.len;
|
|
176
|
-
uint64_t end = t.len;
|
|
177
|
-
/* make sure we have some room */
|
|
178
|
-
size_t added = 0;
|
|
179
|
-
size_t capa = fiobj_str_capa(dest);
|
|
180
|
-
if (capa <= end + s.len + 64) {
|
|
181
|
-
if (0) {
|
|
182
|
-
capa = (((capa >> 12) + 1) << 12) - 1;
|
|
183
|
-
capa = fiobj_str_capa_assert(dest, capa);
|
|
184
|
-
} else {
|
|
185
|
-
capa = fiobj_str_capa_assert(dest, (end + s.len + 64));
|
|
186
|
-
}
|
|
187
|
-
fio_str_info_s tmp = fiobj_obj2cstr(dest);
|
|
188
|
-
t = tmp;
|
|
189
|
-
}
|
|
190
|
-
while (len) {
|
|
191
|
-
char *restrict writer = (char *)t.data;
|
|
192
|
-
while (len && src[0] > 32 && src[0] != '"' && src[0] != '\\') {
|
|
193
|
-
len--;
|
|
194
|
-
writer[end++] = *(src++);
|
|
195
|
-
}
|
|
196
|
-
if (!len)
|
|
197
|
-
break;
|
|
198
|
-
switch (src[0]) {
|
|
199
|
-
case '\b':
|
|
200
|
-
writer[end++] = '\\';
|
|
201
|
-
writer[end++] = 'b';
|
|
202
|
-
added++;
|
|
203
|
-
break; /* from switch */
|
|
204
|
-
case '\f':
|
|
205
|
-
writer[end++] = '\\';
|
|
206
|
-
writer[end++] = 'f';
|
|
207
|
-
added++;
|
|
208
|
-
break; /* from switch */
|
|
209
|
-
case '\n':
|
|
210
|
-
writer[end++] = '\\';
|
|
211
|
-
writer[end++] = 'n';
|
|
212
|
-
added++;
|
|
213
|
-
break; /* from switch */
|
|
214
|
-
case '\r':
|
|
215
|
-
writer[end++] = '\\';
|
|
216
|
-
writer[end++] = 'r';
|
|
217
|
-
added++;
|
|
218
|
-
break; /* from switch */
|
|
219
|
-
case '\t':
|
|
220
|
-
writer[end++] = '\\';
|
|
221
|
-
writer[end++] = 't';
|
|
222
|
-
added++;
|
|
223
|
-
break; /* from switch */
|
|
224
|
-
case '"':
|
|
225
|
-
case '\\':
|
|
226
|
-
case '/':
|
|
227
|
-
writer[end++] = '\\';
|
|
228
|
-
writer[end++] = src[0];
|
|
229
|
-
added++;
|
|
230
|
-
break; /* from switch */
|
|
231
|
-
default:
|
|
232
|
-
if (src[0] <= 31) {
|
|
233
|
-
/* MUST escape all control values less than 32 */
|
|
234
|
-
writer[end++] = '\\';
|
|
235
|
-
writer[end++] = 'u';
|
|
236
|
-
writer[end++] = '0';
|
|
237
|
-
writer[end++] = '0';
|
|
238
|
-
writer[end++] = hex_chars[src[0] >> 4];
|
|
239
|
-
writer[end++] = hex_chars[src[0] & 15];
|
|
240
|
-
added += 4;
|
|
241
|
-
} else
|
|
242
|
-
writer[end++] = src[0];
|
|
243
|
-
break; /* from switch */
|
|
244
|
-
}
|
|
245
|
-
src++;
|
|
246
|
-
len--;
|
|
247
|
-
if (added >= 48 && capa <= end + len + 64) {
|
|
248
|
-
writer[end] = 0;
|
|
249
|
-
fiobj_str_resize(dest, end);
|
|
250
|
-
fiobj_str_capa_assert(dest, (end + len + 64));
|
|
251
|
-
t = fiobj_obj2cstr(dest);
|
|
252
|
-
writer = (char *)t.data;
|
|
253
|
-
capa = t.capa;
|
|
254
|
-
added = 0;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
t.data[end++] = '"';
|
|
258
|
-
fiobj_str_resize(dest, end);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
typedef struct {
|
|
262
|
-
FIOBJ dest;
|
|
263
|
-
FIOBJ parent;
|
|
264
|
-
fio_json_stack_s *stack;
|
|
265
|
-
uintptr_t count;
|
|
266
|
-
uint8_t pretty;
|
|
267
|
-
} obj2json_data_s;
|
|
268
|
-
|
|
269
|
-
static int fiobj_obj2json_task(FIOBJ o, void *data_) {
|
|
270
|
-
obj2json_data_s *data = data_;
|
|
271
|
-
uint8_t add_seperator = 1;
|
|
272
|
-
if (fiobj_hash_key_in_loop()) {
|
|
273
|
-
write_safe_str(data->dest, fiobj_hash_key_in_loop());
|
|
274
|
-
fiobj_str_write(data->dest, ":", 1);
|
|
275
|
-
}
|
|
276
|
-
switch (FIOBJ_TYPE(o)) {
|
|
277
|
-
case FIOBJ_T_NUMBER:
|
|
278
|
-
case FIOBJ_T_NULL:
|
|
279
|
-
case FIOBJ_T_TRUE:
|
|
280
|
-
case FIOBJ_T_FALSE:
|
|
281
|
-
case FIOBJ_T_FLOAT:
|
|
282
|
-
fiobj_str_join(data->dest, o);
|
|
283
|
-
--data->count;
|
|
284
|
-
break;
|
|
285
|
-
|
|
286
|
-
case FIOBJ_T_DATA:
|
|
287
|
-
case FIOBJ_T_UNKNOWN:
|
|
288
|
-
case FIOBJ_T_STRING:
|
|
289
|
-
write_safe_str(data->dest, o);
|
|
290
|
-
--data->count;
|
|
291
|
-
break;
|
|
292
|
-
|
|
293
|
-
case FIOBJ_T_ARRAY:
|
|
294
|
-
--data->count;
|
|
295
|
-
fio_json_stack_push(data->stack, data->parent);
|
|
296
|
-
fio_json_stack_push(data->stack, (FIOBJ)data->count);
|
|
297
|
-
data->parent = o;
|
|
298
|
-
data->count = fiobj_ary_count(o);
|
|
299
|
-
fiobj_str_write(data->dest, "[", 1);
|
|
300
|
-
add_seperator = 0;
|
|
301
|
-
break;
|
|
302
|
-
|
|
303
|
-
case FIOBJ_T_HASH:
|
|
304
|
-
--data->count;
|
|
305
|
-
fio_json_stack_push(data->stack, data->parent);
|
|
306
|
-
fio_json_stack_push(data->stack, (FIOBJ)data->count);
|
|
307
|
-
data->parent = o;
|
|
308
|
-
data->count = fiobj_hash_count(o);
|
|
309
|
-
fiobj_str_write(data->dest, "{", 1);
|
|
310
|
-
add_seperator = 0;
|
|
311
|
-
break;
|
|
312
|
-
}
|
|
313
|
-
if (data->pretty) {
|
|
314
|
-
fiobj_str_capa_assert(data->dest,
|
|
315
|
-
fiobj_obj2cstr(data->dest).len +
|
|
316
|
-
(fio_json_stack_count(data->stack) * 5));
|
|
317
|
-
while (!data->count && data->parent) {
|
|
318
|
-
if (FIOBJ_TYPE_IS(data->parent, FIOBJ_T_HASH)) {
|
|
319
|
-
fiobj_str_write(data->dest, "}", 1);
|
|
320
|
-
} else {
|
|
321
|
-
fiobj_str_write(data->dest, "]", 1);
|
|
322
|
-
}
|
|
323
|
-
add_seperator = 1;
|
|
324
|
-
data->count = 0;
|
|
325
|
-
fio_json_stack_pop(data->stack, &data->count);
|
|
326
|
-
data->parent = FIOBJ_INVALID;
|
|
327
|
-
fio_json_stack_pop(data->stack, &data->parent);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (add_seperator && data->parent) {
|
|
331
|
-
fiobj_str_write(data->dest, ",\n", 2);
|
|
332
|
-
uintptr_t indent = fio_json_stack_count(data->stack) - 1;
|
|
333
|
-
fiobj_str_capa_assert(data->dest,
|
|
334
|
-
fiobj_obj2cstr(data->dest).len + (indent * 2));
|
|
335
|
-
fio_str_info_s buf = fiobj_obj2cstr(data->dest);
|
|
336
|
-
while (indent--) {
|
|
337
|
-
buf.data[buf.len++] = ' ';
|
|
338
|
-
buf.data[buf.len++] = ' ';
|
|
339
|
-
}
|
|
340
|
-
fiobj_str_resize(data->dest, buf.len);
|
|
341
|
-
}
|
|
342
|
-
} else {
|
|
343
|
-
fiobj_str_capa_assert(data->dest,
|
|
344
|
-
fiobj_obj2cstr(data->dest).len +
|
|
345
|
-
(fio_json_stack_count(data->stack) << 1));
|
|
346
|
-
while (!data->count && data->parent) {
|
|
347
|
-
if (FIOBJ_TYPE_IS(data->parent, FIOBJ_T_HASH)) {
|
|
348
|
-
fiobj_str_write(data->dest, "}", 1);
|
|
349
|
-
} else {
|
|
350
|
-
fiobj_str_write(data->dest, "]", 1);
|
|
351
|
-
}
|
|
352
|
-
add_seperator = 1;
|
|
353
|
-
data->count = 0;
|
|
354
|
-
data->parent = FIOBJ_INVALID;
|
|
355
|
-
fio_json_stack_pop(data->stack, &data->count);
|
|
356
|
-
fio_json_stack_pop(data->stack, &data->parent);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
if (add_seperator && data->parent) {
|
|
360
|
-
fiobj_str_write(data->dest, ",", 1);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
return 0;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/* *****************************************************************************
|
|
368
|
-
FIOBJ API
|
|
369
|
-
***************************************************************************** */
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Parses JSON, setting `pobj` to point to the new Object.
|
|
373
|
-
*
|
|
374
|
-
* Returns the number of bytes consumed. On Error, 0 is returned and no data is
|
|
375
|
-
* consumed.
|
|
376
|
-
*/
|
|
377
|
-
size_t fiobj_json2obj(FIOBJ *pobj, const void *data, size_t len) {
|
|
378
|
-
fiobj_json_parser_s p = {.top = FIOBJ_INVALID};
|
|
379
|
-
size_t consumed = fio_json_parse(&p.p, data, len);
|
|
380
|
-
if (!consumed || p.p.depth) {
|
|
381
|
-
fiobj_free(fio_json_stack_get(&p.stack, 0));
|
|
382
|
-
p.top = FIOBJ_INVALID;
|
|
383
|
-
}
|
|
384
|
-
fio_json_stack_free(&p.stack);
|
|
385
|
-
fiobj_free(p.key);
|
|
386
|
-
*pobj = p.top;
|
|
387
|
-
return consumed;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Updates a Hash using JSON data.
|
|
392
|
-
*
|
|
393
|
-
* Parsing errors and non-dictionar object JSON data are silently ignored,
|
|
394
|
-
* attempting to update the Hash as much as possible before any errors
|
|
395
|
-
* encountered.
|
|
396
|
-
*
|
|
397
|
-
* Conflicting Hash data is overwritten (prefering the new over the old).
|
|
398
|
-
*
|
|
399
|
-
* Returns the number of bytes consumed. On Error, 0 is returned and no data is
|
|
400
|
-
* consumed.
|
|
401
|
-
*/
|
|
402
|
-
size_t fiobj_hash_update_json(FIOBJ hash, const void *data, size_t len) {
|
|
403
|
-
if (!hash)
|
|
404
|
-
return 0;
|
|
405
|
-
fiobj_json_parser_s p = {.top = FIOBJ_INVALID, .target = hash};
|
|
406
|
-
size_t consumed = fio_json_parse(&p.p, data, len);
|
|
407
|
-
fio_json_stack_free(&p.stack);
|
|
408
|
-
fiobj_free(p.key);
|
|
409
|
-
if (p.top != hash)
|
|
410
|
-
fiobj_free(p.top);
|
|
411
|
-
return consumed;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Formats an object into a JSON string, appending the JSON string to an
|
|
416
|
-
* existing String. Remember to `fiobj_free`.
|
|
417
|
-
*/
|
|
418
|
-
FIOBJ fiobj_obj2json2(FIOBJ dest, FIOBJ o, uint8_t pretty) {
|
|
419
|
-
assert(dest && FIOBJ_TYPE_IS(dest, FIOBJ_T_STRING));
|
|
420
|
-
if (!o) {
|
|
421
|
-
fiobj_str_write(dest, "null", 4);
|
|
422
|
-
return 0;
|
|
423
|
-
}
|
|
424
|
-
fio_json_stack_s stack = FIO_ARY_INIT;
|
|
425
|
-
obj2json_data_s data = {
|
|
426
|
-
.dest = dest,
|
|
427
|
-
.stack = &stack,
|
|
428
|
-
.pretty = pretty,
|
|
429
|
-
.count = 1,
|
|
430
|
-
};
|
|
431
|
-
if (!o || !FIOBJ_IS_ALLOCATED(o) || !FIOBJECT2VTBL(o)->each) {
|
|
432
|
-
fiobj_obj2json_task(o, &data);
|
|
433
|
-
return dest;
|
|
434
|
-
}
|
|
435
|
-
fiobj_each2(o, fiobj_obj2json_task, &data);
|
|
436
|
-
fio_json_stack_free(&stack);
|
|
437
|
-
return dest;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
/* Formats an object into a JSON string. Remember to `fiobj_free`. */
|
|
441
|
-
FIOBJ fiobj_obj2json(FIOBJ obj, uint8_t pretty) {
|
|
442
|
-
return fiobj_obj2json2(fiobj_str_buf(128), obj, pretty);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/* *****************************************************************************
|
|
446
|
-
Test
|
|
447
|
-
***************************************************************************** */
|
|
448
|
-
|
|
449
|
-
#if DEBUG
|
|
450
|
-
void fiobj_test_json(void) {
|
|
451
|
-
fprintf(stderr, "=== Testing JSON parser (simple test)\n");
|
|
452
|
-
#define TEST_ASSERT(cond, ...) \
|
|
453
|
-
if (!(cond)) { \
|
|
454
|
-
fprintf(stderr, "* " __VA_ARGS__); \
|
|
455
|
-
fprintf(stderr, "\n !!! Testing failed !!!\n"); \
|
|
456
|
-
exit(-1); \
|
|
457
|
-
}
|
|
458
|
-
char json_str[] = "{\"array\":[1,2,3,\"boom\"],\"my\":{\"secret\":42},"
|
|
459
|
-
"\"true\":true,\"false\":false,\"null\":null,\"float\":-2."
|
|
460
|
-
"2,\"string\":\"I \\\"wrote\\\" this.\"}";
|
|
461
|
-
char json_str_update[] = "{\"array\":[1,2,3]}";
|
|
462
|
-
char json_str2[] =
|
|
463
|
-
"[\n \"JSON Test Pattern pass1\",\n {\"object with 1 "
|
|
464
|
-
"member\":[\"array with 1 element\"]},\n {},\n [],\n -42,\n "
|
|
465
|
-
"true,\n false,\n null,\n {\n \"integer\": 1234567890,\n "
|
|
466
|
-
" \"real\": -9876.543210,\n \"e\": 0.123456789e-12,\n "
|
|
467
|
-
" \"E\": 1.234567890E+34,\n \"\": 23456789012E66,\n "
|
|
468
|
-
"\"zero\": 0,\n \"one\": 1,\n \"space\": \" \",\n "
|
|
469
|
-
"\"quote\": \"\\\"\",\n \"backslash\": \"\\\\\",\n "
|
|
470
|
-
"\"controls\": \"\\b\\f\\n\\r\\t\",\n \"slash\": \"/ & \\/\",\n "
|
|
471
|
-
" \"alpha\": \"abcdefghijklmnopqrstuvwyz\",\n \"ALPHA\": "
|
|
472
|
-
"\"ABCDEFGHIJKLMNOPQRSTUVWYZ\",\n \"digit\": \"0123456789\",\n "
|
|
473
|
-
" \"0123456789\": \"digit\",\n \"special\": "
|
|
474
|
-
"\"`1~!@#$%^&*()_+-={':[,]}|;.</>?\",\n \"hex\": "
|
|
475
|
-
"\"\\u0123\\u4567\\u89AB\\uCDEF\\uabcd\\uef4A\",\n \"true\": "
|
|
476
|
-
"true,\n \"false\": false,\n \"null\": null,\n "
|
|
477
|
-
"\"array\":[ ],\n \"object\":{ },\n \"address\": \"50 "
|
|
478
|
-
"St. James Street\",\n \"url\": \"http://www.JSON.org/\",\n "
|
|
479
|
-
" \"comment\": \"// /* <!-- --\",\n \"# -- --> */\": \" \",\n "
|
|
480
|
-
" \" s p a c e d \" :[1,2 , 3\n\n,\n\n4 , 5 , 6 "
|
|
481
|
-
" ,7 ],\"compact\":[1,2,3,4,5,6,7],\n \"jsontext\": "
|
|
482
|
-
"\"{\\\"object with 1 member\\\":[\\\"array with 1 element\\\"]}\",\n "
|
|
483
|
-
" \"quotes\": \"" \\u0022 %22 0x22 034 "\",\n "
|
|
484
|
-
"\"\\/"
|
|
485
|
-
"\\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$"
|
|
486
|
-
"%^&*()_+-=[]{}|;:',./<>?\"\n: \"A key can be any string\"\n },\n "
|
|
487
|
-
"0.5 "
|
|
488
|
-
",98.6\n,\n99.44\n,\n\n1066,\n1e1,\n0.1e1,\n1e-1,\n1e00,2e+00,2e-00\n,"
|
|
489
|
-
"\"rosebud\"]";
|
|
490
|
-
|
|
491
|
-
FIOBJ o = 0;
|
|
492
|
-
TEST_ASSERT(fiobj_json2obj(&o, "1", 2) == 1,
|
|
493
|
-
"JSON number parsing failed to run!\n");
|
|
494
|
-
TEST_ASSERT(o, "JSON (single) object missing!\n");
|
|
495
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(o, FIOBJ_T_NUMBER),
|
|
496
|
-
"JSON (single) not a number!\n");
|
|
497
|
-
TEST_ASSERT(fiobj_obj2num(o) == 1, "JSON (single) not == 1!\n");
|
|
498
|
-
fiobj_free(o);
|
|
499
|
-
|
|
500
|
-
TEST_ASSERT(fiobj_json2obj(&o, "2.0", 5) == 3,
|
|
501
|
-
"JSON float parsing failed to run!\n");
|
|
502
|
-
TEST_ASSERT(o, "JSON (float) object missing!\n");
|
|
503
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(o, FIOBJ_T_FLOAT), "JSON (float) not a float!\n");
|
|
504
|
-
TEST_ASSERT(fiobj_obj2float(o) == 2, "JSON (float) not == 2!\n");
|
|
505
|
-
fiobj_free(o);
|
|
506
|
-
|
|
507
|
-
TEST_ASSERT(fiobj_json2obj(&o, json_str, sizeof(json_str)) ==
|
|
508
|
-
(sizeof(json_str) - 1),
|
|
509
|
-
"JSON parsing failed to run!\n");
|
|
510
|
-
TEST_ASSERT(o, "JSON object missing!\n");
|
|
511
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(o, FIOBJ_T_HASH),
|
|
512
|
-
"JSON root not a dictionary (not a hash)!\n");
|
|
513
|
-
FIOBJ tmp = fiobj_hash_get2(o, fiobj_hash_string("array", 5));
|
|
514
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(tmp, FIOBJ_T_ARRAY),
|
|
515
|
-
"JSON 'array' not an Array!\n");
|
|
516
|
-
TEST_ASSERT(fiobj_obj2num(fiobj_ary_index(tmp, 0)) == 1,
|
|
517
|
-
"JSON 'array' index 0 error!\n");
|
|
518
|
-
TEST_ASSERT(fiobj_obj2num(fiobj_ary_index(tmp, 1)) == 2,
|
|
519
|
-
"JSON 'array' index 1 error!\n");
|
|
520
|
-
TEST_ASSERT(fiobj_obj2num(fiobj_ary_index(tmp, 2)) == 3,
|
|
521
|
-
"JSON 'array' index 2 error!\n");
|
|
522
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(fiobj_ary_index(tmp, 3), FIOBJ_T_STRING),
|
|
523
|
-
"JSON 'array' index 3 type error!\n");
|
|
524
|
-
TEST_ASSERT(!memcmp("boom", fiobj_obj2cstr(fiobj_ary_index(tmp, 3)).data, 4),
|
|
525
|
-
"JSON 'array' index 3 error!\n");
|
|
526
|
-
tmp = fiobj_hash_get2(o, fiobj_hash_string("my", 2));
|
|
527
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(tmp, FIOBJ_T_HASH),
|
|
528
|
-
"JSON 'my:secret' not a Hash!\n");
|
|
529
|
-
TEST_ASSERT(
|
|
530
|
-
FIOBJ_TYPE_IS(fiobj_hash_get2(tmp, fiobj_hash_string("secret", 6)),
|
|
531
|
-
FIOBJ_T_NUMBER),
|
|
532
|
-
"JSON 'my:secret' doesn't hold a number!\n");
|
|
533
|
-
TEST_ASSERT(
|
|
534
|
-
fiobj_obj2num(fiobj_hash_get2(tmp, fiobj_hash_string("secret", 6))) == 42,
|
|
535
|
-
"JSON 'my:secret' not 42!\n");
|
|
536
|
-
TEST_ASSERT(fiobj_hash_get2(o, fiobj_hash_string("true", 4)) == fiobj_true(),
|
|
537
|
-
"JSON 'true' not true!\n");
|
|
538
|
-
TEST_ASSERT(fiobj_hash_get2(o, fiobj_hash_string("false", 5)) ==
|
|
539
|
-
fiobj_false(),
|
|
540
|
-
"JSON 'false' not false!\n");
|
|
541
|
-
TEST_ASSERT(fiobj_hash_get2(o, fiobj_hash_string("null", 4)) == fiobj_null(),
|
|
542
|
-
"JSON 'null' not null!\n");
|
|
543
|
-
tmp = fiobj_hash_get2(o, fiobj_hash_string("float", 5));
|
|
544
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(tmp, FIOBJ_T_FLOAT), "JSON 'float' not a float!\n");
|
|
545
|
-
tmp = fiobj_hash_get2(o, fiobj_hash_string("string", 6));
|
|
546
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(tmp, FIOBJ_T_STRING),
|
|
547
|
-
"JSON 'string' not a string!\n");
|
|
548
|
-
TEST_ASSERT(!strcmp(fiobj_obj2cstr(tmp).data, "I \"wrote\" this."),
|
|
549
|
-
"JSON 'string' incorrect!\n");
|
|
550
|
-
fprintf(stderr, "* passed.\n");
|
|
551
|
-
fprintf(stderr, "=== Testing JSON formatting (simple test)\n");
|
|
552
|
-
tmp = fiobj_obj2json(o, 0);
|
|
553
|
-
fprintf(stderr, "* data (%p):\n%.*s\n", (void *)fiobj_obj2cstr(tmp).data,
|
|
554
|
-
(int)fiobj_obj2cstr(tmp).len, fiobj_obj2cstr(tmp).data);
|
|
555
|
-
if (!strcmp(fiobj_obj2cstr(tmp).data, json_str))
|
|
556
|
-
fprintf(stderr, "* Stringify == Original.\n");
|
|
557
|
-
TEST_ASSERT(
|
|
558
|
-
fiobj_hash_update_json(o, json_str_update, strlen(json_str_update)),
|
|
559
|
-
"JSON update failed to parse data.");
|
|
560
|
-
fiobj_free(tmp);
|
|
561
|
-
|
|
562
|
-
tmp = fiobj_hash_get2(o, fiobj_hash_string("array", 5));
|
|
563
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(tmp, FIOBJ_T_ARRAY),
|
|
564
|
-
"JSON updated 'array' not an Array!\n");
|
|
565
|
-
TEST_ASSERT(fiobj_ary_count(tmp) == 3, "JSON updated 'array' not updated?");
|
|
566
|
-
tmp = fiobj_hash_get2(o, fiobj_hash_string("float", 5));
|
|
567
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(tmp, FIOBJ_T_FLOAT),
|
|
568
|
-
"JSON updated (old) 'float' missing!\n");
|
|
569
|
-
fiobj_free(o);
|
|
570
|
-
fprintf(stderr, "* passed.\n");
|
|
571
|
-
|
|
572
|
-
fprintf(stderr, "=== Testing JSON parsing (UTF-8 and special cases)\n");
|
|
573
|
-
fiobj_json2obj(&o, "[\"\\uD834\\uDD1E\"]", 16);
|
|
574
|
-
TEST_ASSERT(o, "JSON G clef String failed to parse!\n");
|
|
575
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(o, FIOBJ_T_ARRAY),
|
|
576
|
-
"JSON G clef container has an incorrect type! (%s)\n",
|
|
577
|
-
fiobj_type_name(o));
|
|
578
|
-
tmp = o;
|
|
579
|
-
o = fiobj_ary_pop(o);
|
|
580
|
-
fiobj_free(tmp);
|
|
581
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(o, FIOBJ_T_STRING),
|
|
582
|
-
"JSON G clef String incorrect type! %p => %s\n", (void *)o,
|
|
583
|
-
fiobj_type_name(o));
|
|
584
|
-
TEST_ASSERT((!strcmp(fiobj_obj2cstr(o).data, "\xF0\x9D\x84\x9E")),
|
|
585
|
-
"JSON G clef String incorrect %s !\n", fiobj_obj2cstr(o).data);
|
|
586
|
-
fiobj_free(o);
|
|
587
|
-
|
|
588
|
-
fiobj_json2obj(&o, "\"\\uD834\\uDD1E\"", 14);
|
|
589
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(o, FIOBJ_T_STRING),
|
|
590
|
-
"JSON direct G clef String incorrect type! %p => %s\n", (void *)o,
|
|
591
|
-
fiobj_type_name(o));
|
|
592
|
-
TEST_ASSERT((!strcmp(fiobj_obj2cstr(o).data, "\xF0\x9D\x84\x9E")),
|
|
593
|
-
"JSON direct G clef String incorrect %s !\n",
|
|
594
|
-
fiobj_obj2cstr(o).data);
|
|
595
|
-
fiobj_free(o);
|
|
596
|
-
fiobj_json2obj(&o, "\"Hello\\u0000World\"", 19);
|
|
597
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(o, FIOBJ_T_STRING),
|
|
598
|
-
"JSON NUL containing String incorrect type! %p => %s\n",
|
|
599
|
-
(void *)o, fiobj_type_name(o));
|
|
600
|
-
TEST_ASSERT(
|
|
601
|
-
(!memcmp(fiobj_obj2cstr(o).data, "Hello\0World", fiobj_obj2cstr(o).len)),
|
|
602
|
-
"JSON NUL containing String incorrect! (%u): %s . %s\n",
|
|
603
|
-
(int)fiobj_obj2cstr(o).len, fiobj_obj2cstr(o).data,
|
|
604
|
-
fiobj_obj2cstr(o).data + 3);
|
|
605
|
-
fiobj_free(o);
|
|
606
|
-
size_t consumed = fiobj_json2obj(&o, json_str2, sizeof(json_str2));
|
|
607
|
-
TEST_ASSERT(
|
|
608
|
-
consumed == (sizeof(json_str2) - 1),
|
|
609
|
-
"JSON messy string failed to parse (consumed %lu instead of %lu\n",
|
|
610
|
-
(unsigned long)consumed, (unsigned long)(sizeof(json_str2) - 1));
|
|
611
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(o, FIOBJ_T_ARRAY),
|
|
612
|
-
"JSON messy string object error\n");
|
|
613
|
-
tmp = fiobj_obj2json(o, 1);
|
|
614
|
-
TEST_ASSERT(FIOBJ_TYPE_IS(tmp, FIOBJ_T_STRING),
|
|
615
|
-
"JSON messy string isn't a string\n");
|
|
616
|
-
fprintf(stderr, "Messy JSON:\n%s\n", fiobj_obj2cstr(tmp).data);
|
|
617
|
-
fiobj_free(o);
|
|
618
|
-
fiobj_free(tmp);
|
|
619
|
-
fprintf(stderr, "* passed.\n");
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
#endif
|
data/ext/iodine/fiobj_json.h
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
#ifndef H_FIOBJ_JSON_H
|
|
2
|
-
#define H_FIOBJ_JSON_H
|
|
3
|
-
|
|
4
|
-
/*
|
|
5
|
-
Copyright: Boaz Segev, 2017-2019
|
|
6
|
-
License: MIT
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
#include <fiobj_ary.h>
|
|
10
|
-
#include <fiobj_hash.h>
|
|
11
|
-
#include <fiobj_numbers.h>
|
|
12
|
-
#include <fiobj_str.h>
|
|
13
|
-
#include <fiobject.h>
|
|
14
|
-
|
|
15
|
-
#ifdef __cplusplus
|
|
16
|
-
extern "C" {
|
|
17
|
-
#endif
|
|
18
|
-
|
|
19
|
-
/* *****************************************************************************
|
|
20
|
-
JSON API
|
|
21
|
-
***************************************************************************** */
|
|
22
|
-
|
|
23
|
-
/** Limit JSON nesting, 32 is the limit to accomodate a 32 bit type. */
|
|
24
|
-
#if !defined(JSON_MAX_DEPTH) || JSON_MAX_DEPTH > 32
|
|
25
|
-
#undef JSON_MAX_DEPTH
|
|
26
|
-
#define JSON_MAX_DEPTH 32
|
|
27
|
-
#endif
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Parses JSON, setting `pobj` to point to the new Object.
|
|
31
|
-
*
|
|
32
|
-
* Returns the number of bytes consumed. On Error, 0 is returned and no data is
|
|
33
|
-
* consumed.
|
|
34
|
-
*/
|
|
35
|
-
size_t fiobj_json2obj(FIOBJ *pobj, const void *data, size_t len);
|
|
36
|
-
/**
|
|
37
|
-
* Stringify an object into a JSON string. Remember to `fiobj_free`.
|
|
38
|
-
*
|
|
39
|
-
* Note that only the foloowing basic fiobj types are supported: Primitives
|
|
40
|
-
* (True / False / NULL), Numbers (Number / Float), Strings, Hashes and Arrays.
|
|
41
|
-
*
|
|
42
|
-
* Some objects (such as the POSIX specific IO type) are unsupported and may be
|
|
43
|
-
* formatted incorrectly.
|
|
44
|
-
*/
|
|
45
|
-
FIOBJ fiobj_obj2json(FIOBJ, uint8_t pretty);
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Formats an object into a JSON string, appending the JSON string to an
|
|
49
|
-
* existing String. Remember to `fiobj_free` as usual.
|
|
50
|
-
*
|
|
51
|
-
* Note that only the following basic fiobj types are supported: Primitives
|
|
52
|
-
* (True / False / NULL), Numbers (Number / Float), Strings, Hashes and
|
|
53
|
-
* Arrays.
|
|
54
|
-
*
|
|
55
|
-
* Some objects (such as the POSIX specific IO type) are unsupported and may be
|
|
56
|
-
* formatted incorrectly.
|
|
57
|
-
*/
|
|
58
|
-
FIOBJ fiobj_obj2json2(FIOBJ dest, FIOBJ object, uint8_t pretty);
|
|
59
|
-
|
|
60
|
-
#if DEBUG
|
|
61
|
-
void fiobj_test_json(void);
|
|
62
|
-
#endif
|
|
63
|
-
|
|
64
|
-
#ifdef __cplusplus
|
|
65
|
-
} /* extern "C" */
|
|
66
|
-
#endif
|
|
67
|
-
|
|
68
|
-
#endif
|