@andrew_l/tl-pack 0.0.2 → 0.0.4
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/BinaryReader.d.ts +7 -1
- package/dist/BinaryReader.js +34 -9
- package/dist/BinaryWriter.d.ts +8 -1
- package/dist/BinaryWriter.js +62 -12
- package/dist/extension.d.ts +11 -0
- package/dist/extension.js +10 -0
- package/dist/helpers.js +23 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/package.json +1 -1
package/dist/BinaryReader.d.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { TLExtension } from './extension.js';
|
|
3
|
+
export interface BinaryReaderOptions {
|
|
4
|
+
extensions?: TLExtension[];
|
|
5
|
+
}
|
|
2
6
|
export declare class BinaryReader {
|
|
3
7
|
private target;
|
|
4
8
|
private targetView;
|
|
5
9
|
private _last?;
|
|
6
10
|
private _dict;
|
|
11
|
+
private extensions;
|
|
7
12
|
offset: number;
|
|
8
13
|
length: number;
|
|
9
14
|
/**
|
|
10
15
|
* Small utility class to read binary data.
|
|
11
16
|
* @param data {Buffer}
|
|
12
17
|
*/
|
|
13
|
-
constructor(data: Buffer | Uint8Array);
|
|
18
|
+
constructor(data: Buffer | Uint8Array, options?: BinaryReaderOptions);
|
|
14
19
|
readByte(): number;
|
|
15
20
|
readInt32(signed?: boolean): number;
|
|
16
21
|
readInt16(signed?: boolean): number;
|
|
@@ -61,6 +66,7 @@ export declare class BinaryReader {
|
|
|
61
66
|
* Reads a object.
|
|
62
67
|
*/
|
|
63
68
|
readObject(): any;
|
|
69
|
+
private readCore;
|
|
64
70
|
readDictionary(): string | null;
|
|
65
71
|
readMap(checkConstructor?: boolean): Record<string, any>;
|
|
66
72
|
decode(value: Buffer | Uint8Array): any;
|
package/dist/BinaryReader.js
CHANGED
|
@@ -5,19 +5,26 @@ export class BinaryReader {
|
|
|
5
5
|
targetView;
|
|
6
6
|
_last;
|
|
7
7
|
_dict;
|
|
8
|
+
extensions;
|
|
8
9
|
offset;
|
|
9
10
|
length;
|
|
10
11
|
/**
|
|
11
12
|
* Small utility class to read binary data.
|
|
12
13
|
* @param data {Buffer}
|
|
13
14
|
*/
|
|
14
|
-
constructor(data) {
|
|
15
|
+
constructor(data, options) {
|
|
15
16
|
this.target = data;
|
|
16
17
|
this.targetView = new DataView(data.buffer, 0, data.length);
|
|
17
18
|
this._last = undefined;
|
|
18
19
|
this._dict = new Map();
|
|
19
20
|
this.offset = 0;
|
|
20
21
|
this.length = data.length;
|
|
22
|
+
this.extensions = new Map();
|
|
23
|
+
if (options && options.extensions) {
|
|
24
|
+
options.extensions.forEach((ext) => {
|
|
25
|
+
this.extensions.set(ext.token, ext);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
21
28
|
}
|
|
22
29
|
readByte() {
|
|
23
30
|
this.assertRead(1);
|
|
@@ -41,7 +48,7 @@ export class BinaryReader {
|
|
|
41
48
|
this._last = this.targetView.getInt16(this.offset, true);
|
|
42
49
|
}
|
|
43
50
|
else {
|
|
44
|
-
this._last = this.targetView.getUint16(this.offset);
|
|
51
|
+
this._last = this.targetView.getUint16(this.offset, true);
|
|
45
52
|
}
|
|
46
53
|
this.offset += 2;
|
|
47
54
|
return this._last;
|
|
@@ -52,7 +59,7 @@ export class BinaryReader {
|
|
|
52
59
|
this._last = this.targetView.getInt8(this.offset);
|
|
53
60
|
}
|
|
54
61
|
else {
|
|
55
|
-
this._last = this.targetView.
|
|
62
|
+
this._last = this.targetView.getUint8(this.offset);
|
|
56
63
|
}
|
|
57
64
|
this.offset += 1;
|
|
58
65
|
return this._last;
|
|
@@ -162,7 +169,20 @@ export class BinaryReader {
|
|
|
162
169
|
* Reads a object.
|
|
163
170
|
*/
|
|
164
171
|
readObject() {
|
|
172
|
+
const offset = this.offset;
|
|
165
173
|
const constructorId = this.readByte();
|
|
174
|
+
const ext = this.extensions.get(constructorId);
|
|
175
|
+
let value;
|
|
176
|
+
if (ext) {
|
|
177
|
+
value = this.readObject();
|
|
178
|
+
value = ext.decode(value);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
value = this.readCore(constructorId);
|
|
182
|
+
}
|
|
183
|
+
return value;
|
|
184
|
+
}
|
|
185
|
+
readCore(constructorId) {
|
|
166
186
|
switch (constructorId) {
|
|
167
187
|
case CORE_TYPES.None:
|
|
168
188
|
return this.readObject();
|
|
@@ -203,22 +223,27 @@ export class BinaryReader {
|
|
|
203
223
|
}
|
|
204
224
|
readDictionary() {
|
|
205
225
|
const constructorId = this.readByte();
|
|
226
|
+
let key = null;
|
|
206
227
|
switch (constructorId) {
|
|
207
228
|
case CORE_TYPES.DictIndex: {
|
|
208
229
|
const idx = this.readLength();
|
|
209
|
-
|
|
230
|
+
key = this._dict.get(idx);
|
|
231
|
+
break;
|
|
210
232
|
}
|
|
211
233
|
case CORE_TYPES.DictValue: {
|
|
212
|
-
|
|
234
|
+
key = this.readString();
|
|
213
235
|
this._dict.set(this._dict.size + 1, key);
|
|
214
|
-
|
|
236
|
+
break;
|
|
215
237
|
}
|
|
216
238
|
case CORE_TYPES.None: {
|
|
217
|
-
|
|
239
|
+
key = null;
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
default: {
|
|
243
|
+
this.seek(-1);
|
|
218
244
|
}
|
|
219
245
|
}
|
|
220
|
-
|
|
221
|
-
return null;
|
|
246
|
+
return key;
|
|
222
247
|
}
|
|
223
248
|
readMap(checkConstructor = true) {
|
|
224
249
|
if (checkConstructor && this.readByte() !== CORE_TYPES.Map) {
|
package/dist/BinaryWriter.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { TLExtension } from './extension.js';
|
|
3
|
+
export interface BinaryWriterOptions {
|
|
4
|
+
extensions?: TLExtension[];
|
|
5
|
+
}
|
|
2
6
|
export declare class BinaryWriter {
|
|
3
7
|
private target;
|
|
4
8
|
private targetView;
|
|
5
9
|
private dict;
|
|
10
|
+
private extensions;
|
|
6
11
|
offset: number;
|
|
7
|
-
constructor();
|
|
12
|
+
constructor(options?: BinaryWriterOptions);
|
|
8
13
|
allocate(size: number): void;
|
|
9
14
|
makeRoom(end: number): void;
|
|
10
15
|
get safeEnd(): number;
|
|
@@ -25,5 +30,7 @@ export declare class BinaryWriter {
|
|
|
25
30
|
writeMap(object: Record<string, any>): void;
|
|
26
31
|
wireDictionary(value: string): void;
|
|
27
32
|
encode(value: any): Uint8Array | Buffer;
|
|
33
|
+
private _writeCustom;
|
|
28
34
|
writeObject(value: any): void;
|
|
35
|
+
private writeCore;
|
|
29
36
|
}
|
package/dist/BinaryWriter.js
CHANGED
|
@@ -21,11 +21,17 @@ export class BinaryWriter {
|
|
|
21
21
|
target;
|
|
22
22
|
targetView;
|
|
23
23
|
dict;
|
|
24
|
+
extensions;
|
|
24
25
|
offset;
|
|
25
|
-
constructor() {
|
|
26
|
-
this.target = Buffer.alloc(0);
|
|
26
|
+
constructor(options) {
|
|
27
27
|
this.dict = new Map();
|
|
28
28
|
this.offset = 0;
|
|
29
|
+
this.extensions = new Map();
|
|
30
|
+
if (options && options.extensions) {
|
|
31
|
+
options.extensions.forEach((ext) => {
|
|
32
|
+
this.extensions.set(ext.token, ext);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
29
35
|
this.target = byteArrayAllocate(8192);
|
|
30
36
|
this.targetView = new DataView(this.target.buffer, 0, this.target.length);
|
|
31
37
|
}
|
|
@@ -105,7 +111,12 @@ export class BinaryWriter {
|
|
|
105
111
|
}
|
|
106
112
|
writeInt8(value, signed = true) {
|
|
107
113
|
this.allocate(1);
|
|
108
|
-
|
|
114
|
+
if (signed) {
|
|
115
|
+
this.target[this.offset++] = value;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
this.targetView.setUint8(this.offset++, value);
|
|
119
|
+
}
|
|
109
120
|
}
|
|
110
121
|
writeFloat(value) {
|
|
111
122
|
this.allocate(4);
|
|
@@ -150,8 +161,6 @@ export class BinaryWriter {
|
|
|
150
161
|
this.target[start++] = (bytes >> 16) % 256;
|
|
151
162
|
}
|
|
152
163
|
this.offset += bytes;
|
|
153
|
-
// this.target.set(bytes, this.offset);
|
|
154
|
-
// this.offset += bytes.length;
|
|
155
164
|
}
|
|
156
165
|
writeBytes(value) {
|
|
157
166
|
const length = value.length;
|
|
@@ -177,11 +186,18 @@ export class BinaryWriter {
|
|
|
177
186
|
const length = value.length;
|
|
178
187
|
this.writeLength(length);
|
|
179
188
|
for (let i = 0; i < length; i++) {
|
|
180
|
-
|
|
189
|
+
if (value[i] === undefined) {
|
|
190
|
+
this.writeNull();
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
this.writeObject(value[i]);
|
|
194
|
+
}
|
|
181
195
|
}
|
|
182
196
|
}
|
|
183
197
|
writeMap(object) {
|
|
184
198
|
for (const key in object) {
|
|
199
|
+
if (object[key] === undefined)
|
|
200
|
+
continue;
|
|
185
201
|
this.wireDictionary(key);
|
|
186
202
|
this.writeObject(object[key]);
|
|
187
203
|
}
|
|
@@ -190,14 +206,12 @@ export class BinaryWriter {
|
|
|
190
206
|
wireDictionary(value) {
|
|
191
207
|
if (this.dict.has(value)) {
|
|
192
208
|
const idx = this.dict.get(value);
|
|
193
|
-
this.
|
|
194
|
-
this.writeLength(idx);
|
|
209
|
+
this.writeCore(CORE_TYPES.DictIndex, idx);
|
|
195
210
|
}
|
|
196
211
|
else {
|
|
197
212
|
const newIndex = this.dict.size + 1;
|
|
198
213
|
this.dict.set(value, newIndex);
|
|
199
|
-
this.
|
|
200
|
-
this.writeString(value);
|
|
214
|
+
this.writeCore(CORE_TYPES.DictValue, value);
|
|
201
215
|
}
|
|
202
216
|
}
|
|
203
217
|
encode(value) {
|
|
@@ -207,18 +221,54 @@ export class BinaryWriter {
|
|
|
207
221
|
this.offset = start;
|
|
208
222
|
return this.target.subarray(start, end);
|
|
209
223
|
}
|
|
224
|
+
_writeCustom(value) {
|
|
225
|
+
for (const ext of this.extensions.values()) {
|
|
226
|
+
const result = ext.encode(value);
|
|
227
|
+
if (result !== undefined) {
|
|
228
|
+
const constructorId = coreType(result);
|
|
229
|
+
if (constructorId === CORE_TYPES.None) {
|
|
230
|
+
throw new TypeError(`Invalid encode extension = ${ext.token} type of ${value}`);
|
|
231
|
+
}
|
|
232
|
+
if (ext.token !== -1) {
|
|
233
|
+
this.writeByte(ext.token);
|
|
234
|
+
}
|
|
235
|
+
this.writeCore(constructorId, result);
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
210
241
|
writeObject(value) {
|
|
211
242
|
if (value === undefined)
|
|
212
243
|
return;
|
|
213
244
|
const constructorId = coreType(value);
|
|
245
|
+
// console.log('write', {
|
|
246
|
+
// offset: this.offset,
|
|
247
|
+
// constructorId: CORE_TYPES[constructorId],
|
|
248
|
+
// value: String(value),
|
|
249
|
+
// });
|
|
214
250
|
if (constructorId === CORE_TYPES.None) {
|
|
215
|
-
|
|
251
|
+
if (this._writeCustom(value)) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
throw new TypeError(`Invalid core type of ${value}`);
|
|
216
255
|
}
|
|
256
|
+
this.writeCore(constructorId, value);
|
|
257
|
+
}
|
|
258
|
+
writeCore(constructorId, value) {
|
|
217
259
|
if (![CORE_TYPES.BoolFalse, CORE_TYPES.BoolTrue, CORE_TYPES.Null].includes(constructorId)) {
|
|
218
260
|
this.writeByte(constructorId);
|
|
219
261
|
}
|
|
220
262
|
switch (constructorId) {
|
|
221
|
-
case CORE_TYPES.
|
|
263
|
+
case CORE_TYPES.DictIndex: {
|
|
264
|
+
return this.writeLength(value);
|
|
265
|
+
}
|
|
266
|
+
case CORE_TYPES.DictValue: {
|
|
267
|
+
return this.writeString(value);
|
|
268
|
+
}
|
|
269
|
+
case CORE_TYPES.BoolFalse: {
|
|
270
|
+
return this.writeBool(value);
|
|
271
|
+
}
|
|
222
272
|
case CORE_TYPES.BoolTrue: {
|
|
223
273
|
return this.writeBool(value);
|
|
224
274
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type EncodeHandler = (value: any) => string | number | undefined;
|
|
2
|
+
export type DecodeHandler = (value: string | number) => any;
|
|
3
|
+
export interface TLExtension {
|
|
4
|
+
token: number;
|
|
5
|
+
encode: EncodeHandler;
|
|
6
|
+
decode: DecodeHandler;
|
|
7
|
+
}
|
|
8
|
+
export declare function createExtension(token: number, { encode, decode }: {
|
|
9
|
+
encode: EncodeHandler;
|
|
10
|
+
decode: DecodeHandler;
|
|
11
|
+
}): TLExtension;
|
package/dist/helpers.js
CHANGED
|
@@ -95,11 +95,32 @@ export function coreType(value) {
|
|
|
95
95
|
if (Array.isArray(value)) {
|
|
96
96
|
return CORE_TYPES.Vector;
|
|
97
97
|
}
|
|
98
|
-
|
|
99
|
-
if (toString.call(value) === '[object Object]') {
|
|
98
|
+
if (isPlainObject(value)) {
|
|
100
99
|
return CORE_TYPES.Map;
|
|
101
100
|
}
|
|
102
101
|
}
|
|
103
102
|
}
|
|
104
103
|
return CORE_TYPES.None;
|
|
105
104
|
}
|
|
105
|
+
/** @ts-ignore */
|
|
106
|
+
const isObject = (val) => toString.call(val) === '[object Object]';
|
|
107
|
+
function isPlainObject(value) {
|
|
108
|
+
let ctor, prot;
|
|
109
|
+
if (!isObject(value))
|
|
110
|
+
return false;
|
|
111
|
+
// If it has modified constructor
|
|
112
|
+
ctor = value.constructor;
|
|
113
|
+
if (ctor === undefined)
|
|
114
|
+
return true;
|
|
115
|
+
// If it has modified prototype
|
|
116
|
+
prot = ctor.prototype;
|
|
117
|
+
if (isObject(prot) === false)
|
|
118
|
+
return false;
|
|
119
|
+
// If constructor does not have an Object-specific method
|
|
120
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
121
|
+
if (prot.hasOwnProperty('isPrototypeOf') === false) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
// Most likely a plain Object
|
|
125
|
+
return true;
|
|
126
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED