ffi-hydrogen 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +30 -0
- data/.travis.yml +10 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +72 -0
- data/Rakefile +46 -0
- data/bench/both.rb +86 -0
- data/bench/encode.rb +57 -0
- data/bench/encrypt.rb +80 -0
- data/bench/init.rb +5 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ffi-hydrogen.gemspec +31 -0
- data/lib/ffi/hydrogen.rb +216 -0
- data/vendor/.clang-format +2 -0
- data/vendor/.gitignore +3 -0
- data/vendor/README.md +2 -0
- data/vendor/libhydrogen/.clang-format +95 -0
- data/vendor/libhydrogen/.gitignore +32 -0
- data/vendor/libhydrogen/.travis.yml +22 -0
- data/vendor/libhydrogen/LICENSE +18 -0
- data/vendor/libhydrogen/Makefile +61 -0
- data/vendor/libhydrogen/Makefile.arduino +51 -0
- data/vendor/libhydrogen/README.md +29 -0
- data/vendor/libhydrogen/hydrogen.c +18 -0
- data/vendor/libhydrogen/hydrogen.h +317 -0
- data/vendor/libhydrogen/impl/common.h +316 -0
- data/vendor/libhydrogen/impl/core.h +220 -0
- data/vendor/libhydrogen/impl/gimli-core/portable.h +39 -0
- data/vendor/libhydrogen/impl/gimli-core/sse2.h +97 -0
- data/vendor/libhydrogen/impl/gimli-core.h +25 -0
- data/vendor/libhydrogen/impl/hash.h +138 -0
- data/vendor/libhydrogen/impl/hydrogen_p.h +83 -0
- data/vendor/libhydrogen/impl/kdf.h +20 -0
- data/vendor/libhydrogen/impl/kx.h +441 -0
- data/vendor/libhydrogen/impl/pwhash.h +281 -0
- data/vendor/libhydrogen/impl/random.h +376 -0
- data/vendor/libhydrogen/impl/secretbox.h +236 -0
- data/vendor/libhydrogen/impl/sign.h +207 -0
- data/vendor/libhydrogen/impl/x25519.h +383 -0
- data/vendor/libhydrogen/library.properties +10 -0
- data/vendor/libhydrogen/logo.png +0 -0
- data/vendor/libhydrogen/tests/tests.c +431 -0
- data/vendor/main.c +140 -0
- data/vendor/stringencoders/.gitignore +25 -0
- data/vendor/stringencoders/.travis.yml +13 -0
- data/vendor/stringencoders/AUTHORS +1 -0
- data/vendor/stringencoders/COPYING +2 -0
- data/vendor/stringencoders/ChangeLog +170 -0
- data/vendor/stringencoders/Doxyfile +276 -0
- data/vendor/stringencoders/INSTALL +119 -0
- data/vendor/stringencoders/LICENSE +22 -0
- data/vendor/stringencoders/Makefile.am +3 -0
- data/vendor/stringencoders/NEWS +3 -0
- data/vendor/stringencoders/README +2 -0
- data/vendor/stringencoders/README.md +32 -0
- data/vendor/stringencoders/bootstrap.sh +3 -0
- data/vendor/stringencoders/configure-gcc-hardened.sh +16 -0
- data/vendor/stringencoders/configure.ac +44 -0
- data/vendor/stringencoders/doxy/footer.html +34 -0
- data/vendor/stringencoders/doxy/header.html +85 -0
- data/vendor/stringencoders/indent.sh +9 -0
- data/vendor/stringencoders/javascript/base64-speed.html +43 -0
- data/vendor/stringencoders/javascript/base64-test.html +209 -0
- data/vendor/stringencoders/javascript/base64.html +18 -0
- data/vendor/stringencoders/javascript/base64.js +176 -0
- data/vendor/stringencoders/javascript/qunit.css +119 -0
- data/vendor/stringencoders/javascript/qunit.js +1062 -0
- data/vendor/stringencoders/javascript/urlparse-test.html +367 -0
- data/vendor/stringencoders/javascript/urlparse.js +328 -0
- data/vendor/stringencoders/make-ci.sh +13 -0
- data/vendor/stringencoders/makerelease.sh +16 -0
- data/vendor/stringencoders/python/b85.py +176 -0
- data/vendor/stringencoders/src/Makefile.am +134 -0
- data/vendor/stringencoders/src/arraytoc.c +85 -0
- data/vendor/stringencoders/src/arraytoc.h +43 -0
- data/vendor/stringencoders/src/extern_c_begin.h +3 -0
- data/vendor/stringencoders/src/extern_c_end.h +3 -0
- data/vendor/stringencoders/src/html_named_entities_generator.py +203 -0
- data/vendor/stringencoders/src/modp_ascii.c +159 -0
- data/vendor/stringencoders/src/modp_ascii.h +162 -0
- data/vendor/stringencoders/src/modp_ascii_data.h +84 -0
- data/vendor/stringencoders/src/modp_ascii_gen.c +55 -0
- data/vendor/stringencoders/src/modp_b16.c +125 -0
- data/vendor/stringencoders/src/modp_b16.h +148 -0
- data/vendor/stringencoders/src/modp_b16_data.h +104 -0
- data/vendor/stringencoders/src/modp_b16_gen.c +65 -0
- data/vendor/stringencoders/src/modp_b2.c +69 -0
- data/vendor/stringencoders/src/modp_b2.h +130 -0
- data/vendor/stringencoders/src/modp_b2_data.h +44 -0
- data/vendor/stringencoders/src/modp_b2_gen.c +36 -0
- data/vendor/stringencoders/src/modp_b36.c +108 -0
- data/vendor/stringencoders/src/modp_b36.h +170 -0
- data/vendor/stringencoders/src/modp_b64.c +254 -0
- data/vendor/stringencoders/src/modp_b64.h +236 -0
- data/vendor/stringencoders/src/modp_b64_data.h +477 -0
- data/vendor/stringencoders/src/modp_b64_gen.c +168 -0
- data/vendor/stringencoders/src/modp_b64r.c +254 -0
- data/vendor/stringencoders/src/modp_b64r.h +242 -0
- data/vendor/stringencoders/src/modp_b64r_data.h +477 -0
- data/vendor/stringencoders/src/modp_b64w.c +254 -0
- data/vendor/stringencoders/src/modp_b64w.h +231 -0
- data/vendor/stringencoders/src/modp_b64w_data.h +477 -0
- data/vendor/stringencoders/src/modp_b85.c +109 -0
- data/vendor/stringencoders/src/modp_b85.h +171 -0
- data/vendor/stringencoders/src/modp_b85_data.h +36 -0
- data/vendor/stringencoders/src/modp_b85_gen.c +65 -0
- data/vendor/stringencoders/src/modp_bjavascript.c +65 -0
- data/vendor/stringencoders/src/modp_bjavascript.h +105 -0
- data/vendor/stringencoders/src/modp_bjavascript_data.h +84 -0
- data/vendor/stringencoders/src/modp_bjavascript_gen.c +58 -0
- data/vendor/stringencoders/src/modp_burl.c +228 -0
- data/vendor/stringencoders/src/modp_burl.h +259 -0
- data/vendor/stringencoders/src/modp_burl_data.h +136 -0
- data/vendor/stringencoders/src/modp_burl_gen.c +121 -0
- data/vendor/stringencoders/src/modp_html.c +128 -0
- data/vendor/stringencoders/src/modp_html.h +53 -0
- data/vendor/stringencoders/src/modp_html_named_entities.h +9910 -0
- data/vendor/stringencoders/src/modp_json.c +315 -0
- data/vendor/stringencoders/src/modp_json.h +103 -0
- data/vendor/stringencoders/src/modp_json_data.h +57 -0
- data/vendor/stringencoders/src/modp_json_gen.py +60 -0
- data/vendor/stringencoders/src/modp_mainpage.h +120 -0
- data/vendor/stringencoders/src/modp_numtoa.c +350 -0
- data/vendor/stringencoders/src/modp_numtoa.h +100 -0
- data/vendor/stringencoders/src/modp_qsiter.c +76 -0
- data/vendor/stringencoders/src/modp_qsiter.h +71 -0
- data/vendor/stringencoders/src/modp_stdint.h +43 -0
- data/vendor/stringencoders/src/modp_utf8.c +88 -0
- data/vendor/stringencoders/src/modp_utf8.h +38 -0
- data/vendor/stringencoders/src/modp_xml.c +311 -0
- data/vendor/stringencoders/src/modp_xml.h +166 -0
- data/vendor/stringencoders/src/stringencoders.pc +10 -0
- data/vendor/stringencoders/src/stringencoders.pc.in +10 -0
- data/vendor/stringencoders/test/Makefile.am +113 -0
- data/vendor/stringencoders/test/apr_base64.c +262 -0
- data/vendor/stringencoders/test/apr_base64.h +120 -0
- data/vendor/stringencoders/test/cxx_test.cc +482 -0
- data/vendor/stringencoders/test/minunit.h +82 -0
- data/vendor/stringencoders/test/modp_ascii_test.c +281 -0
- data/vendor/stringencoders/test/modp_b16_test.c +288 -0
- data/vendor/stringencoders/test/modp_b2_test.c +250 -0
- data/vendor/stringencoders/test/modp_b64_test.c +266 -0
- data/vendor/stringencoders/test/modp_b85_test.c +130 -0
- data/vendor/stringencoders/test/modp_bjavascript_test.c +137 -0
- data/vendor/stringencoders/test/modp_burl_test.c +423 -0
- data/vendor/stringencoders/test/modp_html_test.c +296 -0
- data/vendor/stringencoders/test/modp_json_test.c +336 -0
- data/vendor/stringencoders/test/modp_numtoa_test.c +545 -0
- data/vendor/stringencoders/test/modp_qsiter_test.c +280 -0
- data/vendor/stringencoders/test/modp_utf8_test.c +188 -0
- data/vendor/stringencoders/test/modp_xml_test.c +339 -0
- data/vendor/stringencoders/test/speedtest.c +241 -0
- data/vendor/stringencoders/test/speedtest_ascii.c +345 -0
- data/vendor/stringencoders/test/speedtest_msg.c +78 -0
- data/vendor/stringencoders/test/speedtest_numtoa.c +276 -0
- metadata +314 -0
@@ -0,0 +1,315 @@
|
|
1
|
+
/**
|
2
|
+
* \file
|
3
|
+
* <pre>
|
4
|
+
* modp_json.c High performance JSON encoder/decoder
|
5
|
+
* https://github.com/client9/stringencoders
|
6
|
+
* NOTE THIS IS UNTESTED AND EXPERIMENTAL.
|
7
|
+
*
|
8
|
+
* Copyright © 2006-2016 Nick Galbreath
|
9
|
+
* All rights reserved.
|
10
|
+
* Released under MIT license. See LICENSE for details.
|
11
|
+
* </PRE>
|
12
|
+
*/
|
13
|
+
|
14
|
+
#include "modp_json.h"
|
15
|
+
#include "modp_json_data.h"
|
16
|
+
#include <assert.h>
|
17
|
+
|
18
|
+
typedef enum {
|
19
|
+
JSON_NONE,
|
20
|
+
JSON_MAP_OPEN,
|
21
|
+
JSON_MAP_CLOSE,
|
22
|
+
JSON_MAP_KEY,
|
23
|
+
JSON_MAP_VAL,
|
24
|
+
JSON_ARY_OPEN,
|
25
|
+
JSON_ARY_CLOSE,
|
26
|
+
JSON_ARY_VAL,
|
27
|
+
} json_state_t;
|
28
|
+
|
29
|
+
static size_t modp_bjson_encode_strlen(const char* src, size_t len);
|
30
|
+
static size_t modp_bjson_encode(char* dest, const char* src, size_t len);
|
31
|
+
|
32
|
+
static void modp_json_add_char(modp_json_ctx* ctx, int c);
|
33
|
+
static void modp_json_add_value(modp_json_ctx* ctx);
|
34
|
+
static void modp_json_add_false(modp_json_ctx* ctx);
|
35
|
+
static void modp_json_add_true(modp_json_ctx* ctx);
|
36
|
+
|
37
|
+
static void modp_json_add_char(modp_json_ctx* ctx, int c)
|
38
|
+
{
|
39
|
+
if (ctx->dest) {
|
40
|
+
*(ctx->dest + ctx->size) = (char)c;
|
41
|
+
}
|
42
|
+
ctx->size += 1;
|
43
|
+
}
|
44
|
+
|
45
|
+
static void modp_json_add_value(modp_json_ctx* ctx)
|
46
|
+
{
|
47
|
+
int depth = ctx->depth;
|
48
|
+
|
49
|
+
switch (ctx->state[depth]) {
|
50
|
+
case JSON_NONE:
|
51
|
+
/* no-op */
|
52
|
+
break;
|
53
|
+
case JSON_MAP_OPEN:
|
54
|
+
/* NO comma */
|
55
|
+
ctx->state[depth] = JSON_MAP_KEY;
|
56
|
+
break;
|
57
|
+
case JSON_ARY_OPEN:
|
58
|
+
/* NO comma */
|
59
|
+
ctx->state[depth] = JSON_ARY_VAL;
|
60
|
+
break;
|
61
|
+
case JSON_ARY_VAL:
|
62
|
+
modp_json_add_char(ctx, ',');
|
63
|
+
break;
|
64
|
+
case JSON_MAP_KEY:
|
65
|
+
modp_json_add_char(ctx, ':');
|
66
|
+
ctx->state[depth] = JSON_MAP_VAL;
|
67
|
+
break;
|
68
|
+
case JSON_MAP_VAL:
|
69
|
+
modp_json_add_char(ctx, ',');
|
70
|
+
ctx->state[depth] = JSON_MAP_KEY;
|
71
|
+
break;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
void modp_json_init(modp_json_ctx* ctx, char* dest)
|
76
|
+
{
|
77
|
+
memset((void*)ctx, 0, sizeof(modp_json_ctx));
|
78
|
+
ctx->dest = dest;
|
79
|
+
}
|
80
|
+
|
81
|
+
size_t modp_json_end(modp_json_ctx* ctx)
|
82
|
+
{
|
83
|
+
if (ctx->dest) {
|
84
|
+
*(ctx->dest + ctx->size) = '\0';
|
85
|
+
}
|
86
|
+
return ctx->size;
|
87
|
+
}
|
88
|
+
|
89
|
+
void modp_json_map_open(modp_json_ctx* ctx)
|
90
|
+
{
|
91
|
+
modp_json_add_value(ctx);
|
92
|
+
|
93
|
+
ctx->depth++;
|
94
|
+
ctx->state[ctx->depth] = JSON_MAP_OPEN;
|
95
|
+
|
96
|
+
modp_json_add_char(ctx, '{');
|
97
|
+
}
|
98
|
+
|
99
|
+
void modp_json_map_close(modp_json_ctx* ctx)
|
100
|
+
{
|
101
|
+
assert(ctx->depth > 0);
|
102
|
+
ctx->depth--;
|
103
|
+
modp_json_add_char(ctx, '}');
|
104
|
+
}
|
105
|
+
|
106
|
+
void modp_json_ary_open(modp_json_ctx* ctx)
|
107
|
+
{
|
108
|
+
modp_json_add_value(ctx);
|
109
|
+
ctx->depth++;
|
110
|
+
ctx->state[ctx->depth] = JSON_ARY_OPEN;
|
111
|
+
modp_json_add_char(ctx, '[');
|
112
|
+
}
|
113
|
+
|
114
|
+
void modp_json_ary_close(modp_json_ctx* ctx)
|
115
|
+
{
|
116
|
+
assert(ctx->depth > 0);
|
117
|
+
ctx->depth--;
|
118
|
+
modp_json_add_char(ctx, ']');
|
119
|
+
}
|
120
|
+
|
121
|
+
static void modp_json_add_true(modp_json_ctx* ctx)
|
122
|
+
{
|
123
|
+
char* wstr;
|
124
|
+
if (ctx->dest) {
|
125
|
+
wstr = ctx->dest + ctx->size;
|
126
|
+
wstr[0] = 't';
|
127
|
+
wstr[1] = 'r';
|
128
|
+
wstr[2] = 'u';
|
129
|
+
wstr[3] = 'e';
|
130
|
+
}
|
131
|
+
ctx->size += 4;
|
132
|
+
}
|
133
|
+
|
134
|
+
static void modp_json_add_false(modp_json_ctx* ctx)
|
135
|
+
{
|
136
|
+
char* wstr;
|
137
|
+
|
138
|
+
if (ctx->dest) {
|
139
|
+
wstr = ctx->dest + ctx->size;
|
140
|
+
wstr[0] = 'f';
|
141
|
+
wstr[1] = 'a';
|
142
|
+
wstr[2] = 'l';
|
143
|
+
wstr[3] = 's';
|
144
|
+
wstr[4] = 'e';
|
145
|
+
}
|
146
|
+
ctx->size += 5;
|
147
|
+
}
|
148
|
+
|
149
|
+
void modp_json_add_bool(modp_json_ctx* ctx, int val)
|
150
|
+
{
|
151
|
+
|
152
|
+
modp_json_add_value(ctx);
|
153
|
+
|
154
|
+
if (val) {
|
155
|
+
modp_json_add_true(ctx);
|
156
|
+
} else {
|
157
|
+
modp_json_add_false(ctx);
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
void modp_json_add_null(modp_json_ctx* ctx)
|
162
|
+
{
|
163
|
+
char* wstr;
|
164
|
+
|
165
|
+
modp_json_add_value(ctx);
|
166
|
+
|
167
|
+
if (ctx->dest) {
|
168
|
+
wstr = ctx->dest + ctx->size;
|
169
|
+
wstr[0] = 'n';
|
170
|
+
wstr[1] = 'u';
|
171
|
+
wstr[2] = 'l';
|
172
|
+
wstr[3] = 'l';
|
173
|
+
}
|
174
|
+
ctx->size += 4;
|
175
|
+
}
|
176
|
+
|
177
|
+
void modp_json_add_uint64(modp_json_ctx* ctx, uint64_t uv,
|
178
|
+
int stringonly)
|
179
|
+
{
|
180
|
+
size_t r = (uv >= 10000000000000000000ULL) ? 20 : (uv >= 1000000000000000000ULL) ? 19 : (uv >= 100000000000000000ULL) ? 18 : (uv >= 10000000000000000ULL) ? 17 : (uv >= 1000000000000000ULL) ? 16 : (uv >= 100000000000000ULL) ? 15 : (uv >= 10000000000000ULL) ? 14 : (uv >= 1000000000000ULL) ? 13 : (uv >= 100000000000ULL) ? 12 : (uv >= 10000000000ULL) ? 11 : (uv >= 1000000000ULL) ? 10 : (uv >= 100000000ULL) ? 9 : (uv >= 10000000ULL) ? 8 : (uv >= 1000000ULL) ? 7 : (uv >= 100000ULL) ? 6 : (uv >= 10000ULL) ? 5 : (uv >= 1000ULL) ? 4 : (uv >= 100ULL) ? 3 : (uv >= 10ULL) ? 2 : 1ULL;
|
181
|
+
|
182
|
+
if (uv > (1ULL << 53)) {
|
183
|
+
stringonly = 1;
|
184
|
+
}
|
185
|
+
|
186
|
+
modp_json_add_value(ctx);
|
187
|
+
|
188
|
+
if (ctx->dest) {
|
189
|
+
char* wstr = ctx->dest + ctx->size;
|
190
|
+
if (stringonly) {
|
191
|
+
wstr[0] = '"';
|
192
|
+
wstr[r + 1] = '"';
|
193
|
+
wstr += r;
|
194
|
+
} else {
|
195
|
+
wstr += r - 1;
|
196
|
+
}
|
197
|
+
|
198
|
+
/* Conversion. Number is reversed. */
|
199
|
+
do
|
200
|
+
*wstr-- = (char)(48 + (uv % 10));
|
201
|
+
while (uv /= 10);
|
202
|
+
}
|
203
|
+
|
204
|
+
if (stringonly) {
|
205
|
+
r += 2;
|
206
|
+
}
|
207
|
+
|
208
|
+
ctx->size += r;
|
209
|
+
}
|
210
|
+
|
211
|
+
void modp_json_add_int32(modp_json_ctx* ctx, int v)
|
212
|
+
{
|
213
|
+
char* wstr;
|
214
|
+
if (v > 0) {
|
215
|
+
return modp_json_add_uint32(ctx, (uint32_t)v);
|
216
|
+
}
|
217
|
+
uint32_t uv = (uint32_t)(-v);
|
218
|
+
size_t r = (uv >= 1000000000) ? 10 : (uv >= 100000000) ? 9 : (uv >= 10000000) ? 8 : (uv >= 1000000) ? 7 : (uv >= 100000) ? 6 : (uv >= 10000) ? 5 : (uv >= 1000) ? 4 : (uv >= 100) ? 3 : (uv >= 10) ? 2 : 1;
|
219
|
+
|
220
|
+
modp_json_add_value(ctx);
|
221
|
+
|
222
|
+
if (ctx->dest) {
|
223
|
+
wstr = ctx->dest + ctx->size;
|
224
|
+
*wstr = '-';
|
225
|
+
wstr += r;
|
226
|
+
/* Conversion. Number is reversed. */
|
227
|
+
do
|
228
|
+
*wstr-- = (char)(48 + (uv % 10));
|
229
|
+
while (uv /= 10);
|
230
|
+
}
|
231
|
+
|
232
|
+
ctx->size += r + 1; /* +1 for '-' minus sign */
|
233
|
+
}
|
234
|
+
|
235
|
+
void modp_json_add_uint32(modp_json_ctx* ctx, uint32_t uv)
|
236
|
+
{
|
237
|
+
char* wstr;
|
238
|
+
size_t r = (uv >= 1000000000UL) ? 10 : (uv >= 100000000UL) ? 9 : (uv >= 10000000UL) ? 8 : (uv >= 1000000UL) ? 7 : (uv >= 100000UL) ? 6 : (uv >= 10000UL) ? 5 : (uv >= 1000UL) ? 4 : (uv >= 100UL) ? 3 : (uv >= 10UL) ? 2 : 1UL;
|
239
|
+
|
240
|
+
modp_json_add_value(ctx);
|
241
|
+
|
242
|
+
if (ctx->dest) {
|
243
|
+
wstr = ctx->dest + ctx->size;
|
244
|
+
wstr += r - 1;
|
245
|
+
do
|
246
|
+
*wstr-- = (char)(48 + (uv % 10));
|
247
|
+
while (uv /= 10);
|
248
|
+
}
|
249
|
+
|
250
|
+
ctx->size += r;
|
251
|
+
}
|
252
|
+
|
253
|
+
void modp_json_add_cstring(modp_json_ctx* ctx, const char* src)
|
254
|
+
{
|
255
|
+
return modp_json_add_string(ctx, src, strlen(src));
|
256
|
+
}
|
257
|
+
|
258
|
+
void modp_json_add_string(modp_json_ctx* ctx, const char* src, size_t len)
|
259
|
+
{
|
260
|
+
modp_json_add_value(ctx);
|
261
|
+
|
262
|
+
if (ctx->dest) {
|
263
|
+
ctx->size += modp_bjson_encode(ctx->dest + ctx->size, src, len);
|
264
|
+
} else {
|
265
|
+
ctx->size += modp_bjson_encode_strlen(src, len);
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
static size_t modp_bjson_encode(char* dest, const char* src, size_t len)
|
270
|
+
{
|
271
|
+
static const char* hexchar = "0123456789ABCDEF";
|
272
|
+
const char* deststart = (const char*)dest;
|
273
|
+
const uint8_t* s = (const uint8_t*)src;
|
274
|
+
const uint8_t* srcend = s + len;
|
275
|
+
uint8_t x;
|
276
|
+
uint8_t val;
|
277
|
+
|
278
|
+
*dest++ = '"';
|
279
|
+
|
280
|
+
while (s < srcend) {
|
281
|
+
x = *s++;
|
282
|
+
val = gsJSONEncodeMap[x];
|
283
|
+
if (val == 'a') {
|
284
|
+
/* a for ascii, as-is */
|
285
|
+
*dest++ = (char)x;
|
286
|
+
} else if (val == 'u') {
|
287
|
+
/* u for unicode, 6 byte escape sequence */
|
288
|
+
dest[0] = '\\';
|
289
|
+
dest[1] = 'u';
|
290
|
+
dest[2] = '0';
|
291
|
+
dest[3] = '0';
|
292
|
+
dest[4] = hexchar[x >> 4];
|
293
|
+
dest[5] = hexchar[x & 0x0F];
|
294
|
+
dest += 6;
|
295
|
+
} else {
|
296
|
+
/* 2 byte escape sequence */
|
297
|
+
dest[0] = '\\';
|
298
|
+
dest[1] = (char)val;
|
299
|
+
dest += 2;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
*dest++ = '"';
|
303
|
+
return (size_t)(dest - deststart);
|
304
|
+
}
|
305
|
+
|
306
|
+
static size_t modp_bjson_encode_strlen(const char* src, size_t len)
|
307
|
+
{
|
308
|
+
const uint8_t* s = (const uint8_t*)src;
|
309
|
+
const uint8_t* srcend = s + len;
|
310
|
+
size_t count = 2; /* for start and end quotes */
|
311
|
+
while (s < srcend) {
|
312
|
+
count += (gsJSONEncodeLenMap[*s++]);
|
313
|
+
}
|
314
|
+
return count;
|
315
|
+
}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
/**
|
2
|
+
* \file modp_json.h
|
3
|
+
* \brief ad-hoc json generator
|
4
|
+
*
|
5
|
+
* Used to serialize data structures.
|
6
|
+
*
|
7
|
+
* There is no decoder.
|
8
|
+
*/
|
9
|
+
|
10
|
+
/*
|
11
|
+
* <PRE>
|
12
|
+
* High Performance c-string to javascript-string encoder
|
13
|
+
*
|
14
|
+
* Copyright © 2014-2016 Nick Galbreath
|
15
|
+
* All rights reserved.
|
16
|
+
*
|
17
|
+
* https://github.com/client9/stringencoders
|
18
|
+
*
|
19
|
+
* Released under MIT license. See LICENSE for details.
|
20
|
+
* </PRE>
|
21
|
+
*/
|
22
|
+
|
23
|
+
#ifndef COM_MODP_STRINGENCODERS_BJSON
|
24
|
+
#define COM_MODP_STRINGENCODERS_BJSON
|
25
|
+
|
26
|
+
#ifdef __cplusplus
|
27
|
+
#ifndef MODP_C_BEGIN_DECLS
|
28
|
+
#define MODP_C_BEGIN_DECLS extern "C" {
|
29
|
+
#define MODP_C_END_DECLS }
|
30
|
+
#endif
|
31
|
+
#else
|
32
|
+
#define MODP_C_BEGIN_DECLS
|
33
|
+
#define MODP_C_END_DECLS
|
34
|
+
#endif
|
35
|
+
|
36
|
+
MODP_C_BEGIN_DECLS
|
37
|
+
|
38
|
+
#ifndef JSON_MAX_DEPTH
|
39
|
+
#define JSON_MAX_DEPTH 10
|
40
|
+
#endif
|
41
|
+
|
42
|
+
/* pull in size_t */
|
43
|
+
#include <stdint.h>
|
44
|
+
#include <string.h>
|
45
|
+
|
46
|
+
typedef struct {
|
47
|
+
int depth;
|
48
|
+
int state[JSON_MAX_DEPTH];
|
49
|
+
size_t size;
|
50
|
+
char* dest;
|
51
|
+
} modp_json_ctx;
|
52
|
+
|
53
|
+
void modp_json_init(modp_json_ctx* ctx, char* dest);
|
54
|
+
size_t modp_json_end(modp_json_ctx* ctx);
|
55
|
+
void modp_json_map_open(modp_json_ctx* ctx);
|
56
|
+
void modp_json_map_close(modp_json_ctx* ctx);
|
57
|
+
void modp_json_ary_open(modp_json_ctx* ctx);
|
58
|
+
void modp_json_ary_close(modp_json_ctx* ctx);
|
59
|
+
|
60
|
+
/*
|
61
|
+
*
|
62
|
+
* Note: to add a 'null string' explicitly use 'add_null' and do NOT
|
63
|
+
* pass in a null pointer here.
|
64
|
+
*/
|
65
|
+
void modp_json_add_string(modp_json_ctx* ctx, const char*, size_t);
|
66
|
+
|
67
|
+
void modp_json_add_cstring(modp_json_ctx* ctx, const char*);
|
68
|
+
|
69
|
+
/*
|
70
|
+
* Sets a json 'false' value if val = 0, other wise sets a 'true' value
|
71
|
+
*/
|
72
|
+
void modp_json_add_bool(modp_json_ctx* ctx, int val);
|
73
|
+
|
74
|
+
void modp_json_add_double(modp_json_ctx* ctx, double d);
|
75
|
+
|
76
|
+
void modp_json_add_int32(modp_json_ctx* ctx, int val);
|
77
|
+
|
78
|
+
void modp_json_add_uint32(modp_json_ctx* ctx, uint32_t val);
|
79
|
+
|
80
|
+
/**
|
81
|
+
* JSON/Javascript only supports a single number type represented by a
|
82
|
+
* 64-bit IEEE floating-point value. This means JSON can not exactly
|
83
|
+
* represent a full 64-bit integer since the mantissa of a double is
|
84
|
+
* only 53 bits. If the input integer needs more than 53 bits then
|
85
|
+
* the value is stored as string "1234567899329342" instead of a
|
86
|
+
* raw/naked numeric value. If you wish to anyways represent 64-bit
|
87
|
+
* integers as a string, use stringonly=1. If you wish to never
|
88
|
+
* casting to a string, use add_uint32 or add_int32 which can be
|
89
|
+
* expressed directly or consider loosing precession and cast to a
|
90
|
+
* double value.
|
91
|
+
*
|
92
|
+
*/
|
93
|
+
void modp_json_add_uint64(modp_json_ctx* ctx, uint64_t val,
|
94
|
+
int stringonly);
|
95
|
+
|
96
|
+
/*
|
97
|
+
* explicitly add a null type
|
98
|
+
*/
|
99
|
+
void modp_json_add_null(modp_json_ctx* ctx);
|
100
|
+
|
101
|
+
MODP_C_END_DECLS
|
102
|
+
|
103
|
+
#endif /* modp_bjson */
|
@@ -0,0 +1,57 @@
|
|
1
|
+
static const uint8_t gsJSONEncodeMap[256] = {
|
2
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't',
|
3
|
+
'n', 'u', 'f', 'r', 'u', 'u', 'u', 'u', 'u', 'u',
|
4
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
5
|
+
'u', 'u', 'a', 'a', '"', 'a', 'a', 'a', 'a', 'a',
|
6
|
+
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
7
|
+
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
8
|
+
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
9
|
+
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
10
|
+
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
11
|
+
'a', 'a', '\\', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
12
|
+
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
13
|
+
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
14
|
+
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'u', 'u',
|
15
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
16
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
17
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
18
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
19
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
20
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
21
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
22
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
23
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
24
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
25
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
26
|
+
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
|
27
|
+
'u', 'u', 'u', 'u', 'u', 'u',
|
28
|
+
};
|
29
|
+
|
30
|
+
static const size_t gsJSONEncodeLenMap[256] = {
|
31
|
+
6, 6, 6, 6, 6, 6, 6, 6, 2, 2,
|
32
|
+
2, 6, 2, 2, 6, 6, 6, 6, 6, 6,
|
33
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
34
|
+
6, 6, 1, 1, 2, 1, 1, 1, 1, 1,
|
35
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
36
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
37
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
38
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
39
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
40
|
+
1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
|
41
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
42
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
43
|
+
1, 1, 1, 1, 1, 1, 1, 1, 6, 6,
|
44
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
45
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
46
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
47
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
48
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
49
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
50
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
51
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
52
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
53
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
54
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
55
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
56
|
+
6, 6, 6, 6, 6, 6,
|
57
|
+
};
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
def intarray_to_c(ary, name):
|
4
|
+
parts = []
|
5
|
+
parts.append("static const size_t {0}[{1}] = {{".format(name,len(ary)))
|
6
|
+
count = 0
|
7
|
+
for val in ary:
|
8
|
+
if (count % 10 == 0):
|
9
|
+
parts.append("\n ")
|
10
|
+
parts.append("{0}, ".format(val))
|
11
|
+
count += 1
|
12
|
+
parts.append("\n};\n")
|
13
|
+
return ''.join(parts)
|
14
|
+
|
15
|
+
def chararray_to_c(ary, name):
|
16
|
+
parts = []
|
17
|
+
parts.append("static const uint8_t {0}[{1}] = {{".format(name,
|
18
|
+
len(ary)))
|
19
|
+
count = 0;
|
20
|
+
for val in ary:
|
21
|
+
if (count % 10 == 0):
|
22
|
+
parts.append("\n ")
|
23
|
+
parts.append("{0:>6}".format("'" + val + "',"))
|
24
|
+
count += 1
|
25
|
+
|
26
|
+
parts.append("\n};\n")
|
27
|
+
return ''.join(parts)
|
28
|
+
|
29
|
+
def json_encodelen_map():
|
30
|
+
lenmap = [ 6 for i in range(256) ]
|
31
|
+
for i in range(32,128):
|
32
|
+
lenmap[i] = 1
|
33
|
+
for i in [0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x5c, 0x22]:
|
34
|
+
lenmap[i] = 2
|
35
|
+
return lenmap
|
36
|
+
|
37
|
+
def json_encode_map():
|
38
|
+
encodemap = [ 'u' for i in range(256) ]
|
39
|
+
|
40
|
+
# things to quad-hex encode \u00XY
|
41
|
+
for i in range(32,128):
|
42
|
+
encodemap[i] = 'a';
|
43
|
+
|
44
|
+
# special escapes
|
45
|
+
encodemap[0x08] = 'b'
|
46
|
+
encodemap[0x09] = 't'
|
47
|
+
encodemap[0x0a] = 'n'
|
48
|
+
encodemap[0x0c] = 'f'
|
49
|
+
encodemap[0x0d] = 'r'
|
50
|
+
encodemap[0x5c] = "\\\\"
|
51
|
+
encodemap[0x22] = "\""
|
52
|
+
|
53
|
+
return encodemap
|
54
|
+
|
55
|
+
if __name__ == '__main__':
|
56
|
+
|
57
|
+
with open('modp_json_data.h', 'w') as fd:
|
58
|
+
fd.write(chararray_to_c(json_encode_map(), "gsJSONEncodeMap"))
|
59
|
+
fd.write("\n")
|
60
|
+
fd.write(intarray_to_c(json_encodelen_map(), "gsJSONEncodeLenMap"))
|
@@ -0,0 +1,120 @@
|
|
1
|
+
/**
|
2
|
+
* \mainpage
|
3
|
+
*
|
4
|
+
* The modp_b family of encoders/decoders.
|
5
|
+
*
|
6
|
+
* Most have a similar interface:
|
7
|
+
* - modp_bXXX_encode(char* dest, char* src, int len) -- encodes src, and puts the result in dest. The caller allocates dest. It returns the strlen of the output.
|
8
|
+
* - modp_bXXX_encode_len(int len) -- returns the amount of memory needed to be allocated BEFORE calling _encode.
|
9
|
+
* - modp_bXXX_encode_strlen(int len) -- returns the strlen of the encoded output (but without doing the encode operation)
|
10
|
+
* - modp_bXXX_decode(char* dest, char* src, int len) -- decodes src and puts result in dest. Returns the number of bytes written.
|
11
|
+
* - modp_bXXX_decode_len(int len) -- the amount of memory needed to decode.
|
12
|
+
*
|
13
|
+
* The header files all include a sample C++ std::string wrapper.
|
14
|
+
*
|
15
|
+
* In addition:
|
16
|
+
* - modp_numtoa.h defines fast integer and float types to char buffer converts.
|
17
|
+
* - modp_ascii.h defines fast toupper, tolower transformations.
|
18
|
+
*
|
19
|
+
* \section modp_b64
|
20
|
+
*
|
21
|
+
* Converts 3 bytes into 4 characters, for 1.33 expansion ratio. This
|
22
|
+
* version is ridiculously fast -- on some platforms the decode
|
23
|
+
* operation is 4x faster than a standard implementation.
|
24
|
+
*
|
25
|
+
* See modp_b64.h for details
|
26
|
+
*
|
27
|
+
* \section modp_b64w
|
28
|
+
*
|
29
|
+
* Does the same type of transformation as modp_b64 but uses a
|
30
|
+
* slightly different alphabet to make it "safe" to use inside a URL.
|
31
|
+
* The mapping is: "/" to "_", * "+" to "-", * "=" to "." If you are
|
32
|
+
* intergating with another base64 encoder, you may need to change
|
33
|
+
* this.
|
34
|
+
*
|
35
|
+
* See modp_b64w.h for details.
|
36
|
+
*
|
37
|
+
*
|
38
|
+
* \section modp_b16
|
39
|
+
*
|
40
|
+
* This is the standard "binary to ascii" encoding that convert 1 byte
|
41
|
+
* into two chars (0-9, a-f). It's actually slower than base64 so
|
42
|
+
* there is not reason to use this except for legacy applications.
|
43
|
+
* (how can this be? Because on decode we have to read 4 bytes to get
|
44
|
+
* 2. and in base64 we read 4 bytes to get 3, so base64's loop is
|
45
|
+
* shorter).
|
46
|
+
*
|
47
|
+
* See modp_b16.h for details
|
48
|
+
*
|
49
|
+
* \section modp_b85
|
50
|
+
*
|
51
|
+
* Base 85 is the "most dense ascii encoding" possible, converting 4
|
52
|
+
* bytes into 5 chars (1.2). The output is 11% smaller than base 64
|
53
|
+
* (1.33/1.2), but unfortunately, it's about twice as slow as base-64
|
54
|
+
* encoding since true division has to be used (instead of raw bit
|
55
|
+
* operations).
|
56
|
+
*
|
57
|
+
* See modp_b85.h for details
|
58
|
+
*
|
59
|
+
* \section mod_b2
|
60
|
+
*
|
61
|
+
* Converts the given string to a base 2 or binary encoding (all
|
62
|
+
* 1s and 0s). For useful for debugging.
|
63
|
+
*
|
64
|
+
* See modp_b2.h for details
|
65
|
+
*
|
66
|
+
* \section modp_burl
|
67
|
+
*
|
68
|
+
* This performs url-encoding and url-decoding. While not a true base
|
69
|
+
* converted like the others, it does use an optimized base-16
|
70
|
+
* converter for the encoded "%XY" data. This has an alternate
|
71
|
+
* encoder that provides a minimal encoding, modp_burl_min_encode.
|
72
|
+
*
|
73
|
+
* See modp_burl.h for details
|
74
|
+
*
|
75
|
+
* \section modp_bjavascript
|
76
|
+
*
|
77
|
+
* Converts a raw c-string into something that can be enbedded into
|
78
|
+
* javascript. This might be useful for server-generated dynamic
|
79
|
+
* javascript. There is no decode function provided. This is only
|
80
|
+
* use when generating raw "text/javascript" files. It is <b>NOT</b>
|
81
|
+
* safe to make javascript that will ultimately be embedded inside
|
82
|
+
* HTML via script tags.
|
83
|
+
*
|
84
|
+
* See modp_bjavascript.h for details
|
85
|
+
*
|
86
|
+
* \section modp_xml
|
87
|
+
*
|
88
|
+
* An experimental XML decoder.
|
89
|
+
*
|
90
|
+
* See modp_xml.h for details
|
91
|
+
*
|
92
|
+
* \section modp_numtoa
|
93
|
+
*
|
94
|
+
* The functions modp_itoa, modp_uitoa, modp_dtoa converts signed integers,
|
95
|
+
* unsigned integers, and 'double' type conversion to char buffer (string).
|
96
|
+
* The advantages over sprintf/snprintf are
|
97
|
+
* - core dump proof
|
98
|
+
* - have a fixed maximum size (e.g. try printf("%f", 2.0e100) for example)
|
99
|
+
* - 5-22x faster!
|
100
|
+
*
|
101
|
+
* See modp_numtoa.h for details
|
102
|
+
*
|
103
|
+
* \section modp_ascii
|
104
|
+
*
|
105
|
+
* modp_toupper and modp_tolower upper or lower case a string using
|
106
|
+
* the standard C locale (i.e. 7-bit ascii). These are 2-22x faster
|
107
|
+
* than using standard ctype functions. Also include is "toprint"
|
108
|
+
* which replaces "unprintable" characters with a "?".
|
109
|
+
*
|
110
|
+
* See modp_ascii.h for details
|
111
|
+
*
|
112
|
+
* \section modp_qsiter
|
113
|
+
*
|
114
|
+
* URL Query string key-value pair iterator. Uses no heap, makes no
|
115
|
+
* copy, makes no modification of input. Think of this as a
|
116
|
+
* super-strtok_r.
|
117
|
+
*
|
118
|
+
* See modp_qsiter.h for details
|
119
|
+
*
|
120
|
+
*/
|