@alexgyver/bson 2.2.1 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bson.js +246 -198
- package/bson.min.js +1 -1
- package/package.json +2 -2
- package/test/index.html +6 -1
package/bson.js
CHANGED
|
@@ -1,237 +1,285 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
1
|
+
//#region Const
|
|
2
|
+
// type
|
|
3
|
+
const BS_TYPE_MASK = 0b11000000;
|
|
4
|
+
const BS_SUBT = 0 << 6;
|
|
5
|
+
const BS_INT = 1 << 6;
|
|
6
|
+
const BS_STR = 2 << 6;
|
|
7
|
+
const BS_CODE = 3 << 6;
|
|
8
|
+
|
|
9
|
+
// subtype
|
|
10
|
+
const BS_SUBT_MASK = 0b00111000;
|
|
11
|
+
const BS_NULL = 0 << 3;
|
|
12
|
+
const BS_BOOL = 1 << 3;
|
|
13
|
+
const BS_CONT = 2 << 3;
|
|
14
|
+
const BS_FLOAT = 3 << 3;
|
|
15
|
+
const BS_BIN = 4 << 3;
|
|
16
|
+
|
|
17
|
+
// type int
|
|
18
|
+
const BS_INT_SMALL = 1 << 5;
|
|
19
|
+
const BS_INT_NEG = 1 << 4;
|
|
20
|
+
const BS_GET_SMALLV = x => x & 0b11111;
|
|
21
|
+
const BS_GET_INT_LEN = x => x & 0b1111;
|
|
22
|
+
|
|
23
|
+
// type string
|
|
24
|
+
// type code
|
|
25
|
+
const BS_EXT_BITS = 5;
|
|
26
|
+
const BS_EXT_FLAG = 1 << BS_EXT_BITS;
|
|
27
|
+
const BS_EXT_MASK = BS_EXT_FLAG - 1;
|
|
28
|
+
const BS_MAX_EXT_LEN = (1 << (BS_EXT_BITS + 8)) - 1;
|
|
29
|
+
const BS_GET_LSB = x => x & BS_EXT_MASK;
|
|
30
|
+
const BS_GET_MSB = x => x >> BS_EXT_BITS;
|
|
31
|
+
const BS_CODE_PREFIX = "__BS#";
|
|
9
32
|
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const BS_CONT_CLOSE =
|
|
33
|
+
// subtype cont
|
|
34
|
+
const BS_CONT_ARR = 0 << 0;
|
|
35
|
+
const BS_CONT_OBJ = 1 << 0;
|
|
36
|
+
const BS_CONT_CLOSE = 0 << 1;
|
|
37
|
+
const BS_CONT_OPEN = 1 << 1;
|
|
14
38
|
|
|
15
|
-
|
|
39
|
+
// subtype float
|
|
40
|
+
const BS_GET_FLOAT_LEN = x => 1 << ((x) & 0b111);
|
|
41
|
+
const BS_FLOAT_F32 = 2;
|
|
16
42
|
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
const BS_DATA_MASK = 0b00011111;
|
|
20
|
-
const BS_DATA = x => x & BS_DATA_MASK;
|
|
43
|
+
// subtype bin
|
|
44
|
+
const BS_GET_BIN_LEN = x => x & 0b111;
|
|
21
45
|
|
|
22
|
-
|
|
23
|
-
|
|
46
|
+
//#region BSDecoder
|
|
47
|
+
export class BSDecoder {
|
|
48
|
+
offset = 0;
|
|
49
|
+
cont = 'root';
|
|
50
|
+
tdec = new TextDecoder();
|
|
24
51
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
52
|
+
constructor(buf, codes) {
|
|
53
|
+
this.buf = buf;
|
|
54
|
+
this.codes = codes;
|
|
55
|
+
}
|
|
29
56
|
|
|
30
|
-
|
|
57
|
+
decode() {
|
|
58
|
+
if (!(this.buf instanceof Uint8Array) || !this.buf.length) return undefined;
|
|
31
59
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
60
|
+
let res = this._decode();
|
|
61
|
+
if (this.offset != this.buf.length) throw this._err("Broken packet");
|
|
62
|
+
return res;
|
|
63
|
+
}
|
|
64
|
+
read(len) {
|
|
65
|
+
if (this.offset + len > this.buf.length) {
|
|
66
|
+
throw this._err("Overflow");
|
|
67
|
+
}
|
|
68
|
+
let res = this.buf.subarray(this.offset, this.offset + len);
|
|
69
|
+
this.offset += len;
|
|
70
|
+
return res;
|
|
71
|
+
}
|
|
72
|
+
readB() {
|
|
73
|
+
return this.read(1)[0];
|
|
74
|
+
}
|
|
75
|
+
readInt(len) {
|
|
76
|
+
let val = 0n;
|
|
77
|
+
let bytes = this.read(len);
|
|
78
|
+
while (len--) val = (val << 8n) | BigInt(bytes[len]);
|
|
79
|
+
return Number(val);
|
|
80
|
+
}
|
|
81
|
+
_ext(hdr) {
|
|
82
|
+
return BS_GET_LSB(hdr) | ((hdr & BS_EXT_FLAG) ? (this.readB() << BS_EXT_BITS) : 0);
|
|
83
|
+
}
|
|
84
|
+
_close(res, isObj) {
|
|
85
|
+
if (res && res.__close !== undefined) {
|
|
86
|
+
if (isObj === res.__close) return true;
|
|
87
|
+
throw this._err("Wrong close");
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
_err(e) {
|
|
92
|
+
return new Error(e + ' in ' + JSON.stringify(this.cont));
|
|
93
|
+
}
|
|
94
|
+
_decode() {
|
|
95
|
+
const header = this.readB();
|
|
35
96
|
|
|
36
|
-
|
|
97
|
+
let type = header & BS_TYPE_MASK;
|
|
98
|
+
if (type == BS_SUBT) type = header & BS_SUBT_MASK;
|
|
37
99
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
export function decodeBson(buf, codes = []) {
|
|
44
|
-
if (!(buf instanceof Uint8Array) || !buf.length) return undefined;
|
|
45
|
-
|
|
46
|
-
const reader = {
|
|
47
|
-
buf,
|
|
48
|
-
offset: 0,
|
|
49
|
-
cont: 'root',
|
|
50
|
-
decoder: new TextDecoder(),
|
|
51
|
-
error(e) {
|
|
52
|
-
return new Error(e + ' in ' + JSON.stringify(this.cont));
|
|
53
|
-
},
|
|
54
|
-
read(len) {
|
|
55
|
-
if (this.offset + len > buf.length) {
|
|
56
|
-
throw this.error("Overflow");
|
|
57
|
-
}
|
|
58
|
-
const res = this.buf.subarray(this.offset, this.offset + len);
|
|
59
|
-
this.offset += len;
|
|
60
|
-
return res;
|
|
61
|
-
},
|
|
62
|
-
readB() {
|
|
63
|
-
return this.read(1)[0];
|
|
64
|
-
}
|
|
65
|
-
};
|
|
100
|
+
switch (type) {
|
|
101
|
+
case BS_CONT:
|
|
102
|
+
if (header & BS_CONT_OPEN) {
|
|
103
|
+
let isObj = !!(header & BS_CONT_OBJ);
|
|
104
|
+
let cont = isObj ? {} : [];
|
|
66
105
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
106
|
+
while (true) {
|
|
107
|
+
this.cont = cont;
|
|
108
|
+
|
|
109
|
+
let res = this._decode();
|
|
110
|
+
if (this._close(res, isObj)) return cont;
|
|
111
|
+
|
|
112
|
+
if (isObj) {
|
|
113
|
+
let val = this._decode();
|
|
114
|
+
if (this._close(val, isObj)) throw this._err("Missed value");
|
|
71
115
|
|
|
72
|
-
|
|
73
|
-
const header = r.readB();
|
|
74
|
-
const data = BS_DATA(header);
|
|
75
|
-
|
|
76
|
-
switch (BS_TYPE(header)) {
|
|
77
|
-
case BS_CONTAINER:
|
|
78
|
-
if (data & BS_CONT_OPEN) {
|
|
79
|
-
let isArr = !!(data & BS_CONT_ARR);
|
|
80
|
-
let cont = isArr ? [] : {};
|
|
81
|
-
let expect = false;
|
|
82
|
-
let key;
|
|
83
|
-
|
|
84
|
-
while (true) {
|
|
85
|
-
r.cont = cont;
|
|
86
|
-
let res = _decode(r, codes);
|
|
87
|
-
|
|
88
|
-
if (res && res.__close !== undefined) {
|
|
89
|
-
if (isArr === res.__close) {
|
|
90
|
-
if (!isArr && expect) throw r.error("Missed value");
|
|
91
|
-
return cont;
|
|
116
|
+
cont[String(res)] = val;
|
|
92
117
|
} else {
|
|
93
|
-
|
|
118
|
+
cont.push(res);
|
|
94
119
|
}
|
|
95
120
|
}
|
|
121
|
+
}
|
|
122
|
+
return { __close: !!(header & BS_CONT_OBJ) };
|
|
96
123
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
124
|
+
case BS_INT:
|
|
125
|
+
if (header & BS_INT_SMALL) {
|
|
126
|
+
return BS_GET_SMALLV(header);
|
|
127
|
+
} else {
|
|
128
|
+
let val = this.readInt(BS_GET_INT_LEN(header));
|
|
129
|
+
return (header & BS_INT_NEG) ? -val : val;
|
|
104
130
|
}
|
|
105
|
-
} else if (data & BS_CONT_CLOSE) {
|
|
106
|
-
return { __close: !!(data & BS_CONT_ARR) };
|
|
107
|
-
} else {
|
|
108
|
-
throw r.error("Unknown cont");
|
|
109
|
-
}
|
|
110
|
-
// break;
|
|
111
131
|
|
|
112
|
-
|
|
113
|
-
|
|
132
|
+
case BS_STR:
|
|
133
|
+
return this.tdec.decode(this.read(this._ext(header)));
|
|
114
134
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return r.decoder.decode(r.read(len));
|
|
118
|
-
}
|
|
135
|
+
case BS_CODE:
|
|
136
|
+
return this.codes[this._ext(header)];
|
|
119
137
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (!size) return 0;
|
|
138
|
+
case BS_NULL:
|
|
139
|
+
return null;
|
|
123
140
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
while (size--) value = (value << 8n) | BigInt(bytes[size]);
|
|
141
|
+
case BS_BOOL:
|
|
142
|
+
return !!(header & 1);
|
|
127
143
|
|
|
128
|
-
|
|
129
|
-
|
|
144
|
+
case BS_FLOAT: {
|
|
145
|
+
let len = BS_GET_FLOAT_LEN(header);
|
|
146
|
+
const b = this.read(len);
|
|
147
|
+
let view = new DataView(b.buffer, b.byteOffset, len);
|
|
148
|
+
return (len == 4) ? view.getFloat32(0, true) : ((len == 8) ? view.getFloat64(0, true) : 0);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
case BS_BIN:
|
|
152
|
+
return this.read(this.readInt(BS_GET_BIN_LEN(header))).slice();
|
|
130
153
|
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
//#region BSEncoder
|
|
158
|
+
export class BSEncoder {
|
|
159
|
+
arr = [];
|
|
160
|
+
tenc = new TextEncoder();
|
|
161
|
+
|
|
162
|
+
constructor(codes = []) {
|
|
163
|
+
this.codes = codes;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
getArray() {
|
|
167
|
+
return Uint8Array.from(this.arr);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
encode(val) {
|
|
171
|
+
let a = this.arr;
|
|
172
|
+
|
|
173
|
+
if (Array.isArray(val)) {
|
|
174
|
+
a.push(BS_SUBT | BS_CONT | BS_CONT_ARR | BS_CONT_OPEN);
|
|
175
|
+
val.forEach(v => this.encode(v));
|
|
176
|
+
a.push(BS_SUBT | BS_CONT | BS_CONT_ARR | BS_CONT_CLOSE);
|
|
177
|
+
} else {
|
|
178
|
+
switch (typeof val) {
|
|
179
|
+
case 'object':
|
|
180
|
+
if (val === null) {
|
|
181
|
+
a.push(BS_SUBT | BS_NULL);
|
|
182
|
+
} else if (val instanceof Uint8Array) {
|
|
183
|
+
let lenb = this._int(val.length);
|
|
184
|
+
a.push(BS_SUBT | BS_BIN | lenb.length);
|
|
185
|
+
a.push(...lenb);
|
|
186
|
+
a.push(...val);
|
|
187
|
+
} else {
|
|
188
|
+
a.push(BS_SUBT | BS_CONT | BS_CONT_OBJ | BS_CONT_OPEN);
|
|
189
|
+
for (const [key, value] of Object.entries(val)) {
|
|
190
|
+
this.encode(key);
|
|
191
|
+
this.encode(value);
|
|
192
|
+
}
|
|
193
|
+
a.push(BS_SUBT | BS_CONT | BS_CONT_OBJ | BS_CONT_CLOSE);
|
|
194
|
+
}
|
|
195
|
+
break;
|
|
131
196
|
|
|
132
|
-
|
|
133
|
-
|
|
197
|
+
case 'number':
|
|
198
|
+
case 'bigint':
|
|
199
|
+
if (Number.isInteger(val)) {
|
|
200
|
+
if (val >= 0 && val < BS_INT_SMALL) {
|
|
201
|
+
a.push(BS_INT | BS_INT_SMALL | val);
|
|
202
|
+
} else {
|
|
203
|
+
let neg = val < 0;
|
|
204
|
+
if (neg) val = -val;
|
|
205
|
+
let bytes = this._int(val);
|
|
206
|
+
a.push(BS_INT | (neg ? BS_INT_NEG : 0) | bytes.length);
|
|
207
|
+
a.push(...bytes);
|
|
208
|
+
}
|
|
209
|
+
} else {
|
|
210
|
+
const buffer = new ArrayBuffer(4);
|
|
211
|
+
new DataView(buffer).setFloat32(0, val, true);
|
|
212
|
+
a.push(BS_SUBT | BS_FLOAT | BS_FLOAT_F32);
|
|
213
|
+
a.push(...new Uint8Array(buffer));
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
|
|
217
|
+
case 'string':
|
|
218
|
+
if (val.startsWith(BS_CODE_PREFIX)) {
|
|
219
|
+
val = val.slice(BS_CODE_PREFIX.length);
|
|
220
|
+
let code = this.codes.indexOf(val);
|
|
221
|
+
if (code >= 0) this._ext(BS_CODE, code);
|
|
222
|
+
else this.encode(val);
|
|
223
|
+
} else {
|
|
224
|
+
const bytes = this.tenc.encode(val);
|
|
225
|
+
const len = Math.min(bytes.length, BS_MAX_EXT_LEN);
|
|
226
|
+
this._ext(BS_STR, len);
|
|
227
|
+
a.push(...bytes.slice(0, len));
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
134
230
|
|
|
135
|
-
|
|
136
|
-
|
|
231
|
+
case 'boolean':
|
|
232
|
+
a.push(BS_SUBT | BS_BOOL | !!val);
|
|
233
|
+
break;
|
|
137
234
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
235
|
+
default:
|
|
236
|
+
a.push(BS_SUBT | BS_NULL);
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
141
239
|
}
|
|
142
240
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
241
|
+
return this;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
_int(v) {
|
|
245
|
+
let t = [];
|
|
246
|
+
v = BigInt(v);
|
|
247
|
+
while (v) {
|
|
248
|
+
t.push(Number(v & 0xFFn));
|
|
249
|
+
v >>= 8n;
|
|
250
|
+
}
|
|
251
|
+
return t;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
_ext(t, v) {
|
|
255
|
+
let a = this.arr;
|
|
256
|
+
if (v < BS_EXT_FLAG) {
|
|
257
|
+
a.push(t | v);
|
|
258
|
+
} else {
|
|
259
|
+
a.push(t | BS_EXT_FLAG | BS_GET_LSB(v));
|
|
260
|
+
a.push(BS_GET_MSB(v));
|
|
146
261
|
}
|
|
147
262
|
}
|
|
148
263
|
}
|
|
149
264
|
|
|
265
|
+
//#region helper
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @param {Uint8Array} buf
|
|
269
|
+
* @param {Array} codes
|
|
270
|
+
* @returns {Object|Array|*}
|
|
271
|
+
*/
|
|
272
|
+
export function decodeBson(buf, codes = []) {
|
|
273
|
+
return new BSDecoder(buf, codes).decode();
|
|
274
|
+
}
|
|
275
|
+
|
|
150
276
|
/**
|
|
151
277
|
* @param {*} val
|
|
278
|
+
* @param {Array} codes
|
|
152
279
|
* @returns {Uint8Array}
|
|
153
280
|
*/
|
|
154
281
|
export function encodeBson(val, codes = []) {
|
|
155
|
-
|
|
156
|
-
_encode(val, arr, codes);
|
|
157
|
-
return Uint8Array.from(arr);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function _encode(val, arr, codes) {
|
|
161
|
-
if (Array.isArray(val)) {
|
|
162
|
-
arr.push(BS_CONTAINER | BS_CONT_ARR | BS_CONT_OPEN);
|
|
163
|
-
val.forEach(v => _encode(v, arr, codes));
|
|
164
|
-
arr.push(BS_CONTAINER | BS_CONT_ARR | BS_CONT_CLOSE);
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
switch (typeof val) {
|
|
169
|
-
case 'object':
|
|
170
|
-
if (val === null) {
|
|
171
|
-
arr.push(BS_NULL);
|
|
172
|
-
} else if (val instanceof Uint8Array) {
|
|
173
|
-
const len = Math.min(val.length, BS_MAX_LEN);
|
|
174
|
-
arr.push(BS_BINARY | BS_D16_MSB(len));
|
|
175
|
-
arr.push(BS_D16_LSB(len));
|
|
176
|
-
arr.push(...val.slice(0, len));
|
|
177
|
-
} else {
|
|
178
|
-
arr.push(BS_CONTAINER | BS_CONT_OBJ | BS_CONT_OPEN);
|
|
179
|
-
for (const [key, value] of Object.entries(val)) {
|
|
180
|
-
_encode(key, arr, codes);
|
|
181
|
-
_encode(value, arr, codes);
|
|
182
|
-
}
|
|
183
|
-
arr.push(BS_CONTAINER | BS_CONT_OBJ | BS_CONT_CLOSE);
|
|
184
|
-
}
|
|
185
|
-
break;
|
|
186
|
-
|
|
187
|
-
case 'bigint':
|
|
188
|
-
case 'number':
|
|
189
|
-
if (Number.isInteger(val)) {
|
|
190
|
-
val = BigInt(val);
|
|
191
|
-
const neg = val < 0;
|
|
192
|
-
if (neg) val = -val;
|
|
193
|
-
let bytes = [];
|
|
194
|
-
while (val) {
|
|
195
|
-
bytes.push(Number(val & 0xFFn));
|
|
196
|
-
val >>= 8n;
|
|
197
|
-
}
|
|
198
|
-
arr.push(BS_INTEGER | (neg ? BS_NEG_MASK : 0) | bytes.length);
|
|
199
|
-
arr.push(...bytes);
|
|
200
|
-
} else {
|
|
201
|
-
const buffer = new ArrayBuffer(BS_FLOAT_SIZE);
|
|
202
|
-
new DataView(buffer).setFloat32(0, val, true);
|
|
203
|
-
arr.push(BS_FLOAT);
|
|
204
|
-
arr.push(...new Uint8Array(buffer));
|
|
205
|
-
}
|
|
206
|
-
break;
|
|
207
|
-
|
|
208
|
-
case 'string':
|
|
209
|
-
if (val.startsWith(BS_CODE_PREFIX)) {
|
|
210
|
-
val = val.slice(BS_CODE_PREFIX.length);
|
|
211
|
-
let code = codes.indexOf(val);
|
|
212
|
-
if (code >= 0) {
|
|
213
|
-
arr.push(BS_CODE | BS_D16_MSB(code));
|
|
214
|
-
arr.push(BS_D16_LSB(code));
|
|
215
|
-
} else {
|
|
216
|
-
_encode(val, arr, codes);
|
|
217
|
-
}
|
|
218
|
-
} else {
|
|
219
|
-
const bytes = new TextEncoder().encode(val);
|
|
220
|
-
const len = Math.min(bytes.length, BS_MAX_LEN);
|
|
221
|
-
arr.push(BS_STRING | BS_D16_MSB(len));
|
|
222
|
-
arr.push(BS_D16_LSB(len));
|
|
223
|
-
arr.push(...bytes.slice(0, len));
|
|
224
|
-
}
|
|
225
|
-
break;
|
|
226
|
-
|
|
227
|
-
case 'boolean':
|
|
228
|
-
arr.push(BS_BOOLEAN | !!val);
|
|
229
|
-
break;
|
|
230
|
-
|
|
231
|
-
default:
|
|
232
|
-
arr.push(BS_NULL);
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
282
|
+
return new BSEncoder(codes).encode(val).getArray();
|
|
235
283
|
}
|
|
236
284
|
|
|
237
285
|
export function getCode(name) {
|
package/bson.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e={d:(r
|
|
1
|
+
var e={d:(t,r)=>{for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{$R:()=>h,GF:()=>i,QC:()=>c,lo:()=>o,mp:()=>n});const r=e=>31&e,s="__BS#";class n{offset=0;cont="root";tdec=new TextDecoder;constructor(e,t){this.buf=e,this.codes=t}decode(){if(!(this.buf instanceof Uint8Array&&this.buf.length))return;let e=this._decode();if(this.offset!=this.buf.length)throw this._err("Broken packet");return e}read(e){if(this.offset+e>this.buf.length)throw this._err("Overflow");let t=this.buf.subarray(this.offset,this.offset+e);return this.offset+=e,t}readB(){return this.read(1)[0]}readInt(e){let t=0n,r=this.read(e);for(;e--;)t=t<<8n|BigInt(r[e]);return Number(t)}_ext(e){return r(e)|(32&e?this.readB()<<5:0)}_close(e,t){if(e&&void 0!==e.__close){if(t===e.__close)return!0;throw this._err("Wrong close")}return!1}_err(e){return new Error(e+" in "+JSON.stringify(this.cont))}_decode(){const e=this.readB();let t=192&e;switch(0==t&&(t=56&e),t){case 16:if(2&e){let t=!!(1&e),r=t?{}:[];for(;;){this.cont=r;let e=this._decode();if(this._close(e,t))return r;if(t){let s=this._decode();if(this._close(s,t))throw this._err("Missed value");r[String(e)]=s}else r.push(e)}}return{__close:!!(1&e)};case 64:if(32&e)return 31&e;{let t=this.readInt(15&e);return 16&e?-t:t}case 128:return this.tdec.decode(this.read(this._ext(e)));case 192:return this.codes[this._ext(e)];case 0:return null;case 8:return!!(1&e);case 24:{let t=(e=>1<<(7&e))(e);const r=this.read(t);let s=new DataView(r.buffer,r.byteOffset,t);return 4==t?s.getFloat32(0,!0):8==t?s.getFloat64(0,!0):0}case 32:return this.read(this.readInt((e=>7&e)(e))).slice()}}}class i{arr=[];tenc=new TextEncoder;constructor(e=[]){this.codes=e}getArray(){return Uint8Array.from(this.arr)}encode(e){let t=this.arr;if(Array.isArray(e))t.push(18),e.forEach(e=>this.encode(e)),t.push(16);else switch(typeof e){case"object":if(null===e)t.push(0);else if(e instanceof Uint8Array){let r=this._int(e.length);t.push(32|r.length),t.push(...r),t.push(...e)}else{t.push(19);for(const[t,r]of Object.entries(e))this.encode(t),this.encode(r);t.push(17)}break;case"number":case"bigint":if(Number.isInteger(e))if(e>=0&&e<32)t.push(96|e);else{let r=e<0;r&&(e=-e);let s=this._int(e);t.push(64|(r?16:0)|s.length),t.push(...s)}else{const r=new ArrayBuffer(4);new DataView(r).setFloat32(0,e,!0),t.push(26),t.push(...new Uint8Array(r))}break;case"string":if(e.startsWith(s)){e=e.slice(s.length);let t=this.codes.indexOf(e);t>=0?this._ext(192,t):this.encode(e)}else{const r=this.tenc.encode(e),s=Math.min(r.length,8191);this._ext(128,s),t.push(...r.slice(0,s))}break;case"boolean":t.push(8|!!e);break;default:t.push(0)}return this}_int(e){let t=[];for(e=BigInt(e);e;)t.push(Number(0xFFn&e)),e>>=8n;return t}_ext(e,t){let s=this.arr;t<32?s.push(e|t):(s.push(32|e|r(t)),s.push(t>>5))}}function o(e,t=[]){return new n(e,t).decode()}function h(e,t=[]){return new i(t).encode(e).getArray()}function c(e){return s+e}const a=t.mp,u=t.GF,l=t.lo,f=t.$R,d=t.QC;export{a as BSDecoder,u as BSEncoder,l as decodeBson,f as encodeBson,d as getCode};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alexgyver/bson",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "Decode BSON from BSON Arduino library",
|
|
5
5
|
"main": "./bson.js",
|
|
6
6
|
"module": "./bson.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"webpack": "^5.105.4",
|
|
18
|
-
"webpack-cli": "^
|
|
18
|
+
"webpack-cli": "^7.0.0",
|
|
19
19
|
"webpack-dev-server": "^5.2.3",
|
|
20
20
|
"style-loader": "^4.0.0",
|
|
21
21
|
"css-loader": "^7.1.4"
|
package/test/index.html
CHANGED
|
@@ -18,13 +18,18 @@
|
|
|
18
18
|
|
|
19
19
|
// =========== encode ===========
|
|
20
20
|
let test = {
|
|
21
|
+
sint: 20,
|
|
21
22
|
int: 123,
|
|
23
|
+
nint: -123,
|
|
22
24
|
float: 3.14,
|
|
23
25
|
arr: [
|
|
24
26
|
"str",
|
|
27
|
+
"0123456789012345678901234567890123456789",
|
|
25
28
|
true,
|
|
26
|
-
|
|
29
|
+
123456789876543,
|
|
30
|
+
-123456789876543,
|
|
27
31
|
new Uint8Array([1, 2, 3]),
|
|
32
|
+
new Uint8Array([]),
|
|
28
33
|
],
|
|
29
34
|
obj: {
|
|
30
35
|
str2: "str2",
|