@alexgyver/bson 1.0.1 → 1.0.2
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 +90 -86
- package/package.json +1 -1
package/bson.js
CHANGED
|
@@ -6,126 +6,130 @@
|
|
|
6
6
|
export default function decodeBson(b, codes = []) {
|
|
7
7
|
if (!b || !(b instanceof Uint8Array)) return null;
|
|
8
8
|
if (!b.length) return {};
|
|
9
|
-
let bins = [];
|
|
10
9
|
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
10
|
+
const BS_STRING = (0 << 5);
|
|
11
|
+
const BS_BOOLEAN = (1 << 5);
|
|
12
|
+
const BS_INTEGER = (2 << 5);
|
|
13
|
+
const BS_FLOAT = (3 << 5);
|
|
14
|
+
const BS_CODE = (4 << 5);
|
|
15
|
+
const BS_BINARY = (5 << 5);
|
|
17
16
|
const BS_CONTAINER = (6 << 5);
|
|
18
|
-
const BS_BINARY = (7 << 5);
|
|
19
|
-
const BS_BIN_PREFIX = "__BSON_BINARY";
|
|
20
|
-
|
|
21
|
-
const BS_NEGATIVE = (1 << 4);
|
|
22
|
-
const BS_BOOLEAN = (1 << 3);
|
|
23
17
|
|
|
24
18
|
const BS_CONT_OBJ = (1 << 4);
|
|
25
19
|
const BS_CONT_OPEN = (1 << 3);
|
|
20
|
+
const BS_NEGATIVE = (1 << 4);
|
|
21
|
+
const BS_BIN_PREFIX = "__BSON_BINARY";
|
|
26
22
|
|
|
27
|
-
function u32toFloat(u32) {
|
|
28
|
-
return new Float32Array(new Uint32Array([u32]).buffer)[0];
|
|
29
|
-
}
|
|
30
23
|
function unpack5(msb5, lsb) {
|
|
31
24
|
return ((msb5 << 8) | lsb) >>> 0;
|
|
32
25
|
}
|
|
33
|
-
function makeBins(obj) {
|
|
26
|
+
function makeBins(obj, bins) {
|
|
34
27
|
if (typeof obj !== 'object') return;
|
|
35
28
|
for (let k in obj) {
|
|
36
29
|
if (typeof obj[k] === "object" && obj[k] !== null) {
|
|
37
|
-
makeBins(obj[k]);
|
|
30
|
+
makeBins(obj[k], bins);
|
|
38
31
|
} else if (typeof obj[k] === "string" && obj[k].startsWith(BS_BIN_PREFIX)) {
|
|
39
32
|
obj[k] = bins[obj[k].split('#')[1]];
|
|
40
33
|
}
|
|
41
34
|
}
|
|
42
35
|
}
|
|
43
36
|
|
|
37
|
+
let bins = [];
|
|
38
|
+
let stack = [];
|
|
39
|
+
let keyf = true;
|
|
44
40
|
let s = '';
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
.
|
|
75
|
-
.replaceAll(/([^\\])(")/ig,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
for (let i = 0; i < b.length; i++) {
|
|
44
|
+
const type = b[i] & 0b11100000;
|
|
45
|
+
const data = b[i] & 0b00011111;
|
|
46
|
+
|
|
47
|
+
switch (type) {
|
|
48
|
+
|
|
49
|
+
case BS_CONTAINER:
|
|
50
|
+
if (data & BS_CONT_OPEN) {
|
|
51
|
+
let t = (data & BS_CONT_OBJ) ? '{' : '[';
|
|
52
|
+
s += t;
|
|
53
|
+
stack.push(t);
|
|
54
|
+
} else {
|
|
55
|
+
if (s[s.length - 1] == ',') s = s.slice(0, -1);
|
|
56
|
+
let t = (data & BS_CONT_OBJ) ? '}' : ']';
|
|
57
|
+
s += t + ',';
|
|
58
|
+
stack.pop();
|
|
59
|
+
}
|
|
60
|
+
keyf = true;
|
|
61
|
+
continue;
|
|
62
|
+
|
|
63
|
+
case BS_CODE:
|
|
64
|
+
s += '"' + codes[unpack5(data, b[++i])] + '"';
|
|
65
|
+
break;
|
|
66
|
+
|
|
67
|
+
case BS_STRING: {
|
|
68
|
+
let len = unpack5(data, b[++i]);
|
|
69
|
+
i++;
|
|
70
|
+
let txt = new TextDecoder().decode(b.slice(i, i + len));
|
|
71
|
+
txt = txt.replaceAll(/([^\\])\\([^\"\\nrt])/ig, "$1\\\\$2")
|
|
72
|
+
.replaceAll(/\t/ig, "\\t")
|
|
73
|
+
.replaceAll(/\n/ig, "\\n")
|
|
74
|
+
.replaceAll(/\r/ig, "\\r")
|
|
75
|
+
.replaceAll(/([^\\])(")/ig, '$1\\"');
|
|
76
|
+
s += '"' + txt + '"';
|
|
77
|
+
i += len - 1;
|
|
78
|
+
} break;
|
|
79
|
+
|
|
80
|
+
case BS_INTEGER: {
|
|
85
81
|
if (data & BS_NEGATIVE) s += '-';
|
|
86
|
-
let len = data &
|
|
82
|
+
let len = data & 0b1111;
|
|
87
83
|
let v = BigInt(0);
|
|
88
84
|
for (let j = 0; j < len; j++) {
|
|
89
85
|
v |= BigInt(b[++i]) << BigInt(j * 8);
|
|
90
86
|
}
|
|
91
87
|
s += v;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
v
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
88
|
+
} break;
|
|
89
|
+
|
|
90
|
+
case BS_BOOLEAN:
|
|
91
|
+
s += (data & 0b1) ? 'true' : 'false';
|
|
92
|
+
break;
|
|
93
|
+
|
|
94
|
+
case BS_FLOAT: {
|
|
95
|
+
let v = 0;
|
|
96
|
+
for (let j = 0; j < 4; j++) {
|
|
97
|
+
v |= b[++i] << (j * 8);
|
|
98
|
+
}
|
|
99
|
+
let f = new Float32Array(new Uint32Array([v]).buffer)[0];
|
|
100
|
+
s += (isNaN(f) || !isFinite(f)) ? 'null' : f.toFixed(data);
|
|
101
|
+
} break;
|
|
102
|
+
|
|
103
|
+
case BS_BINARY: {
|
|
104
|
+
let len = unpack5(data, b[++i]);
|
|
105
|
+
i++;
|
|
106
|
+
s += '"' + BS_BIN_PREFIX + '#' + bins.length + '"';
|
|
107
|
+
bins.push(b.slice(i, i + len));
|
|
108
|
+
i += len - 1;
|
|
109
|
+
} break;
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (stack[stack.length - 1] === '{') {
|
|
114
|
+
s += keyf ? ':' : ',';
|
|
115
|
+
keyf = !keyf;
|
|
116
|
+
} else {
|
|
109
117
|
s += ',';
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
case BS_BINARY: {
|
|
113
|
-
let len = unpack5(data, b[++i]);
|
|
114
|
-
i++;
|
|
115
|
-
s += '"' + BS_BIN_PREFIX + '#' + bins.length + '",';
|
|
116
|
-
bins.push(b.slice(i, i + len));
|
|
117
|
-
i += len - 1;
|
|
118
|
-
} break;
|
|
118
|
+
}
|
|
119
119
|
}
|
|
120
|
+
} catch (e) {
|
|
121
|
+
console.log(s);
|
|
122
|
+
throw new Error("BSON decode error");
|
|
120
123
|
}
|
|
124
|
+
|
|
121
125
|
if (s[s.length - 1] == ',') s = s.slice(0, -1);
|
|
122
126
|
|
|
123
127
|
try {
|
|
124
128
|
let obj = JSON.parse(s);
|
|
125
|
-
if (bins.length) makeBins(obj);
|
|
129
|
+
if (bins.length) makeBins(obj, bins);
|
|
126
130
|
return obj;
|
|
127
131
|
} catch (e) {
|
|
128
132
|
console.log(s);
|
|
129
|
-
throw new Error("JSON error")
|
|
133
|
+
throw new Error("JSON parse error");
|
|
130
134
|
}
|
|
131
135
|
}
|