bin-serde 1.4.1 → 1.5.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/.prettierrc +9 -0
- package/index.ts +114 -102
- package/lib/index.d.ts +9 -7
- package/lib/index.js +90 -77
- package/package.json +1 -1
package/.prettierrc
ADDED
package/index.ts
CHANGED
|
@@ -3,184 +3,197 @@ import utf8Size from "utf8-buffer-size";
|
|
|
3
3
|
|
|
4
4
|
export class Writer {
|
|
5
5
|
private pos = 0;
|
|
6
|
-
private view: DataView;
|
|
7
6
|
private bytes: Uint8Array;
|
|
7
|
+
private _view: DataView | null = null;
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
this.
|
|
11
|
-
this.bytes = new Uint8Array(this.view.buffer);
|
|
9
|
+
constructor(initialSize = 256) {
|
|
10
|
+
this.bytes = new Uint8Array(Math.max(initialSize, 16));
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
writeUInt8(val: number) {
|
|
15
14
|
this.ensureSize(1);
|
|
16
|
-
this.
|
|
17
|
-
this.pos += 1;
|
|
15
|
+
this.bytes[this.pos++] = val;
|
|
18
16
|
return this;
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
this.ensureSize(
|
|
23
|
-
this.view.
|
|
24
|
-
this.pos +=
|
|
19
|
+
writeUInt16(val: number) {
|
|
20
|
+
this.ensureSize(2);
|
|
21
|
+
this.view.setUint16(this.pos, val);
|
|
22
|
+
this.pos += 2;
|
|
25
23
|
return this;
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
this.ensureSize(
|
|
30
|
-
this.view.
|
|
31
|
-
this.pos +=
|
|
26
|
+
writeUInt32(val: number) {
|
|
27
|
+
this.ensureSize(4);
|
|
28
|
+
this.view.setUint32(this.pos, val);
|
|
29
|
+
this.pos += 4;
|
|
32
30
|
return this;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
writeUVarint(val: number) {
|
|
36
34
|
if (val < 0x80) {
|
|
37
|
-
this.
|
|
38
|
-
this.view.setUint8(this.pos, val);
|
|
39
|
-
this.pos += 1;
|
|
35
|
+
this.writeUInt8(val);
|
|
40
36
|
} else if (val < 0x4000) {
|
|
41
|
-
this.
|
|
42
|
-
this.view.setUint16(this.pos, (val & 0x7f) | ((val & 0x3f80) << 1) | 0x8000);
|
|
43
|
-
this.pos += 2;
|
|
37
|
+
this.writeUInt16((val & 0x7f) | ((val & 0x3f80) << 1) | 0x8000);
|
|
44
38
|
} else if (val < 0x200000) {
|
|
45
|
-
this.
|
|
46
|
-
this.
|
|
47
|
-
this.view.setUint16(this.pos + 1, (val & 0x7f) | ((val & 0x3f80) << 1) | 0x8000);
|
|
48
|
-
this.pos += 3;
|
|
39
|
+
this.writeUInt8((val >> 14) | 0x80);
|
|
40
|
+
this.writeUInt16((val & 0x7f) | ((val & 0x3f80) << 1) | 0x8000);
|
|
49
41
|
} else if (val < 0x10000000) {
|
|
50
|
-
this.
|
|
51
|
-
this.view.setUint32(
|
|
52
|
-
this.pos,
|
|
42
|
+
this.writeUInt32(
|
|
53
43
|
(val & 0x7f) | ((val & 0x3f80) << 1) | ((val & 0x1fc000) << 2) | ((val & 0xfe00000) << 3) | 0x80808000
|
|
54
44
|
);
|
|
55
|
-
this.pos += 4;
|
|
56
45
|
} else if (val < 0x800000000) {
|
|
57
|
-
this.
|
|
58
|
-
this.
|
|
59
|
-
this.view.setUint32(
|
|
60
|
-
this.pos + 1,
|
|
46
|
+
this.writeUInt8(Math.floor(val / 0x10000000) | 0x80);
|
|
47
|
+
this.writeUInt32(
|
|
61
48
|
(val & 0x7f) | ((val & 0x3f80) << 1) | ((val & 0x1fc000) << 2) | ((val & 0xfe00000) << 3) | 0x80808000
|
|
62
49
|
);
|
|
63
|
-
this.pos += 5;
|
|
64
50
|
} else if (val < 0x40000000000) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.
|
|
68
|
-
this.view.setUint32(
|
|
69
|
-
this.pos + 2,
|
|
51
|
+
const shiftedVal = Math.floor(val / 0x10000000);
|
|
52
|
+
this.writeUInt16((shiftedVal & 0x7f) | ((shiftedVal & 0x3f80) << 1) | 0x8080);
|
|
53
|
+
this.writeUInt32(
|
|
70
54
|
(val & 0x7f) | ((val & 0x3f80) << 1) | ((val & 0x1fc000) << 2) | ((val & 0xfe00000) << 3) | 0x80808000
|
|
71
55
|
);
|
|
72
|
-
this.pos += 6;
|
|
73
56
|
} else {
|
|
74
57
|
throw new Error("Value out of range");
|
|
75
58
|
}
|
|
76
59
|
return this;
|
|
77
60
|
}
|
|
78
61
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this.writeUVarint(Number((bigval >> 63n) ^ (bigval << 1n)));
|
|
62
|
+
writeVarint(val: number) {
|
|
63
|
+
this.writeUVarint((val << 1) ^ (val >> 31));
|
|
82
64
|
return this;
|
|
83
65
|
}
|
|
84
66
|
|
|
85
|
-
|
|
67
|
+
writeFloat(val: number) {
|
|
86
68
|
this.ensureSize(4);
|
|
87
69
|
this.view.setFloat32(this.pos, val, true);
|
|
88
70
|
this.pos += 4;
|
|
89
71
|
return this;
|
|
90
72
|
}
|
|
91
73
|
|
|
92
|
-
|
|
74
|
+
writeBits(bits: boolean[]) {
|
|
75
|
+
const numBytes = Math.ceil(bits.length / 8);
|
|
76
|
+
this.ensureSize(numBytes);
|
|
93
77
|
for (let i = 0; i < bits.length; i += 8) {
|
|
94
78
|
let byte = 0;
|
|
95
|
-
for (let j = 0; j < 8; j++) {
|
|
96
|
-
if (i + j
|
|
97
|
-
|
|
79
|
+
for (let j = 0; j < 8 && i + j < bits.length; j++) {
|
|
80
|
+
if (bits[i + j]) {
|
|
81
|
+
byte |= 1 << j;
|
|
98
82
|
}
|
|
99
|
-
byte |= (bits[i + j] ? 1 : 0) << j;
|
|
100
83
|
}
|
|
101
|
-
this.
|
|
84
|
+
this.bytes[this.pos++] = byte;
|
|
102
85
|
}
|
|
103
86
|
return this;
|
|
104
87
|
}
|
|
105
88
|
|
|
106
|
-
|
|
89
|
+
writeStringAscii(val: string) {
|
|
107
90
|
if (val.length === 0) {
|
|
108
91
|
return this;
|
|
109
92
|
}
|
|
110
93
|
this.ensureSize(val.length);
|
|
111
94
|
for (let i = 0; i < val.length; i++) {
|
|
112
|
-
this.
|
|
95
|
+
this.bytes[this.pos++] = val.charCodeAt(i);
|
|
113
96
|
}
|
|
114
97
|
return this;
|
|
115
98
|
}
|
|
116
99
|
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
100
|
+
writeStringUtf8(val: string, len?: number) {
|
|
101
|
+
if (len != null) {
|
|
102
|
+
if (len === 0) {
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
this.ensureSize(len);
|
|
122
106
|
pack(val, this.bytes, this.pos);
|
|
123
|
-
this.pos +=
|
|
124
|
-
|
|
125
|
-
|
|
107
|
+
this.pos += len;
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
if (val.length === 0) {
|
|
111
|
+
this.writeUVarint(0);
|
|
112
|
+
return this;
|
|
126
113
|
}
|
|
114
|
+
const byteSize = utf8Size(val);
|
|
115
|
+
this.writeUVarint(byteSize);
|
|
116
|
+
this.ensureSize(byteSize);
|
|
117
|
+
pack(val, this.bytes, this.pos);
|
|
118
|
+
this.pos += byteSize;
|
|
127
119
|
return this;
|
|
128
120
|
}
|
|
129
121
|
|
|
130
|
-
|
|
122
|
+
writeBuffer(buf: Uint8Array) {
|
|
131
123
|
this.ensureSize(buf.length);
|
|
132
124
|
this.bytes.set(buf, this.pos);
|
|
133
125
|
this.pos += buf.length;
|
|
134
126
|
return this;
|
|
135
127
|
}
|
|
136
128
|
|
|
137
|
-
|
|
129
|
+
concat(other: Writer) {
|
|
130
|
+
const otherLen = other.pos;
|
|
131
|
+
this.ensureSize(otherLen);
|
|
132
|
+
if (otherLen < 64) {
|
|
133
|
+
for (let i = 0; i < otherLen; i++) {
|
|
134
|
+
this.bytes[this.pos++] = other.bytes[i];
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
this.bytes.set(other.bytes.subarray(0, otherLen), this.pos);
|
|
138
|
+
this.pos += otherLen;
|
|
139
|
+
}
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
toBuffer() {
|
|
138
144
|
return this.bytes.subarray(0, this.pos);
|
|
139
145
|
}
|
|
140
146
|
|
|
147
|
+
get size(): number {
|
|
148
|
+
return this.pos;
|
|
149
|
+
}
|
|
150
|
+
|
|
141
151
|
private ensureSize(size: number) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
if (this.bytes.length >= this.pos + size) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
let newSize = this.bytes.length * 2;
|
|
156
|
+
while (newSize < this.pos + size) {
|
|
157
|
+
newSize *= 2;
|
|
158
|
+
}
|
|
159
|
+
const newBytes = new Uint8Array(newSize);
|
|
160
|
+
newBytes.set(this.bytes);
|
|
161
|
+
this.bytes = newBytes;
|
|
162
|
+
this._view = null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private get view(): DataView {
|
|
166
|
+
if (!this._view) {
|
|
167
|
+
this._view = new DataView(this.bytes.buffer);
|
|
148
168
|
}
|
|
169
|
+
return this._view;
|
|
149
170
|
}
|
|
150
171
|
}
|
|
151
172
|
|
|
152
173
|
export class Reader {
|
|
153
174
|
private pos = 0;
|
|
154
|
-
private view: DataView;
|
|
155
175
|
private bytes: Uint8Array;
|
|
176
|
+
private view: DataView;
|
|
156
177
|
|
|
157
|
-
|
|
178
|
+
constructor(buf: Uint8Array) {
|
|
179
|
+
this.bytes = buf;
|
|
158
180
|
this.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
159
|
-
this.bytes = new Uint8Array(this.view.buffer, buf.byteOffset, buf.byteLength);
|
|
160
181
|
}
|
|
161
182
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
this.pos += 1;
|
|
165
|
-
return val;
|
|
183
|
+
readUInt8() {
|
|
184
|
+
return this.bytes[this.pos++];
|
|
166
185
|
}
|
|
167
186
|
|
|
168
|
-
|
|
187
|
+
readUInt32() {
|
|
169
188
|
const val = this.view.getUint32(this.pos);
|
|
170
189
|
this.pos += 4;
|
|
171
190
|
return val;
|
|
172
191
|
}
|
|
173
192
|
|
|
174
|
-
|
|
175
|
-
const val = this.view.getBigUint64(this.pos);
|
|
176
|
-
this.pos += 8;
|
|
177
|
-
return val;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
public readUVarint() {
|
|
193
|
+
readUVarint() {
|
|
181
194
|
let val = 0;
|
|
182
195
|
while (true) {
|
|
183
|
-
|
|
196
|
+
const byte = this.readUInt8();
|
|
184
197
|
if (byte < 0x80) {
|
|
185
198
|
return val + byte;
|
|
186
199
|
}
|
|
@@ -188,43 +201,42 @@ export class Reader {
|
|
|
188
201
|
}
|
|
189
202
|
}
|
|
190
203
|
|
|
191
|
-
|
|
192
|
-
const val =
|
|
193
|
-
return
|
|
204
|
+
readVarint() {
|
|
205
|
+
const val = this.readUVarint();
|
|
206
|
+
return (val >>> 1) ^ -(val & 1);
|
|
194
207
|
}
|
|
195
208
|
|
|
196
|
-
|
|
209
|
+
readFloat() {
|
|
197
210
|
const val = this.view.getFloat32(this.pos, true);
|
|
198
211
|
this.pos += 4;
|
|
199
212
|
return val;
|
|
200
213
|
}
|
|
201
214
|
|
|
202
|
-
|
|
215
|
+
readBits(numBits: number) {
|
|
203
216
|
const numBytes = Math.ceil(numBits / 8);
|
|
204
|
-
const bytes = this.bytes.slice(this.pos, this.pos + numBytes);
|
|
205
217
|
const bits: boolean[] = [];
|
|
206
|
-
for (
|
|
207
|
-
|
|
208
|
-
|
|
218
|
+
for (let i = 0; i < numBytes; i++) {
|
|
219
|
+
const byte = this.readUInt8();
|
|
220
|
+
for (let j = 0; j < 8 && bits.length < numBits; j++) {
|
|
221
|
+
bits.push(((byte >> j) & 1) === 1);
|
|
209
222
|
}
|
|
210
223
|
}
|
|
211
|
-
this.pos += numBytes;
|
|
212
224
|
return bits;
|
|
213
225
|
}
|
|
214
226
|
|
|
215
|
-
|
|
227
|
+
readStringAscii(len: number) {
|
|
216
228
|
if (len === 0) {
|
|
217
229
|
return "";
|
|
218
230
|
}
|
|
219
231
|
let val = "";
|
|
220
232
|
for (let i = 0; i < len; i++) {
|
|
221
|
-
val += String.fromCharCode(this.
|
|
233
|
+
val += String.fromCharCode(this.readUInt8());
|
|
222
234
|
}
|
|
223
235
|
return val;
|
|
224
236
|
}
|
|
225
237
|
|
|
226
|
-
|
|
227
|
-
if (len
|
|
238
|
+
readStringUtf8(len?: number) {
|
|
239
|
+
if (len == null) {
|
|
228
240
|
len = this.readUVarint();
|
|
229
241
|
}
|
|
230
242
|
if (len === 0) {
|
|
@@ -235,13 +247,13 @@ export class Reader {
|
|
|
235
247
|
return val;
|
|
236
248
|
}
|
|
237
249
|
|
|
238
|
-
|
|
250
|
+
readBuffer(numBytes: number) {
|
|
239
251
|
const bytes = this.bytes.slice(this.pos, this.pos + numBytes);
|
|
240
252
|
this.pos += numBytes;
|
|
241
253
|
return bytes;
|
|
242
254
|
}
|
|
243
255
|
|
|
244
|
-
|
|
245
|
-
return this.
|
|
256
|
+
remaining() {
|
|
257
|
+
return this.bytes.length - this.pos;
|
|
246
258
|
}
|
|
247
259
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
export declare class Writer {
|
|
2
2
|
private pos;
|
|
3
|
-
private view;
|
|
4
3
|
private bytes;
|
|
5
|
-
|
|
4
|
+
private _view;
|
|
5
|
+
constructor(initialSize?: number);
|
|
6
6
|
writeUInt8(val: number): this;
|
|
7
|
+
writeUInt16(val: number): this;
|
|
7
8
|
writeUInt32(val: number): this;
|
|
8
|
-
writeUInt64(val: bigint): this;
|
|
9
9
|
writeUVarint(val: number): this;
|
|
10
10
|
writeVarint(val: number): this;
|
|
11
11
|
writeFloat(val: number): this;
|
|
12
12
|
writeBits(bits: boolean[]): this;
|
|
13
13
|
writeStringAscii(val: string): this;
|
|
14
|
-
writeStringUtf8(val: string): this;
|
|
14
|
+
writeStringUtf8(val: string, len?: number): this;
|
|
15
15
|
writeBuffer(buf: Uint8Array): this;
|
|
16
|
+
concat(other: Writer): this;
|
|
16
17
|
toBuffer(): Uint8Array;
|
|
18
|
+
get size(): number;
|
|
17
19
|
private ensureSize;
|
|
20
|
+
private get view();
|
|
18
21
|
}
|
|
19
22
|
export declare class Reader {
|
|
20
23
|
private pos;
|
|
21
|
-
private view;
|
|
22
24
|
private bytes;
|
|
23
|
-
|
|
25
|
+
private view;
|
|
26
|
+
constructor(buf: Uint8Array);
|
|
24
27
|
readUInt8(): number;
|
|
25
28
|
readUInt32(): number;
|
|
26
|
-
readUInt64(): bigint;
|
|
27
29
|
readUVarint(): number;
|
|
28
30
|
readVarint(): number;
|
|
29
31
|
readFloat(): number;
|
package/lib/index.js
CHANGED
|
@@ -2,16 +2,20 @@ import { pack, unpack } from "./utf8-buffer.js";
|
|
|
2
2
|
import utf8Size from "utf8-buffer-size";
|
|
3
3
|
export class Writer {
|
|
4
4
|
pos = 0;
|
|
5
|
-
view;
|
|
6
5
|
bytes;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.bytes = new Uint8Array(
|
|
6
|
+
_view = null;
|
|
7
|
+
constructor(initialSize = 256) {
|
|
8
|
+
this.bytes = new Uint8Array(Math.max(initialSize, 16));
|
|
10
9
|
}
|
|
11
10
|
writeUInt8(val) {
|
|
12
11
|
this.ensureSize(1);
|
|
13
|
-
this.
|
|
14
|
-
this
|
|
12
|
+
this.bytes[this.pos++] = val;
|
|
13
|
+
return this;
|
|
14
|
+
}
|
|
15
|
+
writeUInt16(val) {
|
|
16
|
+
this.ensureSize(2);
|
|
17
|
+
this.view.setUint16(this.pos, val);
|
|
18
|
+
this.pos += 2;
|
|
15
19
|
return this;
|
|
16
20
|
}
|
|
17
21
|
writeUInt32(val) {
|
|
@@ -20,46 +24,28 @@ export class Writer {
|
|
|
20
24
|
this.pos += 4;
|
|
21
25
|
return this;
|
|
22
26
|
}
|
|
23
|
-
writeUInt64(val) {
|
|
24
|
-
this.ensureSize(8);
|
|
25
|
-
this.view.setBigUint64(this.pos, val);
|
|
26
|
-
this.pos += 8;
|
|
27
|
-
return this;
|
|
28
|
-
}
|
|
29
27
|
writeUVarint(val) {
|
|
30
28
|
if (val < 0x80) {
|
|
31
|
-
this.
|
|
32
|
-
this.view.setUint8(this.pos, val);
|
|
33
|
-
this.pos += 1;
|
|
29
|
+
this.writeUInt8(val);
|
|
34
30
|
}
|
|
35
31
|
else if (val < 0x4000) {
|
|
36
|
-
this.
|
|
37
|
-
this.view.setUint16(this.pos, (val & 0x7f) | ((val & 0x3f80) << 1) | 0x8000);
|
|
38
|
-
this.pos += 2;
|
|
32
|
+
this.writeUInt16((val & 0x7f) | ((val & 0x3f80) << 1) | 0x8000);
|
|
39
33
|
}
|
|
40
34
|
else if (val < 0x200000) {
|
|
41
|
-
this.
|
|
42
|
-
this.
|
|
43
|
-
this.view.setUint16(this.pos + 1, (val & 0x7f) | ((val & 0x3f80) << 1) | 0x8000);
|
|
44
|
-
this.pos += 3;
|
|
35
|
+
this.writeUInt8((val >> 14) | 0x80);
|
|
36
|
+
this.writeUInt16((val & 0x7f) | ((val & 0x3f80) << 1) | 0x8000);
|
|
45
37
|
}
|
|
46
38
|
else if (val < 0x10000000) {
|
|
47
|
-
this.
|
|
48
|
-
this.view.setUint32(this.pos, (val & 0x7f) | ((val & 0x3f80) << 1) | ((val & 0x1fc000) << 2) | ((val & 0xfe00000) << 3) | 0x80808000);
|
|
49
|
-
this.pos += 4;
|
|
39
|
+
this.writeUInt32((val & 0x7f) | ((val & 0x3f80) << 1) | ((val & 0x1fc000) << 2) | ((val & 0xfe00000) << 3) | 0x80808000);
|
|
50
40
|
}
|
|
51
41
|
else if (val < 0x800000000) {
|
|
52
|
-
this.
|
|
53
|
-
this.
|
|
54
|
-
this.view.setUint32(this.pos + 1, (val & 0x7f) | ((val & 0x3f80) << 1) | ((val & 0x1fc000) << 2) | ((val & 0xfe00000) << 3) | 0x80808000);
|
|
55
|
-
this.pos += 5;
|
|
42
|
+
this.writeUInt8(Math.floor(val / 0x10000000) | 0x80);
|
|
43
|
+
this.writeUInt32((val & 0x7f) | ((val & 0x3f80) << 1) | ((val & 0x1fc000) << 2) | ((val & 0xfe00000) << 3) | 0x80808000);
|
|
56
44
|
}
|
|
57
45
|
else if (val < 0x40000000000) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.
|
|
61
|
-
this.view.setUint32(this.pos + 2, (val & 0x7f) | ((val & 0x3f80) << 1) | ((val & 0x1fc000) << 2) | ((val & 0xfe00000) << 3) | 0x80808000);
|
|
62
|
-
this.pos += 6;
|
|
46
|
+
const shiftedVal = Math.floor(val / 0x10000000);
|
|
47
|
+
this.writeUInt16((shiftedVal & 0x7f) | ((shiftedVal & 0x3f80) << 1) | 0x8080);
|
|
48
|
+
this.writeUInt32((val & 0x7f) | ((val & 0x3f80) << 1) | ((val & 0x1fc000) << 2) | ((val & 0xfe00000) << 3) | 0x80808000);
|
|
63
49
|
}
|
|
64
50
|
else {
|
|
65
51
|
throw new Error("Value out of range");
|
|
@@ -67,8 +53,7 @@ export class Writer {
|
|
|
67
53
|
return this;
|
|
68
54
|
}
|
|
69
55
|
writeVarint(val) {
|
|
70
|
-
|
|
71
|
-
this.writeUVarint(Number((bigval >> 63n) ^ (bigval << 1n)));
|
|
56
|
+
this.writeUVarint((val << 1) ^ (val >> 31));
|
|
72
57
|
return this;
|
|
73
58
|
}
|
|
74
59
|
writeFloat(val) {
|
|
@@ -78,15 +63,16 @@ export class Writer {
|
|
|
78
63
|
return this;
|
|
79
64
|
}
|
|
80
65
|
writeBits(bits) {
|
|
66
|
+
const numBytes = Math.ceil(bits.length / 8);
|
|
67
|
+
this.ensureSize(numBytes);
|
|
81
68
|
for (let i = 0; i < bits.length; i += 8) {
|
|
82
69
|
let byte = 0;
|
|
83
|
-
for (let j = 0; j < 8; j++) {
|
|
84
|
-
if (i + j
|
|
85
|
-
|
|
70
|
+
for (let j = 0; j < 8 && i + j < bits.length; j++) {
|
|
71
|
+
if (bits[i + j]) {
|
|
72
|
+
byte |= 1 << j;
|
|
86
73
|
}
|
|
87
|
-
byte |= (bits[i + j] ? 1 : 0) << j;
|
|
88
74
|
}
|
|
89
|
-
this.
|
|
75
|
+
this.bytes[this.pos++] = byte;
|
|
90
76
|
}
|
|
91
77
|
return this;
|
|
92
78
|
}
|
|
@@ -96,21 +82,29 @@ export class Writer {
|
|
|
96
82
|
}
|
|
97
83
|
this.ensureSize(val.length);
|
|
98
84
|
for (let i = 0; i < val.length; i++) {
|
|
99
|
-
this.
|
|
85
|
+
this.bytes[this.pos++] = val.charCodeAt(i);
|
|
100
86
|
}
|
|
101
87
|
return this;
|
|
102
88
|
}
|
|
103
|
-
writeStringUtf8(val) {
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
89
|
+
writeStringUtf8(val, len) {
|
|
90
|
+
if (len != null) {
|
|
91
|
+
if (len === 0) {
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
this.ensureSize(len);
|
|
108
95
|
pack(val, this.bytes, this.pos);
|
|
109
|
-
this.pos +=
|
|
96
|
+
this.pos += len;
|
|
97
|
+
return this;
|
|
110
98
|
}
|
|
111
|
-
|
|
112
|
-
this.
|
|
99
|
+
if (val.length === 0) {
|
|
100
|
+
this.writeUVarint(0);
|
|
101
|
+
return this;
|
|
113
102
|
}
|
|
103
|
+
const byteSize = utf8Size(val);
|
|
104
|
+
this.writeUVarint(byteSize);
|
|
105
|
+
this.ensureSize(byteSize);
|
|
106
|
+
pack(val, this.bytes, this.pos);
|
|
107
|
+
this.pos += byteSize;
|
|
114
108
|
return this;
|
|
115
109
|
}
|
|
116
110
|
writeBuffer(buf) {
|
|
@@ -119,46 +113,66 @@ export class Writer {
|
|
|
119
113
|
this.pos += buf.length;
|
|
120
114
|
return this;
|
|
121
115
|
}
|
|
116
|
+
concat(other) {
|
|
117
|
+
const otherLen = other.pos;
|
|
118
|
+
this.ensureSize(otherLen);
|
|
119
|
+
if (otherLen < 64) {
|
|
120
|
+
for (let i = 0; i < otherLen; i++) {
|
|
121
|
+
this.bytes[this.pos++] = other.bytes[i];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
this.bytes.set(other.bytes.subarray(0, otherLen), this.pos);
|
|
126
|
+
this.pos += otherLen;
|
|
127
|
+
}
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
122
130
|
toBuffer() {
|
|
123
131
|
return this.bytes.subarray(0, this.pos);
|
|
124
132
|
}
|
|
133
|
+
get size() {
|
|
134
|
+
return this.pos;
|
|
135
|
+
}
|
|
125
136
|
ensureSize(size) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
if (this.bytes.length >= this.pos + size) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
let newSize = this.bytes.length * 2;
|
|
141
|
+
while (newSize < this.pos + size) {
|
|
142
|
+
newSize *= 2;
|
|
132
143
|
}
|
|
144
|
+
const newBytes = new Uint8Array(newSize);
|
|
145
|
+
newBytes.set(this.bytes);
|
|
146
|
+
this.bytes = newBytes;
|
|
147
|
+
this._view = null;
|
|
148
|
+
}
|
|
149
|
+
get view() {
|
|
150
|
+
if (!this._view) {
|
|
151
|
+
this._view = new DataView(this.bytes.buffer);
|
|
152
|
+
}
|
|
153
|
+
return this._view;
|
|
133
154
|
}
|
|
134
155
|
}
|
|
135
156
|
export class Reader {
|
|
136
157
|
pos = 0;
|
|
137
|
-
view;
|
|
138
158
|
bytes;
|
|
159
|
+
view;
|
|
139
160
|
constructor(buf) {
|
|
161
|
+
this.bytes = buf;
|
|
140
162
|
this.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
141
|
-
this.bytes = new Uint8Array(this.view.buffer, buf.byteOffset, buf.byteLength);
|
|
142
163
|
}
|
|
143
164
|
readUInt8() {
|
|
144
|
-
|
|
145
|
-
this.pos += 1;
|
|
146
|
-
return val;
|
|
165
|
+
return this.bytes[this.pos++];
|
|
147
166
|
}
|
|
148
167
|
readUInt32() {
|
|
149
168
|
const val = this.view.getUint32(this.pos);
|
|
150
169
|
this.pos += 4;
|
|
151
170
|
return val;
|
|
152
171
|
}
|
|
153
|
-
readUInt64() {
|
|
154
|
-
const val = this.view.getBigUint64(this.pos);
|
|
155
|
-
this.pos += 8;
|
|
156
|
-
return val;
|
|
157
|
-
}
|
|
158
172
|
readUVarint() {
|
|
159
173
|
let val = 0;
|
|
160
174
|
while (true) {
|
|
161
|
-
|
|
175
|
+
const byte = this.readUInt8();
|
|
162
176
|
if (byte < 0x80) {
|
|
163
177
|
return val + byte;
|
|
164
178
|
}
|
|
@@ -166,8 +180,8 @@ export class Reader {
|
|
|
166
180
|
}
|
|
167
181
|
}
|
|
168
182
|
readVarint() {
|
|
169
|
-
const val =
|
|
170
|
-
return
|
|
183
|
+
const val = this.readUVarint();
|
|
184
|
+
return (val >>> 1) ^ -(val & 1);
|
|
171
185
|
}
|
|
172
186
|
readFloat() {
|
|
173
187
|
const val = this.view.getFloat32(this.pos, true);
|
|
@@ -176,14 +190,13 @@ export class Reader {
|
|
|
176
190
|
}
|
|
177
191
|
readBits(numBits) {
|
|
178
192
|
const numBytes = Math.ceil(numBits / 8);
|
|
179
|
-
const bytes = this.bytes.slice(this.pos, this.pos + numBytes);
|
|
180
193
|
const bits = [];
|
|
181
|
-
for (
|
|
182
|
-
|
|
183
|
-
|
|
194
|
+
for (let i = 0; i < numBytes; i++) {
|
|
195
|
+
const byte = this.readUInt8();
|
|
196
|
+
for (let j = 0; j < 8 && bits.length < numBits; j++) {
|
|
197
|
+
bits.push(((byte >> j) & 1) === 1);
|
|
184
198
|
}
|
|
185
199
|
}
|
|
186
|
-
this.pos += numBytes;
|
|
187
200
|
return bits;
|
|
188
201
|
}
|
|
189
202
|
readStringAscii(len) {
|
|
@@ -192,12 +205,12 @@ export class Reader {
|
|
|
192
205
|
}
|
|
193
206
|
let val = "";
|
|
194
207
|
for (let i = 0; i < len; i++) {
|
|
195
|
-
val += String.fromCharCode(this.
|
|
208
|
+
val += String.fromCharCode(this.readUInt8());
|
|
196
209
|
}
|
|
197
210
|
return val;
|
|
198
211
|
}
|
|
199
212
|
readStringUtf8(len) {
|
|
200
|
-
if (len
|
|
213
|
+
if (len == null) {
|
|
201
214
|
len = this.readUVarint();
|
|
202
215
|
}
|
|
203
216
|
if (len === 0) {
|
|
@@ -213,6 +226,6 @@ export class Reader {
|
|
|
213
226
|
return bytes;
|
|
214
227
|
}
|
|
215
228
|
remaining() {
|
|
216
|
-
return this.
|
|
229
|
+
return this.bytes.length - this.pos;
|
|
217
230
|
}
|
|
218
231
|
}
|