@btc-vision/transaction 1.2.15 → 1.3.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/browser/_version.d.ts +1 -1
- package/browser/buffer/BinaryReader.d.ts +22 -20
- package/browser/buffer/BinaryWriter.d.ts +12 -17
- package/browser/index.js +1 -1
- package/browser/keypair/Address.d.ts +1 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/buffer/BinaryReader.d.ts +22 -20
- package/build/buffer/BinaryReader.js +134 -113
- package/build/buffer/BinaryWriter.d.ts +12 -17
- package/build/buffer/BinaryWriter.js +60 -82
- package/build/keypair/Address.d.ts +1 -0
- package/build/keypair/Address.js +3 -0
- package/package.json +15 -15
- package/src/_version.ts +1 -1
- package/src/buffer/BinaryReader.ts +230 -173
- package/src/buffer/BinaryWriter.ts +57 -93
- package/src/keypair/Address.ts +4 -0
|
@@ -14,13 +14,13 @@ import { BufferLike, i32, Selector, u16, u32, u8 } from '../utils/types.js';
|
|
|
14
14
|
|
|
15
15
|
export class BinaryReader {
|
|
16
16
|
private buffer: DataView;
|
|
17
|
-
|
|
18
17
|
private currentOffset: i32 = 0;
|
|
19
18
|
|
|
20
19
|
constructor(bytes: BufferLike) {
|
|
21
20
|
this.buffer = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
22
21
|
}
|
|
23
22
|
|
|
23
|
+
// Helpers for comparisons; unchanged
|
|
24
24
|
public static stringCompare(a: string, b: string): number {
|
|
25
25
|
return a.localeCompare(b);
|
|
26
26
|
}
|
|
@@ -39,246 +39,280 @@ export class BinaryReader {
|
|
|
39
39
|
|
|
40
40
|
public setBuffer(bytes: BufferLike): void {
|
|
41
41
|
this.buffer = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
42
|
-
|
|
43
42
|
this.currentOffset = 0;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Reads a single unsigned byte (u8).
|
|
47
|
+
*/
|
|
48
|
+
public readU8(): u8 {
|
|
49
|
+
this.verifyEnd(this.currentOffset + U8_BYTE_LENGTH);
|
|
50
|
+
const value = this.buffer.getUint8(this.currentOffset);
|
|
51
|
+
this.currentOffset += U8_BYTE_LENGTH;
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
49
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Reads an unsigned 16-bit integer. By default, big-endian.
|
|
57
|
+
* @param be - Endianness; true means big-endian (the default).
|
|
58
|
+
*/
|
|
59
|
+
public readU16(be: boolean = true): u16 {
|
|
60
|
+
this.verifyEnd(this.currentOffset + U16_BYTE_LENGTH);
|
|
61
|
+
const value = this.buffer.getUint16(this.currentOffset, !be);
|
|
62
|
+
this.currentOffset += U16_BYTE_LENGTH;
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Reads an unsigned 32-bit integer. By default, big-endian.
|
|
68
|
+
* @param be - Endianness; true means big-endian (the default).
|
|
69
|
+
*/
|
|
70
|
+
public readU32(be: boolean = true): u32 {
|
|
71
|
+
this.verifyEnd(this.currentOffset + U32_BYTE_LENGTH);
|
|
72
|
+
const value = this.buffer.getUint32(this.currentOffset, !be);
|
|
73
|
+
this.currentOffset += U32_BYTE_LENGTH;
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Reads an unsigned 64-bit integer. By default, big-endian.
|
|
79
|
+
* @param be - Endianness; true means big-endian (the default).
|
|
80
|
+
*/
|
|
81
|
+
public readU64(be: boolean = true): bigint {
|
|
82
|
+
this.verifyEnd(this.currentOffset + U64_BYTE_LENGTH);
|
|
83
|
+
const value = this.buffer.getBigUint64(this.currentOffset, !be);
|
|
84
|
+
this.currentOffset += U64_BYTE_LENGTH;
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Reads a 128-bit unsigned integer. By default, read big-endian.
|
|
90
|
+
* @param be - Endianness; true => big-endian (default).
|
|
91
|
+
*/
|
|
92
|
+
public readU128(be: boolean = true): bigint {
|
|
93
|
+
const raw = this.readBytes(U128_BYTE_LENGTH);
|
|
94
|
+
let bytes = raw;
|
|
95
|
+
// If data was written in little-endian, we reverse before interpreting
|
|
96
|
+
if (!be) {
|
|
97
|
+
bytes = this.reverseBytes(raw);
|
|
98
|
+
}
|
|
99
|
+
return BigInt('0x' + this.toHexString(bytes));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Reads a 256-bit unsigned integer. Same approach as readU128.
|
|
104
|
+
* @param be - Endianness; true => big-endian (default).
|
|
105
|
+
*/
|
|
106
|
+
public readU256(be: boolean = true): bigint {
|
|
107
|
+
const raw = this.readBytes(U256_BYTE_LENGTH);
|
|
108
|
+
let bytes = raw;
|
|
109
|
+
if (!be) {
|
|
110
|
+
bytes = this.reverseBytes(raw);
|
|
111
|
+
}
|
|
112
|
+
return BigInt('0x' + this.toHexString(bytes));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Reads a 128-bit signed integer. Interpret the sign bit if big-endian.
|
|
117
|
+
* @param be - Endianness; true => big-endian (default).
|
|
118
|
+
*/
|
|
119
|
+
public readI128(be: boolean = true): bigint {
|
|
120
|
+
const raw = this.readBytes(I128_BYTE_LENGTH);
|
|
121
|
+
let bytes = raw;
|
|
122
|
+
if (!be) {
|
|
123
|
+
bytes = this.reverseBytes(raw);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Construct as a 128-bit two's complement
|
|
127
|
+
let value = BigInt('0x' + this.toHexString(bytes));
|
|
128
|
+
|
|
129
|
+
// If the top bit is set (sign bit in big-endian), interpret negative
|
|
130
|
+
const signBitMask = 0x80;
|
|
131
|
+
if (bytes[0] & signBitMask) {
|
|
132
|
+
// (1 << 128)
|
|
133
|
+
const twoTo128 = BigInt(1) << BigInt(128);
|
|
134
|
+
// 2's complement
|
|
135
|
+
value = value - twoTo128;
|
|
136
|
+
}
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Read a boolean (u8 != 0).
|
|
142
|
+
*/
|
|
143
|
+
public readBoolean(): boolean {
|
|
144
|
+
return this.readU8() !== 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Reads 32 bits
|
|
149
|
+
*/
|
|
150
|
+
public readSelector(): Selector {
|
|
151
|
+
return this.readU32(true);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Reads a raw sequence of bytes (length must be known).
|
|
156
|
+
* If zeroStop = true, stops if we encounter 0x00 early.
|
|
157
|
+
*/
|
|
158
|
+
public readBytes(length: u32, zeroStop: boolean = false): Uint8Array {
|
|
159
|
+
this.verifyEnd(this.currentOffset + length);
|
|
160
|
+
let bytes = new Uint8Array(length);
|
|
161
|
+
|
|
162
|
+
for (let i: u32 = 0; i < length; i++) {
|
|
163
|
+
const b = this.buffer.getUint8(this.currentOffset++);
|
|
164
|
+
if (zeroStop && b === 0) {
|
|
165
|
+
bytes = bytes.subarray(0, i);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
bytes[i] = b;
|
|
169
|
+
}
|
|
170
|
+
return bytes;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Reads a string of the given length in raw bytes. By default, do NOT zero-stop
|
|
175
|
+
* (matching how we wrote the raw bytes).
|
|
176
|
+
*/
|
|
177
|
+
public readString(length: u16): string {
|
|
178
|
+
const textDecoder = new TextDecoder();
|
|
179
|
+
const bytes = this.readBytes(length, false);
|
|
180
|
+
return textDecoder.decode(bytes);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Reads a string that was written as [u16 length][raw bytes].
|
|
185
|
+
*/
|
|
186
|
+
public readStringWithLength(be: boolean = true): string {
|
|
187
|
+
const length = this.readU16(be);
|
|
188
|
+
return this.readString(length);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Reads an address.
|
|
193
|
+
*/
|
|
194
|
+
public readAddress(): Address {
|
|
195
|
+
const bytes: u8[] = Array.from(this.readBytes(ADDRESS_BYTE_LENGTH));
|
|
196
|
+
return new Address(bytes);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Reads bytes written as [u32 length][bytes].
|
|
201
|
+
* @param maxLength if > 0, enforces an upper bound
|
|
202
|
+
* @param be
|
|
203
|
+
*/
|
|
204
|
+
public readBytesWithLength(maxLength: number = 0, be: boolean = true): Uint8Array {
|
|
205
|
+
const length = this.readU32(be);
|
|
206
|
+
if (maxLength > 0 && length > maxLength) {
|
|
207
|
+
throw new Error('Data length exceeds maximum length.');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return this.readBytes(length);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ------------------ Array readers ------------------ //
|
|
214
|
+
|
|
215
|
+
public readAddressArray(be: boolean = true): Address[] {
|
|
216
|
+
const length = this.readU16(be);
|
|
217
|
+
const result: Address[] = new Array<Address>(length);
|
|
50
218
|
for (let i = 0; i < length; i++) {
|
|
51
219
|
result[i] = this.readAddress();
|
|
52
220
|
}
|
|
53
|
-
|
|
54
221
|
return result;
|
|
55
222
|
}
|
|
56
223
|
|
|
57
|
-
public readU256Array(): bigint[] {
|
|
58
|
-
const length = this.readU16();
|
|
224
|
+
public readU256Array(be: boolean = true): bigint[] {
|
|
225
|
+
const length = this.readU16(be);
|
|
59
226
|
const result: bigint[] = new Array<bigint>(length);
|
|
60
|
-
|
|
61
227
|
for (let i = 0; i < length; i++) {
|
|
62
|
-
result[i] = this.readU256();
|
|
228
|
+
result[i] = this.readU256(be);
|
|
63
229
|
}
|
|
64
|
-
|
|
65
230
|
return result;
|
|
66
231
|
}
|
|
67
232
|
|
|
68
|
-
public readU128Array(): bigint[] {
|
|
69
|
-
const length = this.readU16();
|
|
233
|
+
public readU128Array(be: boolean = true): bigint[] {
|
|
234
|
+
const length = this.readU16(be);
|
|
70
235
|
const result: bigint[] = new Array<bigint>(length);
|
|
71
|
-
|
|
72
236
|
for (let i = 0; i < length; i++) {
|
|
73
|
-
result[i] = this.readU128();
|
|
237
|
+
result[i] = this.readU128(be);
|
|
74
238
|
}
|
|
75
|
-
|
|
76
239
|
return result;
|
|
77
240
|
}
|
|
78
241
|
|
|
79
|
-
public readU64Array(): bigint[] {
|
|
80
|
-
const length = this.readU16();
|
|
242
|
+
public readU64Array(be: boolean = true): bigint[] {
|
|
243
|
+
const length = this.readU16(be);
|
|
81
244
|
const result: bigint[] = new Array<bigint>(length);
|
|
82
|
-
|
|
83
245
|
for (let i = 0; i < length; i++) {
|
|
84
|
-
result[i] = this.readU64();
|
|
246
|
+
result[i] = this.readU64(be);
|
|
85
247
|
}
|
|
86
|
-
|
|
87
248
|
return result;
|
|
88
249
|
}
|
|
89
250
|
|
|
90
|
-
public readU32Array(): u32[] {
|
|
91
|
-
const length = this.readU16();
|
|
251
|
+
public readU32Array(be: boolean = true): u32[] {
|
|
252
|
+
const length = this.readU16(be);
|
|
92
253
|
const result: u32[] = new Array<u32>(length);
|
|
93
|
-
|
|
94
254
|
for (let i = 0; i < length; i++) {
|
|
95
|
-
result[i] = this.readU32();
|
|
255
|
+
result[i] = this.readU32(be);
|
|
96
256
|
}
|
|
97
|
-
|
|
98
257
|
return result;
|
|
99
258
|
}
|
|
100
259
|
|
|
101
|
-
public readU16Array(): u16[] {
|
|
102
|
-
const length = this.readU16();
|
|
260
|
+
public readU16Array(be: boolean = true): u16[] {
|
|
261
|
+
const length = this.readU16(be);
|
|
103
262
|
const result: u16[] = new Array<u16>(length);
|
|
104
|
-
|
|
105
263
|
for (let i = 0; i < length; i++) {
|
|
106
|
-
result[i] = this.readU16();
|
|
264
|
+
result[i] = this.readU16(be);
|
|
107
265
|
}
|
|
108
|
-
|
|
109
266
|
return result;
|
|
110
267
|
}
|
|
111
268
|
|
|
112
269
|
public readU8Array(): u8[] {
|
|
113
|
-
const length = this.readU16();
|
|
270
|
+
const length = this.readU16(true); // by default big-endian
|
|
114
271
|
const result: u8[] = new Array<u8>(length);
|
|
115
|
-
|
|
116
272
|
for (let i = 0; i < length; i++) {
|
|
117
273
|
result[i] = this.readU8();
|
|
118
274
|
}
|
|
119
|
-
|
|
120
275
|
return result;
|
|
121
276
|
}
|
|
122
277
|
|
|
123
|
-
public readStringArray(): string[] {
|
|
124
|
-
const length = this.readU16();
|
|
278
|
+
public readStringArray(be: boolean = true): string[] {
|
|
279
|
+
const length = this.readU16(be);
|
|
125
280
|
const result: string[] = new Array<string>(length);
|
|
126
|
-
|
|
127
281
|
for (let i = 0; i < length; i++) {
|
|
128
|
-
result[i] = this.readStringWithLength();
|
|
282
|
+
result[i] = this.readStringWithLength(be);
|
|
129
283
|
}
|
|
130
|
-
|
|
131
284
|
return result;
|
|
132
285
|
}
|
|
133
286
|
|
|
134
|
-
public readBytesArray(): Uint8Array[] {
|
|
135
|
-
const length = this.readU16();
|
|
287
|
+
public readBytesArray(be: boolean = true): Uint8Array[] {
|
|
288
|
+
const length = this.readU16(be);
|
|
136
289
|
const result: Uint8Array[] = new Array<Uint8Array>(length);
|
|
137
|
-
|
|
138
290
|
for (let i = 0; i < length; i++) {
|
|
139
|
-
result[i] = this.readBytesWithLength();
|
|
291
|
+
result[i] = this.readBytesWithLength(0, be);
|
|
140
292
|
}
|
|
141
|
-
|
|
142
293
|
return result;
|
|
143
294
|
}
|
|
144
295
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return this.readBytes(length);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
public readU8(): u8 {
|
|
156
|
-
this.verifyEnd(this.currentOffset + U8_BYTE_LENGTH);
|
|
157
|
-
|
|
158
|
-
const value = this.buffer.getUint8(this.currentOffset);
|
|
159
|
-
this.currentOffset += U8_BYTE_LENGTH;
|
|
160
|
-
|
|
161
|
-
return value;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
public readU16(): u16 {
|
|
165
|
-
this.verifyEnd(this.currentOffset + U16_BYTE_LENGTH);
|
|
166
|
-
|
|
167
|
-
const value = this.buffer.getUint16(this.currentOffset, true);
|
|
168
|
-
this.currentOffset += U16_BYTE_LENGTH;
|
|
169
|
-
|
|
170
|
-
return value;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
public readU32(le: boolean = true): u32 {
|
|
174
|
-
this.verifyEnd(this.currentOffset + U32_BYTE_LENGTH);
|
|
175
|
-
|
|
176
|
-
const value = this.buffer.getUint32(this.currentOffset, le);
|
|
177
|
-
this.currentOffset += U32_BYTE_LENGTH;
|
|
178
|
-
|
|
179
|
-
return value;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
public readU64(): bigint {
|
|
183
|
-
this.verifyEnd(this.currentOffset + U64_BYTE_LENGTH);
|
|
184
|
-
|
|
185
|
-
const value: bigint = this.buffer.getBigUint64(this.currentOffset, true);
|
|
186
|
-
this.currentOffset += U64_BYTE_LENGTH;
|
|
187
|
-
|
|
188
|
-
return value;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
public readAddressValueTuple(): AddressMap<bigint> {
|
|
192
|
-
const length = this.readU16();
|
|
296
|
+
/**
|
|
297
|
+
* Reads [u16 length][ (address, u256) pairs ].
|
|
298
|
+
*/
|
|
299
|
+
public readAddressValueTuple(be: boolean = true): AddressMap<bigint> {
|
|
300
|
+
const length = this.readU16(be);
|
|
193
301
|
const result = new AddressMap<bigint>();
|
|
194
302
|
|
|
195
303
|
for (let i = 0; i < length; i++) {
|
|
196
304
|
const address = this.readAddress();
|
|
197
|
-
const value = this.readU256();
|
|
198
|
-
|
|
199
|
-
if (result.has(address)) throw new Error('Duplicate address found in map');
|
|
305
|
+
const value = this.readU256(be);
|
|
200
306
|
|
|
307
|
+
if (result.has(address)) {
|
|
308
|
+
throw new Error('Duplicate address found in map');
|
|
309
|
+
}
|
|
201
310
|
result.set(address, value);
|
|
202
311
|
}
|
|
203
|
-
|
|
204
312
|
return result;
|
|
205
313
|
}
|
|
206
314
|
|
|
207
|
-
|
|
208
|
-
const next16Bytes = this.readBytes(U128_BYTE_LENGTH);
|
|
209
|
-
|
|
210
|
-
return BigInt(
|
|
211
|
-
'0x' + next16Bytes.reduce((acc, byte) => acc + byte.toString(16).padStart(2, '0'), ''),
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
public readU256(): bigint {
|
|
216
|
-
const next32Bytes = this.readBytes(U256_BYTE_LENGTH);
|
|
217
|
-
|
|
218
|
-
return BigInt(
|
|
219
|
-
'0x' + next32Bytes.reduce((acc, byte) => acc + byte.toString(16).padStart(2, '0'), ''),
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
readI128() {
|
|
224
|
-
const next16Bytes = this.readBytes(I128_BYTE_LENGTH);
|
|
225
|
-
let value = BigInt(
|
|
226
|
-
'0x' + next16Bytes.reduce((acc, byte) => acc + byte.toString(16).padStart(2, '0'), ''),
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
if (next16Bytes[0] & 0x80) {
|
|
230
|
-
const mask = (BigInt(1) << BigInt(128)) - BigInt(1);
|
|
231
|
-
value = (value ^ mask) + BigInt(1);
|
|
232
|
-
value = -value;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return value;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
public readBytes(length: u32, zeroStop: boolean = false): Uint8Array {
|
|
239
|
-
let bytes: Uint8Array = new Uint8Array(length);
|
|
240
|
-
for (let i: u32 = 0; i < length; i++) {
|
|
241
|
-
const byte: u8 = this.readU8();
|
|
242
|
-
if (zeroStop && byte === 0) {
|
|
243
|
-
bytes = bytes.slice(0, i);
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
bytes[i] = byte;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
return bytes;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
public readString(length: u16): string {
|
|
254
|
-
const textDecoder = new TextDecoder();
|
|
255
|
-
const bytes = this.readBytes(length, true);
|
|
256
|
-
|
|
257
|
-
return textDecoder.decode(bytes);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
public readSelector(): Selector {
|
|
261
|
-
return this.readU32(false);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
public readStringWithLength(): string {
|
|
265
|
-
const length = this.readU16();
|
|
266
|
-
|
|
267
|
-
return this.readString(length);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
public readBoolean(): boolean {
|
|
271
|
-
return this.readU8() !== 0;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
public readAddress(): Address {
|
|
275
|
-
const bytes: u8[] = new Array<u8>(ADDRESS_BYTE_LENGTH);
|
|
276
|
-
for (let i: u32 = 0; i < ADDRESS_BYTE_LENGTH; i++) {
|
|
277
|
-
bytes[i] = this.readU8();
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return new Address(bytes);
|
|
281
|
-
}
|
|
315
|
+
// --------------------------------------------------- //
|
|
282
316
|
|
|
283
317
|
public getOffset(): u16 {
|
|
284
318
|
return this.currentOffset;
|
|
@@ -288,9 +322,32 @@ export class BinaryReader {
|
|
|
288
322
|
this.currentOffset = offset;
|
|
289
323
|
}
|
|
290
324
|
|
|
325
|
+
/**
|
|
326
|
+
* Verifies we have enough bytes in the buffer to read up to `size`.
|
|
327
|
+
*/
|
|
291
328
|
public verifyEnd(size: i32): void {
|
|
292
|
-
if (
|
|
293
|
-
throw new Error(
|
|
329
|
+
if (size > this.buffer.byteLength) {
|
|
330
|
+
throw new Error(
|
|
331
|
+
`Attempt to read beyond buffer length: requested up to byte offset ${size}, but buffer is only ${this.buffer.byteLength} bytes.`,
|
|
332
|
+
);
|
|
294
333
|
}
|
|
295
334
|
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Utility: reverses a byte array in-place or returns a reversed copy.
|
|
338
|
+
*/
|
|
339
|
+
private reverseBytes(bytes: Uint8Array): Uint8Array {
|
|
340
|
+
const out = new Uint8Array(bytes.length);
|
|
341
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
342
|
+
out[i] = bytes[bytes.length - 1 - i];
|
|
343
|
+
}
|
|
344
|
+
return out;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Utility: turn bytes into a hex string without `0x` prefix.
|
|
349
|
+
*/
|
|
350
|
+
private toHexString(bytes: Uint8Array): string {
|
|
351
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
352
|
+
}
|
|
296
353
|
}
|