json-as 0.4.2 → 0.4.5
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/LICENSE +0 -0
- package/README.md +39 -5
- package/as-pect.asconfig.json +24 -0
- package/as-pect.config.js +30 -0
- package/asconfig.json +1 -16
- package/assembly/__benches__/as-tral.d.ts +0 -0
- package/assembly/__benches__/benchmark.ts +35 -30
- package/assembly/__tests__/as-json.spec.ts +0 -0
- package/assembly/__tests__/as-pect.d.ts +1 -0
- package/assembly/chars.ts +2 -1
- package/assembly/index.ts +305 -190
- package/assembly/test.ts +67 -17
- package/assembly/tsconfig.json +0 -0
- package/assembly/util.ts +30 -0
- package/index.ts +0 -1
- package/package.json +7 -6
- package/tests/index.js +0 -0
- package/tests/test.js +0 -0
- package/transform/lib/index.js +74 -78
- package/transform/package.json +1 -2
- package/transform/src/index.old.js +0 -0
- package/transform/src/index.ts +109 -98
- package/transform/tsconfig.json +1 -1
package/assembly/index.ts
CHANGED
|
@@ -1,21 +1,48 @@
|
|
|
1
1
|
import { StringSink } from "as-string-sink/assembly";
|
|
2
2
|
import { Variant } from "as-variant/assembly";
|
|
3
|
+
import { isSpace } from "assemblyscript/std/assembly/util/string";
|
|
4
|
+
import { stringify } from "as-console/assembly";
|
|
3
5
|
import {
|
|
4
6
|
backSlashCode,
|
|
5
7
|
colonCode,
|
|
6
8
|
commaCode,
|
|
9
|
+
eCode,
|
|
10
|
+
fCode,
|
|
11
|
+
forwardSlashCode,
|
|
7
12
|
leftBraceCode,
|
|
8
13
|
leftBracketCode,
|
|
9
14
|
quoteCode,
|
|
10
15
|
rightBraceCode,
|
|
11
|
-
rightBracketCode
|
|
16
|
+
rightBracketCode,
|
|
17
|
+
tCode,
|
|
12
18
|
} from "./chars";
|
|
19
|
+
import { removeWhitespace, unsafeCharCodeAt } from "./util";
|
|
13
20
|
|
|
14
21
|
/**
|
|
15
22
|
* JSON Encoder/Decoder for AssemblyScript
|
|
16
23
|
*/
|
|
17
|
-
export
|
|
18
|
-
|
|
24
|
+
export class JSON {
|
|
25
|
+
private static parseObjectValue<T>(data: string): T {
|
|
26
|
+
let type!: T;
|
|
27
|
+
if (isString<T>()) {
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
return data.replaceAll('\\"', '"');
|
|
30
|
+
} else if (isBoolean<T>()) {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
return parseBoolean<T>(data);
|
|
33
|
+
} else if (isFloat<T>() || isInteger<T>()) {
|
|
34
|
+
return parseNumber<T>(data);
|
|
35
|
+
} else if (isArrayLike<T>()) {
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
return parseArray<T>(data);
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
} else if (isDefined(type.__JSON_Deserialize)) {
|
|
40
|
+
return parseObject<T>(data);
|
|
41
|
+
} else {
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
19
46
|
/**
|
|
20
47
|
* Stringifies valid JSON data.
|
|
21
48
|
* ```js
|
|
@@ -24,19 +51,15 @@ export namespace JSON {
|
|
|
24
51
|
* @param data T
|
|
25
52
|
* @returns string
|
|
26
53
|
*/
|
|
27
|
-
|
|
54
|
+
static stringify<T = Nullable | null>(data: T): string {
|
|
28
55
|
// String
|
|
29
|
-
if (isString(
|
|
30
|
-
return
|
|
56
|
+
if (isString<T>()) {
|
|
57
|
+
return '"' + (<string>data).replaceAll('"', '\\"') + '"';
|
|
31
58
|
}
|
|
32
59
|
// Boolean
|
|
33
|
-
else if (isBoolean(
|
|
60
|
+
else if (isBoolean<T>()) {
|
|
34
61
|
return data ? "true" : "false";
|
|
35
62
|
}
|
|
36
|
-
// Null
|
|
37
|
-
else if (isNullable<T>() && data == null) {
|
|
38
|
-
return "null";
|
|
39
|
-
}
|
|
40
63
|
// Integers/Floats
|
|
41
64
|
// @ts-ignore
|
|
42
65
|
else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
|
|
@@ -46,20 +69,28 @@ export namespace JSON {
|
|
|
46
69
|
// Class-Based serialization
|
|
47
70
|
// @ts-ignore
|
|
48
71
|
else if (isDefined(data.__JSON_Serialize)) {
|
|
49
|
-
|
|
72
|
+
// @ts-ignore
|
|
50
73
|
return data.__JSON_Serialize();
|
|
51
74
|
}
|
|
52
75
|
// ArrayLike
|
|
53
|
-
else if (isArrayLike(
|
|
76
|
+
else if (isArrayLike<T>()) {
|
|
54
77
|
let result = new StringSink("[");
|
|
78
|
+
// @ts-ignore
|
|
55
79
|
if (data.length == 0) return "[]";
|
|
80
|
+
// @ts-ignore
|
|
56
81
|
for (let i = 0; i < data.length - 1; i++) {
|
|
82
|
+
// @ts-ignore
|
|
57
83
|
result.write(stringify(unchecked(data[i])));
|
|
58
84
|
result.write(",");
|
|
59
85
|
}
|
|
86
|
+
// @ts-ignore
|
|
60
87
|
result.write(stringify(unchecked(data[data.length - 1])));
|
|
61
88
|
result.write("]");
|
|
62
89
|
return result.toString();
|
|
90
|
+
}
|
|
91
|
+
// Null
|
|
92
|
+
else if (isNullable<T>() && data == null) {
|
|
93
|
+
return "null";
|
|
63
94
|
} else {
|
|
64
95
|
return "null";
|
|
65
96
|
}
|
|
@@ -72,7 +103,7 @@ export namespace JSON {
|
|
|
72
103
|
* @param data string
|
|
73
104
|
* @returns T
|
|
74
105
|
*/
|
|
75
|
-
|
|
106
|
+
static parse<T = Variant>(data: string): T {
|
|
76
107
|
let type!: T;
|
|
77
108
|
if (isString<T>()) {
|
|
78
109
|
// @ts-ignore
|
|
@@ -83,48 +114,11 @@ export namespace JSON {
|
|
|
83
114
|
} else if (isFloat<T>() || isInteger<T>()) {
|
|
84
115
|
return parseNumber<T>(data);
|
|
85
116
|
} else if (isArrayLike<T>()) {
|
|
86
|
-
return parseArray<T>(data);
|
|
87
117
|
// @ts-ignore
|
|
88
|
-
|
|
89
|
-
const len: u32 = data.length - 1
|
|
90
|
-
let schema!: T
|
|
91
|
-
const result = new Map<string, string>()
|
|
92
|
-
let lastPos: u32 = 1
|
|
93
|
-
let key: string = ''
|
|
94
|
-
let instr: u32 = 0
|
|
95
|
-
let char: u32 = 0
|
|
96
|
-
let depth: u32 = 0
|
|
97
|
-
let fdepth: u32 = 0
|
|
98
|
-
for (let i: u32 = 1; i < len; i++) {
|
|
99
|
-
char = data.charCodeAt(i)
|
|
100
|
-
if (char === "\"".charCodeAt(0) && data.charCodeAt(i - 1) !== "/".charCodeAt(0)) instr = (instr ? 0 : 1)
|
|
101
|
-
else if (instr === 0) {
|
|
102
|
-
if (char === leftBraceCode || char === leftBracketCode) depth++
|
|
103
|
-
if (char === rightBraceCode || char === rightBracketCode) fdepth++
|
|
104
|
-
}
|
|
105
|
-
if (depth !== 0 && depth === fdepth) {
|
|
106
|
-
result.set(key, data.slice(lastPos + 1, i + 1))
|
|
107
|
-
// Reset the depth
|
|
108
|
-
depth = 0
|
|
109
|
-
fdepth = 0
|
|
110
|
-
// Set new lastPos
|
|
111
|
-
lastPos = i + 1
|
|
112
|
-
}
|
|
113
|
-
if (depth === 0) {
|
|
114
|
-
if (char === colonCode) {
|
|
115
|
-
key = data.slice(lastPos + 1, i - 1)
|
|
116
|
-
lastPos = i
|
|
117
|
-
}
|
|
118
|
-
else if (char === commaCode) {
|
|
119
|
-
if ((i - lastPos) > 0) result.set(key, data.slice(lastPos + 1, i))
|
|
120
|
-
lastPos = i + 1
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if ((len - lastPos) > 0) result.set(key, data.slice(lastPos + 1, len))
|
|
118
|
+
return parseArray<T>(data.trimStart());
|
|
126
119
|
// @ts-ignore
|
|
127
|
-
|
|
120
|
+
} else if (isDefined(type.__JSON_Deserialize)) {
|
|
121
|
+
return parseObject<T>(data.trimStart());
|
|
128
122
|
} else {
|
|
129
123
|
// @ts-ignore
|
|
130
124
|
return null;
|
|
@@ -134,25 +128,21 @@ export namespace JSON {
|
|
|
134
128
|
|
|
135
129
|
// @ts-ignore
|
|
136
130
|
@inline
|
|
137
|
-
|
|
138
|
-
return '"' + data.replaceAll('"', '\\"') + '"';
|
|
139
|
-
}
|
|
140
|
-
// @ts-ignore
|
|
141
|
-
@inline
|
|
142
|
-
function parseString(data: string): string {
|
|
131
|
+
function parseString(data: string): string {
|
|
143
132
|
return data.slice(1, data.length - 1).replaceAll('\\"', '"');
|
|
144
133
|
}
|
|
145
134
|
|
|
146
135
|
// @ts-ignore
|
|
147
136
|
@inline
|
|
148
|
-
|
|
137
|
+
function parseBoolean<T extends boolean>(data: string): T {
|
|
149
138
|
if (data.length > 3 && data.startsWith("true")) return <T>true;
|
|
150
139
|
else if (data.length > 4 && data.startsWith("false")) return <T>false;
|
|
151
140
|
else throw new Error(`JSON: Cannot parse "${data}" as boolean`);
|
|
152
141
|
}
|
|
142
|
+
|
|
153
143
|
// @ts-ignore
|
|
154
144
|
@inline
|
|
155
|
-
|
|
145
|
+
function parseNumber<T>(data: string): T {
|
|
156
146
|
let type: T;
|
|
157
147
|
// @ts-ignore
|
|
158
148
|
if (type instanceof f64) return F64.parseFloat(data);
|
|
@@ -176,162 +166,287 @@ export namespace JSON {
|
|
|
176
166
|
);
|
|
177
167
|
}
|
|
178
168
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
let
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
169
|
+
export function parseObject<T>(data: string): T {
|
|
170
|
+
let schema!: T;
|
|
171
|
+
const result = new Map<string, string>();
|
|
172
|
+
let key: usize = 0;
|
|
173
|
+
let depth = 1;
|
|
174
|
+
let char = 0;
|
|
175
|
+
for (
|
|
176
|
+
let outerLoopIndex = 1;
|
|
177
|
+
outerLoopIndex < data.length - 1;
|
|
178
|
+
outerLoopIndex++
|
|
179
|
+
) {
|
|
180
|
+
char = unsafeCharCodeAt(data, outerLoopIndex);
|
|
181
|
+
if (char === leftBracketCode) {
|
|
182
|
+
for (
|
|
183
|
+
let arrayValueIndex = outerLoopIndex;
|
|
184
|
+
arrayValueIndex < data.length - 1;
|
|
185
|
+
arrayValueIndex++
|
|
186
|
+
) {
|
|
187
|
+
char = unsafeCharCodeAt(data, arrayValueIndex);
|
|
188
|
+
if (char === leftBracketCode) {
|
|
189
|
+
depth = depth << 1;
|
|
190
|
+
} else if (char === rightBracketCode) {
|
|
191
|
+
depth = depth >> 1;
|
|
192
|
+
if (depth === 1) {
|
|
193
|
+
++arrayValueIndex;
|
|
194
|
+
result.set(
|
|
195
|
+
changetype<string>(key),
|
|
196
|
+
data.slice(outerLoopIndex, arrayValueIndex)
|
|
197
|
+
);
|
|
198
|
+
outerLoopIndex = arrayValueIndex;
|
|
199
|
+
key = 0;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
} else if (char === leftBraceCode) {
|
|
205
|
+
for (
|
|
206
|
+
let objectValueIndex = outerLoopIndex;
|
|
207
|
+
objectValueIndex < data.length - 1;
|
|
208
|
+
objectValueIndex++
|
|
209
|
+
) {
|
|
210
|
+
char = unsafeCharCodeAt(data, objectValueIndex);
|
|
211
|
+
if (char === leftBraceCode) {
|
|
212
|
+
depth = depth << 1;
|
|
213
|
+
} else if (char === rightBraceCode) {
|
|
214
|
+
depth = depth >> 1;
|
|
215
|
+
if (depth === 1) {
|
|
216
|
+
++objectValueIndex;
|
|
217
|
+
result.set(
|
|
218
|
+
changetype<string>(key),
|
|
219
|
+
data.slice(outerLoopIndex, objectValueIndex)
|
|
220
|
+
);
|
|
221
|
+
outerLoopIndex = objectValueIndex;
|
|
222
|
+
key = 0;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
} else if (char === quoteCode) {
|
|
228
|
+
for (
|
|
229
|
+
let stringValueIndex = ++outerLoopIndex;
|
|
230
|
+
stringValueIndex < data.length - 1;
|
|
231
|
+
stringValueIndex++
|
|
232
|
+
) {
|
|
233
|
+
char = unsafeCharCodeAt(data, stringValueIndex);
|
|
234
|
+
if (
|
|
235
|
+
char === quoteCode &&
|
|
236
|
+
unsafeCharCodeAt(data, stringValueIndex - 1) !== backSlashCode
|
|
237
|
+
) {
|
|
238
|
+
if (key === 0) {
|
|
239
|
+
key = changetype<usize>(
|
|
240
|
+
data.slice(outerLoopIndex, stringValueIndex)
|
|
241
|
+
);
|
|
242
|
+
} else {
|
|
243
|
+
result.set(
|
|
244
|
+
changetype<string>(key),
|
|
245
|
+
data.slice(outerLoopIndex, stringValueIndex)
|
|
246
|
+
);
|
|
247
|
+
key = 0;
|
|
248
|
+
}
|
|
249
|
+
outerLoopIndex = ++stringValueIndex;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
} else if (
|
|
254
|
+
char === tCode &&
|
|
255
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "r".charCodeAt(0) &&
|
|
256
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "u".charCodeAt(0) &&
|
|
257
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
258
|
+
) {
|
|
259
|
+
result.set(changetype<string>(key), "true");
|
|
260
|
+
key = 0;
|
|
261
|
+
} else if (
|
|
262
|
+
char === fCode &&
|
|
263
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "a".charCodeAt(0) &&
|
|
264
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "l".charCodeAt(0) &&
|
|
265
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "s".charCodeAt(0) &&
|
|
266
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
267
|
+
) {
|
|
268
|
+
result.set(changetype<string>(key), "false");
|
|
269
|
+
key = 0;
|
|
270
|
+
} else if (char >= 48 && char <= 57) {
|
|
271
|
+
let numberValueIndex = ++outerLoopIndex;
|
|
272
|
+
for (; numberValueIndex < data.length - 1; numberValueIndex++) {
|
|
273
|
+
char = unsafeCharCodeAt(data, numberValueIndex);
|
|
274
|
+
if (
|
|
275
|
+
char === commaCode ||
|
|
276
|
+
isSpace(char) ||
|
|
277
|
+
numberValueIndex == data.length - 2
|
|
278
|
+
) {
|
|
279
|
+
result.set(
|
|
280
|
+
changetype<string>(key),
|
|
281
|
+
data.slice(outerLoopIndex - 1, numberValueIndex)
|
|
282
|
+
);
|
|
283
|
+
outerLoopIndex = numberValueIndex;
|
|
284
|
+
key = 0;
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
194
288
|
}
|
|
195
289
|
}
|
|
196
|
-
//console.log(data.slice(lastPos, data.length - 1))
|
|
197
290
|
// @ts-ignore
|
|
198
|
-
|
|
291
|
+
return schema.__JSON_Deserialize(result);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// @ts-ignore
|
|
295
|
+
@inline
|
|
296
|
+
// @ts-ignore
|
|
297
|
+
export function parseArray<T extends unknown[]>(data: string): T {
|
|
298
|
+
// TODO: Replace with opt
|
|
299
|
+
let type!: valueof<T>;
|
|
300
|
+
if (type instanceof String) {
|
|
301
|
+
return <T>parseStringArray(data);
|
|
302
|
+
} else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
|
|
303
|
+
// @ts-ignore
|
|
304
|
+
return parseNumberArray<T>(data);
|
|
305
|
+
} else if (isBoolean<valueof<T>>()) {
|
|
199
306
|
// @ts-ignore
|
|
200
|
-
|
|
201
|
-
)
|
|
307
|
+
return parseBooleanArray<T>(data);
|
|
308
|
+
} else if (isArrayLike<valueof<T>>()) {
|
|
309
|
+
// @ts-ignore
|
|
310
|
+
return parseArrayArray<T>(data);
|
|
311
|
+
// @ts-ignore
|
|
312
|
+
} else if (isDefined(type.__JSON_Deserialize)) {
|
|
313
|
+
// @ts-ignore
|
|
314
|
+
return parseObjectArray<T>(data);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// @ts-ignore
|
|
319
|
+
@inline
|
|
320
|
+
export function parseStringArray(data: string): string[] {
|
|
321
|
+
const result: string[] = [];
|
|
322
|
+
let lastPos = 0;
|
|
323
|
+
let instr = false;
|
|
324
|
+
for (let i = 1; i < data.length - 1; i++) {
|
|
325
|
+
if (unsafeCharCodeAt(data, i) === quoteCode) {
|
|
326
|
+
if (instr === false) {
|
|
327
|
+
instr = true;
|
|
328
|
+
lastPos = i;
|
|
329
|
+
} else if (unsafeCharCodeAt(data, i - 1) !== backSlashCode) {
|
|
330
|
+
instr = false;
|
|
331
|
+
result.push(data.slice(lastPos + 1, i).replaceAll('\\"', '"'));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
202
335
|
return result;
|
|
203
336
|
}
|
|
204
337
|
|
|
205
338
|
// @ts-ignore
|
|
206
339
|
@inline
|
|
207
|
-
|
|
340
|
+
export function parseBooleanArray<T extends boolean[]>(data: string): T {
|
|
208
341
|
const result = instantiate<T>();
|
|
209
|
-
|
|
210
|
-
let
|
|
211
|
-
let i
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
char
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
342
|
+
let lastPos = 1;
|
|
343
|
+
let char = 0;
|
|
344
|
+
for (let i = 1; i < data.length - 1; i++) {
|
|
345
|
+
char = unsafeCharCodeAt(data, i);
|
|
346
|
+
/*// if char == "t" && i+3 == "e"
|
|
347
|
+
if (char === tCode && data.charCodeAt(i + 3) === eCode) {
|
|
348
|
+
//i += 3;
|
|
349
|
+
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+2)));
|
|
350
|
+
//i++;
|
|
351
|
+
} else if (char === fCode && data.charCodeAt(i + 4) === eCode) {
|
|
352
|
+
//i += 4;
|
|
353
|
+
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+3)));
|
|
354
|
+
//i++;
|
|
355
|
+
}*/
|
|
356
|
+
if (char === tCode || char === fCode) {
|
|
357
|
+
lastPos = i;
|
|
358
|
+
} else if (char === eCode) {
|
|
359
|
+
i++;
|
|
360
|
+
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i)));
|
|
219
361
|
}
|
|
220
362
|
}
|
|
221
|
-
// @ts-ignore
|
|
222
|
-
result.push(
|
|
223
|
-
// @ts-ignore
|
|
224
|
-
parseBoolean<valueof<T>>(data.slice(lastPos, data.length - 1).trimStart())
|
|
225
|
-
);
|
|
226
363
|
return result;
|
|
227
364
|
}
|
|
228
365
|
|
|
229
366
|
// @ts-ignore
|
|
230
367
|
@inline
|
|
231
|
-
|
|
368
|
+
export function parseNumberArray<T extends number[]>(data: string): T {
|
|
232
369
|
const result = instantiate<T>();
|
|
233
|
-
|
|
234
|
-
let
|
|
235
|
-
let
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
let inDepth: u32 = 0;
|
|
244
|
-
let outDepth: u32 = 0;
|
|
245
|
-
for (; i < len; i++) {
|
|
246
|
-
char = data.charCodeAt(i);
|
|
247
|
-
if (char == quoteCode && data.charCodeAt(i - 1) != backSlashCode)
|
|
248
|
-
isStr = !isStr;
|
|
249
|
-
if (char == leftBraceCode || char == leftBracketCode) {
|
|
250
|
-
inDepth++;
|
|
251
|
-
isStruct = true;
|
|
252
|
-
} else if (char == rightBraceCode || char == rightBracketCode) {
|
|
253
|
-
outDepth++;
|
|
254
|
-
isStruct = true;
|
|
255
|
-
}
|
|
256
|
-
if (!isStr) {
|
|
257
|
-
if (!isStruct) {
|
|
258
|
-
// This removes whitespace before and after an element
|
|
259
|
-
/*if (offset != 0 && isSpace(char)) {
|
|
260
|
-
lastPos++;
|
|
261
|
-
} else {
|
|
262
|
-
if (isSpace(char)) offset++;
|
|
263
|
-
}*/
|
|
264
|
-
// This checks to see if we are dealing with structures such as Objects and Arrays
|
|
265
|
-
if (char == commaCode) {
|
|
266
|
-
// @ts-ignore
|
|
267
|
-
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i).trim()));
|
|
268
|
-
//offset = 0;
|
|
269
|
-
lastPos = i + 1;
|
|
270
|
-
}
|
|
271
|
-
} else {
|
|
272
|
-
if (inDepth == outDepth) {
|
|
273
|
-
i++;
|
|
274
|
-
//console.log(`Struct-${data.slice(lastPos, i).trim()}-`)
|
|
275
|
-
lastPos = i + 1;
|
|
276
|
-
inDepth = 0;
|
|
277
|
-
outDepth = 0;
|
|
278
|
-
isStruct = false;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
370
|
+
let lastPos = 0;
|
|
371
|
+
let char = 0;
|
|
372
|
+
let i = 1;
|
|
373
|
+
for (; i < data.length - 1; i++) {
|
|
374
|
+
char = unsafeCharCodeAt(data, i);
|
|
375
|
+
if (lastPos === 0 && char >= 48 && char <= 57) {
|
|
376
|
+
lastPos = i;
|
|
377
|
+
} else if ((isSpace(char) || char == commaCode) && lastPos > 0) {
|
|
378
|
+
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i)));
|
|
379
|
+
lastPos = 0;
|
|
281
380
|
}
|
|
282
381
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
382
|
+
for (; i > lastPos; i--) {
|
|
383
|
+
char = unsafeCharCodeAt(data, i);
|
|
384
|
+
if (char !== rightBracketCode) {
|
|
385
|
+
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i + 1)));
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
288
388
|
}
|
|
289
|
-
char = data.charCodeAt(--len);
|
|
290
|
-
while (isSpace(char)) {
|
|
291
|
-
len--;
|
|
292
|
-
char = data.charCodeAt(len);
|
|
293
|
-
}*/
|
|
294
|
-
|
|
295
|
-
// @ts-ignore
|
|
296
|
-
// Handle empty arrays
|
|
297
|
-
data = data.slice(lastPos, len).trim();
|
|
298
|
-
// @ts-ignore
|
|
299
|
-
if (data.length != 0) result.push(JSON.parse<valueof<T>>(data));
|
|
300
|
-
//if (data.length != 0) console.log(`Trailing-${data.slice(lastPos, len).trim()}-`)
|
|
301
389
|
return result;
|
|
302
390
|
}
|
|
303
391
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
let char
|
|
309
|
-
let
|
|
310
|
-
let
|
|
311
|
-
let
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
lastPos =
|
|
320
|
-
isKey = true;
|
|
392
|
+
// @ts-ignore
|
|
393
|
+
@inline
|
|
394
|
+
export function parseArrayArray<T extends unknown[][]>(data: string): T {
|
|
395
|
+
const result = instantiate<T>();
|
|
396
|
+
let char = 0;
|
|
397
|
+
let lastPos = 0;
|
|
398
|
+
let depth = 1;
|
|
399
|
+
let i = 1;
|
|
400
|
+
// Find start of bracket
|
|
401
|
+
//for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) {}
|
|
402
|
+
//i++;
|
|
403
|
+
for (; i < data.length - 1; i++) {
|
|
404
|
+
char = unsafeCharCodeAt(data, i);
|
|
405
|
+
if (char === leftBracketCode) {
|
|
406
|
+
if (depth === 1) {
|
|
407
|
+
lastPos = i;
|
|
321
408
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
409
|
+
// Shifting is 6% faster than incrementing
|
|
410
|
+
depth = depth << 1;
|
|
411
|
+
} else if (char === rightBracketCode) {
|
|
412
|
+
depth = depth >> 1;
|
|
413
|
+
if (depth === 1) {
|
|
414
|
+
i++;
|
|
415
|
+
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i)));
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return result;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// @ts-ignore
|
|
423
|
+
@inline
|
|
424
|
+
export function parseObjectArray<T extends unknown[][]>(data: string): T {
|
|
425
|
+
const result = instantiate<T>();
|
|
426
|
+
let char = 0;
|
|
427
|
+
let lastPos = 1;
|
|
428
|
+
let depth = 1;
|
|
429
|
+
let i = 1;
|
|
430
|
+
// Find start of bracket
|
|
431
|
+
//for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) { }
|
|
432
|
+
//i++;
|
|
433
|
+
for (; i < data.length - 1; i++) {
|
|
434
|
+
char = unsafeCharCodeAt(data, i);
|
|
435
|
+
if (char === leftBraceCode) {
|
|
436
|
+
if (depth === 1) {
|
|
325
437
|
lastPos = i;
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
438
|
+
}
|
|
439
|
+
// Shifting is 6% faster than incrementing
|
|
440
|
+
depth = depth << 1;
|
|
441
|
+
} else if (char === rightBraceCode) {
|
|
442
|
+
depth = depth >> 1;
|
|
443
|
+
if (depth === 1) {
|
|
444
|
+
i++;
|
|
445
|
+
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i)));
|
|
329
446
|
}
|
|
330
447
|
}
|
|
331
448
|
}
|
|
332
|
-
result
|
|
333
|
-
//console.log(stringify(result))
|
|
334
|
-
//return obj
|
|
449
|
+
return result;
|
|
335
450
|
}
|
|
336
451
|
|
|
337
|
-
class Nullable {
|
|
452
|
+
class Nullable {}
|