@cloudpss/ubjson 0.5.38 → 0.5.40
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/base/decoder.d.ts +1 -0
- package/dist/base/decoder.d.ts.map +1 -0
- package/dist/base/encoder.d.ts +3 -1
- package/dist/base/encoder.d.ts.map +1 -0
- package/dist/base/encoder.js +45 -188
- package/dist/base/encoder.js.map +1 -1
- package/dist/decoder.d.ts +1 -0
- package/dist/decoder.d.ts.map +1 -0
- package/dist/encoder.d.ts +5 -0
- package/dist/encoder.d.ts.map +1 -0
- package/dist/encoder.js +22 -14
- package/dist/encoder.js.map +1 -1
- package/dist/helper/constants.d.ts +1 -0
- package/dist/helper/constants.d.ts.map +1 -0
- package/dist/helper/decode.d.ts +6 -3
- package/dist/helper/decode.d.ts.map +1 -0
- package/dist/helper/decode.js +26 -15
- package/dist/helper/decode.js.map +1 -1
- package/dist/helper/encode.d.ts +19 -1
- package/dist/helper/encode.d.ts.map +1 -0
- package/dist/helper/encode.js +138 -16
- package/dist/helper/encode.js.map +1 -1
- package/dist/helper/errors.d.ts +1 -0
- package/dist/helper/errors.d.ts.map +1 -0
- package/dist/helper/string-decoder.d.ts +5 -2
- package/dist/helper/string-decoder.d.ts.map +1 -0
- package/dist/helper/string-decoder.js +10 -38
- package/dist/helper/string-decoder.js.map +1 -1
- package/dist/helper/string-encoder.d.ts +1 -0
- package/dist/helper/string-encoder.d.ts.map +1 -0
- package/dist/helper/utils.d.ts +1 -0
- package/dist/helper/utils.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/rxjs/decoder.d.ts +1 -0
- package/dist/rxjs/decoder.d.ts.map +1 -0
- package/dist/rxjs/encoder.d.ts +1 -0
- package/dist/rxjs/encoder.d.ts.map +1 -0
- package/dist/rxjs/index.d.ts +1 -0
- package/dist/rxjs/index.d.ts.map +1 -0
- package/dist/stream/decoder.d.ts +1 -0
- package/dist/stream/decoder.d.ts.map +1 -0
- package/dist/stream/encoder.d.ts +1 -0
- package/dist/stream/encoder.d.ts.map +1 -0
- package/dist/stream/index.d.ts +1 -0
- package/dist/stream/index.d.ts.map +1 -0
- package/dist/stream-helper/decoder.d.ts +1 -0
- package/dist/stream-helper/decoder.d.ts.map +1 -0
- package/dist/stream-helper/encoder.d.ts +3 -1
- package/dist/stream-helper/encoder.d.ts.map +1 -0
- package/dist/stream-helper/encoder.js +31 -30
- package/dist/stream-helper/encoder.js.map +1 -1
- package/jest.config.js +1 -1
- package/package.json +3 -4
- package/src/base/encoder.ts +53 -174
- package/src/encoder.ts +24 -14
- package/src/helper/decode.ts +30 -18
- package/src/helper/encode.ts +141 -15
- package/src/helper/string-decoder.ts +10 -39
- package/src/stream-helper/encoder.ts +33 -33
- package/tests/encode.js +8 -0
- package/tests/string-encoding.js +1 -10
- package/tests/tsconfig.json +1 -7
- package/tsconfig.json +1 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { unsupportedView } from '../helper/errors.js';
|
|
2
1
|
import { encode, stringByteLength } from '../helper/string-encoder.js';
|
|
3
2
|
import { EncoderBase } from '../base/encoder.js';
|
|
4
3
|
const BLOCK_SIZE = 1024 * 64; // 64 KiB
|
|
@@ -98,57 +97,59 @@ export class StreamEncoderHelper extends EncoderBase {
|
|
|
98
97
|
}
|
|
99
98
|
}
|
|
100
99
|
/** @inheritdoc */
|
|
101
|
-
writeLargeTypedArrayData(value) {
|
|
100
|
+
writeLargeTypedArrayData(type, value) {
|
|
102
101
|
this.ensureCapacity(-1);
|
|
103
|
-
|
|
102
|
+
const { byteLength } = value;
|
|
103
|
+
if (type === 85 /* constants.UINT8 */ || type === 105 /* constants.INT8 */) {
|
|
104
104
|
// fast path for typed arrays with `BYTES_PER_ELEMENT` of 1
|
|
105
105
|
// divide buffer to 64k chunks
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
const { buffer, byteOffset } = value;
|
|
107
|
+
for (let i = 0; i < byteLength; i += BLOCK_SIZE) {
|
|
108
|
+
this.onChunk(new Uint8Array(buffer.slice(byteOffset + i, byteOffset + i + BLOCK_SIZE)));
|
|
108
109
|
}
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
.BYTES_PER_ELEMENT;
|
|
114
|
-
if (value instanceof Int16Array) {
|
|
112
|
+
if (type === 68 /* constants.FLOAT64 */) {
|
|
113
|
+
const arrayLength = byteLength / 8;
|
|
115
114
|
for (let i = 0; i < arrayLength; i++) {
|
|
116
|
-
this.ensureCapacity(
|
|
117
|
-
this.view.
|
|
118
|
-
this.length +=
|
|
115
|
+
this.ensureCapacity(8);
|
|
116
|
+
this.view.setFloat64(this.length, value[i]);
|
|
117
|
+
this.length += 8;
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
|
-
else if (
|
|
120
|
+
else if (type === 108 /* constants.INT32 */) {
|
|
121
|
+
const arrayLength = byteLength / 4;
|
|
122
122
|
for (let i = 0; i < arrayLength; i++) {
|
|
123
|
-
this.ensureCapacity(
|
|
123
|
+
this.ensureCapacity(4);
|
|
124
124
|
this.view.setInt32(this.length, value[i]);
|
|
125
|
-
this.length +=
|
|
125
|
+
this.length += 4;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
else if (
|
|
128
|
+
else if (type === 76 /* constants.INT64 */) {
|
|
129
|
+
const arrayLength = byteLength / 8;
|
|
129
130
|
for (let i = 0; i < arrayLength; i++) {
|
|
130
|
-
this.ensureCapacity(
|
|
131
|
-
this.view.
|
|
132
|
-
this.length +=
|
|
131
|
+
this.ensureCapacity(8);
|
|
132
|
+
this.view.setBigInt64(this.length, value[i]);
|
|
133
|
+
this.length += 8;
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
|
-
else if (
|
|
136
|
+
else if (type === 100 /* constants.FLOAT32 */) {
|
|
137
|
+
const arrayLength = byteLength / 4;
|
|
136
138
|
for (let i = 0; i < arrayLength; i++) {
|
|
137
|
-
this.ensureCapacity(
|
|
138
|
-
this.view.
|
|
139
|
-
this.length +=
|
|
139
|
+
this.ensureCapacity(4);
|
|
140
|
+
this.view.setFloat32(this.length, value[i]);
|
|
141
|
+
this.length += 4;
|
|
140
142
|
}
|
|
141
143
|
}
|
|
142
|
-
else
|
|
144
|
+
else {
|
|
145
|
+
(type);
|
|
146
|
+
const arrayLength = byteLength / 2;
|
|
143
147
|
for (let i = 0; i < arrayLength; i++) {
|
|
144
|
-
this.ensureCapacity(
|
|
145
|
-
this.view.
|
|
146
|
-
this.length +=
|
|
148
|
+
this.ensureCapacity(2);
|
|
149
|
+
this.view.setInt16(this.length, value[i]);
|
|
150
|
+
this.length += 2;
|
|
147
151
|
}
|
|
148
152
|
}
|
|
149
|
-
else {
|
|
150
|
-
unsupportedView(value);
|
|
151
|
-
}
|
|
152
153
|
}
|
|
153
154
|
/** 获取写入结果 */
|
|
154
155
|
encode(value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoder.js","sourceRoot":"","sources":["../../src/stream-helper/encoder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"encoder.js","sourceRoot":"","sources":["../../src/stream-helper/encoder.ts"],"names":[],"mappings":"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"}
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudpss/ubjson",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.40",
|
|
4
4
|
"author": "CloudPSS",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -22,14 +22,13 @@
|
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/lodash": "^4.17.7",
|
|
24
24
|
"lodash": "^4.17.21",
|
|
25
|
-
"ref-impl": "npm:@cloudpss/ubjson@0.5.
|
|
25
|
+
"ref-impl": "npm:@cloudpss/ubjson@0.5.39"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"rxjs": "^7.8.1"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
|
-
"
|
|
32
|
-
"build": "pnpm clean && tsc",
|
|
31
|
+
"build": "pnpm clean && tsc --build --force",
|
|
33
32
|
"clean": "rimraf dist",
|
|
34
33
|
"test": "NODE_NO_WARNINGS=1 NODE_OPTIONS=\"${NODE_OPTIONS:-} --experimental-vm-modules\" jest"
|
|
35
34
|
}
|
package/src/base/encoder.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import { constants } from '../helper/constants.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
type EncodeCursor,
|
|
4
|
+
I8_MASK,
|
|
5
|
+
type TypedArrayType,
|
|
6
|
+
writeNumber,
|
|
7
|
+
writeTypedArray,
|
|
8
|
+
writeTypedArrayData,
|
|
9
|
+
writeTypedArrayHeader,
|
|
10
|
+
} from '../helper/encode.js';
|
|
11
|
+
import { unsupportedType } from '../helper/errors.js';
|
|
4
12
|
import { stringByteLength, encodeInto } from '../helper/string-encoder.js';
|
|
5
13
|
|
|
6
14
|
const LARGE_DATA_LENGTH = 65536;
|
|
15
|
+
const { isArray } = Array;
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
17
|
+
const { isView } = ArrayBuffer;
|
|
18
|
+
const { keys: objectKeys } = Object;
|
|
7
19
|
|
|
8
20
|
/** 编码至 ubjson */
|
|
9
21
|
export abstract class EncoderBase {
|
|
@@ -43,47 +55,14 @@ export abstract class EncoderBase {
|
|
|
43
55
|
}
|
|
44
56
|
return;
|
|
45
57
|
case 'number':
|
|
46
|
-
|
|
47
|
-
if ((value | 0) === value) {
|
|
48
|
-
if (value >= 0 && value <= 255) {
|
|
49
|
-
this.ensureCapacity(2);
|
|
50
|
-
this.data[this.length++] = constants.UINT8;
|
|
51
|
-
this.data[this.length++] = value;
|
|
52
|
-
} else if (value >= -128 && value <= 127) {
|
|
53
|
-
this.ensureCapacity(2);
|
|
54
|
-
this.data[this.length++] = constants.INT8;
|
|
55
|
-
this.data[this.length++] = value;
|
|
56
|
-
} else if (value >= -32768 && value <= 32767) {
|
|
57
|
-
this.ensureCapacity(3);
|
|
58
|
-
this.data[this.length++] = constants.INT16;
|
|
59
|
-
this.data[this.length++] = value >> 8;
|
|
60
|
-
this.data[this.length++] = value & 0xff;
|
|
61
|
-
} else {
|
|
62
|
-
this.ensureCapacity(5);
|
|
63
|
-
this.data[this.length++] = constants.INT32;
|
|
64
|
-
this.view.setInt32(this.length, value);
|
|
65
|
-
this.length += 4;
|
|
66
|
-
}
|
|
67
|
-
} else if (Number.isNaN(value) || Math.fround(value) === value) {
|
|
68
|
-
// 如果不会损失精度,使用 32 位浮点
|
|
69
|
-
this.ensureCapacity(5);
|
|
70
|
-
this.data[this.length++] = constants.FLOAT32;
|
|
71
|
-
this.view.setFloat32(this.length, value);
|
|
72
|
-
this.length += 4;
|
|
73
|
-
} else {
|
|
74
|
-
this.ensureCapacity(9);
|
|
75
|
-
this.data[this.length++] = constants.FLOAT64;
|
|
76
|
-
this.view.setFloat64(this.length, value);
|
|
77
|
-
this.length += 8;
|
|
78
|
-
}
|
|
79
|
-
return;
|
|
58
|
+
return writeNumber(this as this & EncodeCursor, value);
|
|
80
59
|
case 'object': {
|
|
81
60
|
if (value === null) {
|
|
82
61
|
this.ensureCapacity(1);
|
|
83
62
|
this.data[this.length++] = constants.NULL;
|
|
84
63
|
return;
|
|
85
64
|
}
|
|
86
|
-
if (
|
|
65
|
+
if (isArray(value)) {
|
|
87
66
|
this.ensureCapacity(1);
|
|
88
67
|
this.data[this.length++] = constants.ARRAY;
|
|
89
68
|
const size = value.length;
|
|
@@ -101,95 +80,34 @@ export abstract class EncoderBase {
|
|
|
101
80
|
this.data[this.length++] = constants.ARRAY_END;
|
|
102
81
|
return;
|
|
103
82
|
}
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
this.write(toJSON.call(value));
|
|
83
|
+
if (isView(value)) {
|
|
84
|
+
if (value.byteLength <= LARGE_DATA_LENGTH) {
|
|
85
|
+
writeTypedArray(this as this & EncodeCursor, value);
|
|
108
86
|
return;
|
|
109
87
|
}
|
|
110
|
-
this
|
|
111
|
-
this.
|
|
112
|
-
// 生成稳定的结果以便 hash 计算
|
|
113
|
-
const keys = Object.keys(value).sort();
|
|
114
|
-
const size = keys.length;
|
|
115
|
-
for (let index = 0; index < size; index++) {
|
|
116
|
-
const key = keys[index]!;
|
|
117
|
-
const element = (value as Record<string, unknown>)[key];
|
|
118
|
-
if (element === undefined || typeof element == 'function') continue;
|
|
119
|
-
this.writeStringData(key);
|
|
120
|
-
this.write(element);
|
|
121
|
-
}
|
|
122
|
-
this.ensureCapacity(1);
|
|
123
|
-
this.data[this.length++] = constants.OBJECT_END;
|
|
88
|
+
const type = writeTypedArrayHeader(this as this & EncodeCursor, value);
|
|
89
|
+
this.writeLargeTypedArrayData(type, value);
|
|
124
90
|
return;
|
|
125
91
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
} else {
|
|
131
|
-
// ARRAY(1) + TYPE_MARKER(1) + TYPE(1) + COUNT_MARKER(1) + COUNT(MAX5) + DATA
|
|
132
|
-
this.ensureCapacity(9 + value.byteLength);
|
|
133
|
-
this.data[this.length++] = constants.ARRAY;
|
|
134
|
-
this.data[this.length++] = constants.TYPE_MARKER;
|
|
135
|
-
if (value instanceof Uint8Array || value instanceof Int8Array) {
|
|
136
|
-
// fast path for typed arrays with `BYTES_PER_ELEMENT` of 1
|
|
137
|
-
this.data[this.length++] = value instanceof Uint8Array ? constants.UINT8 : constants.INT8;
|
|
138
|
-
this.data[this.length++] = constants.COUNT_MARKER;
|
|
139
|
-
writeLength(this as this & EncodeCursor, value.length);
|
|
140
|
-
this.data.set(value, this.length);
|
|
141
|
-
this.length += value.byteLength;
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const arrayLength = (value as Int16Array | Int32Array | BigInt64Array | Float32Array | Float64Array)
|
|
146
|
-
.length;
|
|
147
|
-
const elementSize = (value as Int16Array | Int32Array | BigInt64Array | Float32Array | Float64Array)
|
|
148
|
-
.BYTES_PER_ELEMENT;
|
|
149
|
-
if (value instanceof Float64Array) {
|
|
150
|
-
this.data[this.length++] = constants.FLOAT64;
|
|
151
|
-
this.data[this.length++] = constants.COUNT_MARKER;
|
|
152
|
-
writeLength(this as this & EncodeCursor, arrayLength);
|
|
153
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
154
|
-
this.view.setFloat64(this.length, value[i]!);
|
|
155
|
-
this.length += elementSize;
|
|
156
|
-
}
|
|
157
|
-
} else if (value instanceof Int32Array) {
|
|
158
|
-
this.data[this.length++] = constants.INT32;
|
|
159
|
-
this.data[this.length++] = constants.COUNT_MARKER;
|
|
160
|
-
writeLength(this as this & EncodeCursor, arrayLength);
|
|
161
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
162
|
-
this.view.setInt32(this.length, value[i]!);
|
|
163
|
-
this.length += elementSize;
|
|
164
|
-
}
|
|
165
|
-
} else if (value instanceof Int16Array) {
|
|
166
|
-
this.data[this.length++] = constants.INT16;
|
|
167
|
-
this.data[this.length++] = constants.COUNT_MARKER;
|
|
168
|
-
writeLength(this as this & EncodeCursor, arrayLength);
|
|
169
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
170
|
-
this.view.setInt16(this.length, value[i]!);
|
|
171
|
-
this.length += elementSize;
|
|
172
|
-
}
|
|
173
|
-
} else if (value instanceof Float32Array) {
|
|
174
|
-
this.data[this.length++] = constants.FLOAT32;
|
|
175
|
-
this.data[this.length++] = constants.COUNT_MARKER;
|
|
176
|
-
writeLength(this as this & EncodeCursor, arrayLength);
|
|
177
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
178
|
-
this.view.setFloat32(this.length, value[i]!);
|
|
179
|
-
this.length += elementSize;
|
|
180
|
-
}
|
|
181
|
-
} else if (value instanceof BigInt64Array) {
|
|
182
|
-
this.data[this.length++] = constants.INT64;
|
|
183
|
-
this.data[this.length++] = constants.COUNT_MARKER;
|
|
184
|
-
writeLength(this as this & EncodeCursor, arrayLength);
|
|
185
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
186
|
-
this.view.setBigInt64(this.length, value[i]!);
|
|
187
|
-
this.length += elementSize;
|
|
188
|
-
}
|
|
189
|
-
} else {
|
|
190
|
-
unsupportedView(value);
|
|
191
|
-
}
|
|
92
|
+
const { toJSON } = value as Record<string, unknown>;
|
|
93
|
+
if (typeof toJSON == 'function') {
|
|
94
|
+
this.write(toJSON.call(value));
|
|
95
|
+
return;
|
|
192
96
|
}
|
|
97
|
+
// 生成稳定的结果以便 hash 计算
|
|
98
|
+
const keys = objectKeys(value).sort();
|
|
99
|
+
const size = keys.length;
|
|
100
|
+
this.ensureCapacity(2 + size);
|
|
101
|
+
this.data[this.length++] = constants.OBJECT;
|
|
102
|
+
for (let index = 0; index < size; index++) {
|
|
103
|
+
const key = keys[index]!;
|
|
104
|
+
const element = (value as Record<string, unknown>)[key];
|
|
105
|
+
if (element === undefined || typeof element == 'function') continue;
|
|
106
|
+
this.writeStringData(key);
|
|
107
|
+
this.write(element);
|
|
108
|
+
}
|
|
109
|
+
this.ensureCapacity(1);
|
|
110
|
+
this.data[this.length++] = constants.OBJECT_END;
|
|
193
111
|
return;
|
|
194
112
|
}
|
|
195
113
|
case 'boolean':
|
|
@@ -230,27 +148,26 @@ export abstract class EncoderBase {
|
|
|
230
148
|
|
|
231
149
|
// 预估头部大小
|
|
232
150
|
const headerSize = strLength < 0x80 ? 2 : strLength < 0x8000 ? 3 : 5;
|
|
233
|
-
const headerPos = this
|
|
234
|
-
const bufLength = encodeInto(value,
|
|
151
|
+
const { length: headerPos, data, view } = this;
|
|
152
|
+
const bufLength = encodeInto(value, data, headerPos + headerSize);
|
|
235
153
|
if (bufLength < 0x80) {
|
|
236
|
-
|
|
237
|
-
this.
|
|
154
|
+
view.setInt16(headerPos, I8_MASK | bufLength);
|
|
155
|
+
this.length = headerPos + 2 + bufLength;
|
|
238
156
|
} else if (bufLength < 0x8000) {
|
|
239
157
|
if (headerSize < 3) {
|
|
240
|
-
|
|
158
|
+
data.copyWithin(headerPos + 3, headerPos + headerSize, headerPos + headerSize + bufLength);
|
|
241
159
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
this.
|
|
160
|
+
data[headerPos] = constants.INT16;
|
|
161
|
+
view.setInt16(headerPos + 1, bufLength);
|
|
162
|
+
this.length = headerPos + 3 + bufLength;
|
|
245
163
|
} else {
|
|
246
164
|
if (headerSize < 5) {
|
|
247
|
-
|
|
165
|
+
data.copyWithin(headerPos + 5, headerPos + headerSize, headerPos + headerSize + bufLength);
|
|
248
166
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
this.length
|
|
167
|
+
data[headerPos] = constants.INT32;
|
|
168
|
+
view.setInt32(headerPos + 1, bufLength);
|
|
169
|
+
this.length = headerPos + 5 + bufLength;
|
|
252
170
|
}
|
|
253
|
-
this.length += bufLength;
|
|
254
171
|
}
|
|
255
172
|
|
|
256
173
|
/** 写入大字符串 */
|
|
@@ -266,45 +183,7 @@ export abstract class EncoderBase {
|
|
|
266
183
|
}
|
|
267
184
|
|
|
268
185
|
/** 写入数组 */
|
|
269
|
-
protected writeLargeTypedArrayData(value: ArrayBufferView): void {
|
|
270
|
-
this
|
|
271
|
-
if (value instanceof Uint8Array || value instanceof Int8Array) {
|
|
272
|
-
// fast path for typed arrays with `BYTES_PER_ELEMENT` of 1
|
|
273
|
-
this.data.set(value, this.length);
|
|
274
|
-
this.length += value.byteLength;
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
const arrayLength = (value as Int16Array | Int32Array | BigInt64Array | Float32Array | Float64Array).length;
|
|
279
|
-
const elementSize = (value as Int16Array | Int32Array | BigInt64Array | Float32Array | Float64Array)
|
|
280
|
-
.BYTES_PER_ELEMENT;
|
|
281
|
-
if (value instanceof Int16Array) {
|
|
282
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
283
|
-
this.view.setInt16(this.length, value[i]!);
|
|
284
|
-
this.length += elementSize;
|
|
285
|
-
}
|
|
286
|
-
} else if (value instanceof Int32Array) {
|
|
287
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
288
|
-
this.view.setInt32(this.length, value[i]!);
|
|
289
|
-
this.length += elementSize;
|
|
290
|
-
}
|
|
291
|
-
} else if (value instanceof Float32Array) {
|
|
292
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
293
|
-
this.view.setFloat32(this.length, value[i]!);
|
|
294
|
-
this.length += elementSize;
|
|
295
|
-
}
|
|
296
|
-
} else if (value instanceof Float64Array) {
|
|
297
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
298
|
-
this.view.setFloat64(this.length, value[i]!);
|
|
299
|
-
this.length += elementSize;
|
|
300
|
-
}
|
|
301
|
-
} else if (value instanceof BigInt64Array) {
|
|
302
|
-
for (let i = 0; i < arrayLength; i++) {
|
|
303
|
-
this.view.setBigInt64(this.length, value[i]!);
|
|
304
|
-
this.length += elementSize;
|
|
305
|
-
}
|
|
306
|
-
} else {
|
|
307
|
-
unsupportedView(value);
|
|
308
|
-
}
|
|
186
|
+
protected writeLargeTypedArrayData(type: TypedArrayType, value: ArrayBufferView): void {
|
|
187
|
+
writeTypedArrayData(this as this & EncodeCursor, type, value);
|
|
309
188
|
}
|
|
310
189
|
}
|
package/src/encoder.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EncoderBase } from './base/encoder.js';
|
|
2
2
|
|
|
3
|
-
const BLOCK_SIZE = 1024 *
|
|
3
|
+
const BLOCK_SIZE = 1024 * 64; // 64 KiB
|
|
4
4
|
const MAX_SIZE = 1024 * 1024 * 128; //128 MiB
|
|
5
5
|
|
|
6
6
|
/** 编码至 ubjson */
|
|
@@ -8,6 +8,8 @@ export class Encoder extends EncoderBase {
|
|
|
8
8
|
private readonly flushedBuffers: Uint8Array[] = [];
|
|
9
9
|
/** 通过内存池减少分配 */
|
|
10
10
|
private readonly pool = new Uint8Array(BLOCK_SIZE);
|
|
11
|
+
/** 缓存当前容量,避免对象访问耗时 */
|
|
12
|
+
private capacity = 0;
|
|
11
13
|
/**
|
|
12
14
|
* 确保 buffer 还有 capacity 的空闲空间
|
|
13
15
|
*/
|
|
@@ -16,9 +18,15 @@ export class Encoder extends EncoderBase {
|
|
|
16
18
|
// 超过最大尺寸限制
|
|
17
19
|
throw new Error('Buffer has exceed max size');
|
|
18
20
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
if (this.capacity >= this.length + capacity) {
|
|
22
|
+
// 无需扩容
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
this.flushBuffer(capacity);
|
|
26
|
+
}
|
|
21
27
|
|
|
28
|
+
/** 提交并扩容 */
|
|
29
|
+
protected flushBuffer(capacity: number): void {
|
|
22
30
|
// 提交目前的数据
|
|
23
31
|
if (this.data === this.pool) {
|
|
24
32
|
this.flushedBuffers.push(this.data.slice(0, this.length));
|
|
@@ -33,16 +41,16 @@ export class Encoder extends EncoderBase {
|
|
|
33
41
|
|
|
34
42
|
/** 分配 buffer */
|
|
35
43
|
private allocUnsafe(size: number): void {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.
|
|
44
|
-
this.view = new DataView(this.data.buffer);
|
|
44
|
+
const data =
|
|
45
|
+
size === BLOCK_SIZE
|
|
46
|
+
? // 从 pool 中获取
|
|
47
|
+
this.pool
|
|
48
|
+
: // 新建 buffer
|
|
49
|
+
new Uint8Array(size);
|
|
50
|
+
this.data = data;
|
|
51
|
+
this.view = new DataView(data.buffer);
|
|
45
52
|
this.length = 0;
|
|
53
|
+
this.capacity = size;
|
|
46
54
|
}
|
|
47
55
|
|
|
48
56
|
/** 获取结果 */
|
|
@@ -53,15 +61,17 @@ export class Encoder extends EncoderBase {
|
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
// 合并缓冲区
|
|
64
|
+
const { length } = this;
|
|
65
|
+
const activeBuffer = this.data.subarray(0, length);
|
|
56
66
|
const flushedBuffers = this.flushedBuffers.splice(0);
|
|
57
|
-
const size = flushedBuffers.reduce((sum, buffer) => sum + buffer.byteLength,
|
|
67
|
+
const size = flushedBuffers.reduce((sum, buffer) => sum + buffer.byteLength, length);
|
|
58
68
|
const result = new Uint8Array(size);
|
|
59
69
|
let offset = 0;
|
|
60
70
|
for (const buffer of flushedBuffers) {
|
|
61
71
|
result.set(buffer, offset);
|
|
62
72
|
offset += buffer.byteLength;
|
|
63
73
|
}
|
|
64
|
-
result.set(
|
|
74
|
+
result.set(activeBuffer, offset);
|
|
65
75
|
return result;
|
|
66
76
|
}
|
|
67
77
|
|
package/src/helper/decode.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { constants } from './constants.js';
|
|
2
2
|
import { UnexpectedEofError, unsupportedType } from './errors.js';
|
|
3
|
-
import { decode
|
|
3
|
+
import { decode } from './string-decoder.js';
|
|
4
4
|
import { toUint8Array } from './utils.js';
|
|
5
|
-
|
|
6
|
-
const { fromEntries } = Object;
|
|
5
|
+
const { defineProperty } = Object;
|
|
7
6
|
const { fromCharCode } = String;
|
|
8
7
|
|
|
9
8
|
/** 数据包装 */
|
|
@@ -161,6 +160,21 @@ export function read(cursor: DecodeCursor): unknown {
|
|
|
161
160
|
return readData(cursor, marker);
|
|
162
161
|
}
|
|
163
162
|
|
|
163
|
+
/** 读取优化对象数据 */
|
|
164
|
+
function readObjectOptimizedData(cursor: DecodeCursor, marker: OptimizedFormatMarkers): unknown {
|
|
165
|
+
const { count, type } = marker;
|
|
166
|
+
const object: Record<string, unknown> = {};
|
|
167
|
+
for (let i = 0; i < count; i++) {
|
|
168
|
+
const key = readKey(cursor);
|
|
169
|
+
const value = readData(cursor, type ?? readMarker(cursor));
|
|
170
|
+
if (key === '__proto__') {
|
|
171
|
+
defineProperty(object, key, { value, enumerable: true, configurable: true, writable: true });
|
|
172
|
+
}
|
|
173
|
+
object[key] = value;
|
|
174
|
+
}
|
|
175
|
+
return object;
|
|
176
|
+
}
|
|
177
|
+
|
|
164
178
|
/** 根据标签读取后续数据 */
|
|
165
179
|
export function readData(cursor: DecodeCursor, marker: number): unknown {
|
|
166
180
|
// 按照出现频率排序
|
|
@@ -178,23 +192,19 @@ export function readData(cursor: DecodeCursor, marker: number): unknown {
|
|
|
178
192
|
const markers = readOptimizedFormatMarkers(cursor);
|
|
179
193
|
if (markers == null) {
|
|
180
194
|
// 直到 '}'
|
|
181
|
-
const object:
|
|
195
|
+
const object: Record<string, unknown> = {};
|
|
182
196
|
while (readMarker(cursor) !== constants.OBJECT_END) {
|
|
183
197
|
cursor.offset--;
|
|
184
|
-
|
|
198
|
+
const key = readKey(cursor);
|
|
199
|
+
const value = read(cursor);
|
|
200
|
+
if (key === '__proto__') {
|
|
201
|
+
defineProperty(object, key, { value, enumerable: true, configurable: true, writable: true });
|
|
202
|
+
}
|
|
203
|
+
object[key] = value;
|
|
185
204
|
}
|
|
186
|
-
return
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const { count, type } = markers;
|
|
190
|
-
const object: Array<[string, unknown]> = [];
|
|
191
|
-
object.length = count;
|
|
192
|
-
for (let i = 0; i < count; i++) {
|
|
193
|
-
const key = readKey(cursor);
|
|
194
|
-
const value = readData(cursor, type ?? readMarker(cursor));
|
|
195
|
-
object[i] = [key, value];
|
|
205
|
+
return object;
|
|
196
206
|
}
|
|
197
|
-
return
|
|
207
|
+
return readObjectOptimizedData(cursor, markers);
|
|
198
208
|
}
|
|
199
209
|
case constants.ARRAY: {
|
|
200
210
|
const markers = readOptimizedFormatMarkers(cursor);
|
|
@@ -336,11 +346,13 @@ export function readKey(cursor: DecodeCursor): string {
|
|
|
336
346
|
cursor.offset = end;
|
|
337
347
|
const { data } = cursor;
|
|
338
348
|
if (end > data.length) cursor.eof();
|
|
339
|
-
return
|
|
349
|
+
return decode(data, begin, end);
|
|
340
350
|
}
|
|
341
351
|
|
|
352
|
+
/** Optimized Format 数据 */
|
|
353
|
+
export type OptimizedFormatMarkers = { type?: number; count: number };
|
|
342
354
|
/** 读取 Optimized Format 数据 */
|
|
343
|
-
export function readOptimizedFormatMarkers(cursor: DecodeCursor):
|
|
355
|
+
export function readOptimizedFormatMarkers(cursor: DecodeCursor): OptimizedFormatMarkers | undefined {
|
|
344
356
|
let type;
|
|
345
357
|
let count;
|
|
346
358
|
switch (readMarker(cursor)) {
|