json-as 0.5.37 → 0.5.39

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.
@@ -1,25 +1,25 @@
1
1
  import { StringSink } from "as-string-sink/assembly";
2
- import { isSpace } from "util/string";
2
+ import { isSpace, CharCode } from "util/string";
3
3
  import {
4
- backSlashCode,
5
- commaCode,
6
- commaWord,
7
- eCode,
8
- fCode,
9
- leftBraceCode,
10
- leftBracketCode,
11
- leftBracketWord,
12
- nCode,
13
- nullWord,
14
- quoteCode,
15
- rCode,
16
- rightBraceCode,
17
- rightBracketCode,
18
- rightBracketWord,
19
- tCode,
20
- trueWord,
21
- uCode,
22
- emptyArrayWord
4
+ backSlashCode,
5
+ commaCode,
6
+ commaWord,
7
+ eCode,
8
+ fCode,
9
+ leftBraceCode,
10
+ leftBracketCode,
11
+ leftBracketWord,
12
+ nCode,
13
+ nullWord,
14
+ quoteCode,
15
+ rCode,
16
+ rightBraceCode,
17
+ rightBracketCode,
18
+ rightBracketWord,
19
+ tCode,
20
+ trueWord,
21
+ uCode,
22
+ emptyArrayWord,
23
23
  } from "./chars";
24
24
  import { parseSciInteger, unsafeCharCodeAt } from "./util";
25
25
 
@@ -27,623 +27,675 @@ import { parseSciInteger, unsafeCharCodeAt } from "./util";
27
27
  * JSON Encoder/Decoder for AssemblyScript
28
28
  */
29
29
  export namespace JSON {
30
- /**
31
- * Stringifies valid JSON data.
32
- * ```js
33
- * JSON.stringify<T>(data)
34
- * ```
35
- * @param data T
36
- * @returns string
37
- */
38
- export function stringify<T>(data: T): string {
39
- // String
40
- if (isString<T>() && data != null) {
41
- // @ts-ignore
42
- return serializeString(data);
43
- } else if (isBoolean<T>()) {
44
- return data ? "true" : "false";
45
- } else if (isNullable<T>() && data == null) {
46
- return "null";
47
- // @ts-ignore
48
- } else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
49
- // @ts-ignore
50
- return data.toString();
51
- // @ts-ignore
52
- } else if (isDefined(data.__JSON_Serialize)) {
53
- // @ts-ignore
54
- return data.__JSON_Serialize();
55
- } else if (data instanceof Date) {
56
- return data.toISOString();
57
- } else if (isArrayLike<T>()) {
58
- // @ts-ignore
59
- if (data.length == 0) {
60
- return emptyArrayWord;
61
- // @ts-ignore
62
- } else if (isString<valueof<T>>()) {
63
- let result = "[";
64
- // @ts-ignore
65
- for (let i = 0; i < data.length - 1; i++) {
66
- // @ts-ignore
67
- result += serializeString(unchecked(data[i]));
68
- result += commaWord;
69
- }
70
- // @ts-ignore
71
- result += serializeString(unchecked(data[data.length - 1]));
72
- result += rightBracketWord;
73
- return result;
74
- // @ts-ignore
75
- } else if (isBoolean<valueof<T>>()) {
76
- // @ts-ignore
77
- return leftBracketWord + data.join(commaWord) + rightBracketWord;
78
- // @ts-ignore
79
- } else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
80
- // @ts-ignore
81
- return leftBracketWord + data.join(commaWord) + rightBracketWord;
82
- } else {
83
- let result = new StringSink(leftBracketWord);
84
- // @ts-ignore
85
- for (let i = 0; i < data.length - 1; i++) {
86
- // @ts-ignore
87
- result.write(JSON.stringify(unchecked(data[i])));
88
- result.write(commaWord);
89
- }
90
- // @ts-ignore
91
- result.write(JSON.stringify(unchecked(data[data.length - 1])));
92
- result.write(rightBracketWord);
93
- return result.toString();
94
- }
95
- } else {
96
- throw new Error(`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
30
+ /**
31
+ * Stringifies valid JSON data.
32
+ * ```js
33
+ * JSON.stringify<T>(data)
34
+ * ```
35
+ * @param data T
36
+ * @returns string
37
+ */
38
+ // @ts-ignore
39
+ @inline export function stringify<
40
+ T
41
+ >(data: T): string {
42
+ // String
43
+ if (isString<T>() && data != null) {
44
+ // @ts-ignore
45
+ return serializeString(data);
46
+ } else if (isBoolean<T>()) {
47
+ return data ? "true" : "false";
48
+ } else if (isNullable<T>() && data == null) {
49
+ return "null";
50
+ // @ts-ignore
51
+ } else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
52
+ // @ts-ignore
53
+ return data.toString();
54
+ // @ts-ignore
55
+ } else if (isDefined(data.__JSON_Serialize)) {
56
+ // @ts-ignore
57
+ return data.__JSON_Serialize();
58
+ } else if (data instanceof Date) {
59
+ return data.toISOString();
60
+ } else if (isArrayLike<T>()) {
61
+ // @ts-ignore
62
+ if (data.length == 0) {
63
+ return emptyArrayWord;
64
+ // @ts-ignore
65
+ } else if (isString<valueof<T>>()) {
66
+ let result = "[";
67
+ // @ts-ignore
68
+ for (let i = 0; i < data.length - 1; i++) {
69
+ // @ts-ignore
70
+ result += serializeString(unchecked(data[i]));
71
+ result += commaWord;
97
72
  }
98
- }
99
- /**
100
- * Parses valid JSON strings into their original format.
101
- * ```js
102
- * JSON.parse<T>(data)
103
- * ```
104
- * @param data string
105
- * @returns T
106
- */
107
- // @ts-ignore
108
- export function parse<T>(data: string): T {
109
- let type: T;
110
- if (isString<T>()) {
111
- // @ts-ignore
112
- return parseString(data);
113
- } else if (isBoolean<T>()) {
114
- // @ts-ignore
115
- return parseBoolean<T>(data);
116
- } else if (isFloat<T>() || isInteger<T>()) {
117
- return parseNumber<T>(data);
118
- } else if (isArrayLike<T>()) {
119
- // @ts-ignore
120
- return parseArray<T>(data.trimStart());
121
- // @ts-ignore
122
- } else if (isNullable<T>() && data == "null") {
123
- // @ts-ignore
124
- return null;
125
- // @ts-ignore
126
- } else if (isDefined(type.__JSON_Set_Key)) {
127
- return parseObject<T>(data.trimStart());
128
- } else if (idof<nonnull<T>>() == idof<Date>()) {
129
- // @ts-ignore
130
- return Date.fromString(data);
131
- } else {
132
- // @ts-ignore
133
- throw new Error(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
73
+ // @ts-ignore
74
+ result += serializeString(unchecked(data[data.length - 1]));
75
+ result += rightBracketWord;
76
+ return result;
77
+ // @ts-ignore
78
+ } else if (isBoolean<valueof<T>>()) {
79
+ // @ts-ignore
80
+ return leftBracketWord + data.join(commaWord) + rightBracketWord;
81
+ // @ts-ignore
82
+ } else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
83
+ // @ts-ignore
84
+ return leftBracketWord + data.join(commaWord) + rightBracketWord;
85
+ } else {
86
+ let result = new StringSink(leftBracketWord);
87
+ // @ts-ignore
88
+ for (let i = 0; i < data.length - 1; i++) {
89
+ // @ts-ignore
90
+ result.write(JSON.stringify(unchecked(data[i])));
91
+ result.write(commaWord);
134
92
  }
93
+ // @ts-ignore
94
+ result.write(JSON.stringify(unchecked(data[data.length - 1])));
95
+ result.write(rightBracketWord);
96
+ return result.toString();
97
+ }
98
+ } else {
99
+ throw new Error(
100
+ `Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
101
+ );
135
102
  }
136
- // @ts-ignore
137
- function parseObjectValue<T>(data: string): T {
138
- let type: T;
139
- if (isString<T>()) {
140
- // @ts-ignore
141
- let result = "";
142
- let last = 0;
143
- let char = 0;
144
- for (let i = 0; i < data.length; i++) {
145
- // \\"
146
- if (unsafeCharCodeAt(data, i) === backSlashCode) {
147
- char = unsafeCharCodeAt(data, ++i);
148
- result += data.slice(last, i - 1)
149
- if (char === 34) {
150
- result += "\"";
151
- last = ++i;
152
- } else if (char === 110) {
153
- result += "\n";
154
- last = ++i;
155
- // 92 98 114 116 102 117
156
- } else if (char >= 92 && char <= 117) {
157
- if (char === 92) {
158
- result += "\\";
159
- last = ++i;
160
- } else if (char === 98) {
161
- result += "\b";
162
- last = ++i;
163
- } else if (char === 102) {
164
- result += "\f";
165
- last = ++i;
166
- } else if (char === 114) {
167
- result += "\r";
168
- last = ++i;
169
- } else if (char === 116) {
170
- result += "\t";
171
- last = ++i;
172
- } else if (char === 117 && load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) === 27584753879220272) {
173
- result += "\u000b";
174
- i += 4;
175
- last = ++i;
176
- }
177
- }
178
- }
103
+ }
104
+ /**
105
+ * Parses valid JSON strings into their original format.
106
+ * ```js
107
+ * JSON.parse<T>(data)
108
+ * ```
109
+ * @param data string
110
+ * @returns T
111
+ */
112
+
113
+ // @ts-ignore
114
+ @inline export function parse<
115
+ T
116
+ >(data: string): T {
117
+ let type: T;
118
+ if (isString<T>()) {
119
+ // @ts-ignore
120
+ return parseString(data);
121
+ } else if (isBoolean<T>()) {
122
+ // @ts-ignore
123
+ return parseBoolean<T>(data);
124
+ } else if (isFloat<T>() || isInteger<T>()) {
125
+ return parseNumber<T>(data);
126
+ } else if (isArrayLike<T>()) {
127
+ // @ts-ignore
128
+ return parseArray<T>(data.trimStart());
129
+ // @ts-ignore
130
+ } else if (isNullable<T>() && data == "null") {
131
+ // @ts-ignore
132
+ return null;
133
+ // @ts-ignore
134
+ } else if (isDefined(type.__JSON_Set_Key)) {
135
+ return parseObject<T>(data.trimStart());
136
+ } else if (idof<nonnull<T>>() == idof<Date>()) {
137
+ // @ts-ignore
138
+ return Date.fromString(data);
139
+ } else {
140
+ // @ts-ignore
141
+ throw new Error(
142
+ `Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
143
+ );
144
+ }
145
+ }
146
+ // @ts-ignore
147
+ @inline function parseObjectValue<
148
+ T
149
+ >(data: string): T {
150
+ let type: T;
151
+ if (isString<T>()) {
152
+ // @ts-ignore
153
+ let result = "";
154
+ let last = 0;
155
+ let char = 0;
156
+ for (let i = 0; i < data.length; i++) {
157
+ // \\"
158
+ if (unsafeCharCodeAt(data, i) === backSlashCode) {
159
+ char = unsafeCharCodeAt(data, ++i);
160
+ result += data.slice(last, i - 1);
161
+ if (char === 34) {
162
+ result += '"';
163
+ last = ++i;
164
+ } else if (char === 110) {
165
+ result += "\n";
166
+ last = ++i;
167
+ // 92 98 114 116 102 117
168
+ } else if (char >= 92 && char <= 117) {
169
+ if (char === 92) {
170
+ result += "\\";
171
+ last = ++i;
172
+ } else if (char === 98) {
173
+ result += "\b";
174
+ last = ++i;
175
+ } else if (char === 102) {
176
+ result += "\f";
177
+ last = ++i;
178
+ } else if (char === 114) {
179
+ result += "\r";
180
+ last = ++i;
181
+ } else if (char === 116) {
182
+ result += "\t";
183
+ last = ++i;
184
+ } else if (
185
+ char === 117 &&
186
+ load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
187
+ 27584753879220272
188
+ ) {
189
+ result += "\u000b";
190
+ i += 4;
191
+ last = ++i;
179
192
  }
180
- result += data.slice(last);
181
- // @ts-ignore
182
- return result;
183
- } else if (isBoolean<T>()) {
184
- // @ts-ignore
185
- return parseBoolean<T>(data);
186
- } else if (isFloat<T>() || isInteger<T>()) {
187
- return parseNumber<T>(data);
188
- } else if (isArrayLike<T>()) {
189
- // @ts-ignore
190
- return parseArray<T>(data);
191
- // @ts-ignore
192
- } else if (isNullable<T>() && data == "null") {
193
- // @ts-ignore
194
- return null;
195
- // @ts-ignore
196
- } else if (isDefined(type.__JSON_Set_Key)) {
197
- return parseObject<T>(data.trimStart());
198
- } else if (idof<nonnull<T>>() == idof<Date>()) {
199
- // @ts-ignore
200
- return Date.fromString(data);
201
- } else {
202
- // @ts-ignore
203
- throw new Error(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`)
193
+ }
204
194
  }
195
+ }
196
+ result += data.slice(last);
197
+ // @ts-ignore
198
+ return result;
199
+ } else if (isBoolean<T>()) {
200
+ // @ts-ignore
201
+ return parseBoolean<T>(data);
202
+ } else if (isFloat<T>() || isInteger<T>()) {
203
+ return parseNumber<T>(data);
204
+ } else if (isArrayLike<T>()) {
205
+ // @ts-ignore
206
+ return parseArray<T>(data);
207
+ // @ts-ignore
208
+ } else if (isNullable<T>() && data == "null") {
209
+ // @ts-ignore
210
+ return null;
211
+ // @ts-ignore
212
+ } else if (isDefined(type.__JSON_Set_Key)) {
213
+ return parseObject<T>(data.trimStart());
214
+ } else if (idof<nonnull<T>>() == idof<Date>()) {
215
+ // @ts-ignore
216
+ return Date.fromString(data);
217
+ } else {
218
+ // @ts-ignore
219
+ throw new Error(
220
+ `Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
221
+ );
205
222
  }
223
+ }
206
224
  }
207
225
 
208
-
209
226
  // @ts-ignore
210
- @inline
211
- function serializeString(data: string): string {
212
- // @ts-ignore
213
- //if (data.length === 0) return "\"\"";
214
- /*
215
- let char: i32 = 0;
216
- if (data.length === 1) {
217
- char = unsafeCharCodeAt(data, 0);
218
- if (char === 34) {
219
- return "\\\"";
220
- } else if (char === 92) {
221
- return "\\n";
222
- } else if (char <= 13 && char >= 8) {
223
- switch (char) {
224
- case 0x5C: {
225
- return "\\\\";
226
- }
227
- case 0x08: {
228
- return "\\b";
229
- }
230
- case 0x0D: {
231
- return "\\r";
232
- }
233
- case 0x09: {
234
- return "\\t";
235
- }
236
- case 0x0C: {
237
- return "\\f";
238
- }
239
- case 0x0B: {
240
- return "\\u000b";
241
- }
242
- }
243
- } else {
244
- return data;
245
- }
246
- }*/
227
+ @inline function serializeString(
228
+ data: string
229
+ ): string {
230
+ // @ts-ignore
231
+ //if (data.length === 0) return "\"\"";
232
+ /*
233
+ let char: i32 = 0;
234
+ if (data.length === 1) {
235
+ char = unsafeCharCodeAt(data, 0);
236
+ if (char === 34) {
237
+ return "\\\"";
238
+ } else if (char === 92) {
239
+ return "\\n";
240
+ } else if (char <= 13 && char >= 8) {
241
+ switch (char) {
242
+ case 0x5C: {
243
+ return "\\\\";
244
+ }
245
+ case 0x08: {
246
+ return "\\b";
247
+ }
248
+ case 0x0D: {
249
+ return "\\r";
250
+ }
251
+ case 0x09: {
252
+ return "\\t";
253
+ }
254
+ case 0x0C: {
255
+ return "\\f";
256
+ }
257
+ case 0x0B: {
258
+ return "\\u000b";
259
+ }
260
+ }
261
+ } else {
262
+ return data;
263
+ }
264
+ }*/
247
265
 
248
- let result = "\"";
266
+ let result = '"';
249
267
 
250
- let last: i32 = 0;
251
- // @ts-ignore
252
- for (let i = 0; i < data.length; i++) {
253
- const char = unsafeCharCodeAt(<string>data, i);
254
- if (char === 34 || char === 92) {
255
- result += (<string>data).slice(last, i) + "\\";
256
- last = i;
257
- i++;
258
- } else if (char <= 13 && char >= 8) {
259
- result += (<string>data).slice(last, i);
260
- last = ++i;
261
- switch (char) {
262
- /*case 0x5C: {
263
- result += "\\\\";
264
- break;
265
- }*/
266
- case 0x08: {
267
- result += "\\b";
268
- break;
269
- }
270
- case 0x0D: {
271
- result += "\\r";
272
- break;
273
- }
274
- case 0x09: {
275
- result += "\\t";
276
- break;
277
- }
278
- case 0x0C: {
279
- result += "\\f";
280
- break;
281
- }
282
- case 0x0B: {
283
- result += "\\u000b";
284
- break;
285
- }
286
- }
268
+ let last: i32 = 0;
269
+ // @ts-ignore
270
+ for (let i = 0; i < data.length; i++) {
271
+ const char = unsafeCharCodeAt(<string>data, i);
272
+ if (char === 34 || char === 92) {
273
+ result += (<string>data).slice(last, i) + "\\";
274
+ last = i;
275
+ i++;
276
+ } else if (char <= 13 && char >= 8) {
277
+ result += (<string>data).slice(last, i);
278
+ last = ++i;
279
+ switch (char) {
280
+ case 8: {
281
+ result += "\\b";
282
+ break;
283
+ }
284
+ case 9: {
285
+ result += "\\t";
286
+ break;
287
+ }
288
+ case 10: {
289
+ result += "\\n";
290
+ break;
291
+ }
292
+ case 11: {
293
+ result += "\\x0B"; // \\u000b
294
+ break;
295
+ }
296
+ case 12: {
297
+ result += "\\f";
298
+ break;
287
299
  }
288
- }// 8 10 13 9 12
289
- if (result.length === 1) return "\"" + data + "\"";
290
- else result += (<string>data).slice(last);
291
- return result + "\"";
300
+ case 13: {
301
+ result += "\\r";
302
+ break;
303
+ }
304
+ }
305
+ }
306
+ }
307
+ if (result.length === 1) return '"' + data + '"';
308
+ else result += (<string>data).slice(last);
309
+ return result + '"';
292
310
  }
293
311
 
294
312
  // @ts-ignore
295
- @inline
296
- function parseString(data: string): string {
297
- let result = "";
298
- let last = 1;
299
- for (let i = 1; i < data.length - 1; i++) {
300
- // \\"
301
- if (unsafeCharCodeAt(data, i) === backSlashCode) {
302
- const char = unsafeCharCodeAt(data, ++i);
303
- result += data.slice(last, i - 1)
304
- if (char === 34) {
305
- result += "\"";
306
- last = ++i;
307
- } else if (char === 110) {
308
- result += "\n";
309
- last = ++i;
310
- // 92 98 114 116 102 117
311
- } else if (char >= 92 && char <= 117) {
312
- switch (char) {
313
- case 92: {
314
- result += "\\";
315
- last = ++i;
316
- break;
317
- }
318
- case 98: {
319
- result += "\b";
320
- last = ++i;
321
- break;
322
- }
323
- case 102: {
324
- result += "\f";
325
- last = ++i;
326
- break;
327
- }
328
- case 114: {
329
- result += "\r";
330
- last = ++i;
331
- break;
332
- }
333
- case 116: {
334
- result += "\t";
335
- last = ++i;
336
- break;
337
- }
338
- default: {
339
- if (char === 117 && load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) === 27584753879220272) {
340
- result += "\u000b";
341
- i += 4;
342
- last = ++i;
343
- }
344
- break;
345
- }
346
- }
313
+ @inline function parseString(
314
+ data: string
315
+ ): string {
316
+ let result = "";
317
+ let last = 1;
318
+ for (let i = 1; i < data.length - 1; i++) {
319
+ // \\"
320
+ if (unsafeCharCodeAt(data, i) === backSlashCode) {
321
+ const char = unsafeCharCodeAt(data, ++i);
322
+ result += data.slice(last, i - 1);
323
+ if (char === 34) {
324
+ result += '"';
325
+ last = ++i;
326
+ } else if (char === 110) {
327
+ result += "\n";
328
+ last = ++i;
329
+ // 92 98 114 116 102 117
330
+ } else if (char >= 92 && char <= 117) {
331
+ switch (char) {
332
+ case 92: {
333
+ result += "\\";
334
+ last = ++i;
335
+ break;
336
+ }
337
+ case 98: {
338
+ result += "\b";
339
+ last = ++i;
340
+ break;
341
+ }
342
+ case 110: {
343
+ result += "\n";
344
+ last = ++i;
345
+ }
346
+ case 102: {
347
+ result += "\f";
348
+ last = ++i;
349
+ break;
350
+ }
351
+ case 114: {
352
+ result += "\r";
353
+ last = ++i;
354
+ break;
355
+ }
356
+ case 116: {
357
+ result += "\t";
358
+ last = ++i;
359
+ break;
360
+ }
361
+ default: {
362
+ if (
363
+ char === 117 &&
364
+ load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
365
+ 27584753879220272
366
+ ) {
367
+ result += "\u000b";
368
+ i += 4;
369
+ last = ++i;
347
370
  }
371
+ break;
372
+ }
348
373
  }
374
+ }
349
375
  }
350
- result += data.slice(last, data.length - 1);
351
- return result;
376
+ }
377
+ result += data.slice(last, data.length - 1);
378
+ return result;
352
379
  }
353
380
 
354
381
  // @ts-ignore
355
- @inline
356
- function parseBoolean<T extends boolean>(data: string): T {
357
- if (data.length > 3 && data.startsWith("true")) return <T>true;
358
- else if (data.length > 4 && data.startsWith("false")) return <T>false;
359
- else throw new Error(`JSON: Cannot parse "${data}" as boolean`);
382
+ @inline function parseBoolean<
383
+ T extends boolean
384
+ >(data: string): T {
385
+ if (data.length > 3 && data.startsWith("true")) return <T>true;
386
+ else if (data.length > 4 && data.startsWith("false")) return <T>false;
387
+ else throw new Error(`JSON: Cannot parse "${data}" as boolean`);
360
388
  }
361
389
 
362
390
  // @ts-ignore
363
- @inline
364
- // @ts-ignore
365
- export function parseNumber<T>(data: string): T {
366
- if (isInteger<T>()) {
367
- // @ts-ignore
368
- return parseSciInteger<T>(data);
369
- }
370
- // @ts-ignore
371
- const type: T = 0;
391
+ @inline export function parseNumber<
392
+ T
393
+ >(data: string): T {
394
+ if (isInteger<T>()) {
372
395
  // @ts-ignore
373
- if (type instanceof f64) return f64.parse(data);
374
- // @ts-ignore
375
- else if (type instanceof f32) return f32.parse(data);
396
+ return parseSciInteger<T>(data);
397
+ }
398
+ // @ts-ignore
399
+ const type: T = 0;
400
+ // @ts-ignore
401
+ if (type instanceof f64) return f64.parse(data);
402
+ // @ts-ignore
403
+ else if (type instanceof f32) return f32.parse(data);
376
404
  }
377
405
 
378
406
  // @ts-ignore
379
- @inline
380
- function parseObject<T>(data: string): T {
381
- let schema: nonnull<T> = changetype<nonnull<T>>(__new(offsetof<nonnull<T>>(), idof<nonnull<T>>()));
382
- let key = "";
383
- let isKey = false;
384
- let depth = 0;
385
- let char = 0;
386
- let outerLoopIndex = 1;
387
- for (; outerLoopIndex < data.length - 1; outerLoopIndex++) {
388
- char = unsafeCharCodeAt(data, outerLoopIndex);
407
+ @inline function parseObject<
408
+ T
409
+ >(data: string): T {
410
+ let schema: nonnull<T> = changetype<nonnull<T>>(
411
+ __new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
412
+ );
413
+ let key = "";
414
+ let isKey = false;
415
+ let depth = 0;
416
+ let char = 0;
417
+ let outerLoopIndex = 1;
418
+ for (; outerLoopIndex < data.length - 1; outerLoopIndex++) {
419
+ char = unsafeCharCodeAt(data, outerLoopIndex);
420
+ if (char === leftBracketCode) {
421
+ for (
422
+ let arrayValueIndex = outerLoopIndex;
423
+ arrayValueIndex < data.length - 1;
424
+ arrayValueIndex++
425
+ ) {
426
+ char = unsafeCharCodeAt(data, arrayValueIndex);
389
427
  if (char === leftBracketCode) {
390
- for (
391
- let arrayValueIndex = outerLoopIndex;
392
- arrayValueIndex < data.length - 1;
393
- arrayValueIndex++
394
- ) {
395
- char = unsafeCharCodeAt(data, arrayValueIndex);
396
- if (char === leftBracketCode) {
397
- depth++;
398
- } else if (char === rightBracketCode) {
399
- depth--;
400
- if (depth === 0) {
401
- ++arrayValueIndex;
402
- // @ts-ignore
403
- schema.__JSON_Set_Key(key, data.slice(outerLoopIndex, arrayValueIndex));
404
- outerLoopIndex = arrayValueIndex;
405
- isKey = false;
406
- break;
407
- }
408
- }
409
- }
410
- } else if (char === leftBraceCode) {
411
- for (
412
- let objectValueIndex = outerLoopIndex;
413
- objectValueIndex < data.length - 1;
414
- objectValueIndex++
415
- ) {
416
- char = unsafeCharCodeAt(data, objectValueIndex);
417
- if (char === leftBraceCode) {
418
- depth++;
419
- } else if (char === rightBraceCode) {
420
- depth--;
421
- if (depth === 0) {
422
- ++objectValueIndex;
423
- // @ts-ignore
424
- schema.__JSON_Set_Key(key, data.slice(outerLoopIndex, objectValueIndex));
425
- outerLoopIndex = objectValueIndex;
426
- isKey = false;
427
- break;
428
- }
429
- }
430
- }
431
- } else if (char === quoteCode) {
432
- for (
433
- let stringValueIndex = ++outerLoopIndex;
434
- stringValueIndex < data.length - 1;
435
- stringValueIndex++
436
- ) {
437
- char = unsafeCharCodeAt(data, stringValueIndex);
438
- if (
439
- char === quoteCode &&
440
- unsafeCharCodeAt(data, stringValueIndex - 1) !== backSlashCode
441
- ) {
442
- if (isKey === false) {
443
- key = data.slice(outerLoopIndex, stringValueIndex);
444
- isKey = true;
445
- } else {
446
- // @ts-ignore
447
- schema.__JSON_Set_Key(key, data.slice(outerLoopIndex, stringValueIndex));
448
- isKey = false;
449
- }
450
- outerLoopIndex = ++stringValueIndex;
451
- break;
452
- }
453
- }
454
- } else if (char == nCode) {
428
+ depth++;
429
+ } else if (char === rightBracketCode) {
430
+ depth--;
431
+ if (depth === 0) {
432
+ ++arrayValueIndex;
455
433
  // @ts-ignore
456
- schema.__JSON_Set_Key(key, nullWord);
434
+ schema.__JSON_Set_Key(
435
+ key,
436
+ data.slice(outerLoopIndex, arrayValueIndex)
437
+ );
438
+ outerLoopIndex = arrayValueIndex;
457
439
  isKey = false;
458
- } else if (
459
- char === tCode &&
460
- unsafeCharCodeAt(data, ++outerLoopIndex) === rCode &&
461
- unsafeCharCodeAt(data, ++outerLoopIndex) === uCode &&
462
- unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
463
- ) {
440
+ break;
441
+ }
442
+ }
443
+ }
444
+ } else if (char === leftBraceCode) {
445
+ for (
446
+ let objectValueIndex = outerLoopIndex;
447
+ objectValueIndex < data.length - 1;
448
+ objectValueIndex++
449
+ ) {
450
+ char = unsafeCharCodeAt(data, objectValueIndex);
451
+ if (char === leftBraceCode) {
452
+ depth++;
453
+ } else if (char === rightBraceCode) {
454
+ depth--;
455
+ if (depth === 0) {
456
+ ++objectValueIndex;
464
457
  // @ts-ignore
465
- schema.__JSON_Set_Key(key, trueWord);
458
+ schema.__JSON_Set_Key(
459
+ key,
460
+ data.slice(outerLoopIndex, objectValueIndex)
461
+ );
462
+ outerLoopIndex = objectValueIndex;
466
463
  isKey = false;
467
- } else if (
468
- char === fCode &&
469
- unsafeCharCodeAt(data, ++outerLoopIndex) === "a".charCodeAt(0) &&
470
- unsafeCharCodeAt(data, ++outerLoopIndex) === "l".charCodeAt(0) &&
471
- unsafeCharCodeAt(data, ++outerLoopIndex) === "s".charCodeAt(0) &&
472
- unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
464
+ break;
465
+ }
466
+ }
467
+ }
468
+ } else if (char === quoteCode) {
469
+ for (
470
+ let stringValueIndex = ++outerLoopIndex;
471
+ stringValueIndex < data.length - 1;
472
+ stringValueIndex++
473
+ ) {
474
+ char = unsafeCharCodeAt(data, stringValueIndex);
475
+ if (
476
+ char === quoteCode &&
477
+ unsafeCharCodeAt(data, stringValueIndex - 1) !== backSlashCode
473
478
  ) {
479
+ if (isKey === false) {
480
+ key = data.slice(outerLoopIndex, stringValueIndex);
481
+ isKey = true;
482
+ } else {
474
483
  // @ts-ignore
475
- schema.__JSON_Set_Key(key, "false");
484
+ schema.__JSON_Set_Key(
485
+ key,
486
+ data.slice(outerLoopIndex, stringValueIndex)
487
+ );
476
488
  isKey = false;
477
- } else if ((char >= 48 && char <= 57) || char === 45) {
478
- let numberValueIndex = ++outerLoopIndex;
479
- for (; numberValueIndex < data.length; numberValueIndex++) {
480
- char = unsafeCharCodeAt(data, numberValueIndex);
481
- if (char === commaCode || char === rightBraceCode || isSpace(char)) {
482
- // @ts-ignore
483
- schema.__JSON_Set_Key(key, data.slice(outerLoopIndex - 1, numberValueIndex));
484
- outerLoopIndex = numberValueIndex;
485
- isKey = false;
486
- break;
487
- }
488
- }
489
+ }
490
+ outerLoopIndex = ++stringValueIndex;
491
+ break;
492
+ }
493
+ }
494
+ } else if (char == nCode) {
495
+ // @ts-ignore
496
+ schema.__JSON_Set_Key(key, nullWord);
497
+ isKey = false;
498
+ } else if (
499
+ char === tCode &&
500
+ unsafeCharCodeAt(data, ++outerLoopIndex) === rCode &&
501
+ unsafeCharCodeAt(data, ++outerLoopIndex) === uCode &&
502
+ unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
503
+ ) {
504
+ // @ts-ignore
505
+ schema.__JSON_Set_Key(key, trueWord);
506
+ isKey = false;
507
+ } else if (
508
+ char === fCode &&
509
+ unsafeCharCodeAt(data, ++outerLoopIndex) === "a".charCodeAt(0) &&
510
+ unsafeCharCodeAt(data, ++outerLoopIndex) === "l".charCodeAt(0) &&
511
+ unsafeCharCodeAt(data, ++outerLoopIndex) === "s".charCodeAt(0) &&
512
+ unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
513
+ ) {
514
+ // @ts-ignore
515
+ schema.__JSON_Set_Key(key, "false");
516
+ isKey = false;
517
+ } else if ((char >= 48 && char <= 57) || char === 45) {
518
+ let numberValueIndex = ++outerLoopIndex;
519
+ for (; numberValueIndex < data.length; numberValueIndex++) {
520
+ char = unsafeCharCodeAt(data, numberValueIndex);
521
+ if (char === commaCode || char === rightBraceCode || isSpace(char)) {
522
+ // @ts-ignore
523
+ schema.__JSON_Set_Key(
524
+ key,
525
+ data.slice(outerLoopIndex - 1, numberValueIndex)
526
+ );
527
+ outerLoopIndex = numberValueIndex;
528
+ isKey = false;
529
+ break;
489
530
  }
531
+ }
490
532
  }
491
- return schema;
533
+ }
534
+ return schema;
492
535
  }
493
536
 
494
537
  // @ts-ignore
495
- @inline
496
- // @ts-ignore
497
- function parseArray<T extends unknown[]>(data: string): T {
498
- if (isString<valueof<T>>()) {
499
- return <T>parseStringArray(data);
500
- } else if (isBoolean<valueof<T>>()) {
501
- // @ts-ignore
502
- return parseBooleanArray<T>(data);
503
- } else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
504
- // @ts-ignore
505
- return parseNumberArray<T>(data);
506
- } else if (isArrayLike<valueof<T>>()) {
507
- // @ts-ignore
508
- return parseArrayArray<T>(data);
509
- // @ts-ignore
510
- } else if (isManaged<valueof<T>>() || isReference<valueof<T>>()) {
511
- const type = changetype<nonnull<valueof<T>>>(__new(offsetof<nonnull<valueof<T>>>(), idof<nonnull<valueof<T>>>()));
512
- // @ts-ignore
513
- if (isDefined(type.__JSON_Set_Key)) {
514
- // @ts-ignore
515
- return parseObjectArray<T>(data);
516
- }
517
- return unreachable();
538
+ @inline function parseArray<
539
+ T extends unknown[]
540
+ >(data: string): T {
541
+ if (isString<valueof<T>>()) {
542
+ return <T>parseStringArray(data);
543
+ } else if (isBoolean<valueof<T>>()) {
544
+ // @ts-ignore
545
+ return parseBooleanArray<T>(data);
546
+ } else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
547
+ // @ts-ignore
548
+ return parseNumberArray<T>(data);
549
+ } else if (isArrayLike<valueof<T>>()) {
550
+ // @ts-ignore
551
+ return parseArrayArray<T>(data);
552
+ // @ts-ignore
553
+ } else if (isManaged<valueof<T>>() || isReference<valueof<T>>()) {
554
+ // We instantiate the required memory for the class and fill it. This is extremely unsafe and uses "a bit of magic".
555
+ const type = changetype<nonnull<valueof<T>>>(
556
+ __new(offsetof<nonnull<valueof<T>>>(), idof<nonnull<valueof<T>>>())
557
+ );
558
+ // @ts-ignore
559
+ if (isDefined(type.__JSON_Set_Key)) {
560
+ // @ts-ignore
561
+ return parseObjectArray<T>(data);
518
562
  }
519
563
  return unreachable();
564
+ }
565
+ return unreachable();
520
566
  }
521
567
 
522
568
  // @ts-ignore
523
- @inline
524
- function parseStringArray(data: string): string[] {
525
- const result: string[] = [];
526
- let lastPos = 0;
527
- let instr = false;
528
- for (let i = 1; i < data.length - 1; i++) {
529
- if (unsafeCharCodeAt(data, i) === quoteCode) {
530
- if (instr === false) {
531
- instr = true;
532
- lastPos = i;
533
- } else if (unsafeCharCodeAt(data, i - 1) !== backSlashCode) {
534
- instr = false;
535
- result.push(data.slice(lastPos + 1, i).replaceAll('\\"', '"'));
536
- }
537
- }
569
+ @inline function parseStringArray(
570
+ data: string
571
+ ): string[] {
572
+ const result: string[] = [];
573
+ let lastPos = 0;
574
+ let instr = false;
575
+ for (let i = 1; i < data.length - 1; i++) {
576
+ if (unsafeCharCodeAt(data, i) === quoteCode) {
577
+ if (instr === false) {
578
+ instr = true;
579
+ lastPos = i;
580
+ } else if (unsafeCharCodeAt(data, i - 1) !== backSlashCode) {
581
+ instr = false;
582
+ result.push(data.slice(lastPos + 1, i).replaceAll('\\"', '"'));
583
+ }
538
584
  }
539
- return result;
585
+ }
586
+ return result;
540
587
  }
541
588
 
542
589
  // @ts-ignore
543
- @inline
544
- function parseBooleanArray<T extends boolean[]>(data: string): T {
545
- const result = instantiate<T>();
546
- let lastPos = 1;
547
- let char = 0;
548
- for (let i = 1; i < data.length - 1; i++) {
549
- char = unsafeCharCodeAt(data, i);
550
- /*// if char == "t" && i+3 == "e"
551
- if (char === tCode && data.charCodeAt(i + 3) === eCode) {
552
- //i += 3;
553
- result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+2)));
554
- //i++;
555
- } else if (char === fCode && data.charCodeAt(i + 4) === eCode) {
556
- //i += 4;
557
- result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+3)));
558
- //i++;
559
- }*/
560
- if (char === tCode || char === fCode) {
561
- lastPos = i;
562
- } else if (char === eCode) {
563
- i++;
564
- result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i)));
565
- }
590
+ @inline function parseBooleanArray<
591
+ T extends boolean[]
592
+ >(data: string): T {
593
+ const result = instantiate<T>();
594
+ let lastPos = 1;
595
+ let char = 0;
596
+ for (let i = 1; i < data.length - 1; i++) {
597
+ char = unsafeCharCodeAt(data, i);
598
+ /*// if char == "t" && i+3 == "e"
599
+ if (char === tCode && data.charCodeAt(i + 3) === eCode) {
600
+ //i += 3;
601
+ result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+2)));
602
+ //i++;
603
+ } else if (char === fCode && data.charCodeAt(i + 4) === eCode) {
604
+ //i += 4;
605
+ result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+3)));
606
+ //i++;
607
+ }*/
608
+ if (char === tCode || char === fCode) {
609
+ lastPos = i;
610
+ } else if (char === eCode) {
611
+ i++;
612
+ result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i)));
566
613
  }
567
- return result;
614
+ }
615
+ return result;
568
616
  }
569
617
 
570
618
  // @ts-ignore
571
- @inline
572
- function parseNumberArray<T extends number[]>(data: string): T {
573
- const result = instantiate<T>();
574
- let lastPos = 0;
575
- let char = 0;
576
- let i = 1;
577
- for (; i < data.length - 1; i++) {
578
- char = unsafeCharCodeAt(data, i);
579
- if ((lastPos === 0 && char >= 48 && char <= 57) || char === 45) {
580
- lastPos = i;
581
- } else if ((isSpace(char) || char == commaCode) && lastPos > 0) {
582
- result.push(parseNumber<valueof<T>>(data.slice(lastPos, i)));
583
- lastPos = 0;
584
- }
619
+ @inline function parseNumberArray<
620
+ T extends number[]
621
+ >(data: string): T {
622
+ const result = instantiate<T>();
623
+ let lastPos = 0;
624
+ let char = 0;
625
+ let i = 1;
626
+ for (; i < data.length - 1; i++) {
627
+ char = unsafeCharCodeAt(data, i);
628
+ if ((lastPos === 0 && char >= 48 && char <= 57) || char === 45) {
629
+ lastPos = i;
630
+ } else if ((isSpace(char) || char == commaCode) && lastPos > 0) {
631
+ result.push(parseNumber<valueof<T>>(data.slice(lastPos, i)));
632
+ lastPos = 0;
585
633
  }
586
- for (; i > lastPos - 1; i--) {
587
- char = unsafeCharCodeAt(data, i);
588
- if (char !== rightBracketCode) {
589
- result.push(parseNumber<valueof<T>>(data.slice(lastPos, i + 1)));
590
- break;
591
- }
634
+ }
635
+ for (; i > lastPos - 1; i--) {
636
+ char = unsafeCharCodeAt(data, i);
637
+ if (char !== rightBracketCode) {
638
+ result.push(parseNumber<valueof<T>>(data.slice(lastPos, i + 1)));
639
+ break;
592
640
  }
593
- return result;
641
+ }
642
+ return result;
594
643
  }
595
644
 
596
645
  // @ts-ignore
597
- @inline
598
- function parseArrayArray<T extends unknown[][]>(data: string): T {
599
- const result = instantiate<T>();
600
- let char = 0;
601
- let lastPos = 0;
602
- let depth = 0;
603
- let i = 1;
604
- // Find start of bracket
605
- //for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) {}
606
- //i++;
607
- for (; i < data.length - 1; i++) {
608
- char = unsafeCharCodeAt(data, i);
609
- if (char === leftBracketCode) {
610
- if (depth === 0) {
611
- lastPos = i;
612
- }
613
- // Shifting is 6% faster than incrementing
614
- depth++;
615
- } else if (char === rightBracketCode) {
616
- depth--;
617
- if (depth === 0) {
618
- i++;
619
- result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i)));
620
- }
621
- }
646
+ @inline function parseArrayArray<
647
+ T extends unknown[][]
648
+ >(data: string): T {
649
+ const result = instantiate<T>();
650
+ let char = 0;
651
+ let lastPos = 0;
652
+ let depth = 0;
653
+ let i = 1;
654
+ // Find start of bracket
655
+ //for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) {}
656
+ //i++;
657
+ for (; i < data.length - 1; i++) {
658
+ char = unsafeCharCodeAt(data, i);
659
+ if (char === leftBracketCode) {
660
+ if (depth === 0) {
661
+ lastPos = i;
662
+ }
663
+ // Shifting is 6% faster than incrementing
664
+ depth++;
665
+ } else if (char === rightBracketCode) {
666
+ depth--;
667
+ if (depth === 0) {
668
+ i++;
669
+ result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i)));
670
+ }
622
671
  }
623
- return result;
672
+ }
673
+ return result;
624
674
  }
625
675
 
626
676
  // @ts-ignore
627
- export function parseObjectArray<T extends unknown[]>(data: string): T {
628
- const result = instantiate<T>();
629
- let char = 0;
630
- let lastPos: u32 = 1;
631
- let depth: u32 = 0;
632
- for (let pos: u32 = 0; pos < <u32>data.length; pos++) {
633
- char = unsafeCharCodeAt(data, pos);
634
- if (char === leftBraceCode) {
635
- if (depth === 0) {
636
- lastPos = pos;
637
- }
638
- depth++;
639
- } else if (char === rightBraceCode) {
640
- depth--;
641
- if (depth === 0) {
642
- pos++;
643
- result.push(JSON.parse<valueof<T>>(data.slice(lastPos, pos)));
644
- //lastPos = pos + 2;
645
- }
646
- }
677
+ @inline export function parseObjectArray<
678
+ T extends unknown[]
679
+ >(data: string): T {
680
+ const result = instantiate<T>();
681
+ let char = 0;
682
+ let lastPos: u32 = 1;
683
+ let depth: u32 = 0;
684
+ for (let pos: u32 = 0; pos < <u32>data.length; pos++) {
685
+ char = unsafeCharCodeAt(data, pos);
686
+ if (char === leftBraceCode) {
687
+ if (depth === 0) {
688
+ lastPos = pos;
689
+ }
690
+ depth++;
691
+ } else if (char === rightBraceCode) {
692
+ depth--;
693
+ if (depth === 0) {
694
+ pos++;
695
+ result.push(JSON.parse<valueof<T>>(data.slice(lastPos, pos)));
696
+ //lastPos = pos + 2;
697
+ }
647
698
  }
648
- return result;
649
- }
699
+ }
700
+ return result;
701
+ }