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