@es-joy/jsoe 0.27.0 → 0.28.0
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/CHANGES.md +33 -0
- package/README.md +3 -1
- package/badges/coverage-badge.svg +1 -1
- package/badges/tests-badge.svg +1 -0
- package/dist/formats/schema.d.ts +11 -0
- package/dist/formats/schema.d.ts.map +1 -1
- package/dist/formats/structuredCloning.d.ts.map +1 -1
- package/dist/fundamentalTypes/arrayType.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/typeChoices.d.ts +32 -2
- package/dist/typeChoices.d.ts.map +1 -1
- package/dist/types.d.ts +8 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/rawTypesonEditor.d.ts +110 -0
- package/dist/utils/rawTypesonEditor.d.ts.map +1 -0
- package/dist/vendor-imports.d.ts +4 -0
- package/docs/proposals/raw-typeson-edit-view.md +575 -0
- package/mmr.json +6 -0
- package/package.json +13 -4
- package/pnpm-workspace.yaml +1 -0
- package/src/formats/schema.js +3 -1
- package/src/formats/structuredCloning.js +24 -17
- package/src/fundamentalTypes/arrayType.js +105 -1
- package/src/jsoe.css +12 -0
- package/src/typeChoices.js +36 -7
- package/src/types.js +13 -2
- package/src/utils/rawTypesonEditor.js +669 -0
- package/src/vendor-imports.js +12 -0
- package/tsconfig.json +1 -1
- package/typings/json-6.d.ts +12 -0
- package/vendor/@codemirror/autocomplete/dist/index.js +2125 -0
- package/vendor/@codemirror/commands/dist/index.js +1826 -0
- package/vendor/@codemirror/lang-javascript/dist/index.js +513 -0
- package/vendor/@codemirror/language/dist/index.js +2693 -0
- package/vendor/@codemirror/lint/dist/index.js +956 -0
- package/vendor/@codemirror/search/dist/index.js +1238 -0
- package/vendor/@codemirror/state/dist/index.js +3947 -0
- package/vendor/@codemirror/view/dist/index.js +11867 -0
- package/vendor/@lezer/common/dist/index.js +2202 -0
- package/vendor/@lezer/highlight/dist/index.js +927 -0
- package/vendor/@lezer/javascript/dist/index.js +192 -0
- package/vendor/@lezer/lr/dist/index.js +1889 -0
- package/vendor/@marijn/find-cluster-break/src/index.js +87 -0
- package/vendor/codemirror/dist/index.js +96 -0
- package/vendor/crelt/index.js +28 -0
- package/vendor/json-6/dist/index.mjs +1783 -0
- package/vendor/style-mod/src/style-mod.js +172 -0
- package/vendor/w3c-keyname/index.js +119 -0
|
@@ -0,0 +1,1783 @@
|
|
|
1
|
+
function createCommonjsModule(fn, module) {
|
|
2
|
+
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
var json6 = createCommonjsModule(function (module, exports) {
|
|
6
|
+
|
|
7
|
+
const version = "1.1.1";
|
|
8
|
+
const VALUE_UNDEFINED = -1;
|
|
9
|
+
const VALUE_UNSET = 0;
|
|
10
|
+
const VALUE_NULL = 1;
|
|
11
|
+
const VALUE_TRUE = 2;
|
|
12
|
+
const VALUE_FALSE = 3;
|
|
13
|
+
const VALUE_STRING = 4;
|
|
14
|
+
const VALUE_NUMBER = 5;
|
|
15
|
+
const VALUE_OBJECT = 6;
|
|
16
|
+
const VALUE_ARRAY = 7;
|
|
17
|
+
const VALUE_NEG_NAN = 8;
|
|
18
|
+
const VALUE_NAN = 9;
|
|
19
|
+
const VALUE_NEG_INFINITY = 10;
|
|
20
|
+
const VALUE_INFINITY = 11; // const VALUE_DATE = 12 // unused yet
|
|
21
|
+
|
|
22
|
+
const VALUE_EMPTY = 13; // [,] makes an array with 'empty item'
|
|
23
|
+
|
|
24
|
+
const WORD_POS_RESET = 0;
|
|
25
|
+
const WORD_POS_TRUE_1 = 1;
|
|
26
|
+
const WORD_POS_TRUE_2 = 2;
|
|
27
|
+
const WORD_POS_TRUE_3 = 3;
|
|
28
|
+
const WORD_POS_FALSE_1 = 5;
|
|
29
|
+
const WORD_POS_FALSE_2 = 6;
|
|
30
|
+
const WORD_POS_FALSE_3 = 7;
|
|
31
|
+
const WORD_POS_FALSE_4 = 8;
|
|
32
|
+
const WORD_POS_NULL_1 = 9;
|
|
33
|
+
const WORD_POS_NULL_2 = 10;
|
|
34
|
+
const WORD_POS_NULL_3 = 11;
|
|
35
|
+
const WORD_POS_UNDEFINED_1 = 12;
|
|
36
|
+
const WORD_POS_UNDEFINED_2 = 13;
|
|
37
|
+
const WORD_POS_UNDEFINED_3 = 14;
|
|
38
|
+
const WORD_POS_UNDEFINED_4 = 15;
|
|
39
|
+
const WORD_POS_UNDEFINED_5 = 16;
|
|
40
|
+
const WORD_POS_UNDEFINED_6 = 17;
|
|
41
|
+
const WORD_POS_UNDEFINED_7 = 18;
|
|
42
|
+
const WORD_POS_UNDEFINED_8 = 19;
|
|
43
|
+
const WORD_POS_NAN_1 = 20;
|
|
44
|
+
const WORD_POS_NAN_2 = 21;
|
|
45
|
+
const WORD_POS_INFINITY_1 = 22;
|
|
46
|
+
const WORD_POS_INFINITY_2 = 23;
|
|
47
|
+
const WORD_POS_INFINITY_3 = 24;
|
|
48
|
+
const WORD_POS_INFINITY_4 = 25;
|
|
49
|
+
const WORD_POS_INFINITY_5 = 26;
|
|
50
|
+
const WORD_POS_INFINITY_6 = 27;
|
|
51
|
+
const WORD_POS_INFINITY_7 = 28;
|
|
52
|
+
const WORD_POS_FIELD = 29;
|
|
53
|
+
const WORD_POS_AFTER_FIELD = 30;
|
|
54
|
+
const WORD_POS_END = 31;
|
|
55
|
+
const CONTEXT_UNKNOWN = 0;
|
|
56
|
+
const CONTEXT_IN_ARRAY = 1; // const CONTEXT_IN_OBJECT = 2
|
|
57
|
+
|
|
58
|
+
const CONTEXT_OBJECT_FIELD = 3;
|
|
59
|
+
const CONTEXT_OBJECT_FIELD_VALUE = 4;
|
|
60
|
+
const contexts = [];
|
|
61
|
+
|
|
62
|
+
function getContext() {
|
|
63
|
+
return contexts.pop() || {
|
|
64
|
+
context: CONTEXT_UNKNOWN,
|
|
65
|
+
elements: null,
|
|
66
|
+
element_array: null
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function dropContext(ctx) {
|
|
71
|
+
contexts.push(ctx);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const buffers = [];
|
|
75
|
+
|
|
76
|
+
function getBuffer() {
|
|
77
|
+
let buf = buffers.pop();
|
|
78
|
+
if (!buf) buf = {
|
|
79
|
+
buf: null,
|
|
80
|
+
n: 0
|
|
81
|
+
};else buf.n = 0;
|
|
82
|
+
return buf;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function dropBuffer(buf) {
|
|
86
|
+
buffers.push(buf);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const JSON6 = exports // istanbul ignore next
|
|
90
|
+
;
|
|
91
|
+
/*
|
|
92
|
+
let _DEBUG_LL = true;
|
|
93
|
+
let _DEBUG_PARSING = true;
|
|
94
|
+
let _DEBUG_PARSING_STACK = true;
|
|
95
|
+
|
|
96
|
+
const log = function(type) {
|
|
97
|
+
if (type === '_DEBUG_PARSING' && !_DEBUG_PARSING) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (type === '_DEBUG_PARSING_STACK' && !_DEBUG_PARSING_STACK) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (type === '_DEBUG_LL' && !_DEBUG_LL) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
console.log.apply(console, [].slice.call(arguments, 1));
|
|
107
|
+
};
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
JSON6.escape = function (string) {
|
|
111
|
+
let output = '';
|
|
112
|
+
if (!string) return string;
|
|
113
|
+
|
|
114
|
+
for (let n = 0; n < string.length; n++) {
|
|
115
|
+
const ch = string[n];
|
|
116
|
+
|
|
117
|
+
if (ch == '"' || ch == '\\' || ch == '`' || ch == '\'') {
|
|
118
|
+
output += '\\';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
output += ch;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return output;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
JSON6.begin = function (cb, reviver) {
|
|
128
|
+
const val = {
|
|
129
|
+
name: null,
|
|
130
|
+
// name of this value (if it's contained in an object)
|
|
131
|
+
value_type: VALUE_UNSET,
|
|
132
|
+
// value from above indiciating the type of this value
|
|
133
|
+
string: '',
|
|
134
|
+
// the string value of this value (strings and number types only)
|
|
135
|
+
contains: null
|
|
136
|
+
};
|
|
137
|
+
const pos = {
|
|
138
|
+
line: 1,
|
|
139
|
+
col: 1
|
|
140
|
+
};
|
|
141
|
+
let n = 0;
|
|
142
|
+
let word = WORD_POS_RESET,
|
|
143
|
+
status = true,
|
|
144
|
+
negative = false,
|
|
145
|
+
result = null,
|
|
146
|
+
elements = undefined,
|
|
147
|
+
element_array = [],
|
|
148
|
+
parse_context = CONTEXT_UNKNOWN,
|
|
149
|
+
comment = 0,
|
|
150
|
+
fromHex = false,
|
|
151
|
+
decimal = false,
|
|
152
|
+
exponent = false,
|
|
153
|
+
exponent_sign = false,
|
|
154
|
+
exponent_digit = false,
|
|
155
|
+
gatheringStringFirstChar = null,
|
|
156
|
+
gatheringString = false,
|
|
157
|
+
gatheringNumber = false,
|
|
158
|
+
stringEscape = false,
|
|
159
|
+
cr_escaped = false,
|
|
160
|
+
unicodeWide = false,
|
|
161
|
+
stringUnicode = false,
|
|
162
|
+
stringHex = false,
|
|
163
|
+
hex_char = 0,
|
|
164
|
+
hex_char_len = 0,
|
|
165
|
+
completed = false;
|
|
166
|
+
const context_stack = {
|
|
167
|
+
first: null,
|
|
168
|
+
last: null,
|
|
169
|
+
saved: null,
|
|
170
|
+
|
|
171
|
+
push(node) {
|
|
172
|
+
let recover = this.saved;
|
|
173
|
+
|
|
174
|
+
if (recover) {
|
|
175
|
+
this.saved = recover.next;
|
|
176
|
+
recover.node = node;
|
|
177
|
+
recover.next = null;
|
|
178
|
+
recover.prior = this.last;
|
|
179
|
+
} else {
|
|
180
|
+
recover = {
|
|
181
|
+
node: node,
|
|
182
|
+
next: null,
|
|
183
|
+
prior: this.last
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (!this.last) this.first = recover;
|
|
188
|
+
this.last = recover;
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
pop() {
|
|
192
|
+
const result = this.last;
|
|
193
|
+
if (!(this.last = result.prior)) this.first = null;
|
|
194
|
+
result.next = this.saved;
|
|
195
|
+
this.saved = result;
|
|
196
|
+
return result.node;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
};
|
|
200
|
+
const inQueue = {
|
|
201
|
+
first: null,
|
|
202
|
+
last: null,
|
|
203
|
+
saved: null,
|
|
204
|
+
|
|
205
|
+
push(node) {
|
|
206
|
+
let recover = this.saved;
|
|
207
|
+
|
|
208
|
+
if (recover) {
|
|
209
|
+
this.saved = recover.next;
|
|
210
|
+
recover.node = node;
|
|
211
|
+
recover.next = null;
|
|
212
|
+
recover.prior = this.last;
|
|
213
|
+
} else {
|
|
214
|
+
recover = {
|
|
215
|
+
node: node,
|
|
216
|
+
next: null,
|
|
217
|
+
prior: this.last
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (!this.last) this.first = recover;else this.last.next = recover;
|
|
222
|
+
this.last = recover;
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
shift() {
|
|
226
|
+
const result = this.first;
|
|
227
|
+
if (!result) return null;
|
|
228
|
+
this.first = result.next;
|
|
229
|
+
if (!this.first) this.last = null;
|
|
230
|
+
result.next = this.saved;
|
|
231
|
+
this.saved = result; // node is in saved...
|
|
232
|
+
|
|
233
|
+
return result.node;
|
|
234
|
+
},
|
|
235
|
+
|
|
236
|
+
unshift(node) {
|
|
237
|
+
// usage in this module, recover will ALWAYS have a saved to use.
|
|
238
|
+
const recover = this.saved; //if( recover ) {
|
|
239
|
+
|
|
240
|
+
this.saved = recover.next;
|
|
241
|
+
recover.node = node;
|
|
242
|
+
recover.next = this.first;
|
|
243
|
+
recover.prior = null; //} else { recover = { node : node, next : this.first, prior : null }; }
|
|
244
|
+
|
|
245
|
+
if (!this.first) this.last = recover;
|
|
246
|
+
this.first = recover;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
function throwEndError(leader
|
|
252
|
+
/* , c */
|
|
253
|
+
) {
|
|
254
|
+
throw new Error(`${leader} at ${n} [${pos.line}:${pos.col}]`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
finalError() {
|
|
259
|
+
if (comment !== 0) {
|
|
260
|
+
// most of the time everything's good.
|
|
261
|
+
switch (comment) {
|
|
262
|
+
case 1:
|
|
263
|
+
return throwEndError("Comment began at end of document");
|
|
264
|
+
|
|
265
|
+
case 2:
|
|
266
|
+
console.log("Warning: '//' comment without end of line ended document");
|
|
267
|
+
break;
|
|
268
|
+
|
|
269
|
+
case 3:
|
|
270
|
+
return throwEndError("Open comment '/*' is missing close at end of document");
|
|
271
|
+
|
|
272
|
+
case 4:
|
|
273
|
+
return throwEndError("Incomplete '/* *' close at end of document");
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (gatheringString) throwEndError("Incomplete string");
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
value() {
|
|
281
|
+
this.finalError();
|
|
282
|
+
const r = result;
|
|
283
|
+
result = undefined;
|
|
284
|
+
return r;
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
reset() {
|
|
288
|
+
word = WORD_POS_RESET;
|
|
289
|
+
status = true;
|
|
290
|
+
if (inQueue.last) inQueue.last.next = inQueue.save;
|
|
291
|
+
inQueue.save = inQueue.first;
|
|
292
|
+
inQueue.first = inQueue.last = null;
|
|
293
|
+
if (context_stack.last) context_stack.last.next = context_stack.save;
|
|
294
|
+
context_stack.save = inQueue.first;
|
|
295
|
+
context_stack.first = context_stack.last = null; //= [];
|
|
296
|
+
|
|
297
|
+
element_array = null;
|
|
298
|
+
elements = undefined;
|
|
299
|
+
parse_context = CONTEXT_UNKNOWN;
|
|
300
|
+
val.value_type = VALUE_UNSET;
|
|
301
|
+
val.name = null;
|
|
302
|
+
val.string = '';
|
|
303
|
+
pos.line = 1;
|
|
304
|
+
pos.col = 1;
|
|
305
|
+
negative = false;
|
|
306
|
+
comment = 0;
|
|
307
|
+
completed = false;
|
|
308
|
+
gatheringString = false;
|
|
309
|
+
stringEscape = false; // string stringEscape intro
|
|
310
|
+
|
|
311
|
+
cr_escaped = false; // carraige return escaped
|
|
312
|
+
//stringUnicode = false; // reading \u
|
|
313
|
+
//unicodeWide = false; // reading \u{} in string
|
|
314
|
+
//stringHex = false; // reading \x in string
|
|
315
|
+
},
|
|
316
|
+
|
|
317
|
+
write(msg) {
|
|
318
|
+
let retcode;
|
|
319
|
+
if (msg !== undefined && typeof msg !== "string") msg = String(msg);
|
|
320
|
+
if (!status) throw new Error("Parser is in an error state, please reset.");
|
|
321
|
+
|
|
322
|
+
for (retcode = this._write(msg, false); retcode > 0; retcode = this._write()) {
|
|
323
|
+
this.finalError();
|
|
324
|
+
if (typeof reviver === 'function') (function walk(holder, key) {
|
|
325
|
+
const value = holder[key];
|
|
326
|
+
|
|
327
|
+
if (value && typeof value === 'object') {
|
|
328
|
+
for (const k in value) {
|
|
329
|
+
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
|
330
|
+
const v = walk(value, k);
|
|
331
|
+
|
|
332
|
+
if (v !== undefined) {
|
|
333
|
+
value[k] = v;
|
|
334
|
+
} else {
|
|
335
|
+
delete value[k];
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return reviver.call(holder, key, value);
|
|
342
|
+
})({
|
|
343
|
+
'': result
|
|
344
|
+
}, '');
|
|
345
|
+
cb(result);
|
|
346
|
+
result = undefined;
|
|
347
|
+
if (retcode < 2) break;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (retcode) this.finalError();
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
_write(msg, complete_at_end) {
|
|
354
|
+
let input;
|
|
355
|
+
let buf;
|
|
356
|
+
let retval = 0;
|
|
357
|
+
|
|
358
|
+
function throwError(leader, c) {
|
|
359
|
+
throw new Error(`${leader} '${String.fromCodePoint(c)}' unexpected at ${n} (near '${buf.substr(n > 4 ? n - 4 : 0, n > 4 ? 3 : n - 1)}[${String.fromCodePoint(c)}]${buf.substr(n, 10)}') [${pos.line}:${pos.col}]`);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function RESET_VAL() {
|
|
363
|
+
val.value_type = VALUE_UNSET;
|
|
364
|
+
val.string = '';
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function arrayPush() {
|
|
368
|
+
switch (val.value_type) {
|
|
369
|
+
case VALUE_NUMBER:
|
|
370
|
+
element_array.push((negative ? -1 : 1) * Number(val.string));
|
|
371
|
+
break;
|
|
372
|
+
|
|
373
|
+
case VALUE_STRING:
|
|
374
|
+
element_array.push(val.string);
|
|
375
|
+
break;
|
|
376
|
+
|
|
377
|
+
case VALUE_TRUE:
|
|
378
|
+
element_array.push(true);
|
|
379
|
+
break;
|
|
380
|
+
|
|
381
|
+
case VALUE_FALSE:
|
|
382
|
+
element_array.push(false);
|
|
383
|
+
break;
|
|
384
|
+
|
|
385
|
+
case VALUE_NEG_NAN:
|
|
386
|
+
element_array.push(-NaN);
|
|
387
|
+
break;
|
|
388
|
+
|
|
389
|
+
case VALUE_NAN:
|
|
390
|
+
element_array.push(NaN);
|
|
391
|
+
break;
|
|
392
|
+
|
|
393
|
+
case VALUE_NEG_INFINITY:
|
|
394
|
+
element_array.push(-Infinity);
|
|
395
|
+
break;
|
|
396
|
+
|
|
397
|
+
case VALUE_INFINITY:
|
|
398
|
+
element_array.push(Infinity);
|
|
399
|
+
break;
|
|
400
|
+
|
|
401
|
+
case VALUE_NULL:
|
|
402
|
+
element_array.push(null);
|
|
403
|
+
break;
|
|
404
|
+
|
|
405
|
+
case VALUE_UNDEFINED:
|
|
406
|
+
element_array.push(undefined);
|
|
407
|
+
break;
|
|
408
|
+
|
|
409
|
+
case VALUE_EMPTY:
|
|
410
|
+
element_array.push(undefined);
|
|
411
|
+
delete element_array[element_array.length - 1];
|
|
412
|
+
break;
|
|
413
|
+
|
|
414
|
+
case VALUE_OBJECT:
|
|
415
|
+
element_array.push(val.contains);
|
|
416
|
+
break;
|
|
417
|
+
|
|
418
|
+
case VALUE_ARRAY:
|
|
419
|
+
element_array.push(val.contains);
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function objectPush() {
|
|
425
|
+
switch (val.value_type) {
|
|
426
|
+
case VALUE_NUMBER:
|
|
427
|
+
elements[val.name] = (negative ? -1 : 1) * Number(val.string);
|
|
428
|
+
break;
|
|
429
|
+
|
|
430
|
+
case VALUE_STRING:
|
|
431
|
+
elements[val.name] = val.string;
|
|
432
|
+
break;
|
|
433
|
+
|
|
434
|
+
case VALUE_TRUE:
|
|
435
|
+
elements[val.name] = true;
|
|
436
|
+
break;
|
|
437
|
+
|
|
438
|
+
case VALUE_FALSE:
|
|
439
|
+
elements[val.name] = false;
|
|
440
|
+
break;
|
|
441
|
+
|
|
442
|
+
case VALUE_NEG_NAN:
|
|
443
|
+
elements[val.name] = -NaN;
|
|
444
|
+
break;
|
|
445
|
+
|
|
446
|
+
case VALUE_NAN:
|
|
447
|
+
elements[val.name] = NaN;
|
|
448
|
+
break;
|
|
449
|
+
|
|
450
|
+
case VALUE_NEG_INFINITY:
|
|
451
|
+
elements[val.name] = -Infinity;
|
|
452
|
+
break;
|
|
453
|
+
|
|
454
|
+
case VALUE_INFINITY:
|
|
455
|
+
elements[val.name] = Infinity;
|
|
456
|
+
break;
|
|
457
|
+
|
|
458
|
+
case VALUE_NULL:
|
|
459
|
+
elements[val.name] = null;
|
|
460
|
+
break;
|
|
461
|
+
|
|
462
|
+
case VALUE_UNDEFINED:
|
|
463
|
+
elements[val.name] = undefined;
|
|
464
|
+
break;
|
|
465
|
+
|
|
466
|
+
case VALUE_OBJECT:
|
|
467
|
+
elements[val.name] = val.contains;
|
|
468
|
+
break;
|
|
469
|
+
|
|
470
|
+
case VALUE_ARRAY:
|
|
471
|
+
elements[val.name] = val.contains;
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function gatherString(start_c) {
|
|
477
|
+
let retval = 0;
|
|
478
|
+
|
|
479
|
+
while (retval == 0 && n < buf.length) {
|
|
480
|
+
let str = buf.charAt(n);
|
|
481
|
+
const cInt = buf.codePointAt(n++);
|
|
482
|
+
|
|
483
|
+
if (cInt >= 0x10000) {
|
|
484
|
+
str += buf.charAt(n);
|
|
485
|
+
n++;
|
|
486
|
+
} //console.log( "gathering....", stringEscape, str, cInt, unicodeWide, stringHex, stringUnicode, hex_char_len );
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
pos.col++;
|
|
490
|
+
|
|
491
|
+
if (cInt == start_c) {
|
|
492
|
+
//( cInt == 34/*'"'*/ ) || ( cInt == 39/*'\''*/ ) || ( cInt == 96/*'`'*/ ) )
|
|
493
|
+
if (stringEscape) {
|
|
494
|
+
if (stringHex) throwError("Incomplete hexidecimal sequence", cInt);else if (unicodeWide) throwError("Incomplete long unicode sequence", cInt);else if (stringUnicode) throwError("Incomplete unicode sequence", cInt);
|
|
495
|
+
|
|
496
|
+
if (cr_escaped) {
|
|
497
|
+
cr_escaped = false; // \\ \r ' :end string, the backslash was used for \r
|
|
498
|
+
|
|
499
|
+
retval = 1; // complete string.
|
|
500
|
+
} else val.string += str; // escaped start quote
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
stringEscape = false;
|
|
504
|
+
} else {
|
|
505
|
+
// quote matches, not escaped, and not processing escape...
|
|
506
|
+
retval = 1;
|
|
507
|
+
}
|
|
508
|
+
} else if (stringEscape) {
|
|
509
|
+
if (unicodeWide) {
|
|
510
|
+
if (cInt == 125
|
|
511
|
+
/*'}'*/
|
|
512
|
+
) {
|
|
513
|
+
val.string += String.fromCodePoint(hex_char);
|
|
514
|
+
unicodeWide = false;
|
|
515
|
+
stringUnicode = false;
|
|
516
|
+
stringEscape = false;
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
hex_char *= 16;
|
|
521
|
+
if (cInt >= 48
|
|
522
|
+
/*'0'*/
|
|
523
|
+
&& cInt <= 57
|
|
524
|
+
/*'9'*/
|
|
525
|
+
) hex_char += cInt - 0x30;else if (cInt >= 65
|
|
526
|
+
/*'A'*/
|
|
527
|
+
&& cInt <= 70
|
|
528
|
+
/*'F'*/
|
|
529
|
+
) hex_char += cInt - 65 + 10;else if (cInt >= 97
|
|
530
|
+
/*'a'*/
|
|
531
|
+
&& cInt <= 102
|
|
532
|
+
/*'f'*/
|
|
533
|
+
) hex_char += cInt - 97 + 10;else {
|
|
534
|
+
throwError("(escaped character, parsing hex of \\u)", cInt);
|
|
535
|
+
}
|
|
536
|
+
continue;
|
|
537
|
+
} else if (stringHex || stringUnicode) {
|
|
538
|
+
if (hex_char_len === 0 && cInt === 123
|
|
539
|
+
/*'{'*/
|
|
540
|
+
) {
|
|
541
|
+
unicodeWide = true;
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
hex_char *= 16;
|
|
546
|
+
if (cInt >= 48
|
|
547
|
+
/*'0'*/
|
|
548
|
+
&& cInt <= 57
|
|
549
|
+
/*'9'*/
|
|
550
|
+
) hex_char += cInt - 0x30;else if (cInt >= 65
|
|
551
|
+
/*'A'*/
|
|
552
|
+
&& cInt <= 70
|
|
553
|
+
/*'F'*/
|
|
554
|
+
) hex_char += cInt - 65 + 10;else if (cInt >= 97
|
|
555
|
+
/*'a'*/
|
|
556
|
+
&& cInt <= 102
|
|
557
|
+
/*'f'*/
|
|
558
|
+
) hex_char += cInt - 97 + 10;else {
|
|
559
|
+
throwError(stringUnicode ? "(escaped character, parsing hex of \\u)" : "(escaped character, parsing hex of \\x)", cInt);
|
|
560
|
+
}
|
|
561
|
+
hex_char_len++;
|
|
562
|
+
|
|
563
|
+
if (stringUnicode) {
|
|
564
|
+
if (hex_char_len == 4) {
|
|
565
|
+
val.string += String.fromCodePoint(hex_char);
|
|
566
|
+
stringUnicode = false;
|
|
567
|
+
stringEscape = false;
|
|
568
|
+
}
|
|
569
|
+
} else if (hex_char_len == 2) {
|
|
570
|
+
val.string += String.fromCodePoint(hex_char);
|
|
571
|
+
stringHex = false;
|
|
572
|
+
stringEscape = false;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
switch (cInt) {
|
|
579
|
+
case 13
|
|
580
|
+
/*'\r'*/
|
|
581
|
+
:
|
|
582
|
+
cr_escaped = true;
|
|
583
|
+
pos.col = 1;
|
|
584
|
+
continue;
|
|
585
|
+
|
|
586
|
+
case 0x2028: // LS (Line separator)
|
|
587
|
+
|
|
588
|
+
case 0x2029:
|
|
589
|
+
// PS (paragraph separator)
|
|
590
|
+
pos.col = 1;
|
|
591
|
+
// no return to get newline reset, so reset line pos.
|
|
592
|
+
// Fallthrough
|
|
593
|
+
|
|
594
|
+
case 10
|
|
595
|
+
/*'\n'*/
|
|
596
|
+
:
|
|
597
|
+
if (cr_escaped) {
|
|
598
|
+
// \\ \r \n
|
|
599
|
+
cr_escaped = false;
|
|
600
|
+
} else {
|
|
601
|
+
// \\ \n
|
|
602
|
+
pos.col = 1;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
pos.line++;
|
|
606
|
+
break;
|
|
607
|
+
|
|
608
|
+
case 116
|
|
609
|
+
/*'t'*/
|
|
610
|
+
:
|
|
611
|
+
val.string += '\t';
|
|
612
|
+
break;
|
|
613
|
+
|
|
614
|
+
case 98
|
|
615
|
+
/*'b'*/
|
|
616
|
+
:
|
|
617
|
+
val.string += '\b';
|
|
618
|
+
break;
|
|
619
|
+
|
|
620
|
+
case 48
|
|
621
|
+
/*'0'*/
|
|
622
|
+
:
|
|
623
|
+
val.string += '\0';
|
|
624
|
+
break;
|
|
625
|
+
|
|
626
|
+
case 110
|
|
627
|
+
/*'n'*/
|
|
628
|
+
:
|
|
629
|
+
val.string += '\n';
|
|
630
|
+
break;
|
|
631
|
+
|
|
632
|
+
case 114
|
|
633
|
+
/*'r'*/
|
|
634
|
+
:
|
|
635
|
+
val.string += '\r';
|
|
636
|
+
break;
|
|
637
|
+
|
|
638
|
+
case 102
|
|
639
|
+
/*'f'*/
|
|
640
|
+
:
|
|
641
|
+
val.string += '\f';
|
|
642
|
+
break;
|
|
643
|
+
|
|
644
|
+
case 118
|
|
645
|
+
/*'v'*/
|
|
646
|
+
:
|
|
647
|
+
val.string += '\v';
|
|
648
|
+
break;
|
|
649
|
+
|
|
650
|
+
case 120
|
|
651
|
+
/*'x'*/
|
|
652
|
+
:
|
|
653
|
+
stringHex = true;
|
|
654
|
+
hex_char_len = 0;
|
|
655
|
+
hex_char = 0;
|
|
656
|
+
continue;
|
|
657
|
+
|
|
658
|
+
case 117
|
|
659
|
+
/*'u'*/
|
|
660
|
+
:
|
|
661
|
+
stringUnicode = true;
|
|
662
|
+
hex_char_len = 0;
|
|
663
|
+
hex_char = 0;
|
|
664
|
+
continue;
|
|
665
|
+
|
|
666
|
+
default:
|
|
667
|
+
val.string += str;
|
|
668
|
+
break;
|
|
669
|
+
} //console.log( "other..." );
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
stringEscape = false;
|
|
673
|
+
} else if (cInt === 92
|
|
674
|
+
/*'\\'*/
|
|
675
|
+
) {
|
|
676
|
+
stringEscape = true;
|
|
677
|
+
} else {
|
|
678
|
+
if (cr_escaped) {
|
|
679
|
+
cr_escaped = false; // \\ \r <any other character>
|
|
680
|
+
|
|
681
|
+
pos.line++;
|
|
682
|
+
pos.col = 2; // newline, plus one character.
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
val.string += str;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return retval;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
function collectNumber() {
|
|
693
|
+
let _n;
|
|
694
|
+
|
|
695
|
+
while ((_n = n) < buf.length) {
|
|
696
|
+
const str = buf.charAt(_n);
|
|
697
|
+
const cInt = buf.codePointAt(n++);
|
|
698
|
+
|
|
699
|
+
if (cInt >= 0x10000) {
|
|
700
|
+
throwError("fault while parsing number;", cInt);
|
|
701
|
+
} //log('_DEBUG_PARSING', "in getting number:", n, cInt, String.fromCodePoint(cInt) );
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
if (cInt == 95
|
|
705
|
+
/*_*/
|
|
706
|
+
) continue;
|
|
707
|
+
pos.col++; // leading zeros should be forbidden.
|
|
708
|
+
|
|
709
|
+
if (cInt >= 48
|
|
710
|
+
/*'0'*/
|
|
711
|
+
&& cInt <= 57
|
|
712
|
+
/*'9'*/
|
|
713
|
+
) {
|
|
714
|
+
if (exponent) {
|
|
715
|
+
exponent_digit = true;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
val.string += str;
|
|
719
|
+
} else if (cInt == 45
|
|
720
|
+
/*'-'*/
|
|
721
|
+
|| cInt == 43
|
|
722
|
+
/*'+'*/
|
|
723
|
+
) {
|
|
724
|
+
if (val.string.length == 0 || exponent && !exponent_sign && !exponent_digit) {
|
|
725
|
+
val.string += str;
|
|
726
|
+
exponent_sign = true;
|
|
727
|
+
} else {
|
|
728
|
+
status = false;
|
|
729
|
+
throwError("fault while parsing number;", cInt); // break;
|
|
730
|
+
}
|
|
731
|
+
} else if (cInt == 46
|
|
732
|
+
/*'.'*/
|
|
733
|
+
) {
|
|
734
|
+
if (!decimal && !fromHex && !exponent) {
|
|
735
|
+
val.string += str;
|
|
736
|
+
decimal = true;
|
|
737
|
+
} else {
|
|
738
|
+
status = false;
|
|
739
|
+
throwError("fault while parsing number;", cInt); // break;
|
|
740
|
+
}
|
|
741
|
+
} else if (fromHex && (cInt >= 95
|
|
742
|
+
/*'a'*/
|
|
743
|
+
&& cInt <= 102
|
|
744
|
+
/*'f'*/
|
|
745
|
+
|| cInt >= 65
|
|
746
|
+
/*'A'*/
|
|
747
|
+
&& cInt <= 70
|
|
748
|
+
/*'F'*/
|
|
749
|
+
)) {
|
|
750
|
+
val.string += str;
|
|
751
|
+
} else if (cInt == 120
|
|
752
|
+
/*'x'*/
|
|
753
|
+
|| cInt == 98
|
|
754
|
+
/*'b'*/
|
|
755
|
+
|| cInt == 111
|
|
756
|
+
/*'o'*/
|
|
757
|
+
|| cInt == 88
|
|
758
|
+
/*'X'*/
|
|
759
|
+
|| cInt == 66
|
|
760
|
+
/*'B'*/
|
|
761
|
+
|| cInt == 79
|
|
762
|
+
/*'O'*/
|
|
763
|
+
) {
|
|
764
|
+
// hex conversion.
|
|
765
|
+
if (!fromHex && val.string == '0') {
|
|
766
|
+
fromHex = true;
|
|
767
|
+
val.string += str;
|
|
768
|
+
} else {
|
|
769
|
+
status = false;
|
|
770
|
+
throwError("fault while parsing number;", cInt); // break;
|
|
771
|
+
}
|
|
772
|
+
} else if (cInt == 101
|
|
773
|
+
/*'e'*/
|
|
774
|
+
|| cInt == 69
|
|
775
|
+
/*'E'*/
|
|
776
|
+
) {
|
|
777
|
+
if (!exponent) {
|
|
778
|
+
val.string += str;
|
|
779
|
+
exponent = true;
|
|
780
|
+
} else {
|
|
781
|
+
status = false;
|
|
782
|
+
throwError("fault while parsing number;", cInt); // break;
|
|
783
|
+
}
|
|
784
|
+
} else {
|
|
785
|
+
if (cInt == 32
|
|
786
|
+
/*' '*/
|
|
787
|
+
|| cInt == 160
|
|
788
|
+
/*   */
|
|
789
|
+
|| cInt == 13 || cInt == 10 || cInt == 9 || cInt == 0xFEFF || cInt == 44
|
|
790
|
+
/*','*/
|
|
791
|
+
|| cInt == 125
|
|
792
|
+
/*'}'*/
|
|
793
|
+
|| cInt == 93
|
|
794
|
+
/*']'*/
|
|
795
|
+
|| cInt == 58
|
|
796
|
+
/*':'*/
|
|
797
|
+
) {
|
|
798
|
+
break;
|
|
799
|
+
} else {
|
|
800
|
+
if (complete_at_end) {
|
|
801
|
+
status = false;
|
|
802
|
+
throwError("fault while parsing number;", cInt);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
break;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
n = _n;
|
|
811
|
+
|
|
812
|
+
if (!complete_at_end && n == buf.length) {
|
|
813
|
+
gatheringNumber = true;
|
|
814
|
+
} else {
|
|
815
|
+
gatheringNumber = false;
|
|
816
|
+
val.value_type = VALUE_NUMBER;
|
|
817
|
+
|
|
818
|
+
if (parse_context == CONTEXT_UNKNOWN) {
|
|
819
|
+
completed = true;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
if (!status) return -1;
|
|
825
|
+
|
|
826
|
+
if (msg && msg.length) {
|
|
827
|
+
input = getBuffer();
|
|
828
|
+
input.buf = msg;
|
|
829
|
+
inQueue.push(input);
|
|
830
|
+
} else {
|
|
831
|
+
if (gatheringNumber) {
|
|
832
|
+
//console.log( "Force completed.")
|
|
833
|
+
gatheringNumber = false;
|
|
834
|
+
val.value_type = VALUE_NUMBER;
|
|
835
|
+
|
|
836
|
+
if (parse_context == CONTEXT_UNKNOWN) {
|
|
837
|
+
completed = true;
|
|
838
|
+
} else {
|
|
839
|
+
throw new Error("context stack is not empty at flush");
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
retval = 1; // if returning buffers, then obviously there's more in this one.
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
while (status && (input = inQueue.shift())) {
|
|
847
|
+
n = input.n;
|
|
848
|
+
buf = input.buf;
|
|
849
|
+
|
|
850
|
+
if (gatheringString) {
|
|
851
|
+
const string_status = gatherString(gatheringStringFirstChar);
|
|
852
|
+
|
|
853
|
+
if (string_status > 0) {
|
|
854
|
+
gatheringString = false;
|
|
855
|
+
val.value_type = VALUE_STRING;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
if (gatheringNumber) {
|
|
860
|
+
collectNumber();
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
while (!completed && status && n < buf.length) {
|
|
864
|
+
let str = buf.charAt(n);
|
|
865
|
+
const cInt = buf.codePointAt(n++);
|
|
866
|
+
|
|
867
|
+
if (cInt >= 0x10000) {
|
|
868
|
+
str += buf.charAt(n);
|
|
869
|
+
n++;
|
|
870
|
+
} //// log('_DEBUG_PARSING', "parsing at ", cInt, str );
|
|
871
|
+
//log('_DEBUG_LL', "processing: ", cInt, str, pos, comment, parse_context, word, val );
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
pos.col++;
|
|
875
|
+
|
|
876
|
+
if (comment) {
|
|
877
|
+
// '/'
|
|
878
|
+
if (comment == 1) {
|
|
879
|
+
// '/'
|
|
880
|
+
if (cInt == 42
|
|
881
|
+
/*'*'*/
|
|
882
|
+
) {
|
|
883
|
+
comment = 3;
|
|
884
|
+
} // '/*'
|
|
885
|
+
else if (cInt != 47
|
|
886
|
+
/*'/'*/
|
|
887
|
+
) {
|
|
888
|
+
// '//'(NOT)
|
|
889
|
+
throwError("fault while parsing;", cInt);
|
|
890
|
+
} else comment = 2; // '//' (valid)
|
|
891
|
+
|
|
892
|
+
} else if (comment == 2) {
|
|
893
|
+
// '// ...'
|
|
894
|
+
if (cInt == 10
|
|
895
|
+
/*'\n'*/
|
|
896
|
+
|| cInt == 13
|
|
897
|
+
/*'\r'*/
|
|
898
|
+
) comment = 0;
|
|
899
|
+
} else if (comment == 3) {
|
|
900
|
+
// '/*... '
|
|
901
|
+
if (cInt == 42
|
|
902
|
+
/*'*'*/
|
|
903
|
+
) comment = 4;
|
|
904
|
+
} else {
|
|
905
|
+
// if( comment == 4 ) { // '/* ... *'
|
|
906
|
+
if (cInt == 47
|
|
907
|
+
/*'/'*/
|
|
908
|
+
) comment = 0;else comment = 3; // any other char, goto expect * to close */
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
continue;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
switch (cInt) {
|
|
915
|
+
case 47
|
|
916
|
+
/*'/'*/
|
|
917
|
+
:
|
|
918
|
+
comment = 1;
|
|
919
|
+
break;
|
|
920
|
+
|
|
921
|
+
case 123
|
|
922
|
+
/*'{'*/
|
|
923
|
+
:
|
|
924
|
+
if (word == WORD_POS_FIELD || word == WORD_POS_AFTER_FIELD || parse_context == CONTEXT_OBJECT_FIELD && word == WORD_POS_RESET) {
|
|
925
|
+
throwError("fault while parsing; getting field name unexpected ", cInt); // break;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
{
|
|
929
|
+
const old_context = getContext(); //log('_DEBUG_PARSING', "Begin a new object; previously pushed into elements; but wait until trailing comma or close previously:%d", val.value_type );
|
|
930
|
+
|
|
931
|
+
val.value_type = VALUE_OBJECT;
|
|
932
|
+
const tmpobj = {};
|
|
933
|
+
if (parse_context == CONTEXT_UNKNOWN) result = elements = tmpobj;
|
|
934
|
+
old_context.context = parse_context;
|
|
935
|
+
old_context.elements = elements;
|
|
936
|
+
old_context.element_array = element_array;
|
|
937
|
+
old_context.name = val.name;
|
|
938
|
+
elements = tmpobj; //log('_DEBUG_PARSING_STACK',"push context (open object): ", context_stack.length );
|
|
939
|
+
|
|
940
|
+
context_stack.push(old_context);
|
|
941
|
+
RESET_VAL();
|
|
942
|
+
parse_context = CONTEXT_OBJECT_FIELD;
|
|
943
|
+
}
|
|
944
|
+
break;
|
|
945
|
+
|
|
946
|
+
case 91
|
|
947
|
+
/*'['*/
|
|
948
|
+
:
|
|
949
|
+
if (parse_context == CONTEXT_OBJECT_FIELD || word == WORD_POS_FIELD || word == WORD_POS_AFTER_FIELD) {
|
|
950
|
+
throwError("Fault while parsing; while getting field name unexpected", cInt); // break;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
if (val.value_type == VALUE_UNSET || val.value_type == VALUE_UNDEFINED) {
|
|
954
|
+
const old_context = getContext(); //log('_DEBUG_PARSING', "Begin a new array; previously pushed into elements; but wait until trailing comma or close previously:%d", val.value_type );
|
|
955
|
+
|
|
956
|
+
val.value_type = VALUE_ARRAY;
|
|
957
|
+
const tmparr = [];
|
|
958
|
+
if (parse_context == CONTEXT_UNKNOWN) result = element_array = tmparr; //else if( parse_context == CONTEXT_IN_ARRAY )
|
|
959
|
+
// element_array.push( tmparr );
|
|
960
|
+
else if (parse_context == CONTEXT_OBJECT_FIELD_VALUE) elements[val.name] = tmparr;
|
|
961
|
+
old_context.context = parse_context;
|
|
962
|
+
old_context.elements = elements;
|
|
963
|
+
old_context.element_array = element_array;
|
|
964
|
+
old_context.name = val.name;
|
|
965
|
+
element_array = tmparr; //log('_DEBUG_PARSING_STACK', "push context (open array): ", context_stack.length );
|
|
966
|
+
|
|
967
|
+
context_stack.push(old_context);
|
|
968
|
+
RESET_VAL();
|
|
969
|
+
parse_context = CONTEXT_IN_ARRAY;
|
|
970
|
+
} else {
|
|
971
|
+
throwError("Unexpected array open after previous value", cInt);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
break;
|
|
975
|
+
|
|
976
|
+
case 58
|
|
977
|
+
/*':'*/
|
|
978
|
+
:
|
|
979
|
+
////log('_DEBUG_PARSING', "colon context:", parse_context );
|
|
980
|
+
if (parse_context == CONTEXT_OBJECT_FIELD) {
|
|
981
|
+
word = WORD_POS_RESET;
|
|
982
|
+
val.name = val.string;
|
|
983
|
+
val.string = '';
|
|
984
|
+
parse_context = CONTEXT_OBJECT_FIELD_VALUE;
|
|
985
|
+
val.value_type = VALUE_UNSET;
|
|
986
|
+
} else {
|
|
987
|
+
if (parse_context == CONTEXT_IN_ARRAY) throwError("(in array, got colon out of string):parsing fault;", cInt);else throwError("(outside any object, got colon out of string):parsing fault;", cInt);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
break;
|
|
991
|
+
|
|
992
|
+
case 125
|
|
993
|
+
/*'}'*/
|
|
994
|
+
:
|
|
995
|
+
////log('_DEBUG_PARSING', "close bracket context:", word, parse_context );
|
|
996
|
+
if (word == WORD_POS_END) {
|
|
997
|
+
// allow starting a new word
|
|
998
|
+
word = WORD_POS_RESET;
|
|
999
|
+
} // coming back after pushing an array or sub-object will reset the context to FIELD, so an end with a field should still push value.
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
if (parse_context == CONTEXT_OBJECT_FIELD) {
|
|
1003
|
+
//log('_DEBUG_PARSING', "close object; empty object %d", val.value_type );
|
|
1004
|
+
//RESET_VAL();
|
|
1005
|
+
val.value_type = VALUE_OBJECT;
|
|
1006
|
+
val.contains = elements;
|
|
1007
|
+
const old_context = context_stack.pop(); //log('_DEBUG_PARSING_STACK',"object pop stack (close obj)", context_stack.length, old_context );
|
|
1008
|
+
|
|
1009
|
+
val.name = old_context.name;
|
|
1010
|
+
parse_context = old_context.context; // this will restore as IN_ARRAY or OBJECT_FIELD
|
|
1011
|
+
|
|
1012
|
+
elements = old_context.elements;
|
|
1013
|
+
element_array = old_context.element_array;
|
|
1014
|
+
dropContext(old_context);
|
|
1015
|
+
|
|
1016
|
+
if (parse_context == CONTEXT_UNKNOWN) {
|
|
1017
|
+
completed = true;
|
|
1018
|
+
}
|
|
1019
|
+
} else if (parse_context == CONTEXT_OBJECT_FIELD_VALUE) {
|
|
1020
|
+
// first, add the last value
|
|
1021
|
+
//log('_DEBUG_PARSING', "close object; push item '%s' %d", val.name, val.value_type );
|
|
1022
|
+
if (val.value_type != VALUE_UNSET) {
|
|
1023
|
+
objectPush();
|
|
1024
|
+
} else {
|
|
1025
|
+
throwError("Fault while parsing field value, close with no value", cInt);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
val.value_type = VALUE_OBJECT;
|
|
1029
|
+
val.contains = elements;
|
|
1030
|
+
const old_context = context_stack.pop(); //log('_DEBUG_PARSING_STACK',"object pop stack (close object)", context_stack.length, old_context );
|
|
1031
|
+
|
|
1032
|
+
val.name = old_context.name;
|
|
1033
|
+
parse_context = old_context.context; // this will restore as IN_ARRAY or OBJECT_FIELD
|
|
1034
|
+
|
|
1035
|
+
elements = old_context.elements;
|
|
1036
|
+
element_array = old_context.element_array;
|
|
1037
|
+
dropContext(old_context);
|
|
1038
|
+
|
|
1039
|
+
if (parse_context == CONTEXT_UNKNOWN) {
|
|
1040
|
+
completed = true;
|
|
1041
|
+
}
|
|
1042
|
+
} else {
|
|
1043
|
+
throwError("Fault while parsing; unexpected", cInt);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
negative = false;
|
|
1047
|
+
break;
|
|
1048
|
+
|
|
1049
|
+
case 93
|
|
1050
|
+
/*']'*/
|
|
1051
|
+
:
|
|
1052
|
+
if (word == WORD_POS_END) word = WORD_POS_RESET;
|
|
1053
|
+
|
|
1054
|
+
if (parse_context == CONTEXT_IN_ARRAY) {
|
|
1055
|
+
//log('_DEBUG_PARSING', "close array, push last element: %d", val.value_type );
|
|
1056
|
+
if (val.value_type != VALUE_UNSET) {
|
|
1057
|
+
arrayPush();
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
val.value_type = VALUE_ARRAY;
|
|
1061
|
+
val.contains = element_array;
|
|
1062
|
+
{
|
|
1063
|
+
const old_context = context_stack.pop(); //log('_DEBUG_PARSING_STACK',"object pop stack (close array)", context_stack.length );
|
|
1064
|
+
|
|
1065
|
+
val.name = old_context.name;
|
|
1066
|
+
parse_context = old_context.context;
|
|
1067
|
+
elements = old_context.elements;
|
|
1068
|
+
element_array = old_context.element_array;
|
|
1069
|
+
dropContext(old_context);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
if (parse_context == CONTEXT_UNKNOWN) {
|
|
1073
|
+
completed = true;
|
|
1074
|
+
}
|
|
1075
|
+
} else {
|
|
1076
|
+
throwError(`bad context ${parse_context}; fault while parsing`, cInt); // fault
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
negative = false;
|
|
1080
|
+
break;
|
|
1081
|
+
|
|
1082
|
+
case 44
|
|
1083
|
+
/*','*/
|
|
1084
|
+
:
|
|
1085
|
+
if (word == WORD_POS_END) word = WORD_POS_RESET; // allow collect new keyword
|
|
1086
|
+
//log('_DEBUG_PARSING', "comma context:", parse_context, val );
|
|
1087
|
+
|
|
1088
|
+
if (parse_context == CONTEXT_IN_ARRAY) {
|
|
1089
|
+
if (val.value_type == VALUE_UNSET) val.value_type = VALUE_EMPTY; // in an array, elements after a comma should init as undefined...
|
|
1090
|
+
//log('_DEBUG_PARSING', "back in array; push item %d", val.value_type );
|
|
1091
|
+
|
|
1092
|
+
arrayPush();
|
|
1093
|
+
RESET_VAL(); // undefined allows [,,,] to be 4 values and [1,2,3,] to be 4 values with an undefined at end.
|
|
1094
|
+
} else if (parse_context == CONTEXT_OBJECT_FIELD_VALUE) {
|
|
1095
|
+
// after an array value, it will have returned to OBJECT_FIELD anyway
|
|
1096
|
+
//log('_DEBUG_PARSING', "comma after field value, push field to object: %s", val.name );
|
|
1097
|
+
parse_context = CONTEXT_OBJECT_FIELD;
|
|
1098
|
+
|
|
1099
|
+
if (val.value_type != VALUE_UNSET) {
|
|
1100
|
+
objectPush();
|
|
1101
|
+
RESET_VAL();
|
|
1102
|
+
} else throwError("Unexpected comma after object field name", cInt);
|
|
1103
|
+
} else {
|
|
1104
|
+
status = false;
|
|
1105
|
+
throwError("bad context; excessive commas while parsing;", cInt); // fault
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
negative = false;
|
|
1109
|
+
break;
|
|
1110
|
+
|
|
1111
|
+
default:
|
|
1112
|
+
if (parse_context == CONTEXT_OBJECT_FIELD) {
|
|
1113
|
+
switch (cInt) {
|
|
1114
|
+
case 96: //'`':
|
|
1115
|
+
|
|
1116
|
+
case 34: //'"':
|
|
1117
|
+
|
|
1118
|
+
case 39:
|
|
1119
|
+
//'\'':
|
|
1120
|
+
if (word == WORD_POS_RESET) {
|
|
1121
|
+
if (val.value_type != VALUE_UNSET) throwError("String begin after previous value", cInt);
|
|
1122
|
+
const string_status = gatherString(cInt); //log('_DEBUG_PARSING', "string gather for object field name :", val.string, string_status );
|
|
1123
|
+
|
|
1124
|
+
if (string_status) {
|
|
1125
|
+
val.value_type = VALUE_STRING;
|
|
1126
|
+
} else {
|
|
1127
|
+
gatheringStringFirstChar = cInt;
|
|
1128
|
+
gatheringString = true;
|
|
1129
|
+
}
|
|
1130
|
+
} else {
|
|
1131
|
+
throwError("fault while parsing; quote not at start of field name", cInt);
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
break;
|
|
1135
|
+
|
|
1136
|
+
case 10:
|
|
1137
|
+
//'\n':
|
|
1138
|
+
pos.line++;
|
|
1139
|
+
pos.col = 1;
|
|
1140
|
+
// fall through to normal space handling - just updated line/col position
|
|
1141
|
+
|
|
1142
|
+
case 13: //'\r':
|
|
1143
|
+
|
|
1144
|
+
case 32: //' ':
|
|
1145
|
+
|
|
1146
|
+
case 160: // :
|
|
1147
|
+
|
|
1148
|
+
case 9: //'\t':
|
|
1149
|
+
|
|
1150
|
+
case 0xFEFF:
|
|
1151
|
+
// ZWNBS is WS though
|
|
1152
|
+
if (word == WORD_POS_END) {
|
|
1153
|
+
// allow collect new keyword
|
|
1154
|
+
word = WORD_POS_RESET;
|
|
1155
|
+
} else if (word == WORD_POS_FIELD) {
|
|
1156
|
+
word = WORD_POS_AFTER_FIELD;
|
|
1157
|
+
} // skip whitespace
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
break;
|
|
1161
|
+
|
|
1162
|
+
default:
|
|
1163
|
+
if (word == WORD_POS_AFTER_FIELD) {
|
|
1164
|
+
status = false;
|
|
1165
|
+
throwError("fault while parsing; character unexpected", cInt);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
if (word == WORD_POS_RESET) word = WORD_POS_FIELD;
|
|
1169
|
+
val.string += str;
|
|
1170
|
+
break;
|
|
1171
|
+
// default
|
|
1172
|
+
}
|
|
1173
|
+
} else switch (cInt) {
|
|
1174
|
+
case 96: //'`':
|
|
1175
|
+
|
|
1176
|
+
case 34: //'"':
|
|
1177
|
+
|
|
1178
|
+
case 39:
|
|
1179
|
+
{
|
|
1180
|
+
//'\'':
|
|
1181
|
+
if (val.value_type === VALUE_UNSET) {
|
|
1182
|
+
const string_status = gatherString(cInt); //log('_DEBUG_PARSING', "string gather for object field value :", val.string, string_status, completed, input.n, buf.length );
|
|
1183
|
+
|
|
1184
|
+
if (string_status) {
|
|
1185
|
+
val.value_type = VALUE_STRING;
|
|
1186
|
+
word = WORD_POS_END;
|
|
1187
|
+
} else {
|
|
1188
|
+
gatheringStringFirstChar = cInt;
|
|
1189
|
+
gatheringString = true;
|
|
1190
|
+
}
|
|
1191
|
+
} else throwError("String unexpected", cInt);
|
|
1192
|
+
|
|
1193
|
+
break;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
case 10:
|
|
1197
|
+
//'\n':
|
|
1198
|
+
pos.line++;
|
|
1199
|
+
pos.col = 1;
|
|
1200
|
+
// Fallthrough
|
|
1201
|
+
|
|
1202
|
+
case 32: //' ':
|
|
1203
|
+
|
|
1204
|
+
case 160: //  
|
|
1205
|
+
|
|
1206
|
+
case 9: //'\t':
|
|
1207
|
+
|
|
1208
|
+
case 13: //'\r':
|
|
1209
|
+
|
|
1210
|
+
case 0xFEFF:
|
|
1211
|
+
//'\uFEFF':
|
|
1212
|
+
if (word == WORD_POS_END) {
|
|
1213
|
+
word = WORD_POS_RESET;
|
|
1214
|
+
|
|
1215
|
+
if (parse_context == CONTEXT_UNKNOWN) {
|
|
1216
|
+
completed = true;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
break;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
if (word !== WORD_POS_RESET) {
|
|
1223
|
+
// breaking in the middle of gathering a keyword.
|
|
1224
|
+
status = false;
|
|
1225
|
+
throwError("fault parsing whitespace", cInt);
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
break;
|
|
1229
|
+
//----------------------------------------------------------
|
|
1230
|
+
// catch characters for true/false/null/undefined which are values outside of quotes
|
|
1231
|
+
|
|
1232
|
+
case 116:
|
|
1233
|
+
//'t':
|
|
1234
|
+
if (word == WORD_POS_RESET) word = WORD_POS_TRUE_1;else if (word == WORD_POS_INFINITY_6) word = WORD_POS_INFINITY_7;else {
|
|
1235
|
+
status = false;
|
|
1236
|
+
throwError("fault parsing", cInt);
|
|
1237
|
+
} // fault
|
|
1238
|
+
|
|
1239
|
+
break;
|
|
1240
|
+
|
|
1241
|
+
case 114:
|
|
1242
|
+
//'r':
|
|
1243
|
+
if (word == WORD_POS_TRUE_1) word = WORD_POS_TRUE_2;else {
|
|
1244
|
+
status = false;
|
|
1245
|
+
throwError("fault parsing", cInt);
|
|
1246
|
+
} // fault
|
|
1247
|
+
|
|
1248
|
+
break;
|
|
1249
|
+
|
|
1250
|
+
case 117:
|
|
1251
|
+
//'u':
|
|
1252
|
+
if (word == WORD_POS_TRUE_2) word = WORD_POS_TRUE_3;else if (word == WORD_POS_NULL_1) word = WORD_POS_NULL_2;else if (word == WORD_POS_RESET) word = WORD_POS_UNDEFINED_1;else {
|
|
1253
|
+
status = false;
|
|
1254
|
+
throwError("fault parsing", cInt);
|
|
1255
|
+
} // fault
|
|
1256
|
+
|
|
1257
|
+
break;
|
|
1258
|
+
|
|
1259
|
+
case 101:
|
|
1260
|
+
//'e':
|
|
1261
|
+
if (word == WORD_POS_TRUE_3) {
|
|
1262
|
+
val.value_type = VALUE_TRUE;
|
|
1263
|
+
word = WORD_POS_END;
|
|
1264
|
+
} else if (word == WORD_POS_FALSE_4) {
|
|
1265
|
+
val.value_type = VALUE_FALSE;
|
|
1266
|
+
word = WORD_POS_END;
|
|
1267
|
+
} else if (word == WORD_POS_UNDEFINED_3) word = WORD_POS_UNDEFINED_4;else if (word == WORD_POS_UNDEFINED_7) word = WORD_POS_UNDEFINED_8;else {
|
|
1268
|
+
status = false;
|
|
1269
|
+
throwError("fault parsing", cInt);
|
|
1270
|
+
} // fault
|
|
1271
|
+
|
|
1272
|
+
|
|
1273
|
+
break;
|
|
1274
|
+
|
|
1275
|
+
case 110:
|
|
1276
|
+
//'n':
|
|
1277
|
+
if (word == WORD_POS_RESET) word = WORD_POS_NULL_1;else if (word == WORD_POS_UNDEFINED_1) word = WORD_POS_UNDEFINED_2;else if (word == WORD_POS_UNDEFINED_6) word = WORD_POS_UNDEFINED_7;else if (word == WORD_POS_INFINITY_1) word = WORD_POS_INFINITY_2;else if (word == WORD_POS_INFINITY_4) word = WORD_POS_INFINITY_5;else {
|
|
1278
|
+
status = false;
|
|
1279
|
+
throwError("fault parsing", cInt);
|
|
1280
|
+
} // fault
|
|
1281
|
+
|
|
1282
|
+
break;
|
|
1283
|
+
|
|
1284
|
+
case 100:
|
|
1285
|
+
//'d':
|
|
1286
|
+
if (word == WORD_POS_UNDEFINED_2) word = WORD_POS_UNDEFINED_3;else if (word == WORD_POS_UNDEFINED_8) {
|
|
1287
|
+
val.value_type = VALUE_UNDEFINED;
|
|
1288
|
+
word = WORD_POS_END;
|
|
1289
|
+
} else {
|
|
1290
|
+
status = false;
|
|
1291
|
+
throwError("fault parsing", cInt);
|
|
1292
|
+
} // fault
|
|
1293
|
+
|
|
1294
|
+
break;
|
|
1295
|
+
|
|
1296
|
+
case 105:
|
|
1297
|
+
//'i':
|
|
1298
|
+
if (word == WORD_POS_UNDEFINED_5) word = WORD_POS_UNDEFINED_6;else if (word == WORD_POS_INFINITY_3) word = WORD_POS_INFINITY_4;else if (word == WORD_POS_INFINITY_5) word = WORD_POS_INFINITY_6;else {
|
|
1299
|
+
status = false;
|
|
1300
|
+
throwError("fault parsing", cInt);
|
|
1301
|
+
} // fault
|
|
1302
|
+
|
|
1303
|
+
break;
|
|
1304
|
+
|
|
1305
|
+
case 108:
|
|
1306
|
+
//'l':
|
|
1307
|
+
if (word == WORD_POS_NULL_2) word = WORD_POS_NULL_3;else if (word == WORD_POS_NULL_3) {
|
|
1308
|
+
val.value_type = VALUE_NULL;
|
|
1309
|
+
word = WORD_POS_END;
|
|
1310
|
+
} else if (word == WORD_POS_FALSE_2) word = WORD_POS_FALSE_3;else {
|
|
1311
|
+
status = false;
|
|
1312
|
+
throwError("fault parsing", cInt);
|
|
1313
|
+
} // fault
|
|
1314
|
+
|
|
1315
|
+
break;
|
|
1316
|
+
|
|
1317
|
+
case 102:
|
|
1318
|
+
//'f':
|
|
1319
|
+
if (word == WORD_POS_RESET) word = WORD_POS_FALSE_1;else if (word == WORD_POS_UNDEFINED_4) word = WORD_POS_UNDEFINED_5;else if (word == WORD_POS_INFINITY_2) word = WORD_POS_INFINITY_3;else {
|
|
1320
|
+
status = false;
|
|
1321
|
+
throwError("fault parsing", cInt);
|
|
1322
|
+
} // fault
|
|
1323
|
+
|
|
1324
|
+
break;
|
|
1325
|
+
|
|
1326
|
+
case 97:
|
|
1327
|
+
//'a':
|
|
1328
|
+
if (word == WORD_POS_FALSE_1) word = WORD_POS_FALSE_2;else if (word == WORD_POS_NAN_1) word = WORD_POS_NAN_2;else {
|
|
1329
|
+
status = false;
|
|
1330
|
+
throwError("fault parsing", cInt);
|
|
1331
|
+
} // fault
|
|
1332
|
+
|
|
1333
|
+
break;
|
|
1334
|
+
|
|
1335
|
+
case 115:
|
|
1336
|
+
//'s':
|
|
1337
|
+
if (word == WORD_POS_FALSE_3) word = WORD_POS_FALSE_4;else {
|
|
1338
|
+
status = false;
|
|
1339
|
+
throwError("fault parsing", cInt);
|
|
1340
|
+
} // fault
|
|
1341
|
+
|
|
1342
|
+
break;
|
|
1343
|
+
|
|
1344
|
+
case 73:
|
|
1345
|
+
//'I':
|
|
1346
|
+
if (word == WORD_POS_RESET) word = WORD_POS_INFINITY_1;else {
|
|
1347
|
+
status = false;
|
|
1348
|
+
throwError("fault parsing", cInt);
|
|
1349
|
+
} // fault
|
|
1350
|
+
|
|
1351
|
+
break;
|
|
1352
|
+
|
|
1353
|
+
case 78:
|
|
1354
|
+
//'N':
|
|
1355
|
+
if (word == WORD_POS_RESET) word = WORD_POS_NAN_1;else if (word == WORD_POS_NAN_2) {
|
|
1356
|
+
val.value_type = negative ? VALUE_NEG_NAN : VALUE_NAN;
|
|
1357
|
+
negative = false;
|
|
1358
|
+
word = WORD_POS_END;
|
|
1359
|
+
} else {
|
|
1360
|
+
status = false;
|
|
1361
|
+
throwError("fault parsing", cInt);
|
|
1362
|
+
} // fault
|
|
1363
|
+
|
|
1364
|
+
break;
|
|
1365
|
+
|
|
1366
|
+
case 121:
|
|
1367
|
+
//'y':
|
|
1368
|
+
if (word == WORD_POS_INFINITY_7) {
|
|
1369
|
+
val.value_type = negative ? VALUE_NEG_INFINITY : VALUE_INFINITY;
|
|
1370
|
+
negative = false;
|
|
1371
|
+
word = WORD_POS_END;
|
|
1372
|
+
} else {
|
|
1373
|
+
status = false;
|
|
1374
|
+
throwError("fault parsing", cInt);
|
|
1375
|
+
} // fault
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
break;
|
|
1379
|
+
|
|
1380
|
+
case 45:
|
|
1381
|
+
//'-':
|
|
1382
|
+
if (word == WORD_POS_RESET) negative = !negative;else {
|
|
1383
|
+
status = false;
|
|
1384
|
+
throwError("fault parsing", cInt);
|
|
1385
|
+
} // fault
|
|
1386
|
+
|
|
1387
|
+
break;
|
|
1388
|
+
|
|
1389
|
+
case 43:
|
|
1390
|
+
//'+':
|
|
1391
|
+
if (word !== WORD_POS_RESET) {
|
|
1392
|
+
status = false;
|
|
1393
|
+
throwError("fault parsing", cInt);
|
|
1394
|
+
} // fault
|
|
1395
|
+
|
|
1396
|
+
|
|
1397
|
+
break;
|
|
1398
|
+
//
|
|
1399
|
+
//----------------------------------------------------------
|
|
1400
|
+
|
|
1401
|
+
default:
|
|
1402
|
+
if (cInt >= 48
|
|
1403
|
+
/*'0'*/
|
|
1404
|
+
&& cInt <= 57
|
|
1405
|
+
/*'9'*/
|
|
1406
|
+
|| cInt == 43
|
|
1407
|
+
/*'+'*/
|
|
1408
|
+
|| cInt == 46
|
|
1409
|
+
/*'.'*/
|
|
1410
|
+
|| cInt == 45
|
|
1411
|
+
/*'-'*/
|
|
1412
|
+
) {
|
|
1413
|
+
fromHex = false;
|
|
1414
|
+
exponent = false;
|
|
1415
|
+
exponent_sign = false;
|
|
1416
|
+
exponent_digit = false;
|
|
1417
|
+
decimal = false;
|
|
1418
|
+
val.string = str;
|
|
1419
|
+
input.n = n;
|
|
1420
|
+
collectNumber();
|
|
1421
|
+
} else {
|
|
1422
|
+
status = false;
|
|
1423
|
+
throwError("fault parsing", cInt);
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
break;
|
|
1427
|
+
// default
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
break;
|
|
1431
|
+
// default of high level switch
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
if (completed) {
|
|
1435
|
+
if (word == WORD_POS_END) {
|
|
1436
|
+
word = WORD_POS_RESET;
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
break;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
if (n == buf.length) {
|
|
1444
|
+
dropBuffer(input);
|
|
1445
|
+
|
|
1446
|
+
if (gatheringString || gatheringNumber || parse_context == CONTEXT_OBJECT_FIELD) {
|
|
1447
|
+
retval = 0;
|
|
1448
|
+
} else {
|
|
1449
|
+
if (parse_context == CONTEXT_UNKNOWN && (val.value_type != VALUE_UNSET || result)) {
|
|
1450
|
+
completed = true;
|
|
1451
|
+
retval = 1;
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
} else {
|
|
1455
|
+
// put these back into the stack.
|
|
1456
|
+
input.n = n;
|
|
1457
|
+
inQueue.unshift(input);
|
|
1458
|
+
retval = 2; // if returning buffers, then obviously there's more in this one.
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
if (completed) break;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
if (completed && val.value_type != VALUE_UNSET) {
|
|
1465
|
+
switch (val.value_type) {
|
|
1466
|
+
case VALUE_NUMBER:
|
|
1467
|
+
result = (negative ? -1 : 1) * Number(val.string);
|
|
1468
|
+
break;
|
|
1469
|
+
|
|
1470
|
+
case VALUE_STRING:
|
|
1471
|
+
result = val.string;
|
|
1472
|
+
break;
|
|
1473
|
+
|
|
1474
|
+
case VALUE_TRUE:
|
|
1475
|
+
result = true;
|
|
1476
|
+
break;
|
|
1477
|
+
|
|
1478
|
+
case VALUE_FALSE:
|
|
1479
|
+
result = false;
|
|
1480
|
+
break;
|
|
1481
|
+
|
|
1482
|
+
case VALUE_NULL:
|
|
1483
|
+
result = null;
|
|
1484
|
+
break;
|
|
1485
|
+
|
|
1486
|
+
case VALUE_UNDEFINED:
|
|
1487
|
+
result = undefined;
|
|
1488
|
+
break;
|
|
1489
|
+
|
|
1490
|
+
case VALUE_NAN:
|
|
1491
|
+
result = NaN;
|
|
1492
|
+
break;
|
|
1493
|
+
|
|
1494
|
+
case VALUE_NEG_NAN:
|
|
1495
|
+
result = -NaN;
|
|
1496
|
+
break;
|
|
1497
|
+
|
|
1498
|
+
case VALUE_INFINITY:
|
|
1499
|
+
result = Infinity;
|
|
1500
|
+
break;
|
|
1501
|
+
|
|
1502
|
+
case VALUE_NEG_INFINITY:
|
|
1503
|
+
result = -Infinity;
|
|
1504
|
+
break;
|
|
1505
|
+
|
|
1506
|
+
case VALUE_OBJECT:
|
|
1507
|
+
// never happens
|
|
1508
|
+
result = val.contains;
|
|
1509
|
+
break;
|
|
1510
|
+
|
|
1511
|
+
case VALUE_ARRAY:
|
|
1512
|
+
// never happens
|
|
1513
|
+
result = val.contains;
|
|
1514
|
+
break;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
negative = false;
|
|
1518
|
+
val.string = '';
|
|
1519
|
+
val.value_type = VALUE_UNSET;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
completed = false;
|
|
1523
|
+
return retval;
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
};
|
|
1527
|
+
};
|
|
1528
|
+
|
|
1529
|
+
const _parser = [Object.freeze(JSON6.begin())];
|
|
1530
|
+
let _parse_level = 0;
|
|
1531
|
+
|
|
1532
|
+
JSON6.parse = function (msg, reviver) {
|
|
1533
|
+
//var parser = JSON6.begin();
|
|
1534
|
+
const parse_level = _parse_level++;
|
|
1535
|
+
if (_parser.length <= parse_level) _parser.push(Object.freeze(JSON6.begin()));
|
|
1536
|
+
const parser = _parser[parse_level];
|
|
1537
|
+
if (typeof msg !== "string") msg = String(msg);
|
|
1538
|
+
parser.reset();
|
|
1539
|
+
|
|
1540
|
+
if (parser._write(msg, true) > 0) {
|
|
1541
|
+
const result = parser.value();
|
|
1542
|
+
if (typeof reviver === 'function') (function walk(holder, key) {
|
|
1543
|
+
const value = holder[key];
|
|
1544
|
+
|
|
1545
|
+
if (value && typeof value === 'object') {
|
|
1546
|
+
for (const k in value) {
|
|
1547
|
+
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
|
1548
|
+
const v = walk(value, k);
|
|
1549
|
+
|
|
1550
|
+
if (v !== undefined) {
|
|
1551
|
+
value[k] = v;
|
|
1552
|
+
} else {
|
|
1553
|
+
delete value[k];
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
return reviver.call(holder, key, value);
|
|
1560
|
+
})({
|
|
1561
|
+
'': result
|
|
1562
|
+
}, '');
|
|
1563
|
+
_parse_level--;
|
|
1564
|
+
return result;
|
|
1565
|
+
} else parser.finalError();
|
|
1566
|
+
|
|
1567
|
+
return undefined;
|
|
1568
|
+
};
|
|
1569
|
+
|
|
1570
|
+
JSON6.stringify = JSON.stringify; //---------------------------------------------------------------------------
|
|
1571
|
+
// Stringify
|
|
1572
|
+
//---------------------------------------------------------------------------
|
|
1573
|
+
|
|
1574
|
+
JSON6.stringifierActive = null;
|
|
1575
|
+
|
|
1576
|
+
JSON6.stringifier = function () {
|
|
1577
|
+
const keywords = {
|
|
1578
|
+
["true"]: true,
|
|
1579
|
+
["false"]: false,
|
|
1580
|
+
["null"]: null,
|
|
1581
|
+
["NaN"]: NaN,
|
|
1582
|
+
["Infinity"]: Infinity,
|
|
1583
|
+
["undefined"]: undefined
|
|
1584
|
+
};
|
|
1585
|
+
let useQuote = '"';
|
|
1586
|
+
let ignoreNonEnumerable = false;
|
|
1587
|
+
return {
|
|
1588
|
+
stringify(o, r, s, as) {
|
|
1589
|
+
return stringify(this, o, r, s, as);
|
|
1590
|
+
},
|
|
1591
|
+
|
|
1592
|
+
setQuote(q) {
|
|
1593
|
+
useQuote = q;
|
|
1594
|
+
},
|
|
1595
|
+
|
|
1596
|
+
get ignoreNonEnumerable() {
|
|
1597
|
+
return ignoreNonEnumerable;
|
|
1598
|
+
},
|
|
1599
|
+
|
|
1600
|
+
set ignoreNonEnumerable(val) {
|
|
1601
|
+
ignoreNonEnumerable = val;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
};
|
|
1605
|
+
|
|
1606
|
+
function getIdentifier(s) {
|
|
1607
|
+
if ("number" === typeof s && !isNaN(s)) {
|
|
1608
|
+
return ["'", s.toString(), "'"].join();
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
if (!s.length) return useQuote + useQuote; // should check also for if any non ident in string...
|
|
1612
|
+
|
|
1613
|
+
return s in keywords
|
|
1614
|
+
/* [ "true","false","null","NaN","Infinity","undefined"].find( keyword=>keyword===s )*/
|
|
1615
|
+
|| /([0-9-])/.test(s[0]) || /((\n|\r|\t)|[ #{}()<>!+\-*/.:,])/.test(s) ? useQuote + JSON6.escape(s) + useQuote : s;
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
function stringify(stringifier, object, replacer, space, asField) {
|
|
1619
|
+
if (object === undefined) return "undefined";
|
|
1620
|
+
if (object === null) return "null";
|
|
1621
|
+
let gap;
|
|
1622
|
+
let indent;
|
|
1623
|
+
let i;
|
|
1624
|
+
const spaceType = typeof space;
|
|
1625
|
+
const repType = typeof replacer;
|
|
1626
|
+
gap = "";
|
|
1627
|
+
indent = "";
|
|
1628
|
+
const stringifier_ = JSON6.stringifierActive;
|
|
1629
|
+
JSON6.stringifierActive = stringifier;
|
|
1630
|
+
|
|
1631
|
+
if (!asField) {
|
|
1632
|
+
asField = "";
|
|
1633
|
+
} // If the space parameter is a number, make an indent string containing that
|
|
1634
|
+
// many spaces.
|
|
1635
|
+
|
|
1636
|
+
|
|
1637
|
+
if (spaceType === "number") {
|
|
1638
|
+
for (i = 0; i < space; i += 1) {
|
|
1639
|
+
indent += " ";
|
|
1640
|
+
} // If the space parameter is a string, it will be used as the indent string.
|
|
1641
|
+
|
|
1642
|
+
} else if (spaceType === "string") {
|
|
1643
|
+
indent = space;
|
|
1644
|
+
} // If there is a replacer, it must be a function or an array.
|
|
1645
|
+
// Otherwise, throw an error.
|
|
1646
|
+
|
|
1647
|
+
|
|
1648
|
+
const rep = replacer;
|
|
1649
|
+
|
|
1650
|
+
if (replacer && repType !== "function" && (repType !== "object" || typeof replacer.length !== "number")) {
|
|
1651
|
+
throw new Error("JSON6.stringify unknown replacer type.");
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
const r = str(asField, {
|
|
1655
|
+
[asField]: object
|
|
1656
|
+
});
|
|
1657
|
+
JSON6.stringifierActive = stringifier_; //DEBUG_STRINGIFY_OUTPUT && console.trace( "Stringify Result:", r );
|
|
1658
|
+
|
|
1659
|
+
return r; // from https://github.com/douglascrockford/JSON-js/blob/master/json2.js#L181
|
|
1660
|
+
|
|
1661
|
+
function str(key, holder) {
|
|
1662
|
+
// Produce a string from holder[key].
|
|
1663
|
+
let i; // The loop counter.
|
|
1664
|
+
|
|
1665
|
+
let k; // The member key.
|
|
1666
|
+
|
|
1667
|
+
let v; // The member value.
|
|
1668
|
+
|
|
1669
|
+
let length;
|
|
1670
|
+
const mind = gap;
|
|
1671
|
+
let partial;
|
|
1672
|
+
let value = holder[key];
|
|
1673
|
+
if ("string" === typeof value) value = getIdentifier(value);
|
|
1674
|
+
|
|
1675
|
+
if (value !== undefined && value !== null && typeof value === "object" && typeof toJSOX === "function") {
|
|
1676
|
+
// is encoding?
|
|
1677
|
+
gap += indent;
|
|
1678
|
+
gap = mind;
|
|
1679
|
+
} // If we were called with a replacer function, then call the replacer to
|
|
1680
|
+
// obtain a replacement value.
|
|
1681
|
+
|
|
1682
|
+
|
|
1683
|
+
if (typeof rep === "function") {
|
|
1684
|
+
value = rep.call(holder, key, value);
|
|
1685
|
+
} // What happens next depends on the value's type.
|
|
1686
|
+
|
|
1687
|
+
|
|
1688
|
+
switch (typeof value) {
|
|
1689
|
+
case "string":
|
|
1690
|
+
return value;
|
|
1691
|
+
|
|
1692
|
+
case "number":
|
|
1693
|
+
return '' + value;
|
|
1694
|
+
//useQuote+JSOX.escape( value )+useQuote;
|
|
1695
|
+
|
|
1696
|
+
case "boolean":
|
|
1697
|
+
return String(value);
|
|
1698
|
+
|
|
1699
|
+
case "object":
|
|
1700
|
+
//_DEBUG_STRINGIFY && console.log( "ENTERING OBJECT EMISSION WITH:", v );
|
|
1701
|
+
//if( v ) return v;
|
|
1702
|
+
// Due to a specification blunder in ECMAScript, typeof null is "object",
|
|
1703
|
+
// so watch out for that case.
|
|
1704
|
+
if (!value) {
|
|
1705
|
+
return "null";
|
|
1706
|
+
} // Make an array to hold the partial results of stringifying this object value.
|
|
1707
|
+
|
|
1708
|
+
|
|
1709
|
+
gap += indent;
|
|
1710
|
+
partial = []; // If the replacer is an array, use it to select the members to be stringified.
|
|
1711
|
+
|
|
1712
|
+
if (rep && typeof rep === "object") {
|
|
1713
|
+
length = rep.length; //_DEBUG_STRINGIFY && console.log( "Working through replacer" );
|
|
1714
|
+
|
|
1715
|
+
for (i = 0; i < length; i += 1) {
|
|
1716
|
+
if (typeof rep[i] === "string") {
|
|
1717
|
+
k = rep[i];
|
|
1718
|
+
v = str(k, value);
|
|
1719
|
+
|
|
1720
|
+
if (v) {
|
|
1721
|
+
partial.push(getIdentifier(k) + (gap ? ": " : ":") + v);
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
} else {
|
|
1726
|
+
// Otherwise, iterate through all of the keys in the object.
|
|
1727
|
+
const keys = []; //_DEBUG_STRINGIFY && console.log( "is something in something?", k, value );
|
|
1728
|
+
|
|
1729
|
+
for (k in value) {
|
|
1730
|
+
if (ignoreNonEnumerable) if (!Object.prototype.propertyIsEnumerable.call(value, k)) {
|
|
1731
|
+
//_DEBUG_STRINGIFY && console.log( "skipping non-enuerable?", k );
|
|
1732
|
+
continue;
|
|
1733
|
+
} // sort properties into keys.
|
|
1734
|
+
|
|
1735
|
+
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
|
1736
|
+
let n;
|
|
1737
|
+
|
|
1738
|
+
for (n = 0; n < keys.length; n++) if (keys[n] > k) {
|
|
1739
|
+
keys.splice(n, 0, k);
|
|
1740
|
+
break;
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
if (n === keys.length) keys.push(k);
|
|
1744
|
+
}
|
|
1745
|
+
} //_DEBUG_STRINGIFY && console.log( "Expanding object keys:", v, keys );
|
|
1746
|
+
|
|
1747
|
+
|
|
1748
|
+
for (let n = 0; n < keys.length; n++) {
|
|
1749
|
+
k = keys[n];
|
|
1750
|
+
|
|
1751
|
+
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
|
1752
|
+
v = str(k, value);
|
|
1753
|
+
|
|
1754
|
+
if (v) {
|
|
1755
|
+
partial.push(getIdentifier(k) + (gap ? ": " : ":") + v);
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
} // Join all of the member texts together, separated with commas,
|
|
1760
|
+
// and wrap them in braces.
|
|
1761
|
+
//_DEBUG_STRINGIFY && console.log( "partial:", partial, protoConverter )
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
v = '' + (partial.length === 0 ? "{}" : gap ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}" : "{" + partial.join(",") + "}");
|
|
1765
|
+
gap = mind; //_DEBUG_STRINGIFY && console.log(" Resulting phrase from this part is:", v );
|
|
1766
|
+
|
|
1767
|
+
return v;
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
};
|
|
1772
|
+
|
|
1773
|
+
JSON6.stringify = function (object, replacer, space) {
|
|
1774
|
+
const stringifier = JSON6.stringifier();
|
|
1775
|
+
return stringifier.stringify(object, replacer, space);
|
|
1776
|
+
};
|
|
1777
|
+
|
|
1778
|
+
JSON6.version = version;
|
|
1779
|
+
});
|
|
1780
|
+
|
|
1781
|
+
var lib = json6;
|
|
1782
|
+
|
|
1783
|
+
export default lib;
|