libshv-js 3.17.0 → 3.21.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/dist/access.d.ts +69 -0
- package/dist/access.js +98 -0
- package/dist/chainpack.d.ts +39 -0
- package/dist/chainpack.js +562 -0
- package/dist/cpcontext.d.ts +18 -0
- package/dist/cpcontext.js +78 -0
- package/dist/cpon.d.ts +55 -0
- package/dist/cpon.js +900 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +26 -0
- package/dist/json.d.ts +3 -0
- package/dist/json.js +118 -0
- package/dist/rpcmessage.d.ts +285 -0
- package/dist/rpcmessage.js +111 -0
- package/dist/rpcvalue.d.ts +56 -0
- package/dist/rpcvalue.js +100 -0
- package/dist/vue-shv.d.ts +92 -0
- package/dist/vue-shv.js +425 -0
- package/dist/ws-client.d.ts +232 -0
- package/dist/ws-client.js +586 -0
- package/dist/zod.d.ts +30 -0
- package/dist/zod.js +112 -0
- package/package.json +1 -1
package/dist/cpon.js
ADDED
|
@@ -0,0 +1,900 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fromCpon = exports.toCpon = exports.CPON_PROTOCOL_TYPE = exports.CponReader = exports.CponWriter = exports.utf8ToString = exports.OneLiners = exports.stringifyDate = void 0;
|
|
4
|
+
/* eslint-disable no-bitwise */
|
|
5
|
+
const rpcvalue_1 = require("./rpcvalue");
|
|
6
|
+
const cpcontext_1 = require("./cpcontext");
|
|
7
|
+
const stringifyDate = (dt) => {
|
|
8
|
+
const epochMsec = dt.getTime();
|
|
9
|
+
let utcOffset = dt.utc_offset;
|
|
10
|
+
const localMsec = epochMsec + (60_000 * (utcOffset ?? 0));
|
|
11
|
+
let res = new Date(localMsec).toISOString();
|
|
12
|
+
const rtrim = ((localMsec % 1000) !== 0) ? 1 : 5;
|
|
13
|
+
res = res.slice(0, Math.max(0, res.length - rtrim));
|
|
14
|
+
if (utcOffset === undefined || utcOffset === 0) {
|
|
15
|
+
res += 'Z';
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
if (utcOffset < 0) {
|
|
19
|
+
res += '-';
|
|
20
|
+
utcOffset = -utcOffset;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
res += '+';
|
|
24
|
+
}
|
|
25
|
+
res += (Math.trunc(utcOffset / 60)).toString().padStart(2, '0');
|
|
26
|
+
if ((utcOffset % 60) !== 0) {
|
|
27
|
+
res += (utcOffset % 60).toString().padStart(2, '0');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return res;
|
|
31
|
+
};
|
|
32
|
+
exports.stringifyDate = stringifyDate;
|
|
33
|
+
const hexify = (byte) => {
|
|
34
|
+
if (byte < 10) {
|
|
35
|
+
return 48 + byte;
|
|
36
|
+
}
|
|
37
|
+
if (byte < 16) {
|
|
38
|
+
return 97 + byte - 10;
|
|
39
|
+
}
|
|
40
|
+
return '?'.codePointAt(0);
|
|
41
|
+
};
|
|
42
|
+
const unhex = (byte) => {
|
|
43
|
+
if (byte >= 48 && byte <= 57) { // 0-9
|
|
44
|
+
return byte - 48;
|
|
45
|
+
}
|
|
46
|
+
if (byte >= 65 && byte <= 70) { // A-F
|
|
47
|
+
return byte - 65 + 10;
|
|
48
|
+
}
|
|
49
|
+
if (byte >= 97 && byte <= 102) { // a-f
|
|
50
|
+
return byte - 97 + 10;
|
|
51
|
+
}
|
|
52
|
+
throw new TypeError('Invalid HEX digit: ' + byte);
|
|
53
|
+
};
|
|
54
|
+
const utf8ToString = (bytearray) => {
|
|
55
|
+
const uint8Array = new Uint8Array(bytearray);
|
|
56
|
+
let str = '';
|
|
57
|
+
for (let i = 0; i < uint8Array.length; i++) {
|
|
58
|
+
const value = uint8Array[i];
|
|
59
|
+
if (value < 0x80) {
|
|
60
|
+
str += String.fromCodePoint(value);
|
|
61
|
+
}
|
|
62
|
+
else if (value > 0xBF && value < 0xE0) {
|
|
63
|
+
str += String.fromCodePoint(((value & 0x1F) << 6) | (uint8Array[i + 1] & 0x3F));
|
|
64
|
+
i += 1;
|
|
65
|
+
}
|
|
66
|
+
else if (value > 0xDF && value < 0xF0) {
|
|
67
|
+
str += String.fromCodePoint(((value & 0x0F) << 12) | ((uint8Array[i + 1] & 0x3F) << 6) | (uint8Array[i + 2] & 0x3F));
|
|
68
|
+
i += 2;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// surrogate pair
|
|
72
|
+
const charCode = (((value & 0x07) << 18) | ((uint8Array[i + 1] & 0x3F) << 12) | ((uint8Array[i + 2] & 0x3F) << 6) | (uint8Array[i + 3] & 0x3F)) - 0x01_00_00;
|
|
73
|
+
str += String.fromCodePoint((charCode >> 10) | 0xD8_00, (charCode & 0x03_FF) | 0xDC_00);
|
|
74
|
+
i += 3;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return str;
|
|
78
|
+
};
|
|
79
|
+
exports.utf8ToString = utf8ToString;
|
|
80
|
+
class CponReader {
|
|
81
|
+
ctx;
|
|
82
|
+
constructor(unpackContext) {
|
|
83
|
+
this.ctx = unpackContext;
|
|
84
|
+
}
|
|
85
|
+
read() {
|
|
86
|
+
let meta;
|
|
87
|
+
this.skipWhitespace();
|
|
88
|
+
let b = this.ctx.peekByte();
|
|
89
|
+
if (b === '<'.codePointAt(0)) {
|
|
90
|
+
meta = this.readMetaMap();
|
|
91
|
+
}
|
|
92
|
+
const implReturn = (x) => {
|
|
93
|
+
const ret = meta !== undefined ? new rpcvalue_1.RpcValueWithMetaData(meta, x) : x;
|
|
94
|
+
return ret;
|
|
95
|
+
};
|
|
96
|
+
this.skipWhitespace();
|
|
97
|
+
b = this.ctx.peekByte();
|
|
98
|
+
// console.log("CHAR:", b, String.fromCodePoint(b));
|
|
99
|
+
// [0-9+-]
|
|
100
|
+
if ((b >= 48 && b <= 57) || b === 43 || b === 45) {
|
|
101
|
+
return implReturn(this.readNumber());
|
|
102
|
+
}
|
|
103
|
+
if (b === '"'.codePointAt(0)) {
|
|
104
|
+
return implReturn(this.readCString());
|
|
105
|
+
}
|
|
106
|
+
if (b === 'b'.codePointAt(0)) {
|
|
107
|
+
this.ctx.getByte();
|
|
108
|
+
b = this.ctx.peekByte();
|
|
109
|
+
if (b === '"'.codePointAt(0)) {
|
|
110
|
+
return implReturn(this.readBlobEsc());
|
|
111
|
+
}
|
|
112
|
+
throw new TypeError('Invalid Blob prefix.');
|
|
113
|
+
}
|
|
114
|
+
if (b === 'x'.codePointAt(0)) {
|
|
115
|
+
this.ctx.getByte();
|
|
116
|
+
b = this.ctx.peekByte();
|
|
117
|
+
if (b === '"'.codePointAt(0)) {
|
|
118
|
+
return implReturn(this.readBlobHex());
|
|
119
|
+
}
|
|
120
|
+
throw new TypeError('Invalid HEX Blob prefix.');
|
|
121
|
+
}
|
|
122
|
+
if (b === '['.codePointAt(0)) {
|
|
123
|
+
return implReturn(this.readList());
|
|
124
|
+
}
|
|
125
|
+
if (b === '{'.codePointAt(0)) {
|
|
126
|
+
return implReturn(this.readMap());
|
|
127
|
+
}
|
|
128
|
+
if (b === 'i'.codePointAt(0)) {
|
|
129
|
+
this.ctx.getByte();
|
|
130
|
+
b = this.ctx.peekByte();
|
|
131
|
+
if (b === '{'.codePointAt(0)) {
|
|
132
|
+
return implReturn(this.readIMap());
|
|
133
|
+
}
|
|
134
|
+
throw new TypeError('Invalid IMap prefix.');
|
|
135
|
+
}
|
|
136
|
+
if (b === 'd'.codePointAt(0)) {
|
|
137
|
+
this.ctx.getByte();
|
|
138
|
+
b = this.ctx.peekByte();
|
|
139
|
+
if (b === '"'.codePointAt(0)) {
|
|
140
|
+
return implReturn(this.readDateTime());
|
|
141
|
+
}
|
|
142
|
+
throw new TypeError('Invalid DateTime prefix.');
|
|
143
|
+
}
|
|
144
|
+
if (b === 't'.codePointAt(0)) {
|
|
145
|
+
this.ctx.getBytes('true');
|
|
146
|
+
return implReturn(true);
|
|
147
|
+
}
|
|
148
|
+
if (b === 'f'.codePointAt(0)) {
|
|
149
|
+
this.ctx.getBytes('false');
|
|
150
|
+
return implReturn(false);
|
|
151
|
+
}
|
|
152
|
+
if (b === 'n'.codePointAt(0)) {
|
|
153
|
+
this.ctx.getBytes('null');
|
|
154
|
+
return implReturn(undefined);
|
|
155
|
+
}
|
|
156
|
+
throw new TypeError('Malformed Cpon input.');
|
|
157
|
+
}
|
|
158
|
+
skipWhitespace() {
|
|
159
|
+
const SPACE = ' '.codePointAt(0);
|
|
160
|
+
const SLASH = '/'.codePointAt(0);
|
|
161
|
+
const STAR = '*'.codePointAt(0);
|
|
162
|
+
const LF = '\n'.codePointAt(0);
|
|
163
|
+
const KEY_DELIM = ':'.codePointAt(0);
|
|
164
|
+
const FIELD_DELIM = ','.codePointAt(0);
|
|
165
|
+
/* eslint-disable max-depth */
|
|
166
|
+
while (true) {
|
|
167
|
+
let b = this.ctx.peekByte();
|
|
168
|
+
if (b < 1) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (b > SPACE) {
|
|
172
|
+
switch (b) {
|
|
173
|
+
case SLASH: {
|
|
174
|
+
this.ctx.getByte();
|
|
175
|
+
b = this.ctx.getByte();
|
|
176
|
+
if (b === STAR) {
|
|
177
|
+
// multiline_comment_entered;
|
|
178
|
+
while (true) {
|
|
179
|
+
b = this.ctx.getByte();
|
|
180
|
+
if (b === STAR) {
|
|
181
|
+
b = this.ctx.getByte();
|
|
182
|
+
if (b === SLASH) {
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else if (b === SLASH) {
|
|
189
|
+
// to end of line comment entered;
|
|
190
|
+
while (true) {
|
|
191
|
+
b = this.ctx.getByte();
|
|
192
|
+
if (b === LF) {
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
throw new TypeError('Malformed comment');
|
|
199
|
+
}
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case KEY_DELIM: {
|
|
203
|
+
this.ctx.getByte();
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
case FIELD_DELIM: {
|
|
207
|
+
this.ctx.getByte();
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
default:
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
this.ctx.getByte();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/* eslint-enable max-depth */
|
|
219
|
+
}
|
|
220
|
+
readDateTime() {
|
|
221
|
+
this.ctx.getByte(); // eat '"'
|
|
222
|
+
let b = this.ctx.peekByte();
|
|
223
|
+
if (b === '"'.codePointAt(0)) {
|
|
224
|
+
// d"" invalid data time
|
|
225
|
+
this.ctx.getByte();
|
|
226
|
+
throw new TypeError('Malformed empty date separator in DateTime');
|
|
227
|
+
}
|
|
228
|
+
const date = this.readDateTimeInner();
|
|
229
|
+
b = this.ctx.getByte();
|
|
230
|
+
if (b !== '"'.codePointAt(0)) {
|
|
231
|
+
throw new TypeError('DateTime literal should be terminated by \'"\'.');
|
|
232
|
+
}
|
|
233
|
+
return date;
|
|
234
|
+
}
|
|
235
|
+
readDateTimeInner() {
|
|
236
|
+
let year = 0;
|
|
237
|
+
let month = 0;
|
|
238
|
+
let day = 1;
|
|
239
|
+
let hour = 0;
|
|
240
|
+
let min = 0;
|
|
241
|
+
let sec = 0;
|
|
242
|
+
let msec = 0;
|
|
243
|
+
let utcOffset = 0;
|
|
244
|
+
year = Number(this.readInt());
|
|
245
|
+
let b = this.ctx.getByte();
|
|
246
|
+
if (b !== '-'.codePointAt(0)) {
|
|
247
|
+
throw new TypeError('Malformed year-month separator in DateTime');
|
|
248
|
+
}
|
|
249
|
+
month = Number(this.readInt());
|
|
250
|
+
b = this.ctx.getByte();
|
|
251
|
+
if (b !== '-'.codePointAt(0)) {
|
|
252
|
+
throw new TypeError('Malformed year-month separator in DateTime');
|
|
253
|
+
}
|
|
254
|
+
day = Number(this.readInt());
|
|
255
|
+
b = this.ctx.getByte();
|
|
256
|
+
if (b !== ' '.codePointAt(0) && b !== 'T'.codePointAt(0)) {
|
|
257
|
+
throw new TypeError('Malformed date-time separator in DateTime');
|
|
258
|
+
}
|
|
259
|
+
hour = Number(this.readInt());
|
|
260
|
+
b = this.ctx.getByte();
|
|
261
|
+
if (b !== ':'.codePointAt(0)) {
|
|
262
|
+
throw new TypeError('Malformed year-month separator in DateTime');
|
|
263
|
+
}
|
|
264
|
+
min = Number(this.readInt());
|
|
265
|
+
b = this.ctx.getByte();
|
|
266
|
+
if (b !== ':'.codePointAt(0)) {
|
|
267
|
+
throw new TypeError('Malformed year-month separator in DateTime');
|
|
268
|
+
}
|
|
269
|
+
sec = Number(this.readInt());
|
|
270
|
+
b = this.ctx.peekByte();
|
|
271
|
+
if (b === '.'.codePointAt(0)) {
|
|
272
|
+
this.ctx.getByte();
|
|
273
|
+
msec = Number(this.readInt());
|
|
274
|
+
}
|
|
275
|
+
b = this.ctx.peekByte();
|
|
276
|
+
if (b === 'Z'.codePointAt(0)) {
|
|
277
|
+
// zulu time
|
|
278
|
+
this.ctx.getByte();
|
|
279
|
+
}
|
|
280
|
+
else if (b === '+'.codePointAt(0) || b === '-'.codePointAt(0)) {
|
|
281
|
+
// UTC time offset
|
|
282
|
+
this.ctx.getByte();
|
|
283
|
+
const ix1 = this.ctx.index;
|
|
284
|
+
const val = Number(this.readInt());
|
|
285
|
+
const n = this.ctx.index - ix1;
|
|
286
|
+
if (!(n === 2 || n === 4)) {
|
|
287
|
+
throw new TypeError('Malformed TS offset in DateTime.');
|
|
288
|
+
}
|
|
289
|
+
if (n === 2) {
|
|
290
|
+
utcOffset = 60 * val;
|
|
291
|
+
}
|
|
292
|
+
else if (n === 4) {
|
|
293
|
+
utcOffset = (60 * (Math.trunc(val / 100))) + (val % 100);
|
|
294
|
+
}
|
|
295
|
+
if (b === '-'.codePointAt(0)) {
|
|
296
|
+
utcOffset = -utcOffset;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// let epoch_sec = CponReader.timegm(year, month, mday, hour, min, sec);
|
|
300
|
+
let epochMsec = Date.UTC(year, month - 1, day, hour, min, sec, msec);
|
|
301
|
+
epochMsec -= utcOffset * 60_000;
|
|
302
|
+
return (0, rpcvalue_1.withOffset)(new Date(epochMsec), utcOffset ?? undefined);
|
|
303
|
+
}
|
|
304
|
+
readCString() {
|
|
305
|
+
const pctx = new cpcontext_1.PackContext();
|
|
306
|
+
this.ctx.getByte(); // eat '"'
|
|
307
|
+
while (true) {
|
|
308
|
+
let b = this.ctx.getByte();
|
|
309
|
+
if (b === '\\'.codePointAt(0)) {
|
|
310
|
+
b = this.ctx.getByte();
|
|
311
|
+
switch (b) {
|
|
312
|
+
case '\\'.codePointAt(0):
|
|
313
|
+
pctx.putByte('\\'.codePointAt(0));
|
|
314
|
+
break;
|
|
315
|
+
case '"'.codePointAt(0):
|
|
316
|
+
pctx.putByte('"'.codePointAt(0));
|
|
317
|
+
break;
|
|
318
|
+
case 'b'.codePointAt(0):
|
|
319
|
+
pctx.putByte('\b'.codePointAt(0));
|
|
320
|
+
break;
|
|
321
|
+
case 'f'.codePointAt(0):
|
|
322
|
+
pctx.putByte('\f'.codePointAt(0));
|
|
323
|
+
break;
|
|
324
|
+
case 'n'.codePointAt(0):
|
|
325
|
+
pctx.putByte('\n'.codePointAt(0));
|
|
326
|
+
break;
|
|
327
|
+
case 'r'.codePointAt(0):
|
|
328
|
+
pctx.putByte('\r'.codePointAt(0));
|
|
329
|
+
break;
|
|
330
|
+
case 't'.codePointAt(0):
|
|
331
|
+
pctx.putByte('\t'.codePointAt(0));
|
|
332
|
+
break;
|
|
333
|
+
case '0'.codePointAt(0):
|
|
334
|
+
pctx.putByte(0);
|
|
335
|
+
break;
|
|
336
|
+
default:
|
|
337
|
+
pctx.putByte(b);
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else if (b === '"'.codePointAt(0)) {
|
|
342
|
+
// end of string
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
pctx.putByte(b);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return utf8ToString(pctx.buffer());
|
|
350
|
+
}
|
|
351
|
+
readBlobEsc() {
|
|
352
|
+
const pctx = new cpcontext_1.PackContext();
|
|
353
|
+
this.ctx.getByte(); // eat '"'
|
|
354
|
+
while (true) {
|
|
355
|
+
let b = this.ctx.getByte();
|
|
356
|
+
if (b === '\\'.codePointAt(0)) {
|
|
357
|
+
b = this.ctx.getByte();
|
|
358
|
+
switch (b) {
|
|
359
|
+
case '\\'.codePointAt(0):
|
|
360
|
+
pctx.putByte('\\'.codePointAt(0));
|
|
361
|
+
break;
|
|
362
|
+
case '"'.codePointAt(0):
|
|
363
|
+
pctx.putByte('"'.codePointAt(0));
|
|
364
|
+
break;
|
|
365
|
+
case 'n'.codePointAt(0):
|
|
366
|
+
pctx.putByte('\n'.codePointAt(0));
|
|
367
|
+
break;
|
|
368
|
+
case 'r'.codePointAt(0):
|
|
369
|
+
pctx.putByte('\r'.codePointAt(0));
|
|
370
|
+
break;
|
|
371
|
+
case 't'.codePointAt(0):
|
|
372
|
+
pctx.putByte('\t'.codePointAt(0));
|
|
373
|
+
break;
|
|
374
|
+
default: {
|
|
375
|
+
const b2 = (unhex(b) * 16) + unhex(this.ctx.getByte());
|
|
376
|
+
pctx.putByte(b2);
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
else if (b === '"'.codePointAt(0)) {
|
|
382
|
+
// end of string
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
else if (b < 128) {
|
|
386
|
+
pctx.putByte(b);
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
throw new TypeError('Escaped Blob characters must be lower than 128, code: ' + b);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return pctx.buffer();
|
|
393
|
+
}
|
|
394
|
+
readBlobHex() {
|
|
395
|
+
const pctx = new cpcontext_1.PackContext();
|
|
396
|
+
this.ctx.getByte(); // eat '"'
|
|
397
|
+
while (true) {
|
|
398
|
+
const b = this.ctx.getByte();
|
|
399
|
+
if (b === '"'.codePointAt(0)) {
|
|
400
|
+
// end of string
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
const b2 = (unhex(b) * 16) + unhex(this.ctx.getByte());
|
|
405
|
+
pctx.putByte(b2);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return pctx.buffer();
|
|
409
|
+
}
|
|
410
|
+
readList() {
|
|
411
|
+
const lst = [];
|
|
412
|
+
this.ctx.getByte(); // eat '['
|
|
413
|
+
while (true) {
|
|
414
|
+
this.skipWhitespace();
|
|
415
|
+
const b = this.ctx.peekByte();
|
|
416
|
+
if (b === ']'.codePointAt(0)) {
|
|
417
|
+
this.ctx.getByte();
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
const item = this.read();
|
|
421
|
+
lst.push(item);
|
|
422
|
+
}
|
|
423
|
+
return lst;
|
|
424
|
+
}
|
|
425
|
+
readMetaMap() {
|
|
426
|
+
return this.implReadMap('metamap', '>'.codePointAt(0));
|
|
427
|
+
}
|
|
428
|
+
readMap() {
|
|
429
|
+
return this.implReadMap('map', '}'.codePointAt(0));
|
|
430
|
+
}
|
|
431
|
+
readIMap() {
|
|
432
|
+
return this.implReadMap('imap', '}'.codePointAt(0));
|
|
433
|
+
}
|
|
434
|
+
readInt() {
|
|
435
|
+
let base = 10;
|
|
436
|
+
let val = 0;
|
|
437
|
+
let neg = false;
|
|
438
|
+
let n = 0;
|
|
439
|
+
for (;; n++) {
|
|
440
|
+
const b = this.ctx.peekByte();
|
|
441
|
+
if (b < 0) {
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
if (b === 43 || b === 45) { // '+','-'
|
|
445
|
+
if (n !== 0) {
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
this.ctx.getByte();
|
|
449
|
+
if (b === 45) {
|
|
450
|
+
neg = true;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
else if (b === 120) { // 'x'
|
|
454
|
+
if (n === 1 && val !== 0) {
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
if (n !== 1) {
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
this.ctx.getByte();
|
|
461
|
+
base = 16;
|
|
462
|
+
}
|
|
463
|
+
else if (b >= 48 && b <= 57) { // '0' - '9'
|
|
464
|
+
this.ctx.getByte();
|
|
465
|
+
val *= base;
|
|
466
|
+
val += b - 48;
|
|
467
|
+
}
|
|
468
|
+
else if (b >= 65 && b <= 70) { // 'A' - 'F'
|
|
469
|
+
if (base !== 16) {
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
this.ctx.getByte();
|
|
473
|
+
val *= base;
|
|
474
|
+
val += b - 65 + 10;
|
|
475
|
+
}
|
|
476
|
+
else if (b >= 97 && b <= 102) { // 'a' - 'f'
|
|
477
|
+
if (base !== 16) {
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
480
|
+
this.ctx.getByte();
|
|
481
|
+
val *= base;
|
|
482
|
+
val += b - 97 + 10;
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if (neg) {
|
|
489
|
+
val = -val;
|
|
490
|
+
}
|
|
491
|
+
return val;
|
|
492
|
+
}
|
|
493
|
+
readNumber() {
|
|
494
|
+
let mantisa = 0;
|
|
495
|
+
let exponent = 0;
|
|
496
|
+
let decimals = 0;
|
|
497
|
+
let decCnt = 0;
|
|
498
|
+
let isDecimal = false;
|
|
499
|
+
let isUint = false;
|
|
500
|
+
let isNeg = false;
|
|
501
|
+
let b = this.ctx.peekByte();
|
|
502
|
+
if (b === 43) { // '+'
|
|
503
|
+
isNeg = false;
|
|
504
|
+
b = this.ctx.getByte();
|
|
505
|
+
}
|
|
506
|
+
else if (b === 45) { // '-'
|
|
507
|
+
isNeg = true;
|
|
508
|
+
b = this.ctx.getByte();
|
|
509
|
+
}
|
|
510
|
+
mantisa = Number(this.readInt());
|
|
511
|
+
b = this.ctx.peekByte();
|
|
512
|
+
(() => {
|
|
513
|
+
while (true) {
|
|
514
|
+
switch (b) {
|
|
515
|
+
case 'u'.codePointAt(0): {
|
|
516
|
+
isUint = true;
|
|
517
|
+
this.ctx.getByte();
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
case '.'.codePointAt(0): {
|
|
521
|
+
isDecimal = true;
|
|
522
|
+
this.ctx.getByte();
|
|
523
|
+
const ix1 = this.ctx.index;
|
|
524
|
+
decimals = Number(this.readInt());
|
|
525
|
+
// if(n < 0)
|
|
526
|
+
// UNPACK_ERROR(CCPCP_RC_MALFORMED_INPUT, "Malformed number decimal part.")
|
|
527
|
+
decCnt = this.ctx.index - ix1;
|
|
528
|
+
b = this.ctx.peekByte();
|
|
529
|
+
if (b >= 0) {
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
case 'e'.codePointAt(0):
|
|
535
|
+
case 'E'.codePointAt(0): {
|
|
536
|
+
isDecimal = true;
|
|
537
|
+
this.ctx.getByte();
|
|
538
|
+
const ix1 = this.ctx.index;
|
|
539
|
+
exponent = Number(this.readInt());
|
|
540
|
+
if (ix1 === this.ctx.index) {
|
|
541
|
+
throw new TypeError('Malformed number exponential part.');
|
|
542
|
+
}
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
default:
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
})();
|
|
550
|
+
if (isDecimal) {
|
|
551
|
+
for (let i = 0; i < decCnt; ++i) {
|
|
552
|
+
mantisa *= 10;
|
|
553
|
+
}
|
|
554
|
+
mantisa += decimals;
|
|
555
|
+
mantisa = isNeg ? -mantisa : mantisa;
|
|
556
|
+
return new rpcvalue_1.Decimal(mantisa, exponent - decCnt);
|
|
557
|
+
}
|
|
558
|
+
if (isUint) {
|
|
559
|
+
return new rpcvalue_1.UInt(mantisa);
|
|
560
|
+
}
|
|
561
|
+
return isNeg ? -mantisa : mantisa;
|
|
562
|
+
}
|
|
563
|
+
implReadMap(mapType, terminator) {
|
|
564
|
+
const map = {
|
|
565
|
+
[rpcvalue_1.shvMapType]: mapType,
|
|
566
|
+
};
|
|
567
|
+
this.ctx.getByte(); // eat start
|
|
568
|
+
while (true) {
|
|
569
|
+
this.skipWhitespace();
|
|
570
|
+
const b = this.ctx.peekByte();
|
|
571
|
+
if (b === terminator) {
|
|
572
|
+
this.ctx.getByte();
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
const key = this.read();
|
|
576
|
+
if (key instanceof rpcvalue_1.RpcValueWithMetaData) {
|
|
577
|
+
throw new TypeError('Map/IMap/MetaMap key can\'t have its own MetaData');
|
|
578
|
+
}
|
|
579
|
+
this.skipWhitespace();
|
|
580
|
+
const val = this.read();
|
|
581
|
+
if (map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'string') {
|
|
582
|
+
map[key] = val;
|
|
583
|
+
}
|
|
584
|
+
else if (map[rpcvalue_1.shvMapType] === 'metamap' && (key instanceof rpcvalue_1.UInt || typeof key === 'number')) {
|
|
585
|
+
map[Number(key)] = val;
|
|
586
|
+
}
|
|
587
|
+
else if (map[rpcvalue_1.shvMapType] === 'map' && typeof key === 'string') {
|
|
588
|
+
map[key] = val;
|
|
589
|
+
}
|
|
590
|
+
else if (map[rpcvalue_1.shvMapType] === 'imap' && (key instanceof rpcvalue_1.UInt || typeof key === 'number')) {
|
|
591
|
+
map[Number(key)] = val;
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
throw new TypeError('Malformed map, invalid key');
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return map;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
exports.CponReader = CponReader;
|
|
601
|
+
class CponWriter {
|
|
602
|
+
indentString;
|
|
603
|
+
oneLiners;
|
|
604
|
+
ctx;
|
|
605
|
+
nestLevel = 0;
|
|
606
|
+
constructor(indentString, oneLiners = OneLiners.Yes) {
|
|
607
|
+
this.indentString = indentString;
|
|
608
|
+
this.oneLiners = oneLiners;
|
|
609
|
+
this.ctx = new cpcontext_1.PackContext();
|
|
610
|
+
}
|
|
611
|
+
write(rpcVal) {
|
|
612
|
+
if (rpcVal instanceof rpcvalue_1.RpcValueWithMetaData) {
|
|
613
|
+
this.writeMeta(rpcVal.meta);
|
|
614
|
+
rpcVal = rpcVal.value;
|
|
615
|
+
}
|
|
616
|
+
switch (true) {
|
|
617
|
+
case rpcVal === undefined:
|
|
618
|
+
this.ctx.writeStringUtf8('null');
|
|
619
|
+
break;
|
|
620
|
+
case typeof rpcVal === 'boolean':
|
|
621
|
+
this.writeBool(rpcVal);
|
|
622
|
+
break;
|
|
623
|
+
case typeof rpcVal === 'string':
|
|
624
|
+
this.writeJSString(rpcVal);
|
|
625
|
+
break;
|
|
626
|
+
case rpcVal instanceof ArrayBuffer:
|
|
627
|
+
this.writeBlob(rpcVal);
|
|
628
|
+
break;
|
|
629
|
+
case rpcVal instanceof rpcvalue_1.UInt:
|
|
630
|
+
this.writeUInt(rpcVal);
|
|
631
|
+
break;
|
|
632
|
+
case typeof rpcVal === 'number':
|
|
633
|
+
this.writeInt(rpcVal);
|
|
634
|
+
break;
|
|
635
|
+
case rpcVal instanceof rpcvalue_1.Double:
|
|
636
|
+
this.writeDouble(rpcVal);
|
|
637
|
+
break;
|
|
638
|
+
case rpcVal instanceof rpcvalue_1.Decimal:
|
|
639
|
+
this.writeDecimal(rpcVal);
|
|
640
|
+
break;
|
|
641
|
+
case Array.isArray(rpcVal):
|
|
642
|
+
this.writeList(rpcVal);
|
|
643
|
+
break;
|
|
644
|
+
case rpcVal instanceof Date:
|
|
645
|
+
this.writeDateTime(rpcVal);
|
|
646
|
+
break;
|
|
647
|
+
case typeof rpcVal === 'object':
|
|
648
|
+
switch (rpcVal[rpcvalue_1.shvMapType]) {
|
|
649
|
+
case 'imap':
|
|
650
|
+
this.writeIMap(rpcVal);
|
|
651
|
+
break;
|
|
652
|
+
case 'map':
|
|
653
|
+
this.writeMap(rpcVal);
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
break;
|
|
657
|
+
default:
|
|
658
|
+
console.log('Can\'t serialize rpc value', rpcVal);
|
|
659
|
+
throw new Error('Can\'t serialize rpc value');
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
writeJSString(str) {
|
|
663
|
+
this.ctx.writeStringUtf8('"');
|
|
664
|
+
for (let i = 0; i < str.length; i++) {
|
|
665
|
+
const charcode = str.codePointAt(i);
|
|
666
|
+
switch (charcode) {
|
|
667
|
+
case 0:
|
|
668
|
+
this.ctx.writeStringUtf8(String.raw `\0`);
|
|
669
|
+
break;
|
|
670
|
+
case '\\'.codePointAt(0):
|
|
671
|
+
this.ctx.writeStringUtf8('\\\\');
|
|
672
|
+
break;
|
|
673
|
+
case '\t'.codePointAt(0):
|
|
674
|
+
this.ctx.writeStringUtf8(String.raw `\t`);
|
|
675
|
+
break;
|
|
676
|
+
case '\b'.codePointAt(0):
|
|
677
|
+
this.ctx.writeStringUtf8(String.raw `\b`);
|
|
678
|
+
break;
|
|
679
|
+
case '\r'.codePointAt(0):
|
|
680
|
+
this.ctx.writeStringUtf8(String.raw `\r`);
|
|
681
|
+
break;
|
|
682
|
+
case '\n'.codePointAt(0):
|
|
683
|
+
this.ctx.writeStringUtf8(String.raw `\n`);
|
|
684
|
+
break;
|
|
685
|
+
case '"'.codePointAt(0):
|
|
686
|
+
this.ctx.writeStringUtf8(String.raw `\"`);
|
|
687
|
+
break;
|
|
688
|
+
default:
|
|
689
|
+
this.ctx.writeCharCodeUtf8(charcode);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
this.ctx.writeStringUtf8('"');
|
|
693
|
+
}
|
|
694
|
+
writeBlob(buffer) {
|
|
695
|
+
this.ctx.writeStringUtf8('b"');
|
|
696
|
+
const data = new Uint8Array(buffer);
|
|
697
|
+
for (const b of data) {
|
|
698
|
+
switch (b) {
|
|
699
|
+
case '\\'.codePointAt(0):
|
|
700
|
+
this.ctx.writeStringUtf8('\\\\');
|
|
701
|
+
break;
|
|
702
|
+
case '\t'.codePointAt(0):
|
|
703
|
+
this.ctx.writeStringUtf8(String.raw `\t`);
|
|
704
|
+
break;
|
|
705
|
+
case '\r'.codePointAt(0):
|
|
706
|
+
this.ctx.writeStringUtf8(String.raw `\r`);
|
|
707
|
+
break;
|
|
708
|
+
case '\n'.codePointAt(0):
|
|
709
|
+
this.ctx.writeStringUtf8(String.raw `\n`);
|
|
710
|
+
break;
|
|
711
|
+
case '"'.codePointAt(0):
|
|
712
|
+
this.ctx.writeStringUtf8(String.raw `\"`);
|
|
713
|
+
break;
|
|
714
|
+
default:
|
|
715
|
+
if (b >= 32 && b < 127) {
|
|
716
|
+
this.ctx.putByte(b);
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
this.ctx.putByte('\\'.codePointAt(0));
|
|
720
|
+
this.ctx.putByte(hexify(b / 16));
|
|
721
|
+
this.ctx.putByte(hexify(b % 16));
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
this.ctx.writeStringUtf8('"');
|
|
726
|
+
}
|
|
727
|
+
writeDateTime(dt) {
|
|
728
|
+
this.ctx.writeStringUtf8('d"');
|
|
729
|
+
this.ctx.writeStringUtf8((0, exports.stringifyDate)(dt));
|
|
730
|
+
this.ctx.writeStringUtf8('"');
|
|
731
|
+
}
|
|
732
|
+
writeBool(b) {
|
|
733
|
+
this.ctx.writeStringUtf8(b ? 'true' : 'false');
|
|
734
|
+
}
|
|
735
|
+
writeMeta(map) {
|
|
736
|
+
this.writeMapContent(map, '<', '>');
|
|
737
|
+
}
|
|
738
|
+
writeIMap(map) {
|
|
739
|
+
this.writeMapContent(map, 'i{', '}');
|
|
740
|
+
}
|
|
741
|
+
writeMap(map) {
|
|
742
|
+
this.writeMapContent(map, '{', '}');
|
|
743
|
+
}
|
|
744
|
+
writeMapContent(map, delimiterStart, delimiterEnd) {
|
|
745
|
+
this.ctx.writeStringUtf8(delimiterStart);
|
|
746
|
+
this.increaseIndentIfNotOneLiner(map);
|
|
747
|
+
this.doIndentIfNotOneliner(map);
|
|
748
|
+
let first = true;
|
|
749
|
+
for (const [key, value] of Object.entries(map)) {
|
|
750
|
+
if (!first) {
|
|
751
|
+
this.ctx.putByte(','.codePointAt(0));
|
|
752
|
+
this.doIndentIfNotOneliner(map);
|
|
753
|
+
}
|
|
754
|
+
first = false;
|
|
755
|
+
if (map[rpcvalue_1.shvMapType] === 'imap') {
|
|
756
|
+
const intKey = Number(key);
|
|
757
|
+
if (Number.isNaN(intKey)) {
|
|
758
|
+
throw new TypeError('Invalid NaN IMap key');
|
|
759
|
+
}
|
|
760
|
+
this.writeInt(intKey);
|
|
761
|
+
}
|
|
762
|
+
else if (map[rpcvalue_1.shvMapType] === 'metamap') {
|
|
763
|
+
const intKey = Number(key);
|
|
764
|
+
if (Number.isNaN(intKey)) {
|
|
765
|
+
this.ctx.putByte('"'.codePointAt(0));
|
|
766
|
+
this.ctx.writeStringUtf8(key.toString());
|
|
767
|
+
this.ctx.putByte('"'.codePointAt(0));
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
this.writeInt(intKey);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
else {
|
|
774
|
+
this.writeJSString(key.toString());
|
|
775
|
+
}
|
|
776
|
+
this.ctx.writeStringUtf8(':');
|
|
777
|
+
this.write(value);
|
|
778
|
+
}
|
|
779
|
+
this.decreaseIndentIfNotOneLiner(map);
|
|
780
|
+
this.doIndentIfNotOneliner(map);
|
|
781
|
+
this.ctx.writeStringUtf8(delimiterEnd);
|
|
782
|
+
}
|
|
783
|
+
writeList(lst) {
|
|
784
|
+
this.ctx.putByte('['.codePointAt(0));
|
|
785
|
+
this.increaseIndentIfNotOneLiner(lst);
|
|
786
|
+
this.doIndentIfNotOneliner(lst);
|
|
787
|
+
for (const [i, element] of lst.entries()) {
|
|
788
|
+
if (i > 0) {
|
|
789
|
+
this.ctx.putByte(','.codePointAt(0));
|
|
790
|
+
this.doIndentIfNotOneliner(lst);
|
|
791
|
+
}
|
|
792
|
+
this.write(element);
|
|
793
|
+
}
|
|
794
|
+
this.decreaseIndentIfNotOneLiner(lst);
|
|
795
|
+
this.doIndentIfNotOneliner(lst);
|
|
796
|
+
this.ctx.putByte(']'.codePointAt(0));
|
|
797
|
+
}
|
|
798
|
+
writeUInt(num) {
|
|
799
|
+
const s = Number(num).toString();
|
|
800
|
+
this.ctx.writeStringUtf8(s);
|
|
801
|
+
this.ctx.putByte('u'.codePointAt(0));
|
|
802
|
+
}
|
|
803
|
+
writeInt(num) {
|
|
804
|
+
const s = Number(num).toString();
|
|
805
|
+
this.ctx.writeStringUtf8(s);
|
|
806
|
+
}
|
|
807
|
+
writeDouble(num) {
|
|
808
|
+
let s = num.value.toString();
|
|
809
|
+
if (!s.includes('.')) {
|
|
810
|
+
s += '.';
|
|
811
|
+
}
|
|
812
|
+
this.ctx.writeStringUtf8(s);
|
|
813
|
+
}
|
|
814
|
+
writeDecimal(val) {
|
|
815
|
+
let { mantisa } = val;
|
|
816
|
+
const { exponent } = val;
|
|
817
|
+
if (mantisa < 0) {
|
|
818
|
+
mantisa = -mantisa;
|
|
819
|
+
this.ctx.putByte('-'.codePointAt(0));
|
|
820
|
+
}
|
|
821
|
+
let str = mantisa.toString();
|
|
822
|
+
const n = str.length;
|
|
823
|
+
const decPlaces = -exponent;
|
|
824
|
+
if (decPlaces > 0 && decPlaces < n) {
|
|
825
|
+
const dotIx = n - decPlaces;
|
|
826
|
+
str = str.slice(0, dotIx) + '.' + str.slice(dotIx);
|
|
827
|
+
}
|
|
828
|
+
else if (decPlaces > 0 && decPlaces <= 3) {
|
|
829
|
+
const extraZeroCnt = decPlaces - n;
|
|
830
|
+
let str0 = '0.';
|
|
831
|
+
for (let i = 0; i < extraZeroCnt; ++i) {
|
|
832
|
+
str0 += '0';
|
|
833
|
+
}
|
|
834
|
+
str = str0 + str;
|
|
835
|
+
}
|
|
836
|
+
else if (decPlaces < 0 && n + exponent <= 9) {
|
|
837
|
+
for (let i = 0; i < exponent; ++i) {
|
|
838
|
+
str += '0';
|
|
839
|
+
}
|
|
840
|
+
str += '.';
|
|
841
|
+
}
|
|
842
|
+
else if (decPlaces === 0) {
|
|
843
|
+
str += '.';
|
|
844
|
+
}
|
|
845
|
+
else {
|
|
846
|
+
str += 'e' + exponent;
|
|
847
|
+
}
|
|
848
|
+
for (let i = 0; i < str.length; ++i) {
|
|
849
|
+
this.ctx.putByte(str.codePointAt(i));
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
doIndentIfNotOneliner(map) {
|
|
853
|
+
if (this.indentString !== undefined && !this.isOneLiner(map)) {
|
|
854
|
+
this.ctx.putByte('\n'.codePointAt(0));
|
|
855
|
+
this.ctx.writeStringUtf8(this.indentString.repeat(this.nestLevel));
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
isOneLiner(value) {
|
|
859
|
+
if (this.oneLiners === OneLiners.No) {
|
|
860
|
+
return false;
|
|
861
|
+
}
|
|
862
|
+
const keyThreshold = Array.isArray(value) ? 10 : 5;
|
|
863
|
+
if (Array.isArray(value)) {
|
|
864
|
+
return value.length <= keyThreshold && !(value.some(x => Array.isArray(x) || (0, rpcvalue_1.isShvMap)(x) || (0, rpcvalue_1.isIMap)(x)));
|
|
865
|
+
}
|
|
866
|
+
return Object.keys(value).length <= keyThreshold && !(Object.values(value).some(x => Array.isArray(x) || (0, rpcvalue_1.isShvMap)(x) || (0, rpcvalue_1.isIMap)(x)));
|
|
867
|
+
}
|
|
868
|
+
increaseIndentIfNotOneLiner(value) {
|
|
869
|
+
if (!this.isOneLiner(value)) {
|
|
870
|
+
this.nestLevel++;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
decreaseIndentIfNotOneLiner(value) {
|
|
874
|
+
if (!this.isOneLiner(value)) {
|
|
875
|
+
this.nestLevel--;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
exports.CponWriter = CponWriter;
|
|
880
|
+
var OneLiners;
|
|
881
|
+
(function (OneLiners) {
|
|
882
|
+
OneLiners[OneLiners["Yes"] = 0] = "Yes";
|
|
883
|
+
OneLiners[OneLiners["No"] = 1] = "No";
|
|
884
|
+
})(OneLiners || (exports.OneLiners = OneLiners = {}));
|
|
885
|
+
const toCpon = (value, indentString, oneLiners = OneLiners.Yes) => {
|
|
886
|
+
const wr = new CponWriter(indentString, oneLiners);
|
|
887
|
+
wr.write(value);
|
|
888
|
+
return new TextDecoder().decode(wr.ctx.buffer());
|
|
889
|
+
};
|
|
890
|
+
exports.toCpon = toCpon;
|
|
891
|
+
const fromCpon = (str) => {
|
|
892
|
+
if (typeof str === 'string') {
|
|
893
|
+
str = new TextEncoder().encode(str);
|
|
894
|
+
}
|
|
895
|
+
const rd = new CponReader(new cpcontext_1.UnpackContext(str.buffer));
|
|
896
|
+
return rd.read();
|
|
897
|
+
};
|
|
898
|
+
exports.fromCpon = fromCpon;
|
|
899
|
+
const CPON_PROTOCOL_TYPE = 2;
|
|
900
|
+
exports.CPON_PROTOCOL_TYPE = CPON_PROTOCOL_TYPE;
|