json-as 0.8.6 → 0.8.8

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 (35) hide show
  1. package/CHANGELOG +2 -1
  2. package/assembly/__benches__/as-json.ts +1 -1
  3. package/assembly/deserialize/array/array.ts +31 -0
  4. package/assembly/deserialize/array/bool.ts +19 -0
  5. package/assembly/deserialize/array/float.ts +24 -0
  6. package/assembly/deserialize/array/integer.ts +24 -0
  7. package/assembly/deserialize/array/map.ts +27 -0
  8. package/assembly/deserialize/array/object.ts +27 -0
  9. package/assembly/deserialize/array/string.ts +29 -0
  10. package/assembly/deserialize/array.ts +37 -0
  11. package/assembly/deserialize/bool.ts +18 -0
  12. package/assembly/deserialize/box.ts +14 -0
  13. package/assembly/deserialize/date.ts +11 -0
  14. package/assembly/deserialize/float.ts +9 -0
  15. package/assembly/deserialize/integer.ts +7 -0
  16. package/assembly/deserialize/map.ts +182 -0
  17. package/assembly/deserialize/object.ts +139 -0
  18. package/assembly/deserialize/string.ts +88 -0
  19. package/assembly/serialize/array.ts +51 -0
  20. package/assembly/serialize/bool.ts +4 -0
  21. package/assembly/serialize/box.ts +10 -0
  22. package/assembly/serialize/date.ts +4 -0
  23. package/assembly/serialize/float.ts +4 -0
  24. package/assembly/serialize/integer.ts +5 -0
  25. package/assembly/serialize/map.ts +24 -0
  26. package/assembly/serialize/object.ts +7 -0
  27. package/assembly/serialize/string.ts +64 -0
  28. package/assembly/src/json.ts +55 -872
  29. package/assembly/src/sink.ts +286 -0
  30. package/assembly/src/util.ts +6 -0
  31. package/assembly/test.ts +8 -1
  32. package/package.json +1 -1
  33. package/transform/lib/index.js +3 -3
  34. package/transform/package.json +1 -1
  35. package/transform/src/index.ts +3 -3
@@ -0,0 +1,286 @@
1
+ import { itoa_buffered, dtoa_buffered } from "util/number";
2
+
3
+ const MIN_BUFFER_LEN = 32;
4
+ const MIN_BUFFER_SIZE: u32 = MIN_BUFFER_LEN << 1;
5
+
6
+ const NEW_LINE_CHAR: u16 = 0x0A; // \n
7
+
8
+ // @ts-ignore: decorator
9
+ @inline function nextPowerOf2(n: u32): u32 {
10
+ return 1 << 32 - clz(n - 1);
11
+ }
12
+
13
+ export class Sink {
14
+ public buffer!: ArrayBuffer;
15
+ public offset: u32 = 0;
16
+
17
+ static withCapacity(capacity: i32): Sink {
18
+ const sink = new Sink();
19
+ sink.buffer = changetype<ArrayBuffer>(__new(
20
+ max<u32>(MIN_BUFFER_SIZE, <u32>capacity << 1),
21
+ idof<ArrayBuffer>())
22
+ );
23
+ return sink;
24
+ }
25
+
26
+ static fromString(initial: string = "", capacity: i32 = MIN_BUFFER_LEN): Sink {
27
+ const sink = new Sink();
28
+ const size = <u32>initial.length << 1;
29
+ sink.buffer = changetype<ArrayBuffer>(__new(
30
+ max<u32>(size, max<u32>(MIN_BUFFER_SIZE, <u32>capacity << 1)),
31
+ idof<ArrayBuffer>())
32
+ );
33
+ if (size) {
34
+ memory.copy(
35
+ changetype<usize>(sink.buffer),
36
+ changetype<usize>(initial),
37
+ size
38
+ );
39
+ sink.offset += size;
40
+ }
41
+ return sink;
42
+ }
43
+
44
+ static fromStringLiteral(initial: string = ""): Sink {
45
+ const sink = new Sink();
46
+ const size = <u32>initial.length << 1;
47
+ sink.buffer = changetype<ArrayBuffer>(__new(
48
+ size,
49
+ idof<ArrayBuffer>())
50
+ );
51
+ if (size) {
52
+ memory.copy(
53
+ changetype<usize>(sink.buffer),
54
+ changetype<usize>(initial),
55
+ size
56
+ );
57
+ sink.offset += size;
58
+ }
59
+ return sink;
60
+ }
61
+
62
+ static fromBuffer(initial: ArrayBuffer, capacity: i32 = MIN_BUFFER_LEN): Sink {
63
+ const sink = new Sink();
64
+ const size = <u32>initial.byteLength;
65
+ sink.buffer = changetype<ArrayBuffer>(__new(
66
+ max<u32>(size, max<u32>(MIN_BUFFER_SIZE, <u32>capacity << 1)),
67
+ idof<ArrayBuffer>())
68
+ );
69
+ if (size) {
70
+ memory.copy(
71
+ changetype<usize>(sink.buffer),
72
+ changetype<usize>(initial),
73
+ size
74
+ );
75
+ sink.offset = size;
76
+ }
77
+ return sink;
78
+ }
79
+
80
+ constructor() { }
81
+
82
+ @inline get length(): i32 {
83
+ return this.offset >> 1;
84
+ }
85
+
86
+ @inline get capacity(): i32 {
87
+ return this.buffer.byteLength >>> 1;
88
+ }
89
+ @inline reset(): void {
90
+ this.offset = 0;
91
+ }
92
+ @inline write(src: string, start: i32 = 0, end: i32 = i32.MAX_VALUE): Sink | null {
93
+ let len = src.length as u32;
94
+
95
+ if (start != 0 || end != i32.MAX_VALUE) {
96
+ let from: i32;
97
+ from = min<i32>(max(start, 0), len);
98
+ end = min<i32>(max(end, 0), len);
99
+ start = min<i32>(from, end);
100
+ end = max<i32>(from, end);
101
+ len = end - start;
102
+ }
103
+
104
+ if (!len) return null;
105
+
106
+ let size = len << 1;
107
+ this.ensureCapacity(size);
108
+ let offset = this.offset;
109
+
110
+ memory.copy(
111
+ changetype<usize>(this.buffer) + offset,
112
+ changetype<usize>(src) + (<usize>start << 1),
113
+ size
114
+ );
115
+ this.offset = offset + size;
116
+ return this;
117
+ }
118
+
119
+ @inline writeLn(src: string = "", start: i32 = 0, end: i32 = i32.MAX_VALUE): Sink {
120
+ let len = src.length as u32;
121
+ if (start != 0 || end != i32.MAX_VALUE) {
122
+ let from: i32;
123
+ from = min<i32>(max(start, 0), len);
124
+ end = min<i32>(max(end, 0), len);
125
+ start = min<i32>(from, end);
126
+ end = max<i32>(from, end);
127
+ len = end - start;
128
+ }
129
+
130
+ let size = len << 1;
131
+ this.ensureCapacity(size + 2);
132
+ let offset = this.offset;
133
+ let dest = changetype<usize>(this.buffer) + offset;
134
+ if (size) memory.copy(dest, changetype<usize>(src) + (<usize>start << 1), size);
135
+ store<u16>(dest + size, NEW_LINE_CHAR);
136
+ this.offset = offset + (size + 2);
137
+ return this;
138
+ }
139
+
140
+ @inline writeCodePoint(code: i32): Sink {
141
+ let hasSur = <u32>code > 0xFFFF;
142
+ this.ensureCapacity(2 << i32(hasSur));
143
+
144
+ let offset = this.offset;
145
+ let dest = changetype<usize>(this.buffer) + offset;
146
+
147
+ if (!hasSur) {
148
+ store<u16>(dest, <u16>code);
149
+ this.offset = offset + 2;
150
+ } else {
151
+ assert(<u32>code <= 0x10FFFF);
152
+ code -= 0x10000;
153
+ let hi = (code & 0x03FF) | 0xDC00;
154
+ let lo = code >>> 10 | 0xD800;
155
+ store<u32>(dest, lo | hi << 16);
156
+ this.offset = offset + 4;
157
+ }
158
+ return this;
159
+ }
160
+
161
+ @inline writeCodePoint16(code: i32): Sink {
162
+ this.ensureCapacity(2);
163
+
164
+ let offset = this.offset;
165
+ let dest = changetype<usize>(this.buffer) + offset;
166
+
167
+ store<u16>(dest, <u16>code);
168
+ this.offset = offset + 2;
169
+
170
+ return this;
171
+ }
172
+
173
+ @inline writeCodePointUnsafe(code: i32): Sink {
174
+ this.ensureCapacity(2);
175
+
176
+ let offset = this.offset;
177
+ let dest = changetype<usize>(this.buffer) + offset;
178
+
179
+ code -= 0x10000;
180
+ let hi = (code & 0x03FF) | 0xDC00;
181
+ let lo = code >>> 10 | 0xD800;
182
+ store<u32>(dest, lo | hi << 16);
183
+ this.offset = offset + 4;
184
+ return this;
185
+ }
186
+
187
+ @inline writeNumber<T extends number>(value: T): Sink {
188
+ let offset = this.offset;
189
+ if (isInteger<T>()) {
190
+ let maxCapacity = 0;
191
+ // this also include size for sign
192
+ if (sizeof<T>() == 1) {
193
+ maxCapacity = 4 << 1;
194
+ } else if (sizeof<T>() == 2) {
195
+ maxCapacity = 6 << 1;
196
+ } else if (sizeof<T>() == 4) {
197
+ maxCapacity = 11 << 1;
198
+ } else if (sizeof<T>() == 8) {
199
+ maxCapacity = 21 << 1;
200
+ }
201
+ this.ensureCapacity(maxCapacity);
202
+ offset += itoa_buffered(
203
+ changetype<usize>(this.buffer) + offset,
204
+ value
205
+ ) << 1;
206
+ } else {
207
+ this.ensureCapacity(32 << 1);
208
+ offset += dtoa_buffered(
209
+ changetype<usize>(this.buffer) + offset,
210
+ value
211
+ ) << 1;
212
+ }
213
+ this.offset = offset;
214
+ return this;
215
+ }
216
+ @inline writeNumberUnsafe<T extends number>(value: T): Sink {
217
+ let offset = this.offset;
218
+ if (isInteger<T>()) {
219
+ offset += itoa_buffered(
220
+ changetype<usize>(this.buffer) + offset,
221
+ value
222
+ ) << 1;
223
+ } else {
224
+ offset += dtoa_buffered(
225
+ changetype<usize>(this.buffer) + offset,
226
+ value
227
+ ) << 1;
228
+ }
229
+ this.offset = offset;
230
+ return this;
231
+ }
232
+ @inline writeIntegerUnsafe<T extends number>(value: T): Sink {
233
+ let offset = this.offset;
234
+ if (isInteger<T>()) {
235
+ offset += itoa_buffered(
236
+ changetype<usize>(this.buffer) + offset,
237
+ value
238
+ ) << 1;
239
+ } else {
240
+ offset += dtoa_buffered(
241
+ changetype<usize>(this.buffer) + offset,
242
+ value
243
+ ) << 1;
244
+ }
245
+ this.offset = offset;
246
+ return this;
247
+ }
248
+
249
+ @inline reserve(capacity: i32, clear: bool = false): void {
250
+ if (clear) this.offset = 0;
251
+ this.buffer = changetype<ArrayBuffer>(__renew(
252
+ changetype<usize>(this.buffer),
253
+ max<u32>(this.offset, max<u32>(MIN_BUFFER_SIZE, <u32>capacity << 1))
254
+ ));
255
+ }
256
+
257
+ @inline shrink(): void {
258
+ this.buffer = changetype<ArrayBuffer>(__renew(
259
+ changetype<usize>(this.buffer),
260
+ max<u32>(this.offset, MIN_BUFFER_SIZE)
261
+ ));
262
+ }
263
+
264
+ @inline clear(): void {
265
+ this.reserve(0, true);
266
+ }
267
+
268
+ @inline toString(): string {
269
+ let size = this.offset;
270
+ if (!size) return "";
271
+ let out = changetype<string>(__new(size, idof<string>()));
272
+ memory.copy(changetype<usize>(out), changetype<usize>(this.buffer), size);
273
+ return out;
274
+ }
275
+
276
+ @inline ensureCapacity(deltaBytes: u32): void {
277
+ let buffer = this.buffer;
278
+ let newSize = this.offset + deltaBytes;
279
+ if (newSize > <u32>buffer.byteLength) {
280
+ this.buffer = changetype<ArrayBuffer>(__renew(
281
+ changetype<usize>(buffer),
282
+ nextPowerOf2(newSize)
283
+ ));
284
+ }
285
+ }
286
+ }
@@ -2,6 +2,12 @@ import { StringSink } from "as-string-sink/assembly";
2
2
  import { isSpace } from "util/string";
3
3
  import { backSlashCode, quoteCode } from "./chars";
4
4
 
5
+ // @ts-ignore: Decorator
6
+ @inline export function isMap<T>(): bool {
7
+ let type = changetype<T>(0);
8
+ return type instanceof Map;
9
+ }
10
+
5
11
  // @ts-ignore: Decorator
6
12
  @inline export function unsafeCharCodeAt(data: string, pos: i32): i32 {
7
13
  return load<u16>(changetype<usize>(data) + ((<usize>pos) << 1));
package/assembly/test.ts CHANGED
@@ -9,11 +9,18 @@ class Foo {
9
9
  tristateValue: Box<bool> | null = null;
10
10
  }
11
11
 
12
+ @json
13
+ class TestBody {
14
+ a!: string;
15
+ b!: u8;
16
+ }
17
+
12
18
  const foo: Foo = {
13
19
  optionalNumber: null,
14
20
  tristateValue: Box.from(true)
15
21
  }
16
-
22
+ console.log(JSON.stringify(JSON.parse<TestBody[]>('[{"a":"hi","b":5},{"a":"bye","b":6}]')))
23
+ console.log(JSON.stringify([foo, foo]))
17
24
  console.log(JSON.stringify(foo));
18
25
 
19
26
  const p1 = JSON.parse<Box<i32> | null>("null");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "0.8.6",
3
+ "version": "0.8.8",
4
4
  "description": "JSON encoder/decoder for AssemblyScript",
5
5
  "types": "assembly/index.ts",
6
6
  "author": "Jairus Tanaka",
@@ -39,7 +39,7 @@ class AsJSONTransform extends BaseVisitor {
39
39
  return;
40
40
  // Prevent from being triggered twice.
41
41
  for (const member of node.members) {
42
- if (member.name.text == "__JSON_Serialize")
42
+ if (member.name.text == "__SERIALIZE")
43
43
  return;
44
44
  }
45
45
  this.currentClass = {
@@ -151,13 +151,13 @@ class AsJSONTransform extends BaseVisitor {
151
151
  this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] =
152
152
  stmt.slice(0, stmt.length - 1);
153
153
  serializeFunc = `
154
- __JSON_Serialize(): string {
154
+ __SERIALIZE(): string {
155
155
  return \`{${this.currentClass.encodeStmts.join("")}}\`;
156
156
  }`;
157
157
  }
158
158
  else {
159
159
  serializeFunc = `
160
- __JSON_Serialize(): string {
160
+ __SERIALIZE(): string {
161
161
  return "{}";
162
162
  }`;
163
163
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@json-as/transform",
3
- "version": "0.8.6",
3
+ "version": "0.8.8",
4
4
  "description": "JSON encoder/decoder for AssemblyScript",
5
5
  "main": "./lib/index.js",
6
6
  "author": "Jairus Tanaka",
@@ -46,7 +46,7 @@ class AsJSONTransform extends BaseVisitor {
46
46
 
47
47
  // Prevent from being triggered twice.
48
48
  for (const member of node.members) {
49
- if (member.name.text == "__JSON_Serialize") return;
49
+ if (member.name.text == "__SERIALIZE") return;
50
50
  }
51
51
 
52
52
  this.currentClass = {
@@ -194,12 +194,12 @@ class AsJSONTransform extends BaseVisitor {
194
194
  this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] =
195
195
  stmt!.slice(0, stmt.length - 1);
196
196
  serializeFunc = `
197
- __JSON_Serialize(): string {
197
+ __SERIALIZE(): string {
198
198
  return \`{${this.currentClass.encodeStmts.join("")}}\`;
199
199
  }`;
200
200
  } else {
201
201
  serializeFunc = `
202
- __JSON_Serialize(): string {
202
+ __SERIALIZE(): string {
203
203
  return "{}";
204
204
  }`;
205
205
  }