json-as 1.2.6 → 1.3.1

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.
Files changed (135) hide show
  1. package/CHANGELOG.md +417 -0
  2. package/README.md +135 -36
  3. package/assembly/custom/util.ts +24 -70
  4. package/assembly/deserialize/float.ts +181 -0
  5. package/assembly/deserialize/helpers/uint.ts +12 -0
  6. package/assembly/deserialize/index/arbitrary.ts +25 -0
  7. package/assembly/deserialize/index/array.ts +61 -0
  8. package/assembly/deserialize/index/bool.ts +1 -0
  9. package/assembly/deserialize/index/date.ts +1 -0
  10. package/assembly/deserialize/index/float.ts +1 -0
  11. package/assembly/deserialize/index/integer.ts +1 -0
  12. package/assembly/deserialize/index/map.ts +1 -0
  13. package/assembly/deserialize/index/object.ts +1 -0
  14. package/assembly/deserialize/index/raw.ts +1 -0
  15. package/assembly/deserialize/index/set.ts +1 -0
  16. package/assembly/deserialize/index/staticarray.ts +1 -0
  17. package/assembly/deserialize/index/string.ts +15 -0
  18. package/assembly/deserialize/index/struct.ts +1 -0
  19. package/assembly/deserialize/index/typedarray.ts +15 -0
  20. package/assembly/deserialize/index/unsigned.ts +1 -0
  21. package/assembly/deserialize/index.ts +14 -0
  22. package/assembly/deserialize/integer.ts +42 -0
  23. package/assembly/deserialize/simd/array/integer.ts +307 -0
  24. package/assembly/deserialize/simd/string.ts +130 -11
  25. package/assembly/deserialize/simple/arbitrary.ts +5 -12
  26. package/assembly/deserialize/simple/array/arbitrary.ts +12 -36
  27. package/assembly/deserialize/simple/array/array.ts +2 -8
  28. package/assembly/deserialize/simple/array/bool.ts +2 -8
  29. package/assembly/deserialize/simple/array/box.ts +2 -8
  30. package/assembly/deserialize/simple/array/float.ts +2 -8
  31. package/assembly/deserialize/simple/array/integer.ts +2 -8
  32. package/assembly/deserialize/simple/array/map.ts +6 -26
  33. package/assembly/deserialize/simple/array/object.ts +6 -26
  34. package/assembly/deserialize/simple/array/raw.ts +18 -61
  35. package/assembly/deserialize/simple/array/string.ts +5 -10
  36. package/assembly/deserialize/simple/array/struct.ts +6 -26
  37. package/assembly/deserialize/simple/array.ts +2 -5
  38. package/assembly/deserialize/simple/bool.ts +2 -6
  39. package/assembly/deserialize/simple/map.ts +29 -102
  40. package/assembly/deserialize/simple/object.ts +24 -81
  41. package/assembly/deserialize/simple/raw.ts +1 -4
  42. package/assembly/deserialize/simple/set.ts +11 -37
  43. package/assembly/deserialize/simple/staticarray/array.ts +1 -1
  44. package/assembly/deserialize/simple/staticarray/bool.ts +1 -1
  45. package/assembly/deserialize/simple/staticarray/float.ts +1 -1
  46. package/assembly/deserialize/simple/staticarray/integer.ts +1 -1
  47. package/assembly/deserialize/simple/staticarray/string.ts +7 -14
  48. package/assembly/deserialize/simple/staticarray/struct.ts +1 -1
  49. package/assembly/deserialize/simple/staticarray.ts +57 -21
  50. package/assembly/deserialize/simple/string.ts +90 -10
  51. package/assembly/deserialize/simple/struct.ts +25 -121
  52. package/assembly/deserialize/simple/typedarray.ts +94 -0
  53. package/assembly/deserialize/swar/array/arbitrary.ts +8 -0
  54. package/assembly/deserialize/swar/array/array.ts +39 -0
  55. package/assembly/deserialize/swar/array/bool.ts +47 -0
  56. package/assembly/deserialize/swar/array/box.ts +8 -0
  57. package/assembly/deserialize/swar/array/float.ts +39 -0
  58. package/assembly/deserialize/swar/array/integer.ts +461 -0
  59. package/assembly/deserialize/swar/array/map.ts +7 -0
  60. package/assembly/deserialize/swar/array/object.ts +44 -0
  61. package/assembly/deserialize/swar/array/raw.ts +8 -0
  62. package/assembly/deserialize/swar/array/shared.ts +96 -0
  63. package/assembly/deserialize/swar/array/string.ts +39 -0
  64. package/assembly/deserialize/swar/array/struct.ts +44 -0
  65. package/assembly/deserialize/swar/array.ts +49 -0
  66. package/assembly/deserialize/swar/string.ts +648 -15
  67. package/assembly/deserialize/unsigned.ts +75 -0
  68. package/assembly/index.d.ts +1 -3
  69. package/assembly/index.ts +316 -374
  70. package/assembly/serialize/index/arbitrary.ts +75 -0
  71. package/assembly/serialize/index/array.ts +1 -0
  72. package/assembly/serialize/index/bool.ts +1 -0
  73. package/assembly/serialize/index/date.ts +1 -0
  74. package/assembly/serialize/index/float.ts +1 -0
  75. package/assembly/serialize/index/integer.ts +1 -0
  76. package/assembly/serialize/index/map.ts +1 -0
  77. package/assembly/serialize/index/object.ts +46 -0
  78. package/assembly/serialize/index/raw.ts +1 -0
  79. package/assembly/serialize/index/set.ts +1 -0
  80. package/assembly/serialize/index/staticarray.ts +1 -0
  81. package/assembly/serialize/index/string.ts +15 -0
  82. package/assembly/serialize/index/struct.ts +1 -0
  83. package/assembly/serialize/index/typedarray.ts +66 -0
  84. package/assembly/serialize/index.ts +13 -0
  85. package/assembly/serialize/simd/string.ts +4 -13
  86. package/assembly/serialize/simple/arbitrary.ts +6 -0
  87. package/assembly/serialize/simple/raw.ts +1 -5
  88. package/assembly/serialize/simple/string.ts +3 -11
  89. package/assembly/serialize/simple/typedarray.ts +63 -0
  90. package/assembly/serialize/swar/string.ts +6 -21
  91. package/assembly/util/concat.ts +1 -5
  92. package/assembly/util/index.ts +1 -0
  93. package/assembly/util/masks.ts +12 -18
  94. package/assembly/util/memory.ts +0 -0
  95. package/assembly/util/snp.ts +1 -4
  96. package/assembly/util/stringScan.ts +24 -0
  97. package/assembly/util/swar.ts +50 -6
  98. package/lib/as-bs.ts +137 -127
  99. package/package.json +26 -5
  100. package/transform/lib/builder.d.ts.map +1 -1
  101. package/transform/lib/builder.js +5 -13
  102. package/transform/lib/builder.js.map +1 -1
  103. package/transform/lib/index.d.ts +1 -0
  104. package/transform/lib/index.d.ts.map +1 -1
  105. package/transform/lib/index.js +672 -757
  106. package/transform/lib/index.js.map +1 -1
  107. package/transform/lib/linkers/alias.d.ts.map +1 -1
  108. package/transform/lib/linkers/alias.js.map +1 -1
  109. package/transform/lib/linkers/custom.d.ts.map +1 -1
  110. package/transform/lib/linkers/custom.js +8 -9
  111. package/transform/lib/linkers/custom.js.map +1 -1
  112. package/transform/lib/linkers/imports.d.ts.map +1 -1
  113. package/transform/lib/linkers/imports.js.map +1 -1
  114. package/transform/lib/types.d.ts +6 -0
  115. package/transform/lib/types.d.ts.map +1 -1
  116. package/transform/lib/types.js +83 -21
  117. package/transform/lib/types.js.map +1 -1
  118. package/transform/lib/util.d.ts.map +1 -1
  119. package/transform/lib/util.js +1 -1
  120. package/transform/lib/util.js.map +1 -1
  121. package/transform/lib/visitor.d.ts.map +1 -1
  122. package/transform/lib/visitor.js +1 -2
  123. package/transform/lib/visitor.js.map +1 -1
  124. package/.prettierrc +0 -3
  125. package/ARCHITECTURE.md +0 -320
  126. package/CONTRIBUTING.md +0 -238
  127. package/TODO +0 -1
  128. package/assembly/deserialize/simple/float.ts +0 -11
  129. package/assembly/deserialize/simple/integer.ts +0 -9
  130. package/assembly/test.ts +0 -30
  131. package/eslint.config.js +0 -60
  132. package/lib/tsconfig.json +0 -8
  133. package/tools/assemblyscript-eslint-local.js +0 -29
  134. package/tools/assemblyscript-eslint.js +0 -29
  135. package/transform/tsconfig.json +0 -35
@@ -1,36 +1,72 @@
1
- import { deserializeStaticArrayInteger } from "./staticarray/integer";
2
- import { deserializeStaticArrayFloat } from "./staticarray/float";
1
+ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
2
+ import { JSON } from "../..";
3
+ import { deserializeArbitraryArray } from "./array/arbitrary";
4
+ import { deserializeArrayArray } from "./array/array";
5
+ import { deserializeBooleanArray } from "./array/bool";
6
+ import { deserializeBoxArray } from "./array/box";
7
+ import { deserializeFloatArray } from "./array/float";
8
+ import { deserializeIntegerArray } from "./array/integer";
9
+ import { deserializeMapArray } from "./array/map";
10
+ import { deserializeObjectArray } from "./array/object";
11
+ import { deserializeRawArray } from "./array/raw";
12
+ import { deserializeStructArray } from "./array/struct";
13
+ import { deserializeStringArray } from "./array/string";
3
14
  import { deserializeStaticArrayBoolean } from "./staticarray/bool";
15
+ import { deserializeStaticArrayFloat } from "./staticarray/float";
16
+ import { deserializeStaticArrayInteger } from "./staticarray/integer";
4
17
  import { deserializeStaticArrayString } from "./staticarray/string";
5
- import { deserializeStaticArrayArray } from "./staticarray/array";
6
- import { deserializeStaticArrayStruct } from "./staticarray/struct";
7
18
 
8
- export function deserializeStaticArray<T extends StaticArray<any>>(
9
- srcStart: usize,
10
- srcEnd: usize,
11
- dst: usize,
12
- ): T {
19
+
20
+ @inline function materializeStaticArray<T extends StaticArray<any>>(src: valueof<T>[], dst: usize): T {
21
+ const byteLength = <usize>src.length * sizeof<valueof<T>>();
22
+ let out = dst;
23
+
24
+ if (!out) {
25
+ out = __new(byteLength, idof<T>());
26
+ } else if (changetype<OBJECT>(out - TOTAL_OVERHEAD).rtSize != byteLength) {
27
+ out = __renew(out, byteLength);
28
+ }
29
+
30
+ const typed = changetype<T>(out);
31
+ for (let i = 0; i < src.length; i++) {
32
+ unchecked((typed[i] = unchecked(src[i])));
33
+ }
34
+ return typed;
35
+ }
36
+
37
+ export function deserializeStaticArray<T extends StaticArray<any>>(srcStart: usize, srcEnd: usize, dst: usize): T {
13
38
  if (isString<valueof<T>>()) {
14
- return <T>deserializeStaticArrayString(srcStart, srcEnd, dst);
39
+ return changetype<T>(deserializeStaticArrayString(srcStart, srcEnd, dst));
15
40
  } else if (isBoolean<valueof<T>>()) {
16
41
  return deserializeStaticArrayBoolean<T>(srcStart, srcEnd, dst);
17
42
  } else if (isInteger<valueof<T>>()) {
18
43
  return deserializeStaticArrayInteger<T>(srcStart, srcEnd, dst);
19
44
  } else if (isFloat<valueof<T>>()) {
20
45
  return deserializeStaticArrayFloat<T>(srcStart, srcEnd, dst);
21
- } else if (isArrayLike<valueof<T>>()) {
22
- return deserializeStaticArrayArray<T>(srcStart, srcEnd, dst);
46
+ } else if (isArray<valueof<T>>()) {
47
+ return materializeStaticArray<T>(deserializeArrayArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
23
48
  } else if (isManaged<valueof<T>>() || isReference<valueof<T>>()) {
24
49
  const type = changetype<nonnull<valueof<T>>>(0);
25
- if (isDefined(type.__DESERIALIZE)) {
26
- return deserializeStaticArrayStruct<T>(srcStart, srcEnd, dst);
50
+ if (type instanceof StaticArray) {
51
+ return materializeStaticArray<T>(deserializeArrayArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
52
+ } else if (type instanceof JSON.Value) {
53
+ return materializeStaticArray<T>(changetype<valueof<T>[]>(deserializeArbitraryArray(srcStart, srcEnd, 0)), dst);
54
+ } else if (type instanceof JSON.Box) {
55
+ return materializeStaticArray<T>(changetype<valueof<T>[]>(deserializeBoxArray<valueof<T>[]>(srcStart, srcEnd, 0)), dst);
56
+ } else if (type instanceof JSON.Obj) {
57
+ return materializeStaticArray<T>(deserializeObjectArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
58
+ } else if (type instanceof JSON.Raw) {
59
+ return materializeStaticArray<T>(changetype<valueof<T>[]>(deserializeRawArray(srcStart, srcEnd, 0)), dst);
60
+ } else if (type instanceof Map) {
61
+ return materializeStaticArray<T>(deserializeMapArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
62
+ // @ts-ignore: supplied by transform
63
+ } else if (isDefined(type.__DESERIALIZE_CUSTOM)) {
64
+ return materializeStaticArray<T>(deserializeStructArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
65
+ // @ts-ignore: supplied by transform
66
+ } else if (isDefined(type.__DESERIALIZE)) {
67
+ return materializeStaticArray<T>(deserializeStructArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
27
68
  }
28
- throw new Error(
29
- "Could not parse static array of type " + nameof<T>() + "!",
30
- );
31
- } else {
32
- throw new Error(
33
- "Could not parse static array of type " + nameof<T>() + "!",
34
- );
35
69
  }
70
+
71
+ throw new Error("Could not parse static array of type " + nameof<T>() + "!");
36
72
  }
@@ -1,19 +1,37 @@
1
+ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
1
2
  import { bs } from "../../../lib/as-bs";
2
- import {
3
- DESERIALIZE_ESCAPE_TABLE,
4
- ESCAPE_HEX_TABLE,
5
- } from "../../globals/tables";
3
+ import { BACK_SLASH, QUOTE } from "../../custom/chars";
4
+ import { DESERIALIZE_ESCAPE_TABLE, ESCAPE_HEX_TABLE } from "../../globals/tables";
6
5
  import { hex4_to_u16_swar } from "../../util/swar";
7
6
 
8
7
  // @ts-ignore: inline
9
- @inline export function deserializeString(
10
- srcStart: usize,
11
- srcEnd: usize,
12
- ): string {
8
+ @inline function writeStringToField(dstFieldPtr: usize, srcStart: usize, byteLength: u32): void {
9
+ if (byteLength == 0) {
10
+ store<usize>(dstFieldPtr, changetype<usize>(""));
11
+ return;
12
+ }
13
+
14
+ const current = load<usize>(dstFieldPtr);
15
+ let stringPtr: usize;
16
+ if (current != 0 && changetype<OBJECT>(current - TOTAL_OVERHEAD).rtSize == byteLength) {
17
+ stringPtr = current;
18
+ } else if (current != 0 && current != changetype<usize>("")) {
19
+ stringPtr = __renew(current, byteLength);
20
+ store<usize>(dstFieldPtr, stringPtr);
21
+ } else {
22
+ stringPtr = __new(byteLength, idof<string>());
23
+ store<usize>(dstFieldPtr, stringPtr);
24
+ }
25
+ memory.copy(stringPtr, srcStart, byteLength);
26
+ }
27
+
28
+ // @ts-ignore: inline
29
+ @inline export function deserializeString(srcStart: usize, srcEnd: usize): string {
13
30
  // Strip quotes
14
31
  srcStart += 2;
15
32
  srcEnd -= 2;
16
- bs.proposeSize(u32(srcEnd - srcStart));
33
+ const outStart = bs.offset - bs.buffer;
34
+ bs.ensureSize(u32(srcEnd - srcStart));
17
35
 
18
36
  while (srcStart < srcEnd) {
19
37
  const block = load<u16>(srcStart);
@@ -43,5 +61,67 @@ import { hex4_to_u16_swar } from "../../util/swar";
43
61
 
44
62
  bs.offset += 2;
45
63
  }
46
- return bs.out<string>();
64
+ return bs.sliceOut<string>(outStart);
65
+ }
66
+
67
+ // @ts-ignore: inline
68
+ @inline export function deserializeStringField<T extends string | null>(srcStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
69
+ if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE) abort("Expected leading quote");
70
+
71
+ const payloadStart = srcStart + 2;
72
+ srcStart = payloadStart;
73
+
74
+ while (srcStart < srcEnd) {
75
+ const char = load<u16>(srcStart);
76
+ if (char == QUOTE) {
77
+ writeStringToField(dstFieldPtr, payloadStart, <u32>(srcStart - payloadStart));
78
+ return srcStart + 2;
79
+ }
80
+ if (char != BACK_SLASH) {
81
+ srcStart += 2;
82
+ continue;
83
+ }
84
+
85
+ const outStart = bs.offset - bs.buffer;
86
+ bs.ensureSize(u32(srcEnd - payloadStart));
87
+ const prefixLen = <u32>(srcStart - payloadStart);
88
+ if (prefixLen != 0) {
89
+ memory.copy(bs.offset, payloadStart, prefixLen);
90
+ bs.offset += prefixLen;
91
+ }
92
+
93
+ while (srcStart < srcEnd) {
94
+ const block = load<u16>(srcStart);
95
+ if (block == QUOTE) {
96
+ bs.toField(outStart, dstFieldPtr);
97
+ return srcStart + 2;
98
+ }
99
+
100
+ if (block != BACK_SLASH) {
101
+ store<u16>(bs.offset, block);
102
+ srcStart += 2;
103
+ bs.offset += 2;
104
+ continue;
105
+ }
106
+
107
+ srcStart += 2;
108
+ const code = load<u16>(srcStart);
109
+ if (code !== 0x75) {
110
+ const escape = load<u16>(DESERIALIZE_ESCAPE_TABLE + code);
111
+ store<u16>(bs.offset, escape);
112
+ srcStart += 2;
113
+ } else {
114
+ const escaped = hex4_to_u16_swar(load<u64>(srcStart, 2));
115
+ store<u16>(bs.offset, escaped);
116
+ srcStart += 10;
117
+ }
118
+ bs.offset += 2;
119
+ }
120
+
121
+ bs.offset = bs.buffer + outStart;
122
+ break;
123
+ }
124
+
125
+ abort("Unterminated string literal");
126
+ return srcStart;
47
127
  }
@@ -1,23 +1,7 @@
1
- import {
2
- BACK_SLASH,
3
- COMMA,
4
- CHAR_F,
5
- BRACE_LEFT,
6
- BRACKET_LEFT,
7
- CHAR_N,
8
- QUOTE,
9
- BRACE_RIGHT,
10
- BRACKET_RIGHT,
11
- CHAR_T,
12
- COLON,
13
- } from "../../custom/chars";
14
- import { isSpace } from "../../util";
1
+ import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars";
2
+ import { isSpace, isUnescapedQuote, scanStringEnd } from "../../util";
15
3
 
16
- export function deserializeStruct<T>(
17
- srcStart: usize,
18
- srcEnd: usize,
19
- dst: usize,
20
- ): T {
4
+ export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize): T {
21
5
  const out = changetype<nonnull<T>>(dst || __new(offsetof<T>(), idof<T>()));
22
6
 
23
7
  // @ts-ignore: supplied by transform
@@ -32,35 +16,22 @@ export function deserializeStruct<T>(
32
16
  while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
33
17
  while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2; // would like to optimize this later
34
18
 
35
- if (srcStart - srcEnd == 0)
36
- throw new Error("Input string had zero length or was all whitespace");
37
- if (load<u16>(srcStart) != BRACE_LEFT)
38
- throw new Error(
39
- "Expected '{' at start of object at position " +
40
- (srcEnd - srcStart).toString(),
41
- );
42
- if (load<u16>(srcEnd - 2) != BRACE_RIGHT)
43
- throw new Error(
44
- "Expected '}' at end of object at position " +
45
- (srcEnd - srcStart).toString(),
46
- );
19
+ if (srcStart - srcEnd == 0) throw new Error("Input string had zero length or was all whitespace");
20
+ if (load<u16>(srcStart) != BRACE_LEFT) throw new Error("Expected '{' at start of object at position " + (srcEnd - srcStart).toString());
21
+ if (load<u16>(srcEnd - 2) != BRACE_RIGHT) throw new Error("Expected '}' at end of object at position " + (srcEnd - srcStart).toString());
47
22
 
48
23
  srcStart += 2;
49
24
  while (srcStart < srcEnd) {
50
25
  let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
51
26
  if (keyStart == 0) {
52
- if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
27
+ if (code == QUOTE && isUnescapedQuote(srcStart)) {
53
28
  if (isKey) {
54
29
  keyStart = lastIndex;
55
30
  keyEnd = srcStart;
56
31
  // console.log("Key: " + ptrToStr(lastIndex, srcStart));
57
32
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
58
33
  while (isSpace((code = load<u16>((srcStart += 2))))) {}
59
- if (code !== COLON)
60
- throw new Error(
61
- "Expected ':' after key at position " +
62
- (srcEnd - srcStart).toString(),
63
- );
34
+ if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcEnd - srcStart).toString());
64
35
  isKey = false;
65
36
  } else {
66
37
  // console.log("Got key start");
@@ -73,27 +44,13 @@ export function deserializeStruct<T>(
73
44
  } else {
74
45
  if (code == QUOTE) {
75
46
  lastIndex = srcStart;
47
+ srcStart = scanStringEnd(srcStart, srcEnd);
48
+ if (srcStart >= srcEnd) throw new Error("Unterminated string in JSON object");
49
+ // @ts-ignore: exists
50
+ out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart + 2, changetype<usize>(out));
76
51
  srcStart += 2;
77
- while (srcStart < srcEnd) {
78
- const code = load<u16>(srcStart);
79
- if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
80
- // console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
81
- // @ts-ignore: exists
82
- out.__DESERIALIZE(
83
- keyStart,
84
- keyEnd,
85
- lastIndex,
86
- srcStart + 2,
87
- changetype<usize>(out),
88
- );
89
- // while (isSpace(load<u16>(srcStart))) srcStart += 2;
90
- srcStart += 4;
91
- // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
92
- keyStart = 0;
93
- break;
94
- }
95
- srcStart += 2;
96
- }
52
+ keyStart = 0;
53
+ continue;
97
54
  } else if (code - 48 <= 9 || code == 45) {
98
55
  lastIndex = srcStart;
99
56
  srcStart += 2;
@@ -102,13 +59,7 @@ export function deserializeStruct<T>(
102
59
  if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
103
60
  // console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
104
61
  // @ts-ignore: exists
105
- out.__DESERIALIZE(
106
- keyStart,
107
- keyEnd,
108
- lastIndex,
109
- srcStart,
110
- changetype<usize>(out),
111
- );
62
+ out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart, changetype<usize>(out));
112
63
  // while (isSpace(load<u16>((srcStart += 2)))) {
113
64
  // /* empty */
114
65
  // }
@@ -126,25 +77,13 @@ export function deserializeStruct<T>(
126
77
  while (srcStart < srcEnd) {
127
78
  const code = load<u16>(srcStart);
128
79
  if (code == QUOTE) {
129
- srcStart += 2;
130
- while (
131
- !(
132
- load<u16>(srcStart) == QUOTE &&
133
- load<u16>(srcStart - 2) != BACK_SLASH
134
- )
135
- )
136
- srcStart += 2;
80
+ srcStart = scanStringEnd(srcStart, srcEnd);
81
+ if (srcStart >= srcEnd) throw new Error("Unterminated string in JSON object");
137
82
  } else if (code == BRACE_RIGHT) {
138
83
  if (--depth == 0) {
139
84
  // console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
140
85
  // @ts-ignore: exists
141
- out.__DESERIALIZE(
142
- keyStart,
143
- keyEnd,
144
- lastIndex,
145
- (srcStart += 2),
146
- changetype<usize>(out),
147
- );
86
+ out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), changetype<usize>(out));
148
87
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
149
88
  keyStart = 0;
150
89
  // while (isSpace(load<u16>(srcStart))) {
@@ -162,25 +101,13 @@ export function deserializeStruct<T>(
162
101
  while (srcStart < srcEnd) {
163
102
  const code = load<u16>(srcStart);
164
103
  if (code == QUOTE) {
165
- srcStart += 2;
166
- while (
167
- !(
168
- load<u16>(srcStart) == QUOTE &&
169
- load<u16>(srcStart - 2) != BACK_SLASH
170
- )
171
- )
172
- srcStart += 2;
104
+ srcStart = scanStringEnd(srcStart, srcEnd);
105
+ if (srcStart >= srcEnd) throw new Error("Unterminated string in JSON object");
173
106
  } else if (code == BRACKET_RIGHT) {
174
107
  if (--depth == 0) {
175
108
  // console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
176
109
  // @ts-ignore: exists
177
- out.__DESERIALIZE(
178
- keyStart,
179
- keyEnd,
180
- lastIndex,
181
- (srcStart += 2),
182
- changetype<usize>(out),
183
- );
110
+ out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), changetype<usize>(out));
184
111
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
185
112
  keyStart = 0;
186
113
  // while (isSpace(load<u16>((srcStart += 2)))) {
@@ -195,13 +122,7 @@ export function deserializeStruct<T>(
195
122
  if (load<u64>(srcStart) == 28429475166421108) {
196
123
  // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
197
124
  // @ts-ignore: exists
198
- out.__DESERIALIZE(
199
- keyStart,
200
- keyEnd,
201
- srcStart,
202
- (srcStart += 8),
203
- changetype<usize>(out),
204
- );
125
+ out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), changetype<usize>(out));
205
126
  // while (isSpace(load<u16>((srcStart += 2)))) {
206
127
  // /* empty */
207
128
  // }
@@ -213,13 +134,7 @@ export function deserializeStruct<T>(
213
134
  if (load<u64>(srcStart, 2) == 28429466576093281) {
214
135
  // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
215
136
  // @ts-ignore: exists
216
- out.__DESERIALIZE(
217
- keyStart,
218
- keyEnd,
219
- srcStart,
220
- (srcStart += 10),
221
- changetype<usize>(out),
222
- );
137
+ out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 10), changetype<usize>(out));
223
138
  // while (isSpace(load<u16>((srcStart += 2)))) {
224
139
  // /* empty */
225
140
  // }
@@ -231,13 +146,7 @@ export function deserializeStruct<T>(
231
146
  if (load<u64>(srcStart) == 30399761348886638) {
232
147
  // console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
233
148
  // @ts-ignore: exists
234
- out.__DESERIALIZE(
235
- keyStart,
236
- keyEnd,
237
- srcStart,
238
- (srcStart += 8),
239
- changetype<usize>(out),
240
- );
149
+ out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), changetype<usize>(out));
241
150
  // while (isSpace(load<u16>((srcStart += 2)))) {
242
151
  /* empty */
243
152
  // }
@@ -248,12 +157,7 @@ export function deserializeStruct<T>(
248
157
  } else if (isSpace(code)) {
249
158
  srcStart += 2;
250
159
  } else {
251
- throw new Error(
252
- "Unexpected character in JSON object '" +
253
- String.fromCharCode(code) +
254
- "' at position " +
255
- (srcEnd - srcStart).toString(),
256
- );
160
+ throw new Error("Unexpected character in JSON object '" + String.fromCharCode(code) + "' at position " + (srcEnd - srcStart).toString());
257
161
  }
258
162
  }
259
163
  }
@@ -0,0 +1,94 @@
1
+ import { COMMA, BRACKET_RIGHT } from "../../custom/chars";
2
+ import { deserializeFloat } from "../index/float";
3
+ import { atoi, isSpace } from "../../util";
4
+
5
+
6
+ @inline function countTypedArrayElements(srcStart: usize, srcEnd: usize): i32 {
7
+ let count = 0;
8
+
9
+ while (srcStart < srcEnd) {
10
+ const code = load<u16>(srcStart);
11
+ if (code - 48 <= 9 || code == 45) {
12
+ count++;
13
+ srcStart += 2;
14
+
15
+ while (srcStart < srcEnd) {
16
+ const code = load<u16>(srcStart);
17
+ if (code == COMMA || code == BRACKET_RIGHT || isSpace(code)) break;
18
+ srcStart += 2;
19
+ }
20
+ }
21
+
22
+ srcStart += 2;
23
+ }
24
+
25
+ return count;
26
+ }
27
+
28
+ export function deserializeTypedArray<T extends ArrayLike<number>>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
29
+ const count = countTypedArrayElements(srcStart, srcEnd);
30
+ let out = changetype<T>(dst || changetype<usize>(instantiate<T>(count)));
31
+
32
+ if (out.length != count) {
33
+ out = changetype<T>(instantiate<T>(count));
34
+ }
35
+
36
+ let index = 0;
37
+ while (srcStart < srcEnd) {
38
+ const code = load<u16>(srcStart);
39
+ if (code - 48 <= 9 || code == 45) {
40
+ const lastIndex = srcStart;
41
+ srcStart += 2;
42
+
43
+ while (srcStart < srcEnd) {
44
+ const code = load<u16>(srcStart);
45
+ if (code == COMMA || code == BRACKET_RIGHT || isSpace(code)) {
46
+ if (isFloat<valueof<T>>()) {
47
+ unchecked((out[index++] = deserializeFloat<valueof<T>>(lastIndex, srcStart)));
48
+ } else {
49
+ unchecked((out[index++] = atoi<valueof<T>>(lastIndex, srcStart)));
50
+ }
51
+ break;
52
+ }
53
+ srcStart += 2;
54
+ }
55
+ }
56
+
57
+ srcStart += 2;
58
+ }
59
+
60
+ return out;
61
+ }
62
+
63
+ export function deserializeArrayBuffer(srcStart: usize, srcEnd: usize, dst: usize = 0): ArrayBuffer {
64
+ const count = countTypedArrayElements(srcStart, srcEnd);
65
+ let out = dst ? changetype<ArrayBuffer>(dst) : new ArrayBuffer(count);
66
+
67
+ if (out.byteLength != count) {
68
+ out = new ArrayBuffer(count);
69
+ }
70
+
71
+ const outStart = changetype<usize>(out);
72
+ let index: usize = 0;
73
+
74
+ while (srcStart < srcEnd) {
75
+ const code = load<u16>(srcStart);
76
+ if (code - 48 <= 9 || code == 45) {
77
+ const lastIndex = srcStart;
78
+ srcStart += 2;
79
+
80
+ while (srcStart < srcEnd) {
81
+ const code = load<u16>(srcStart);
82
+ if (code == COMMA || code == BRACKET_RIGHT || isSpace(code)) {
83
+ store<u8>(outStart + index++, atoi<u8>(lastIndex, srcStart));
84
+ break;
85
+ }
86
+ srcStart += 2;
87
+ }
88
+ }
89
+
90
+ srcStart += 2;
91
+ }
92
+
93
+ return out;
94
+ }
@@ -0,0 +1,8 @@
1
+ import { JSON } from "../../..";
2
+ import { ensureArrayField } from "./shared";
3
+
4
+
5
+ @inline export function deserializeArbitraryArrayField(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
6
+ ensureArrayField<JSON.Value[]>(fieldPtr);
7
+ throw new Error("Failed to parse JSON!");
8
+ }
@@ -0,0 +1,39 @@
1
+ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../../custom/chars";
2
+ import { deserializeArrayField } from "../array";
3
+ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
4
+
5
+
6
+ @inline export function deserializeArrayArrayField<T extends unknown[][]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
7
+ const out = ensureArrayField<T>(fieldPtr);
8
+ let index = 0;
9
+
10
+ do {
11
+ if (srcStart >= srcEnd || load<u16>(srcStart) != BRACKET_LEFT) break;
12
+ srcStart += 2;
13
+ if (srcStart >= srcEnd) break;
14
+ if (load<u16>(srcStart) == BRACKET_RIGHT) {
15
+ out.length = 0;
16
+ return srcStart + 2;
17
+ }
18
+
19
+ while (srcStart < srcEnd) {
20
+ const slot = ensureArrayElementSlot<T>(out, index);
21
+ srcStart = deserializeArrayField<valueof<T>>(srcStart, srcEnd, slot);
22
+ if (!srcStart || srcStart >= srcEnd) break;
23
+
24
+ const code = load<u16>(srcStart);
25
+ if (code == COMMA) {
26
+ srcStart += 2;
27
+ index++;
28
+ continue;
29
+ }
30
+ if (code == BRACKET_RIGHT) {
31
+ out.length = index + 1;
32
+ return srcStart + 2;
33
+ }
34
+ break;
35
+ }
36
+ } while (false);
37
+
38
+ throw new Error("Failed to parse JSON!");
39
+ }
@@ -0,0 +1,47 @@
1
+ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA, FALSE_WORD_U64, TRUE_WORD_U64 } from "../../../custom/chars";
2
+ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
3
+
4
+
5
+ @inline export function deserializeBooleanArrayField<T extends boolean[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
6
+ const out = ensureArrayField<T>(fieldPtr);
7
+ let index = 0;
8
+
9
+ do {
10
+ if (srcStart >= srcEnd || load<u16>(srcStart) != BRACKET_LEFT) break;
11
+ srcStart += 2;
12
+ if (srcStart >= srcEnd) break;
13
+ if (load<u16>(srcStart) == BRACKET_RIGHT) {
14
+ out.length = 0;
15
+ return srcStart + 2;
16
+ }
17
+
18
+ while (srcStart < srcEnd) {
19
+ const slot = ensureArrayElementSlot<T>(out, index);
20
+ const block = load<u64>(srcStart);
21
+ if (block == TRUE_WORD_U64) {
22
+ store<valueof<T>>(slot, true);
23
+ srcStart += 8;
24
+ } else if (block == FALSE_WORD_U64) {
25
+ store<valueof<T>>(slot, false);
26
+ srcStart += 10;
27
+ } else {
28
+ break;
29
+ }
30
+
31
+ if (srcStart >= srcEnd) break;
32
+ const code = load<u16>(srcStart);
33
+ if (code == COMMA) {
34
+ srcStart += 2;
35
+ index++;
36
+ continue;
37
+ }
38
+ if (code == BRACKET_RIGHT) {
39
+ out.length = index + 1;
40
+ return srcStart + 2;
41
+ }
42
+ break;
43
+ }
44
+ } while (false);
45
+
46
+ throw new Error("Failed to parse JSON!");
47
+ }
@@ -0,0 +1,8 @@
1
+ import { JSON } from "../../..";
2
+ import { ensureArrayField } from "./shared";
3
+
4
+
5
+ @inline export function deserializeBoxArrayField<T extends JSON.Box<any>[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
6
+ ensureArrayField<T>(fieldPtr);
7
+ throw new Error("Failed to parse JSON!");
8
+ }
@@ -0,0 +1,39 @@
1
+ import { deserializeFloatField } from "../../float";
2
+ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../../custom/chars";
3
+ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
4
+
5
+
6
+ @inline export function deserializeFloatArrayField<T extends number[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
7
+ const out = ensureArrayField<T>(fieldPtr);
8
+ let index = 0;
9
+
10
+ do {
11
+ if (srcStart >= srcEnd || load<u16>(srcStart) != BRACKET_LEFT) break;
12
+ srcStart += 2;
13
+ if (srcStart >= srcEnd) break;
14
+ if (load<u16>(srcStart) == BRACKET_RIGHT) {
15
+ out.length = 0;
16
+ return srcStart + 2;
17
+ }
18
+
19
+ while (srcStart < srcEnd) {
20
+ const slot = ensureArrayElementSlot<T>(out, index);
21
+ srcStart = deserializeFloatField<valueof<T>>(srcStart, srcEnd, slot);
22
+ if (!srcStart || srcStart >= srcEnd) break;
23
+
24
+ const code = load<u16>(srcStart);
25
+ if (code == COMMA) {
26
+ srcStart += 2;
27
+ index++;
28
+ continue;
29
+ }
30
+ if (code == BRACKET_RIGHT) {
31
+ out.length = index + 1;
32
+ return srcStart + 2;
33
+ }
34
+ break;
35
+ }
36
+ } while (false);
37
+
38
+ throw new Error("Failed to parse JSON!");
39
+ }