json-as 0.5.37 → 0.5.38
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.
- package/README.md +118 -116
- package/as-pect.asconfig.json +24 -24
- package/asconfig.json +18 -20
- package/assembly/__benches__/as-json.ts +30 -17
- package/assembly/__tests__/as-json.spec.ts +30 -22
- package/assembly/index.ts +1 -1
- package/assembly/src/chars.ts +1 -1
- package/assembly/src/json.ts +127 -103
- package/assembly/src/util.ts +40 -18
- package/assembly/test.ts +194 -13
- package/assembly/tsconfig.json +94 -1
- package/index.ts +1 -1
- package/package.json +1 -1
- package/transform/lib/hash.js +48 -50
- package/transform/lib/index.js +25 -7
- package/transform/lib/types.js +12 -12
- package/transform/package.json +36 -36
- package/transform/src/index.ts +54 -30
- package/transform/tsconfig.json +70 -70
- package/tsconfig.json +12 -12
- package/transform/src/hash.ts +0 -83
package/assembly/src/json.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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
4
|
backSlashCode,
|
|
5
5
|
commaCode,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
tCode,
|
|
20
20
|
trueWord,
|
|
21
21
|
uCode,
|
|
22
|
-
emptyArrayWord
|
|
22
|
+
emptyArrayWord,
|
|
23
23
|
} from "./chars";
|
|
24
24
|
import { parseSciInteger, unsafeCharCodeAt } from "./util";
|
|
25
25
|
|
|
@@ -35,7 +35,8 @@ export namespace JSON {
|
|
|
35
35
|
* @param data T
|
|
36
36
|
* @returns string
|
|
37
37
|
*/
|
|
38
|
-
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
@inline export function stringify<T>(data: T): string {
|
|
39
40
|
// String
|
|
40
41
|
if (isString<T>() && data != null) {
|
|
41
42
|
// @ts-ignore
|
|
@@ -93,7 +94,9 @@ export namespace JSON {
|
|
|
93
94
|
return result.toString();
|
|
94
95
|
}
|
|
95
96
|
} else {
|
|
96
|
-
throw new Error(
|
|
97
|
+
throw new Error(
|
|
98
|
+
`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
99
|
+
);
|
|
97
100
|
}
|
|
98
101
|
}
|
|
99
102
|
/**
|
|
@@ -104,8 +107,9 @@ export namespace JSON {
|
|
|
104
107
|
* @param data string
|
|
105
108
|
* @returns T
|
|
106
109
|
*/
|
|
110
|
+
|
|
107
111
|
// @ts-ignore
|
|
108
|
-
export function parse<T>(data: string): T {
|
|
112
|
+
@inline export function parse<T>(data: string): T {
|
|
109
113
|
let type: T;
|
|
110
114
|
if (isString<T>()) {
|
|
111
115
|
// @ts-ignore
|
|
@@ -130,11 +134,13 @@ export namespace JSON {
|
|
|
130
134
|
return Date.fromString(data);
|
|
131
135
|
} else {
|
|
132
136
|
// @ts-ignore
|
|
133
|
-
throw new Error(
|
|
137
|
+
throw new Error(
|
|
138
|
+
`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
139
|
+
);
|
|
134
140
|
}
|
|
135
141
|
}
|
|
136
142
|
// @ts-ignore
|
|
137
|
-
function parseObjectValue<T>(data: string): T {
|
|
143
|
+
@inline function parseObjectValue<T>(data: string): T {
|
|
138
144
|
let type: T;
|
|
139
145
|
if (isString<T>()) {
|
|
140
146
|
// @ts-ignore
|
|
@@ -145,9 +151,9 @@ export namespace JSON {
|
|
|
145
151
|
// \\"
|
|
146
152
|
if (unsafeCharCodeAt(data, i) === backSlashCode) {
|
|
147
153
|
char = unsafeCharCodeAt(data, ++i);
|
|
148
|
-
result += data.slice(last, i - 1)
|
|
154
|
+
result += data.slice(last, i - 1);
|
|
149
155
|
if (char === 34) {
|
|
150
|
-
result += "
|
|
156
|
+
result += '"';
|
|
151
157
|
last = ++i;
|
|
152
158
|
} else if (char === 110) {
|
|
153
159
|
result += "\n";
|
|
@@ -169,7 +175,11 @@ export namespace JSON {
|
|
|
169
175
|
} else if (char === 116) {
|
|
170
176
|
result += "\t";
|
|
171
177
|
last = ++i;
|
|
172
|
-
} else if (
|
|
178
|
+
} else if (
|
|
179
|
+
char === 117 &&
|
|
180
|
+
load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
|
|
181
|
+
27584753879220272
|
|
182
|
+
) {
|
|
173
183
|
result += "\u000b";
|
|
174
184
|
i += 4;
|
|
175
185
|
last = ++i;
|
|
@@ -200,52 +210,52 @@ export namespace JSON {
|
|
|
200
210
|
return Date.fromString(data);
|
|
201
211
|
} else {
|
|
202
212
|
// @ts-ignore
|
|
203
|
-
throw new Error(
|
|
213
|
+
throw new Error(
|
|
214
|
+
`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
215
|
+
);
|
|
204
216
|
}
|
|
205
217
|
}
|
|
206
218
|
}
|
|
207
219
|
|
|
208
|
-
|
|
209
220
|
// @ts-ignore
|
|
210
|
-
@inline
|
|
211
|
-
function serializeString(data: string): string {
|
|
221
|
+
@inline function serializeString(data: string): string {
|
|
212
222
|
// @ts-ignore
|
|
213
223
|
//if (data.length === 0) return "\"\"";
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
224
|
+
/*
|
|
225
|
+
let char: i32 = 0;
|
|
226
|
+
if (data.length === 1) {
|
|
227
|
+
char = unsafeCharCodeAt(data, 0);
|
|
228
|
+
if (char === 34) {
|
|
229
|
+
return "\\\"";
|
|
230
|
+
} else if (char === 92) {
|
|
231
|
+
return "\\n";
|
|
232
|
+
} else if (char <= 13 && char >= 8) {
|
|
233
|
+
switch (char) {
|
|
234
|
+
case 0x5C: {
|
|
235
|
+
return "\\\\";
|
|
236
|
+
}
|
|
237
|
+
case 0x08: {
|
|
238
|
+
return "\\b";
|
|
239
|
+
}
|
|
240
|
+
case 0x0D: {
|
|
241
|
+
return "\\r";
|
|
242
|
+
}
|
|
243
|
+
case 0x09: {
|
|
244
|
+
return "\\t";
|
|
245
|
+
}
|
|
246
|
+
case 0x0C: {
|
|
247
|
+
return "\\f";
|
|
248
|
+
}
|
|
249
|
+
case 0x0B: {
|
|
250
|
+
return "\\u000b";
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
return data;
|
|
255
|
+
}
|
|
256
|
+
}*/
|
|
247
257
|
|
|
248
|
-
let result = "
|
|
258
|
+
let result = '"';
|
|
249
259
|
|
|
250
260
|
let last: i32 = 0;
|
|
251
261
|
// @ts-ignore
|
|
@@ -259,50 +269,49 @@ function serializeString(data: string): string {
|
|
|
259
269
|
result += (<string>data).slice(last, i);
|
|
260
270
|
last = ++i;
|
|
261
271
|
switch (char) {
|
|
262
|
-
|
|
263
|
-
result += "\\\\";
|
|
264
|
-
break;
|
|
265
|
-
}*/
|
|
266
|
-
case 0x08: {
|
|
272
|
+
case 8: {
|
|
267
273
|
result += "\\b";
|
|
268
274
|
break;
|
|
269
275
|
}
|
|
270
|
-
case
|
|
271
|
-
result += "\\
|
|
276
|
+
case 9: {
|
|
277
|
+
result += "\\t";
|
|
272
278
|
break;
|
|
273
279
|
}
|
|
274
|
-
case
|
|
275
|
-
result += "\\
|
|
280
|
+
case 10: {
|
|
281
|
+
result += "\\n";
|
|
276
282
|
break;
|
|
277
283
|
}
|
|
278
|
-
case
|
|
284
|
+
case 11: {
|
|
285
|
+
result += "\\x0B"; // \\u000b
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case 12: {
|
|
279
289
|
result += "\\f";
|
|
280
290
|
break;
|
|
281
291
|
}
|
|
282
|
-
case
|
|
283
|
-
result += "\\
|
|
292
|
+
case 13: {
|
|
293
|
+
result += "\\r";
|
|
284
294
|
break;
|
|
285
295
|
}
|
|
286
296
|
}
|
|
287
297
|
}
|
|
288
|
-
}
|
|
289
|
-
if (result.length === 1) return "
|
|
298
|
+
}
|
|
299
|
+
if (result.length === 1) return '"' + data + '"';
|
|
290
300
|
else result += (<string>data).slice(last);
|
|
291
|
-
return result + "
|
|
301
|
+
return result + '"';
|
|
292
302
|
}
|
|
293
303
|
|
|
294
304
|
// @ts-ignore
|
|
295
|
-
@inline
|
|
296
|
-
function parseString(data: string): string {
|
|
305
|
+
@inline function parseString(data: string): string {
|
|
297
306
|
let result = "";
|
|
298
307
|
let last = 1;
|
|
299
308
|
for (let i = 1; i < data.length - 1; i++) {
|
|
300
309
|
// \\"
|
|
301
310
|
if (unsafeCharCodeAt(data, i) === backSlashCode) {
|
|
302
311
|
const char = unsafeCharCodeAt(data, ++i);
|
|
303
|
-
result += data.slice(last, i - 1)
|
|
312
|
+
result += data.slice(last, i - 1);
|
|
304
313
|
if (char === 34) {
|
|
305
|
-
result += "
|
|
314
|
+
result += '"';
|
|
306
315
|
last = ++i;
|
|
307
316
|
} else if (char === 110) {
|
|
308
317
|
result += "\n";
|
|
@@ -320,6 +329,10 @@ function parseString(data: string): string {
|
|
|
320
329
|
last = ++i;
|
|
321
330
|
break;
|
|
322
331
|
}
|
|
332
|
+
case 110: {
|
|
333
|
+
result += "\n";
|
|
334
|
+
last = ++i;
|
|
335
|
+
}
|
|
323
336
|
case 102: {
|
|
324
337
|
result += "\f";
|
|
325
338
|
last = ++i;
|
|
@@ -336,7 +349,11 @@ function parseString(data: string): string {
|
|
|
336
349
|
break;
|
|
337
350
|
}
|
|
338
351
|
default: {
|
|
339
|
-
if (
|
|
352
|
+
if (
|
|
353
|
+
char === 117 &&
|
|
354
|
+
load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
|
|
355
|
+
27584753879220272
|
|
356
|
+
) {
|
|
340
357
|
result += "\u000b";
|
|
341
358
|
i += 4;
|
|
342
359
|
last = ++i;
|
|
@@ -352,17 +369,14 @@ function parseString(data: string): string {
|
|
|
352
369
|
}
|
|
353
370
|
|
|
354
371
|
// @ts-ignore
|
|
355
|
-
@inline
|
|
356
|
-
function parseBoolean<T extends boolean>(data: string): T {
|
|
372
|
+
@inline function parseBoolean<T extends boolean>(data: string): T {
|
|
357
373
|
if (data.length > 3 && data.startsWith("true")) return <T>true;
|
|
358
374
|
else if (data.length > 4 && data.startsWith("false")) return <T>false;
|
|
359
375
|
else throw new Error(`JSON: Cannot parse "${data}" as boolean`);
|
|
360
376
|
}
|
|
361
377
|
|
|
362
378
|
// @ts-ignore
|
|
363
|
-
@inline
|
|
364
|
-
// @ts-ignore
|
|
365
|
-
export function parseNumber<T>(data: string): T {
|
|
379
|
+
@inline export function parseNumber<T>(data: string): T {
|
|
366
380
|
if (isInteger<T>()) {
|
|
367
381
|
// @ts-ignore
|
|
368
382
|
return parseSciInteger<T>(data);
|
|
@@ -376,9 +390,10 @@ export function parseNumber<T>(data: string): T {
|
|
|
376
390
|
}
|
|
377
391
|
|
|
378
392
|
// @ts-ignore
|
|
379
|
-
@inline
|
|
380
|
-
|
|
381
|
-
|
|
393
|
+
@inline function parseObject<T>(data: string): T {
|
|
394
|
+
let schema: nonnull<T> = changetype<nonnull<T>>(
|
|
395
|
+
__new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
|
|
396
|
+
);
|
|
382
397
|
let key = "";
|
|
383
398
|
let isKey = false;
|
|
384
399
|
let depth = 0;
|
|
@@ -400,7 +415,10 @@ function parseObject<T>(data: string): T {
|
|
|
400
415
|
if (depth === 0) {
|
|
401
416
|
++arrayValueIndex;
|
|
402
417
|
// @ts-ignore
|
|
403
|
-
schema.__JSON_Set_Key(
|
|
418
|
+
schema.__JSON_Set_Key(
|
|
419
|
+
key,
|
|
420
|
+
data.slice(outerLoopIndex, arrayValueIndex)
|
|
421
|
+
);
|
|
404
422
|
outerLoopIndex = arrayValueIndex;
|
|
405
423
|
isKey = false;
|
|
406
424
|
break;
|
|
@@ -421,7 +439,10 @@ function parseObject<T>(data: string): T {
|
|
|
421
439
|
if (depth === 0) {
|
|
422
440
|
++objectValueIndex;
|
|
423
441
|
// @ts-ignore
|
|
424
|
-
schema.__JSON_Set_Key(
|
|
442
|
+
schema.__JSON_Set_Key(
|
|
443
|
+
key,
|
|
444
|
+
data.slice(outerLoopIndex, objectValueIndex)
|
|
445
|
+
);
|
|
425
446
|
outerLoopIndex = objectValueIndex;
|
|
426
447
|
isKey = false;
|
|
427
448
|
break;
|
|
@@ -444,7 +465,10 @@ function parseObject<T>(data: string): T {
|
|
|
444
465
|
isKey = true;
|
|
445
466
|
} else {
|
|
446
467
|
// @ts-ignore
|
|
447
|
-
schema.__JSON_Set_Key(
|
|
468
|
+
schema.__JSON_Set_Key(
|
|
469
|
+
key,
|
|
470
|
+
data.slice(outerLoopIndex, stringValueIndex)
|
|
471
|
+
);
|
|
448
472
|
isKey = false;
|
|
449
473
|
}
|
|
450
474
|
outerLoopIndex = ++stringValueIndex;
|
|
@@ -480,7 +504,10 @@ function parseObject<T>(data: string): T {
|
|
|
480
504
|
char = unsafeCharCodeAt(data, numberValueIndex);
|
|
481
505
|
if (char === commaCode || char === rightBraceCode || isSpace(char)) {
|
|
482
506
|
// @ts-ignore
|
|
483
|
-
schema.__JSON_Set_Key(
|
|
507
|
+
schema.__JSON_Set_Key(
|
|
508
|
+
key,
|
|
509
|
+
data.slice(outerLoopIndex - 1, numberValueIndex)
|
|
510
|
+
);
|
|
484
511
|
outerLoopIndex = numberValueIndex;
|
|
485
512
|
isKey = false;
|
|
486
513
|
break;
|
|
@@ -492,9 +519,7 @@ function parseObject<T>(data: string): T {
|
|
|
492
519
|
}
|
|
493
520
|
|
|
494
521
|
// @ts-ignore
|
|
495
|
-
@inline
|
|
496
|
-
// @ts-ignore
|
|
497
|
-
function parseArray<T extends unknown[]>(data: string): T {
|
|
522
|
+
@inline function parseArray<T extends unknown[]>(data: string): T {
|
|
498
523
|
if (isString<valueof<T>>()) {
|
|
499
524
|
return <T>parseStringArray(data);
|
|
500
525
|
} else if (isBoolean<valueof<T>>()) {
|
|
@@ -508,7 +533,10 @@ function parseArray<T extends unknown[]>(data: string): T {
|
|
|
508
533
|
return parseArrayArray<T>(data);
|
|
509
534
|
// @ts-ignore
|
|
510
535
|
} else if (isManaged<valueof<T>>() || isReference<valueof<T>>()) {
|
|
511
|
-
|
|
536
|
+
// We instantiate the required memory for the class and fill it. This is extremely unsafe and uses "a bit of magic".
|
|
537
|
+
const type = changetype<nonnull<valueof<T>>>(
|
|
538
|
+
__new(offsetof<nonnull<valueof<T>>>(), idof<nonnull<valueof<T>>>())
|
|
539
|
+
);
|
|
512
540
|
// @ts-ignore
|
|
513
541
|
if (isDefined(type.__JSON_Set_Key)) {
|
|
514
542
|
// @ts-ignore
|
|
@@ -520,8 +548,7 @@ function parseArray<T extends unknown[]>(data: string): T {
|
|
|
520
548
|
}
|
|
521
549
|
|
|
522
550
|
// @ts-ignore
|
|
523
|
-
@inline
|
|
524
|
-
function parseStringArray(data: string): string[] {
|
|
551
|
+
@inline function parseStringArray(data: string): string[] {
|
|
525
552
|
const result: string[] = [];
|
|
526
553
|
let lastPos = 0;
|
|
527
554
|
let instr = false;
|
|
@@ -540,23 +567,22 @@ function parseStringArray(data: string): string[] {
|
|
|
540
567
|
}
|
|
541
568
|
|
|
542
569
|
// @ts-ignore
|
|
543
|
-
@inline
|
|
544
|
-
function parseBooleanArray<T extends boolean[]>(data: string): T {
|
|
570
|
+
@inline function parseBooleanArray<T extends boolean[]>(data: string): T {
|
|
545
571
|
const result = instantiate<T>();
|
|
546
572
|
let lastPos = 1;
|
|
547
573
|
let char = 0;
|
|
548
574
|
for (let i = 1; i < data.length - 1; i++) {
|
|
549
575
|
char = unsafeCharCodeAt(data, i);
|
|
550
576
|
/*// if char == "t" && i+3 == "e"
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
577
|
+
if (char === tCode && data.charCodeAt(i + 3) === eCode) {
|
|
578
|
+
//i += 3;
|
|
579
|
+
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+2)));
|
|
580
|
+
//i++;
|
|
581
|
+
} else if (char === fCode && data.charCodeAt(i + 4) === eCode) {
|
|
582
|
+
//i += 4;
|
|
583
|
+
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+3)));
|
|
584
|
+
//i++;
|
|
585
|
+
}*/
|
|
560
586
|
if (char === tCode || char === fCode) {
|
|
561
587
|
lastPos = i;
|
|
562
588
|
} else if (char === eCode) {
|
|
@@ -568,8 +594,7 @@ function parseBooleanArray<T extends boolean[]>(data: string): T {
|
|
|
568
594
|
}
|
|
569
595
|
|
|
570
596
|
// @ts-ignore
|
|
571
|
-
@inline
|
|
572
|
-
function parseNumberArray<T extends number[]>(data: string): T {
|
|
597
|
+
@inline function parseNumberArray<T extends number[]>(data: string): T {
|
|
573
598
|
const result = instantiate<T>();
|
|
574
599
|
let lastPos = 0;
|
|
575
600
|
let char = 0;
|
|
@@ -594,8 +619,7 @@ function parseNumberArray<T extends number[]>(data: string): T {
|
|
|
594
619
|
}
|
|
595
620
|
|
|
596
621
|
// @ts-ignore
|
|
597
|
-
@inline
|
|
598
|
-
function parseArrayArray<T extends unknown[][]>(data: string): T {
|
|
622
|
+
@inline function parseArrayArray<T extends unknown[][]>(data: string): T {
|
|
599
623
|
const result = instantiate<T>();
|
|
600
624
|
let char = 0;
|
|
601
625
|
let lastPos = 0;
|
|
@@ -624,7 +648,7 @@ function parseArrayArray<T extends unknown[][]>(data: string): T {
|
|
|
624
648
|
}
|
|
625
649
|
|
|
626
650
|
// @ts-ignore
|
|
627
|
-
export function parseObjectArray<T extends unknown[]>(data: string): T {
|
|
651
|
+
@inline export function parseObjectArray<T extends unknown[]>(data: string): T {
|
|
628
652
|
const result = instantiate<T>();
|
|
629
653
|
let char = 0;
|
|
630
654
|
let lastPos: u32 = 1;
|
|
@@ -646,4 +670,4 @@ export function parseObjectArray<T extends unknown[]>(data: string): T {
|
|
|
646
670
|
}
|
|
647
671
|
}
|
|
648
672
|
return result;
|
|
649
|
-
}
|
|
673
|
+
}
|
package/assembly/src/util.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StringSink } from "as-string-sink/assembly";
|
|
2
|
-
import {
|
|
2
|
+
import { isSpace } from "util/string";
|
|
3
3
|
import { backSlashCode, quoteCode } from "./chars";
|
|
4
4
|
|
|
5
5
|
// @ts-ignore
|
|
@@ -8,6 +8,8 @@ export function unsafeCharCodeAt(data: string, pos: i32): i32 {
|
|
|
8
8
|
return load<u16>(changetype<usize>(data) + ((<usize>pos) << 1));
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
@inline
|
|
11
13
|
export function removeWhitespace(data: string): string {
|
|
12
14
|
const result = new StringSink();
|
|
13
15
|
let instr = false;
|
|
@@ -34,15 +36,24 @@ export function removeWhitespace(data: string): string {
|
|
|
34
36
|
@inline
|
|
35
37
|
export function escapeChar(char: string): string {
|
|
36
38
|
switch (unsafeCharCodeAt(char, 0)) {
|
|
37
|
-
case 0x22:
|
|
38
|
-
|
|
39
|
-
case
|
|
40
|
-
|
|
41
|
-
case
|
|
42
|
-
|
|
43
|
-
case
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
case 0x22:
|
|
40
|
+
return '\\"';
|
|
41
|
+
case 0x5c:
|
|
42
|
+
return "\\\\";
|
|
43
|
+
case 0x08:
|
|
44
|
+
return "\\b";
|
|
45
|
+
case 0x0a:
|
|
46
|
+
return "\\n";
|
|
47
|
+
case 0x0d:
|
|
48
|
+
return "\\r";
|
|
49
|
+
case 0x09:
|
|
50
|
+
return "\\t";
|
|
51
|
+
case 0x0c:
|
|
52
|
+
return "\\f";
|
|
53
|
+
case 0x0b:
|
|
54
|
+
return "\\u000b";
|
|
55
|
+
default:
|
|
56
|
+
return char;
|
|
46
57
|
}
|
|
47
58
|
}
|
|
48
59
|
|
|
@@ -51,6 +62,9 @@ export function escapeChar(char: string): string {
|
|
|
51
62
|
* Suffers no overhead besides function calling and a if/else.
|
|
52
63
|
* @returns depth of array
|
|
53
64
|
*/
|
|
65
|
+
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
@inline
|
|
54
68
|
export function getArrayDepth<T>(depth: i32 = 1): i32 {
|
|
55
69
|
// @ts-ignore
|
|
56
70
|
if (!isArray<T>()) {
|
|
@@ -68,15 +82,19 @@ export function getArrayDepth<T>(depth: i32 = 1): i32 {
|
|
|
68
82
|
/**
|
|
69
83
|
* Implementation of ATOI. Can be much much faster with SIMD.
|
|
70
84
|
* Benchmark: 40-46m ops/s
|
|
71
|
-
*/
|
|
72
|
-
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
// @ts-ignore
|
|
73
88
|
@inline
|
|
74
89
|
export function atoi_fast<T extends number>(str: string, offset: i32 = 0): T {
|
|
75
90
|
// @ts-ignore
|
|
76
91
|
let val: T = 0;
|
|
77
|
-
for (; offset <
|
|
92
|
+
for (; offset < str.length << 1; offset += 2) {
|
|
78
93
|
// @ts-ignore
|
|
79
|
-
val =
|
|
94
|
+
val =
|
|
95
|
+
(val << 1) +
|
|
96
|
+
(val << 3) +
|
|
97
|
+
(load<u16>(changetype<usize>(str) + <usize>offset) - 48);
|
|
80
98
|
// We use load because in this case, there is no need to have bounds-checking
|
|
81
99
|
}
|
|
82
100
|
return val;
|
|
@@ -87,20 +105,22 @@ export function atoi_fast<T extends number>(str: string, offset: i32 = 0): T {
|
|
|
87
105
|
* Benchmark: Hovers around 30m ops/s
|
|
88
106
|
* Only safe if the string is valid.
|
|
89
107
|
* @param str integer to parse. example: 123e1, 123e-1, 123E100
|
|
90
|
-
* @returns
|
|
108
|
+
* @returns
|
|
91
109
|
*/
|
|
110
|
+
|
|
111
|
+
// @ts-ignore
|
|
92
112
|
@inline
|
|
93
113
|
export function parseSciInteger<T extends number>(str: string): T {
|
|
94
114
|
// @ts-ignore
|
|
95
115
|
let val: T = 0;
|
|
96
116
|
let offset = 0;
|
|
97
|
-
for (; offset <
|
|
117
|
+
for (; offset < str.length << 1; offset += 2) {
|
|
98
118
|
const char = load<u16>(changetype<usize>(str) + <usize>offset);
|
|
99
119
|
if (char === 101 || char === 69) {
|
|
100
120
|
const char = load<u16>(changetype<usize>(str) + <usize>(offset += 2));
|
|
101
121
|
if (char === 45) {
|
|
102
122
|
// @ts-ignore
|
|
103
|
-
val /= sciNote<T>(atoi_fast<T>(str, offset += 2));
|
|
123
|
+
val /= sciNote<T>(atoi_fast<T>(str, (offset += 2)));
|
|
104
124
|
// @ts-ignore
|
|
105
125
|
return val;
|
|
106
126
|
} else {
|
|
@@ -117,6 +137,8 @@ export function parseSciInteger<T extends number>(str: string): T {
|
|
|
117
137
|
return val;
|
|
118
138
|
}
|
|
119
139
|
|
|
140
|
+
// @ts-ignore
|
|
141
|
+
@inline
|
|
120
142
|
function sciNote<T extends number>(num: T): T {
|
|
121
143
|
let res = 1;
|
|
122
144
|
if (num > 0) {
|
|
@@ -130,4 +152,4 @@ function sciNote<T extends number>(num: T): T {
|
|
|
130
152
|
}
|
|
131
153
|
// @ts-ignore
|
|
132
154
|
return res;
|
|
133
|
-
}
|
|
155
|
+
}
|