ffi-hydrogen 0.1.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 +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
|
+
*/
|