json-as 0.5.51 → 0.5.54
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/.github/workflows/nodejs.yml +25 -0
- package/LICENSE +17 -17
- package/README.md +0 -23
- package/assembly/__benches__/as-json.ts +23 -61
- package/assembly/__tests__/as-json.spec.ts +14 -26
- package/assembly/src/json.ts +47 -82
- package/assembly/src/util.ts +217 -56
- package/assembly/test.ts +4 -277
- package/bench-results/INTEGER-PARSING.md +52 -0
- package/bench.js +1 -3
- package/package.json +11 -8
- package/transform/lib/index.js +77 -48
- package/transform/package.json +1 -1
- package/asconfig.json +0 -15
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Node.js CI
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
|
|
10
|
+
steps:
|
|
11
|
+
- name: Checkout the repository
|
|
12
|
+
uses: actions/checkout@v2
|
|
13
|
+
|
|
14
|
+
- name: Setup Node.js
|
|
15
|
+
uses: actions/setup-node@v2
|
|
16
|
+
|
|
17
|
+
- name: Install dependencies
|
|
18
|
+
if: steps.node-cache.outputs.cache-hit != 'true'
|
|
19
|
+
run: yarn
|
|
20
|
+
|
|
21
|
+
- name: Test to see if the project compiles
|
|
22
|
+
run: yarn build:test
|
|
23
|
+
|
|
24
|
+
- name: Perform tests
|
|
25
|
+
run: yarn run test:aspect
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
MIT License
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Copyright (c) 2023 Jairus Tanaka <jairus.v.tanaka@outlook.com>
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -68,29 +68,6 @@ const stringified = JSON.stringify<Player>(player);
|
|
|
68
68
|
const parsed = JSON.parse<Player>(stringified);
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
## Deviations from the spec
|
|
72
|
-
|
|
73
|
-
This implementation does not hold strongly to the JSON specification. Rather, design and behavior are inspired by the JSON implementation found in Google's v8 engine.
|
|
74
|
-
|
|
75
|
-
- No support for dynamic types
|
|
76
|
-
- Unsafe by design--parser assumes valid JSON
|
|
77
|
-
- Partial whitespace support--parser prefers speed over handling whitespace effectively. Users may use the `removeWhitespace` function provided by `json-as/src/util.ts`
|
|
78
|
-
- Is not based off of the official spec, but rather the behavior of the JSON C implementation found in google's v8 engine
|
|
79
|
-
- Support for scientific notation on integers. Float support coming soon.
|
|
80
|
-
|
|
81
|
-
## Implemented features
|
|
82
|
-
|
|
83
|
-
Fully supports:
|
|
84
|
-
|
|
85
|
-
- Strings
|
|
86
|
-
- Integers
|
|
87
|
-
- Floats (Scientific notation not implemented)
|
|
88
|
-
- Booleans
|
|
89
|
-
- Arrays
|
|
90
|
-
- Objects
|
|
91
|
-
- Date
|
|
92
|
-
- Null
|
|
93
|
-
|
|
94
71
|
## Performance
|
|
95
72
|
|
|
96
73
|
Here are some benchmarks I took with `tinybench` (JavaScript) and `astral` (AssemblyScript).
|
|
@@ -1,64 +1,10 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
-
import {
|
|
3
|
-
import { atoi_fast, parseSciInteger, unsafeCharCodeAt } from "../src/util";
|
|
4
|
-
import { HASH } from "util/hash";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let last = 1;
|
|
8
|
-
let char = 0;
|
|
9
|
-
let inStr = false;
|
|
10
|
-
let key: string | null = null;
|
|
11
|
-
let pos = 0;
|
|
12
|
-
|
|
2
|
+
import { snip_fast } from "../src/util";
|
|
13
3
|
@json
|
|
14
4
|
class Vec3 {
|
|
15
5
|
x: i32;
|
|
16
6
|
y: i32;
|
|
17
7
|
z: i32;
|
|
18
|
-
@inline __JSON_Deserialize(
|
|
19
|
-
data: string,
|
|
20
|
-
to: Vec3
|
|
21
|
-
): Vec3 {
|
|
22
|
-
for (; pos < data.length - 1; pos++) {
|
|
23
|
-
char = unsafeCharCodeAt(data, pos);
|
|
24
|
-
if (inStr === false && char === quoteCode) {
|
|
25
|
-
if (key != null) {
|
|
26
|
-
if (unsafeCharCodeAt(key!, 0) == 120) {
|
|
27
|
-
to.x = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
28
|
-
} else if (unsafeCharCodeAt(key!, 0) == 121) {
|
|
29
|
-
to.y = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
30
|
-
} else if (unsafeCharCodeAt(key!, 0) == 122) {
|
|
31
|
-
to.z = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
last = ++pos;
|
|
35
|
-
inStr = true;
|
|
36
|
-
} else if (
|
|
37
|
-
char === quoteCode &&
|
|
38
|
-
unsafeCharCodeAt(data, pos - 1) != backSlashCode
|
|
39
|
-
) {
|
|
40
|
-
inStr = false;
|
|
41
|
-
key = data.substring(last, pos);
|
|
42
|
-
last = pos += 2;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (key != null) {
|
|
46
|
-
if (unsafeCharCodeAt(key!, 0) == 120) {
|
|
47
|
-
to.x = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
48
|
-
} else if (unsafeCharCodeAt(key!, 0) == 121) {
|
|
49
|
-
to.y = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
50
|
-
} else if (unsafeCharCodeAt(key!, 0) == 122) {
|
|
51
|
-
to.z = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
last = 1;
|
|
56
|
-
char = 0;
|
|
57
|
-
inStr = false;
|
|
58
|
-
key = null;
|
|
59
|
-
pos = 0;
|
|
60
|
-
return to;
|
|
61
|
-
}
|
|
62
8
|
}
|
|
63
9
|
|
|
64
10
|
const vec: Vec3 = {
|
|
@@ -66,15 +12,31 @@ const vec: Vec3 = {
|
|
|
66
12
|
y: 1,
|
|
67
13
|
z: 8,
|
|
68
14
|
}
|
|
15
|
+
|
|
16
|
+
bench("Parse Number SNIP", () => {
|
|
17
|
+
blackbox<i32>(snip_fast<i32>("12345"));
|
|
18
|
+
});
|
|
69
19
|
/*
|
|
20
|
+
bench("Parse Number ATOI", () => {
|
|
21
|
+
blackbox<i32>(atoi_fast<i32>("12345"));
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
bench("Parse Number STDLIB", () => {
|
|
25
|
+
blackbox<i32>(i32.parse("12345"));
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
bench("Parse Number OLD", () => {
|
|
29
|
+
blackbox<i32>(parseSciInteger<i32>("12345"));
|
|
30
|
+
});
|
|
31
|
+
*/
|
|
70
32
|
bench("Stringify Object (Vec3)", () => {
|
|
71
33
|
blackbox<string>(vec.__JSON_Serialize());
|
|
72
34
|
});
|
|
73
35
|
|
|
74
36
|
// TODO: Make this allocate without crashing
|
|
75
|
-
bench("Parse Object (Vec3)", () => {
|
|
76
|
-
blackbox<Vec3>(vec.__JSON_Deserialize('{"x":0,"y":0,"z":0}', vec));
|
|
77
|
-
});
|
|
37
|
+
//bench("Parse Object (Vec3)", () => {
|
|
38
|
+
// blackbox<Vec3>(vec.__JSON_Deserialize('{"x":0,"y":0,"z":0}', vec));
|
|
39
|
+
//});
|
|
78
40
|
|
|
79
41
|
bench("Stringify Number Array", () => {
|
|
80
42
|
blackbox(JSON.stringify<i32[]>([1, 2, 3]));
|
|
@@ -87,7 +49,7 @@ bench("Parse Number Array", () => {
|
|
|
87
49
|
bench("Stringify String", () => {
|
|
88
50
|
blackbox(JSON.stringify(blackbox('Hello "World!')));
|
|
89
51
|
});
|
|
90
|
-
|
|
52
|
+
|
|
91
53
|
bench("Parse String", () => {
|
|
92
54
|
blackbox(JSON.parse<string>(blackbox('"Hello "World!"')));
|
|
93
55
|
});
|
|
@@ -110,12 +72,12 @@ bench("Parse Boolean", () => {
|
|
|
110
72
|
|
|
111
73
|
bench("Stringify Integer", () => {
|
|
112
74
|
blackbox(JSON.stringify(blackbox(314)));
|
|
113
|
-
})
|
|
75
|
+
});*/
|
|
114
76
|
|
|
115
77
|
bench("Parse Integer", () => {
|
|
116
78
|
blackbox(JSON.parse<i32>(blackbox("314")));
|
|
117
79
|
});
|
|
118
|
-
|
|
80
|
+
/*
|
|
119
81
|
bench("Stringify Float", () => {
|
|
120
82
|
blackbox(JSON.stringify(blackbox(3.14)));
|
|
121
83
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
-
function canSerde<T>(data: T): void {
|
|
3
|
-
|
|
4
|
-
const deserialized = JSON.stringify<T>(JSON.parse<T>(
|
|
5
|
-
expect(
|
|
2
|
+
function canSerde<T>(data: T, toBe: string = ""): void {
|
|
3
|
+
if (!toBe) toBe = JSON.stringify<T>(data);
|
|
4
|
+
const deserialized = JSON.stringify<T>(JSON.parse<T>(JSON.stringify(data)));
|
|
5
|
+
expect(deserialized).toBe(toBe);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
// @ts-ignore
|
|
@@ -46,23 +46,20 @@ describe("Ser/de Numbers", () => {
|
|
|
46
46
|
it("should ser/de integers", () => {
|
|
47
47
|
canSerde<i32>(0);
|
|
48
48
|
|
|
49
|
-
canSerde<u32>(100);
|
|
50
|
-
canSerde<u64>(101);
|
|
51
|
-
canSerde<i32>(-100);
|
|
52
|
-
canSerde<i64>(-101);
|
|
49
|
+
canSerde<u32>(100, "100");
|
|
50
|
+
canSerde<u64>(101, "101");
|
|
51
|
+
canSerde<i32>(-100, "-100");
|
|
52
|
+
canSerde<i64>(-101, "-101");
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
it("should ser/de floats", () => {
|
|
56
|
-
canSerde<f64>(7.23);
|
|
57
|
-
canSerde<f64>(10e2);
|
|
58
|
-
canSerde<f64>(10e2);
|
|
56
|
+
canSerde<f64>(7.23, "7.23");
|
|
57
|
+
canSerde<f64>(10e2, "1000.0");
|
|
59
58
|
|
|
60
|
-
canSerde<f64>(123456e-5);
|
|
59
|
+
canSerde<f64>(123456e-5, "1.23456");
|
|
61
60
|
|
|
62
|
-
canSerde<f64>(
|
|
63
|
-
|
|
64
|
-
canSerde<f64>(0.0);
|
|
65
|
-
canSerde<f64>(7.23);
|
|
61
|
+
canSerde<f64>(0.0, "0.0");
|
|
62
|
+
canSerde<f64>(7.23, "7.23");
|
|
66
63
|
});
|
|
67
64
|
|
|
68
65
|
it("should ser/de booleans", () => {
|
|
@@ -71,15 +68,6 @@ describe("Ser/de Numbers", () => {
|
|
|
71
68
|
canSerde<boolean>(true);
|
|
72
69
|
canSerde<boolean>(false);
|
|
73
70
|
});
|
|
74
|
-
|
|
75
|
-
it("should ser/de BigInt objects", () => {
|
|
76
|
-
canSerde<i32>(0);
|
|
77
|
-
|
|
78
|
-
canSerde<u32>(100);
|
|
79
|
-
canSerde<u64>(101);
|
|
80
|
-
canSerde<i32>(-100);
|
|
81
|
-
canSerde<i64>(-101);
|
|
82
|
-
});
|
|
83
71
|
});
|
|
84
72
|
|
|
85
73
|
describe("Ser/de Array", () => {
|
|
@@ -161,6 +149,6 @@ describe("Ser/de Objects", () => {
|
|
|
161
149
|
z: 8.3,
|
|
162
150
|
},
|
|
163
151
|
isVerified: true,
|
|
164
|
-
});
|
|
152
|
+
}, '{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}');
|
|
165
153
|
});
|
|
166
154
|
});
|
package/assembly/src/json.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StringSink } from "as-string-sink/assembly";
|
|
2
|
-
import { isSpace
|
|
2
|
+
import { isSpace } from "util/string";
|
|
3
3
|
import {
|
|
4
4
|
backSlashCode,
|
|
5
5
|
commaCode,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
uCode,
|
|
22
22
|
emptyArrayWord,
|
|
23
23
|
} from "./chars";
|
|
24
|
-
import {
|
|
24
|
+
import { snip_fast, unsafeCharCodeAt } from "./util";
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* JSON Encoder/Decoder for AssemblyScript
|
|
@@ -35,14 +35,11 @@ export namespace JSON {
|
|
|
35
35
|
* @param data T
|
|
36
36
|
* @returns string
|
|
37
37
|
*/
|
|
38
|
-
// @ts-ignore
|
|
39
|
-
@inline export function stringify<
|
|
40
|
-
T
|
|
41
|
-
>(data: T): string {
|
|
38
|
+
// @ts-ignore: Decorator
|
|
39
|
+
@inline export function stringify<T>(data: T): string {
|
|
42
40
|
// String
|
|
43
41
|
if (isString<T>() && data != null) {
|
|
44
|
-
|
|
45
|
-
return serializeString(data);
|
|
42
|
+
return serializeString(data as string);
|
|
46
43
|
} else if (isBoolean<T>()) {
|
|
47
44
|
return data ? "true" : "false";
|
|
48
45
|
} else if (isNullable<T>() && data == null) {
|
|
@@ -51,9 +48,9 @@ export namespace JSON {
|
|
|
51
48
|
} else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
|
|
52
49
|
// @ts-ignore
|
|
53
50
|
return data.toString();
|
|
54
|
-
// @ts-ignore
|
|
51
|
+
// @ts-ignore: Hidden function
|
|
55
52
|
} else if (isDefined(data.__JSON_Serialize)) {
|
|
56
|
-
// @ts-ignore
|
|
53
|
+
// @ts-ignore: Hidden function
|
|
57
54
|
return data.__JSON_Serialize();
|
|
58
55
|
} else if (data instanceof Date) {
|
|
59
56
|
return data.toISOString();
|
|
@@ -110,10 +107,8 @@ export namespace JSON {
|
|
|
110
107
|
* @returns T
|
|
111
108
|
*/
|
|
112
109
|
|
|
113
|
-
// @ts-ignore
|
|
114
|
-
@inline export function parse<
|
|
115
|
-
T
|
|
116
|
-
>(data: string): T {
|
|
110
|
+
// @ts-ignore: Decorator
|
|
111
|
+
@inline export function parse<T>(data: string): T {
|
|
117
112
|
let type: T;
|
|
118
113
|
if (isString<T>()) {
|
|
119
114
|
// @ts-ignore
|
|
@@ -143,20 +138,17 @@ export namespace JSON {
|
|
|
143
138
|
);
|
|
144
139
|
}
|
|
145
140
|
}
|
|
146
|
-
// @ts-ignore
|
|
147
|
-
@inline function parseObjectValue<
|
|
148
|
-
T
|
|
149
|
-
>(data: string): T {
|
|
141
|
+
// @ts-ignore: Decorator
|
|
142
|
+
@inline function parseObjectValue<T>(data: string): T {
|
|
150
143
|
let type: T;
|
|
151
144
|
if (isString<T>()) {
|
|
152
145
|
// @ts-ignore
|
|
153
146
|
let result = "";
|
|
154
147
|
let last = 0;
|
|
155
|
-
let char = 0;
|
|
156
148
|
for (let i = 0; i < data.length; i++) {
|
|
157
149
|
// \\"
|
|
158
150
|
if (unsafeCharCodeAt(data, i) === backSlashCode) {
|
|
159
|
-
char = unsafeCharCodeAt(data, ++i);
|
|
151
|
+
const char = unsafeCharCodeAt(data, ++i);
|
|
160
152
|
result += data.slice(last, i - 1);
|
|
161
153
|
if (char === 34) {
|
|
162
154
|
result += '"';
|
|
@@ -184,7 +176,7 @@ export namespace JSON {
|
|
|
184
176
|
} else if (
|
|
185
177
|
char === 117 &&
|
|
186
178
|
load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
|
|
187
|
-
|
|
179
|
+
27584753879220272
|
|
188
180
|
) {
|
|
189
181
|
result += "\u000b";
|
|
190
182
|
i += 4;
|
|
@@ -223,10 +215,8 @@ export namespace JSON {
|
|
|
223
215
|
}
|
|
224
216
|
}
|
|
225
217
|
|
|
226
|
-
// @ts-ignore
|
|
227
|
-
@inline function serializeString(
|
|
228
|
-
data: string
|
|
229
|
-
): string {
|
|
218
|
+
// @ts-ignore: Decorator
|
|
219
|
+
@inline function serializeString(data: string): string {
|
|
230
220
|
// @ts-ignore
|
|
231
221
|
//if (data.length === 0) return "\"\"";
|
|
232
222
|
/*
|
|
@@ -309,10 +299,8 @@ export namespace JSON {
|
|
|
309
299
|
return result + '"';
|
|
310
300
|
}
|
|
311
301
|
|
|
312
|
-
// @ts-ignore
|
|
313
|
-
@inline function parseString(
|
|
314
|
-
data: string
|
|
315
|
-
): string {
|
|
302
|
+
// @ts-ignore: Decorator
|
|
303
|
+
@inline function parseString(data: string): string {
|
|
316
304
|
let result = "";
|
|
317
305
|
let last = 1;
|
|
318
306
|
for (let i = 1; i < data.length - 1; i++) {
|
|
@@ -359,7 +347,7 @@ export namespace JSON {
|
|
|
359
347
|
if (
|
|
360
348
|
char === 117 &&
|
|
361
349
|
load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
|
|
362
|
-
|
|
350
|
+
27584753879220272
|
|
363
351
|
) {
|
|
364
352
|
result += "\u000b";
|
|
365
353
|
i += 4;
|
|
@@ -375,22 +363,18 @@ export namespace JSON {
|
|
|
375
363
|
return result;
|
|
376
364
|
}
|
|
377
365
|
|
|
378
|
-
// @ts-ignore
|
|
379
|
-
@inline function parseBoolean<
|
|
380
|
-
T extends boolean
|
|
381
|
-
>(data: string): T {
|
|
366
|
+
// @ts-ignore: Decorator
|
|
367
|
+
@inline function parseBoolean<T extends boolean>(data: string): T {
|
|
382
368
|
if (data.length > 3 && data.startsWith("true")) return <T>true;
|
|
383
369
|
else if (data.length > 4 && data.startsWith("false")) return <T>false;
|
|
384
370
|
else throw new Error(`JSON: Cannot parse "${data}" as boolean`);
|
|
385
371
|
}
|
|
386
372
|
|
|
387
|
-
// @ts-ignore
|
|
388
|
-
@inline export function parseNumber<
|
|
389
|
-
T
|
|
390
|
-
>(data: string): T {
|
|
373
|
+
// @ts-ignore: Decorator
|
|
374
|
+
@inline export function parseNumber<T>(data: string): T {
|
|
391
375
|
if (isInteger<T>()) {
|
|
392
376
|
// @ts-ignore
|
|
393
|
-
return
|
|
377
|
+
return snip_fast<T>(data);
|
|
394
378
|
}
|
|
395
379
|
// @ts-ignore
|
|
396
380
|
const type: T = 0;
|
|
@@ -400,27 +384,24 @@ export namespace JSON {
|
|
|
400
384
|
else if (type instanceof f32) return f32.parse(data);
|
|
401
385
|
}
|
|
402
386
|
|
|
403
|
-
// @ts-ignore
|
|
404
|
-
@inline function parseObject<
|
|
405
|
-
T
|
|
406
|
-
>(data: string): T {
|
|
387
|
+
// @ts-ignore: Decorator
|
|
388
|
+
@inline function parseObject<T>(data: string): T {
|
|
407
389
|
let schema: nonnull<T> = changetype<nonnull<T>>(
|
|
408
390
|
__new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
|
|
409
391
|
);
|
|
410
392
|
let key = "";
|
|
411
393
|
let isKey = false;
|
|
412
394
|
let depth = 0;
|
|
413
|
-
let char = 0;
|
|
414
395
|
let outerLoopIndex = 1;
|
|
415
396
|
for (; outerLoopIndex < data.length - 1; outerLoopIndex++) {
|
|
416
|
-
char = unsafeCharCodeAt(data, outerLoopIndex);
|
|
397
|
+
const char = unsafeCharCodeAt(data, outerLoopIndex);
|
|
417
398
|
if (char === leftBracketCode) {
|
|
418
399
|
for (
|
|
419
400
|
let arrayValueIndex = outerLoopIndex;
|
|
420
401
|
arrayValueIndex < data.length - 1;
|
|
421
402
|
arrayValueIndex++
|
|
422
403
|
) {
|
|
423
|
-
char = unsafeCharCodeAt(data, arrayValueIndex);
|
|
404
|
+
const char = unsafeCharCodeAt(data, arrayValueIndex);
|
|
424
405
|
if (char === leftBracketCode) {
|
|
425
406
|
depth++;
|
|
426
407
|
} else if (char === rightBracketCode) {
|
|
@@ -444,7 +425,7 @@ export namespace JSON {
|
|
|
444
425
|
objectValueIndex < data.length - 1;
|
|
445
426
|
objectValueIndex++
|
|
446
427
|
) {
|
|
447
|
-
char = unsafeCharCodeAt(data, objectValueIndex);
|
|
428
|
+
const char = unsafeCharCodeAt(data, objectValueIndex);
|
|
448
429
|
if (char === leftBraceCode) {
|
|
449
430
|
depth++;
|
|
450
431
|
} else if (char === rightBraceCode) {
|
|
@@ -468,7 +449,7 @@ export namespace JSON {
|
|
|
468
449
|
stringValueIndex < data.length - 1;
|
|
469
450
|
stringValueIndex++
|
|
470
451
|
) {
|
|
471
|
-
char = unsafeCharCodeAt(data, stringValueIndex);
|
|
452
|
+
const char = unsafeCharCodeAt(data, stringValueIndex);
|
|
472
453
|
if (
|
|
473
454
|
char === quoteCode &&
|
|
474
455
|
unsafeCharCodeAt(data, stringValueIndex - 1) !== backSlashCode
|
|
@@ -514,7 +495,7 @@ export namespace JSON {
|
|
|
514
495
|
} else if ((char >= 48 && char <= 57) || char === 45) {
|
|
515
496
|
let numberValueIndex = ++outerLoopIndex;
|
|
516
497
|
for (; numberValueIndex < data.length; numberValueIndex++) {
|
|
517
|
-
char = unsafeCharCodeAt(data, numberValueIndex);
|
|
498
|
+
const char = unsafeCharCodeAt(data, numberValueIndex);
|
|
518
499
|
if (char === commaCode || char === rightBraceCode || isSpace(char)) {
|
|
519
500
|
// @ts-ignore
|
|
520
501
|
schema.__JSON_Set_Key(
|
|
@@ -531,10 +512,8 @@ export namespace JSON {
|
|
|
531
512
|
return schema;
|
|
532
513
|
}
|
|
533
514
|
|
|
534
|
-
// @ts-ignore
|
|
535
|
-
@inline function parseArray<
|
|
536
|
-
T extends unknown[]
|
|
537
|
-
>(data: string): T {
|
|
515
|
+
// @ts-ignore: Decorator
|
|
516
|
+
@inline function parseArray<T extends unknown[]>(data: string): T {
|
|
538
517
|
if (isString<valueof<T>>()) {
|
|
539
518
|
return <T>parseStringArray(data);
|
|
540
519
|
} else if (isBoolean<valueof<T>>()) {
|
|
@@ -562,10 +541,8 @@ export namespace JSON {
|
|
|
562
541
|
return unreachable();
|
|
563
542
|
}
|
|
564
543
|
|
|
565
|
-
// @ts-ignore
|
|
566
|
-
@inline function parseStringArray(
|
|
567
|
-
data: string
|
|
568
|
-
): string[] {
|
|
544
|
+
// @ts-ignore: Decorator
|
|
545
|
+
@inline function parseStringArray(data: string): string[] {
|
|
569
546
|
const result: string[] = [];
|
|
570
547
|
let lastPos = 0;
|
|
571
548
|
let instr = false;
|
|
@@ -583,15 +560,12 @@ export namespace JSON {
|
|
|
583
560
|
return result;
|
|
584
561
|
}
|
|
585
562
|
|
|
586
|
-
// @ts-ignore
|
|
587
|
-
@inline function parseBooleanArray<
|
|
588
|
-
T extends boolean[]
|
|
589
|
-
>(data: string): T {
|
|
563
|
+
// @ts-ignore: Decorator
|
|
564
|
+
@inline function parseBooleanArray<T extends boolean[]>(data: string): T {
|
|
590
565
|
const result = instantiate<T>();
|
|
591
566
|
let lastPos = 1;
|
|
592
|
-
let char = 0;
|
|
593
567
|
for (let i = 1; i < data.length - 1; i++) {
|
|
594
|
-
char = unsafeCharCodeAt(data, i);
|
|
568
|
+
const char = unsafeCharCodeAt(data, i);
|
|
595
569
|
/*// if char == "t" && i+3 == "e"
|
|
596
570
|
if (char === tCode && data.charCodeAt(i + 3) === eCode) {
|
|
597
571
|
//i += 3;
|
|
@@ -612,16 +586,13 @@ export namespace JSON {
|
|
|
612
586
|
return result;
|
|
613
587
|
}
|
|
614
588
|
|
|
615
|
-
// @ts-ignore
|
|
616
|
-
@inline function parseNumberArray<
|
|
617
|
-
T extends number[]
|
|
618
|
-
>(data: string): T {
|
|
589
|
+
// @ts-ignore: Decorator
|
|
590
|
+
@inline function parseNumberArray<T extends number[]>(data: string): T {
|
|
619
591
|
const result = instantiate<T>();
|
|
620
592
|
let lastPos = 0;
|
|
621
|
-
let char = 0;
|
|
622
593
|
let i = 1;
|
|
623
594
|
for (; i < data.length - 1; i++) {
|
|
624
|
-
char = unsafeCharCodeAt(data, i);
|
|
595
|
+
const char = unsafeCharCodeAt(data, i);
|
|
625
596
|
if ((lastPos === 0 && char >= 48 && char <= 57) || char === 45) {
|
|
626
597
|
lastPos = i;
|
|
627
598
|
} else if ((isSpace(char) || char == commaCode) && lastPos > 0) {
|
|
@@ -630,7 +601,7 @@ export namespace JSON {
|
|
|
630
601
|
}
|
|
631
602
|
}
|
|
632
603
|
for (; i > lastPos - 1; i--) {
|
|
633
|
-
char = unsafeCharCodeAt(data, i);
|
|
604
|
+
const char = unsafeCharCodeAt(data, i);
|
|
634
605
|
if (char !== rightBracketCode) {
|
|
635
606
|
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i + 1)));
|
|
636
607
|
break;
|
|
@@ -639,12 +610,9 @@ export namespace JSON {
|
|
|
639
610
|
return result;
|
|
640
611
|
}
|
|
641
612
|
|
|
642
|
-
// @ts-ignore
|
|
643
|
-
@inline function parseArrayArray<
|
|
644
|
-
T extends unknown[][]
|
|
645
|
-
>(data: string): T {
|
|
613
|
+
// @ts-ignore: Decorator
|
|
614
|
+
@inline function parseArrayArray<T extends unknown[][]>(data: string): T {
|
|
646
615
|
const result = instantiate<T>();
|
|
647
|
-
let char = 0;
|
|
648
616
|
let lastPos = 0;
|
|
649
617
|
let depth = 0;
|
|
650
618
|
let i = 1;
|
|
@@ -652,7 +620,7 @@ export namespace JSON {
|
|
|
652
620
|
//for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) {}
|
|
653
621
|
//i++;
|
|
654
622
|
for (; i < data.length - 1; i++) {
|
|
655
|
-
char = unsafeCharCodeAt(data, i);
|
|
623
|
+
const char = unsafeCharCodeAt(data, i);
|
|
656
624
|
if (char === leftBracketCode) {
|
|
657
625
|
if (depth === 0) {
|
|
658
626
|
lastPos = i;
|
|
@@ -670,16 +638,13 @@ export namespace JSON {
|
|
|
670
638
|
return result;
|
|
671
639
|
}
|
|
672
640
|
|
|
673
|
-
// @ts-ignore
|
|
674
|
-
@inline export function parseObjectArray<
|
|
675
|
-
T extends unknown[]
|
|
676
|
-
>(data: string): T {
|
|
641
|
+
// @ts-ignore: Decorator
|
|
642
|
+
@inline export function parseObjectArray<T extends unknown[]>(data: string): T {
|
|
677
643
|
const result = instantiate<T>();
|
|
678
|
-
let char = 0;
|
|
679
644
|
let lastPos: u32 = 1;
|
|
680
645
|
let depth: u32 = 0;
|
|
681
646
|
for (let pos: u32 = 0; pos < <u32>data.length; pos++) {
|
|
682
|
-
char = unsafeCharCodeAt(data, pos);
|
|
647
|
+
const char = unsafeCharCodeAt(data, pos);
|
|
683
648
|
if (char === leftBraceCode) {
|
|
684
649
|
if (depth === 0) {
|
|
685
650
|
lastPos = pos;
|