bireader 1.0.14 → 1.0.17

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.
@@ -1,44 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.bireader = void 0;
4
+ const common_1 = require("./common");
4
5
  /**
6
+ * Binary reader, includes bitfields and strings
5
7
  *
6
- * byte reader, includes bitfields and strings
7
- *
8
- * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```
9
- * @param {number} byteOffset - byte offset to start reader, default is 0
10
- * @param {number} bitOffset - bit offset to start reader, 0-7
11
- * @param {string} endianness - endianness ```big``` or ```little``` (default ```little```)
8
+ * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```. Always found in ``biwriter.data``
9
+ * @param {number} byteOffset - Byte offset to start reader (default 0)
10
+ * @param {number} bitOffset - Bit offset 0-7 to start reader (default 0)
11
+ * @param {string} endianness - Endianness ```big``` or ```little``` (default ```little```)
12
+ * @param {boolean} strict - Strict mode: if true does not extend supplied array on outside write (default true)
12
13
  */
13
14
  class bireader {
14
- check_size(read_size, read_bits) {
15
- const new_off = this.offset + (read_size || 0) + Math.ceil((this.bitoffset + (read_bits || 0)) / 8);
16
- if (new_off > this.size) {
17
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
18
- throw new Error(`Reader reached end of data: reading to ` + new_off + " at " + this.offset + " of " + this.size);
19
- }
20
- }
21
15
  isBuffer(obj) {
22
- return (typeof Buffer !== 'undefined' && obj instanceof Buffer);
16
+ return (0, common_1.buffcheck)(obj);
23
17
  }
24
18
  isBufferOrUint8Array(obj) {
25
- return obj instanceof Uint8Array || this.isBuffer(obj);
19
+ return (0, common_1.arraybuffcheck)(this, obj);
20
+ }
21
+ extendArray(to_padd) {
22
+ return (0, common_1.extendarray)(this, to_padd);
23
+ }
24
+ check_size(write_bytes, write_bit, offset) {
25
+ return (0, common_1.checkSize)(this, write_bytes || 0, write_bit || 0, offset || this.offset);
26
26
  }
27
27
  /**
28
+ * Binary reader, includes bitfields and strings
28
29
  *
29
- * byte reader, includes bitfields and strings
30
- *
31
- * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```
32
- * @param {number} byteOffset - byte offset to start reader, default is 0
33
- * @param {number} bitOffset - bit offset to start reader, 0-7
34
- * @param {string} endianness - endianness ```big``` or ```little``` (default ```little```)
30
+ * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```. Always found in ``biwriter.data``
31
+ * @param {number} byteOffset - Byte offset to start reader (default 0)
32
+ * @param {number} bitOffset - Bit offset 0-7 to start reader (default 0)
33
+ * @param {string} endianness - Endianness ```big``` or ```little``` (default ```little```)
34
+ * @param {boolean} strict - Strict mode: if true does not extend supplied array on outside write (default true)
35
35
  */
36
- constructor(data, byteOffset, bitOffset, endianness) {
36
+ constructor(data, byteOffset, bitOffset, endianness, strict) {
37
37
  this.endian = "little";
38
38
  this.offset = 0;
39
39
  this.bitoffset = 0;
40
40
  this.size = 0;
41
+ this.strict = false;
41
42
  this.errorDump = true;
43
+ this.data = [];
42
44
  if (endianness != undefined && typeof endianness != "string") {
43
45
  throw new Error("Endian must be big or little");
44
46
  }
@@ -57,6 +59,14 @@ class bireader {
57
59
  if (bitOffset != undefined) {
58
60
  this.bitoffset = bitOffset % 8;
59
61
  }
62
+ if (typeof strict == "boolean") {
63
+ this.strict = strict;
64
+ }
65
+ else {
66
+ if (strict != undefined) {
67
+ throw new Error("Strict mode must be true of false");
68
+ }
69
+ }
60
70
  if (data == undefined) {
61
71
  throw new Error("Data required");
62
72
  }
@@ -121,126 +131,98 @@ class bireader {
121
131
  le() {
122
132
  this.endianness("little");
123
133
  }
134
+ //
135
+ // move from current position
136
+ //
124
137
  /**
125
- * Move current read byte or bit position
138
+ * Offset current byte or bit position
139
+ * Note: Will extend array if strict mode is off and outside of max size
126
140
  *
127
- * @param {number} bytes - bytes to skip
128
- * @param {number} bits - bits to skip
141
+ * @param {number} bytes - Bytes to skip
142
+ * @param {number} bits - Bits to skip (0-7)
129
143
  */
130
144
  skip(bytes, bits) {
131
- this.check_size(bytes || 0);
132
- if ((((bytes || 0) + this.offset) + Math.ceil((this.bitoffset + (bits || 0)) / 8)) > this.size) {
133
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
134
- throw new Error("Seek outside of size of data: " + this.size);
135
- }
136
- this.bitoffset += (bits || 0) % 8;
137
- this.offset += (bytes || 0);
145
+ return (0, common_1.skip)(this, bytes, bits);
138
146
  }
139
147
  /**
140
- * Move current read byte or bit position
148
+ * Offset current byte or bit position
149
+ * Note: Will extend array if strict mode is off and outside of max size
141
150
  *
142
- * @param {number} bytes - bytes to skip
143
- * @param {number} bits - bits to skip
151
+ * @param {number} bytes - Bytes to skip
152
+ * @param {number} bits - Bits to skip (0-7)
144
153
  */
145
- fskip(bytes, bits) {
154
+ jump(bytes, bits) {
146
155
  this.skip(bytes, bits);
147
156
  }
157
+ //
158
+ // directly set current position
159
+ //
148
160
  /**
149
- * Change current byte or bit read position
161
+ * Change position directly to address
162
+ * Note: Will extend array if strict mode is off and outside of max size
150
163
  *
151
- * @param {number} byte - byte to jump to
152
- * @param {number} bit - bit to jump to (0-7)
164
+ * @param {number} byte - byte to set to
165
+ * @param {number} bit - bit to set to (0-7)
153
166
  */
154
167
  goto(byte, bit) {
155
- const new_size = (byte + Math.ceil((bit || 0) / 8));
156
- if (new_size > this.size) {
157
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
158
- throw new Error("Goto outside of size of data: goto " + new_size + " of " + this.size);
159
- }
160
- this.offset = byte;
161
- this.bitoffset = (bit || 0) % 8;
168
+ return (0, common_1.goto)(this, byte, bit);
162
169
  }
163
170
  /**
164
- * Change current byte or bit read position
171
+ * Change position directly to address
172
+ * Note: Will extend array if strict mode is off and outside of max size
165
173
  *
166
- * @param {number} byte - byte to jump to
167
- * @param {number} bit - bit to jump to (0-7)
174
+ * @param {number} byte - byte to set to
175
+ * @param {number} bit - bit to set to (0-7)
168
176
  */
169
177
  seek(byte, bit) {
170
- this.goto(byte, bit);
171
- }
172
- /**
173
- * Change current byte or bit read position
174
- *
175
- * @param {number} byte - byte to jump to
176
- * @param {number} bit - bit to jump to (0-7)
177
- */
178
- fseek(byte, bit) {
179
- this.goto(byte, bit);
178
+ return this.goto(byte, bit);
180
179
  }
181
180
  /**
182
- * Change current byte or bit read position
181
+ * Change position directly to address
182
+ * Note: Will extend array if strict mode is off and outside of max size
183
183
  *
184
- * @param {number} byte - byte to jump to
185
- * @param {number} bit - bit to jump to (0-7)
186
- */
187
- jump(byte, bit) {
188
- this.goto(byte, bit);
189
- }
190
- /**
191
- * Change current byte or bit read position
192
- *
193
- * @param {number} byte - byte to jump to
194
- * @param {number} bit - bit to jump to (0-7)
184
+ * @param {number} byte - byte to set to
185
+ * @param {number} bit - bit to set to (0-7)
195
186
  */
196
187
  pointer(byte, bit) {
197
- this.goto(byte, bit);
188
+ return this.goto(byte, bit);
198
189
  }
199
190
  /**
200
- * Change current byte or bit read position
191
+ * Change position directly to address
192
+ * Note: Will extend array if strict mode is off and outside of max size
201
193
  *
202
- * @param {number} byte - byte to jump to
203
- * @param {number} bit - bit to jump to (0-7)
194
+ * @param {number} byte - byte to set to
195
+ * @param {number} bit - bit to set to (0-7)
204
196
  */
205
197
  warp(byte, bit) {
206
- this.goto(byte, bit);
207
- }
208
- /**
209
- * Change current byte or bit read position
210
- *
211
- * @param {number} byte - byte to jump to
212
- * @param {number} bit - bit to jump to (0-7)
213
- */
214
- fsetpos(byte, bit) {
215
- this.goto(byte, bit);
198
+ return this.goto(byte, bit);
216
199
  }
200
+ //
201
+ //go to start
202
+ //
217
203
  /**
218
- * Set offset to start of file
204
+ * Set byte and bit position to start of data
219
205
  */
220
206
  rewind() {
221
207
  this.offset = 0;
222
208
  this.bitoffset = 0;
223
209
  }
224
210
  /**
225
- * Set offset to start of file
211
+ * Set byte and bit position to start of data
226
212
  */
227
213
  gotostart() {
228
214
  this.offset = 0;
229
215
  this.bitoffset = 0;
230
216
  }
231
- /**
232
- * Set offset to start of file
233
- */
234
- tostart() {
235
- this.offset = 0;
236
- this.bitoffset = 0;
237
- }
217
+ //
218
+ //get position
219
+ //
238
220
  /**
239
221
  * Get the current byte position
240
222
  *
241
223
  * @return {number} current byte position
242
224
  */
243
- ftell() {
225
+ tell() {
244
226
  return this.offset;
245
227
  }
246
228
  /**
@@ -248,7 +230,7 @@ class bireader {
248
230
  *
249
231
  * @return {number} current byte position
250
232
  */
251
- tell() {
233
+ getOffset() {
252
234
  return this.offset;
253
235
  }
254
236
  /**
@@ -256,113 +238,530 @@ class bireader {
256
238
  *
257
239
  * @return {number} current byte position
258
240
  */
259
- fgetpos() {
241
+ saveOffset() {
260
242
  return this.offset;
261
243
  }
262
244
  /**
263
- * Get the current byte position
245
+ * Get the current bit position (0-7)
264
246
  *
265
- * @return {number} current byte position
247
+ * @return {number} current bit position
266
248
  */
267
- saveOffset() {
268
- return this.offset;
249
+ tellB() {
250
+ return this.bitoffset;
269
251
  }
270
252
  /**
271
- * Truncates array from start to current position unless supplied
272
- * Note: Does not affect supplied data
273
- * @param {number} startOffset - Start location, default 0
274
- * @param {number} endOffset - end location, default current write position
275
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
253
+ * Get the current bit position (0-7)
254
+ *
255
+ * @return {number} current bit position
256
+ */
257
+ getOffsetBit() {
258
+ return this.bitoffset;
259
+ }
260
+ /**
261
+ * Get the current bit position (0-7)
262
+ *
263
+ * @return {number} current bit position
264
+ */
265
+ saveOffsetAbsBit() {
266
+ return (this.offset * 8) + this.bitoffset;
267
+ }
268
+ /**
269
+ * Get the current absolute bit position (from start of data)
270
+ *
271
+ * @return {number} current absolute bit position
272
+ */
273
+ tellAbsB() {
274
+ return (this.offset * 8) + this.bitoffset;
275
+ }
276
+ /**
277
+ * Get the current absolute bit position (from start of data)
278
+ *
279
+ * @return {number} current absolute bit position
280
+ */
281
+ getOffsetAbsBit() {
282
+ return (this.offset * 8) + this.bitoffset;
283
+ }
284
+ /**
285
+ * Get the current absolute bit position (from start of data)
286
+ *
287
+ * @return {number} current absolute bit position
276
288
  */
277
- clip(startOffset, endOffset) {
278
- if ((endOffset || this.offset) > this.size) {
279
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
280
- throw new Error("End offset outside of data: endOffset" + endOffset + " of " + this.size);
289
+ saveOffsetBit() {
290
+ return (this.offset * 8) + this.bitoffset;
291
+ }
292
+ //
293
+ //strict mode change
294
+ //
295
+ /**
296
+ * Disallows extending data if position is outside of max size
297
+ */
298
+ restrict() {
299
+ this.strict = true;
300
+ }
301
+ /**
302
+ * Allows extending data if position is outside of max size
303
+ */
304
+ unrestrict() {
305
+ this.strict = false;
306
+ }
307
+ //
308
+ //math
309
+ //
310
+ /**
311
+ * XOR data
312
+ *
313
+ * @param {number|string|Uint8Array|Buffer} xorKey - Value, string or array to XOR
314
+ * @param {number} startOffset - Start location (default current byte position)
315
+ * @param {number} endOffset - End location (default end of data)
316
+ * @param {boolean} consume - Move current position to end of data (default false)
317
+ */
318
+ xor(xorKey, startOffset, endOffset, consume) {
319
+ var XORKey = xorKey;
320
+ if (typeof xorKey == "number") {
321
+ //pass
322
+ }
323
+ else if (typeof xorKey == "string") {
324
+ //pass
325
+ }
326
+ else if (this.isBufferOrUint8Array(XORKey)) {
327
+ //pass
328
+ }
329
+ else {
330
+ throw new Error("XOR must be a number, string, Uint8Array or Buffer");
281
331
  }
282
- return this.data.slice(startOffset || 0, endOffset || this.offset);
332
+ return (0, common_1.XOR)(this, xorKey, startOffset || this.offset, endOffset || this.size, consume || false);
283
333
  }
284
334
  /**
285
- * Truncates array from start to current position unless supplied
286
- * Note: Does not affect supplied data
287
- * @param {number} startOffset - Start location, default 0
288
- * @param {number} endOffset - end location, default current write position
289
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
335
+ * XOR data
336
+ *
337
+ * @param {number|string|Uint8Array|Buffer} xorKey - Value, string or array to XOR
338
+ * @param {number} length - Length in bytes to XOR from curent position (default 1 byte for value, length of string or array for Uint8Array or Buffer)
339
+ * @param {boolean} consume - Move current position to end of data (default false)
290
340
  */
291
- crop(startOffset, endOffset) {
292
- if ((endOffset || this.offset) > this.size) {
293
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
294
- throw new Error("End offset outside of data: endOffset" + endOffset + " of " + this.size);
341
+ xorThis(xorKey, length, consume) {
342
+ var Length = length || 1;
343
+ var XORKey = xorKey;
344
+ if (typeof xorKey == "number") {
345
+ Length = length || 1;
346
+ }
347
+ else if (typeof xorKey == "string") {
348
+ const encoder = new TextEncoder().encode(xorKey);
349
+ XORKey = encoder;
350
+ Length = length || encoder.length;
351
+ }
352
+ else if (this.isBufferOrUint8Array(XORKey)) {
353
+ Length = length || xorKey.length;
354
+ }
355
+ else {
356
+ throw new Error("XOR must be a number, string, Uint8Array or Buffer");
295
357
  }
296
- return this.data.slice(startOffset || 0, endOffset || this.offset);
358
+ return (0, common_1.XOR)(this, XORKey, this.offset, this.offset + Length, consume || false);
297
359
  }
298
360
  /**
299
- * Truncates array from start to current position unless supplied
300
- * Note: Does not affect supplied data
301
- * @param {number} startOffset - Start location, default 0
302
- * @param {number} endOffset - end location, default current write position
303
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
361
+ * OR data
362
+ *
363
+ * @param {number|string|Uint8Array|Buffer} orKey - Value, string or array to OR
364
+ * @param {number} startOffset - Start location (default current byte position)
365
+ * @param {number} endOffset - End location (default end of data)
366
+ * @param {boolean} consume - Move current position to end of data (default false)
304
367
  */
305
- truncate(startOffset, endOffset) {
306
- if ((endOffset || this.offset) > this.size) {
307
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
308
- throw new Error("End offset outside of data: endOffset" + endOffset + " of " + this.size);
368
+ or(orKey, startOffset, endOffset, consume) {
369
+ var ORKey = orKey;
370
+ if (typeof orKey == "number") {
371
+ //pass
309
372
  }
310
- return this.data.slice(startOffset || 0, endOffset || this.offset);
373
+ else if (typeof orKey == "string") {
374
+ //pass
375
+ }
376
+ else if (this.isBufferOrUint8Array(ORKey)) {
377
+ //pass
378
+ }
379
+ else {
380
+ throw new Error("OR must be a number, string, Uint8Array or Buffer");
381
+ }
382
+ return (0, common_1.OR)(this, orKey, startOffset || this.offset, endOffset || this.size, consume || false);
311
383
  }
312
384
  /**
313
- * Truncates array from start to current position unless supplied
314
- * Note: Does not affect supplied data
315
- * @param {number} startOffset - Start location, default 0
316
- * @param {number} endOffset - end location, default current write position
317
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
385
+ * OR data
386
+ *
387
+ * @param {number|string|Uint8Array|Buffer} orKey - Value, string or array to OR
388
+ * @param {number} length - Length in bytes to OR from curent position (default 1 byte for value, length of string or array for Uint8Array or Buffer)
389
+ * @param {boolean} consume - Move current position to end of data (default false)
318
390
  */
319
- slice(startOffset, endOffset) {
320
- if ((endOffset || this.offset) > this.size) {
321
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
322
- throw new Error("End offset outside of data: endOffset" + endOffset + " of " + this.size);
391
+ orThis(orKey, length, consume) {
392
+ var Length = length || 1;
393
+ var ORKey = orKey;
394
+ if (typeof orKey == "number") {
395
+ Length = length || 1;
323
396
  }
324
- return this.data.slice(startOffset || 0, endOffset || this.offset);
397
+ else if (typeof orKey == "string") {
398
+ const encoder = new TextEncoder().encode(orKey);
399
+ ORKey = encoder;
400
+ Length = length || encoder.length;
401
+ }
402
+ else if (this.isBufferOrUint8Array(ORKey)) {
403
+ Length = length || orKey.length;
404
+ }
405
+ else {
406
+ throw new Error("OR must be a number, string, Uint8Array or Buffer");
407
+ }
408
+ return (0, common_1.OR)(this, ORKey, this.offset, this.offset + Length, consume || false);
325
409
  }
326
410
  /**
327
- * Extract array from current position to length supplied
328
- * Note: Does not affect supplied data
329
- * @param {number} length - length of data to copy from current offset
330
- * @param {number} consume - moves offset to end of length
331
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
411
+ * AND data
412
+ *
413
+ * @param {number|string|Uint8Array|Buffer} andKey - Value, string or array to AND
414
+ * @param {number} startOffset - Start location (default current byte position)
415
+ * @param {number} endOffset - End location (default end of data)
416
+ * @param {boolean} consume - Move current position to end of data (default false)
332
417
  */
333
- extract(length, consume) {
334
- if (this.offset + (length || 0) > this.size) {
335
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
336
- throw new Error("End offset outside of data: at " + this.offset + " reading " + length + " of" + this.size);
418
+ and(andKey, startOffset, endOffset, consume) {
419
+ var ANDKey = andKey;
420
+ if (typeof andKey == "number") {
421
+ //pass
422
+ }
423
+ else if (typeof andKey == "string") {
424
+ //pass
337
425
  }
338
- const extract = this.data.slice(this.offset, Number(this.offset + (length || 0)));
339
- if (consume) {
340
- this.offset += length;
426
+ else if (this.isBufferOrUint8Array(ANDKey)) {
427
+ //pass
341
428
  }
342
- return extract;
429
+ else {
430
+ throw new Error("AND must be a number, string, Uint8Array or Buffer");
431
+ }
432
+ return (0, common_1.AND)(this, andKey, startOffset || this.offset, endOffset || this.size, consume || false);
433
+ }
434
+ /**
435
+ * AND data
436
+ *
437
+ * @param {number|string|Uint8Array|Buffer} andKey - Value, string or array to AND
438
+ * @param {number} length - Length in bytes to AND from curent position (default 1 byte for value, length of string or array for Uint8Array or Buffer)
439
+ * @param {boolean} consume - Move current position to end of data (default false)
440
+ */
441
+ andThis(andKey, length, consume) {
442
+ var Length = length || 1;
443
+ var ANDKey = andKey;
444
+ if (typeof andKey == "number") {
445
+ Length = length || 1;
446
+ }
447
+ else if (typeof andKey == "string") {
448
+ const encoder = new TextEncoder().encode(andKey);
449
+ ANDKey = encoder;
450
+ Length = length || encoder.length;
451
+ }
452
+ else if (this.isBufferOrUint8Array(ANDKey)) {
453
+ Length = length || andKey.length;
454
+ }
455
+ else {
456
+ throw new Error("XOR must be a number, string, Uint8Array or Buffer");
457
+ }
458
+ return (0, common_1.AND)(this, ANDKey, this.offset, this.offset + Length, consume || false);
459
+ }
460
+ /**
461
+ * Not data
462
+ *
463
+ * @param {number} startOffset - Start location (default current byte position)
464
+ * @param {number} endOffset - End location (default end of data)
465
+ * @param {boolean} consume - Move current position to end of data (default false)
466
+ */
467
+ not(startOffset, endOffset, consume) {
468
+ return (0, common_1.NOT)(this, startOffset || this.offset, endOffset || this.size, consume || false);
469
+ }
470
+ /**
471
+ * Not data
472
+ *
473
+ * @param {number} length - Length in bytes to NOT from curent position (default 1 byte for value, length of string or array for Uint8Array or Buffer)
474
+ * @param {boolean} consume - Move current position to end of data (default false)
475
+ */
476
+ notThis(length, consume) {
477
+ return (0, common_1.NOT)(this, this.offset, this.offset + (length || 1), consume || false);
478
+ }
479
+ /**
480
+ * Left shift data
481
+ *
482
+ * @param {number} shiftValue - Value to left shift
483
+ * @param {number} startOffset - Start location (default current byte position)
484
+ * @param {number} endOffset - End location (default end of data)
485
+ * @param {boolean} consume - Move current position to end of data (default false)
486
+ */
487
+ lShift(shiftValue, startOffset, endOffset, consume) {
488
+ if (typeof shiftValue != "number") {
489
+ throw new Error("Shift value must be a number");
490
+ }
491
+ return (0, common_1.LSHIFT)(this, shiftValue, startOffset || this.offset, endOffset || this.size, consume || false);
492
+ }
493
+ /**
494
+ * Left shift data
495
+ *
496
+ * @param {number} shiftValue - Value to left shift
497
+ * @param {number} length - Length in bytes to left shift from curent position (default 1 byte for value, length of string or array for Uint8Array or Buffer)
498
+ * @param {boolean} consume - Move current position to end of data (default false)
499
+ */
500
+ lShiftThis(shiftValue, length, consume) {
501
+ var Length = length || 1;
502
+ if (typeof shiftValue != "number") {
503
+ throw new Error("Shift value must be a number");
504
+ }
505
+ return (0, common_1.LSHIFT)(this, shiftValue, this.offset, this.offset + Length, consume || false);
506
+ }
507
+ /**
508
+ * Right shift data
509
+ *
510
+ * @param {number} shiftValue - Value to right shift
511
+ * @param {number} startOffset - Start location (default current byte position)
512
+ * @param {number} endOffset - End location (default end of data)
513
+ * @param {boolean} consume - Move current position to end of data (default false)
514
+ */
515
+ rShift(shiftValue, startOffset, endOffset, consume) {
516
+ if (typeof shiftValue != "number") {
517
+ throw new Error("Shift value must be a number");
518
+ }
519
+ return (0, common_1.RSHIFT)(this, shiftValue, startOffset || this.offset, endOffset || this.size, consume || false);
520
+ }
521
+ /**
522
+ * Right shift data
523
+ *
524
+ * @param {number} shiftValue - Value to right shift
525
+ * @param {number} length - Length in bytes to right shift from curent position (default 1 byte for value, length of string or array for Uint8Array or Buffer)
526
+ * @param {boolean} consume - Move current position to end of data (default false)
527
+ */
528
+ rShiftThis(shiftValue, length, consume) {
529
+ var Length = length || 1;
530
+ if (typeof shiftValue != "number") {
531
+ throw new Error("Shift value must be a number");
532
+ }
533
+ return (0, common_1.RSHIFT)(this, shiftValue, this.offset, this.offset + Length, consume || false);
534
+ }
535
+ /**
536
+ * Add value to data
537
+ *
538
+ * @param {number} addValue - Value to add
539
+ * @param {number} startOffset - Start location (default current byte position)
540
+ * @param {number} endOffset - End location (default end of data)
541
+ * @param {boolean} consume - Move current position to end of data (default false)
542
+ */
543
+ add(addValue, startOffset, endOffset, consume) {
544
+ if (typeof addValue != "number") {
545
+ throw new Error("Add value must be a number");
546
+ }
547
+ return (0, common_1.ADD)(this, addValue, startOffset || this.offset, endOffset || this.size, consume || false);
548
+ }
549
+ /**
550
+ * Add value to data
551
+ *
552
+ * @param {number} addValue - Value to add
553
+ * @param {number} length - Length in bytes to add from curent position (default 1 byte for value, length of string or array for Uint8Array or Buffer)
554
+ * @param {boolean} consume - Move current position to end of data (default false)
555
+ */
556
+ addThis(addValue, length, consume) {
557
+ var Length = length || 1;
558
+ if (typeof addValue != "number") {
559
+ throw new Error("Add value must be a number");
560
+ }
561
+ return (0, common_1.ADD)(this, addValue, this.offset, this.offset + Length, consume || false);
562
+ }
563
+ //
564
+ //remove part of data
565
+ //
566
+ /**
567
+ * Deletes part of data from start to current byte position unless supplied, returns removed
568
+ * Note: Errors in strict mode
569
+ *
570
+ * @param {number} startOffset - Start location (default 0)
571
+ * @param {number} endOffset - End location (default current position)
572
+ * @param {boolean} consume - Move position to end of removed data (default false)
573
+ * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
574
+ */
575
+ delete(startOffset, endOffset, consume) {
576
+ return (0, common_1.remove)(this, startOffset || 0, endOffset || this.offset, consume || false, true);
577
+ }
578
+ /**
579
+ * Deletes part of data from start to current byte position unless supplied, returns removed
580
+ * Note: Errors in strict mode
581
+ *
582
+ * @param {number} startOffset - Start location (default 0)
583
+ * @param {number} endOffset - End location (default current position)
584
+ * @param {boolean} consume - Move position to end of removed data (default false)
585
+ * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
586
+ */
587
+ clip(startOffset, endOffset, consume) {
588
+ return (0, common_1.remove)(this, startOffset || 0, endOffset || this.offset, consume || false, true);
589
+ }
590
+ /**
591
+ * Deletes part of data from current byte position to supplied length, returns removed
592
+ * Note: Errors in strict mode
593
+ *
594
+ * @param {number} length - Length of data in bytes to remove
595
+ * @param {boolean} consume - Move position to end of removed data (default false)
596
+ * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
597
+ */
598
+ crop(length, consume) {
599
+ return (0, common_1.remove)(this, this.offset, this.offset + (length || 0), consume || false, true);
343
600
  }
344
601
  /**
345
- * Extract array from current position to length supplied
602
+ * Deletes part of data from current position to supplied length, returns removed
603
+ * Note: Only works in strict mode
604
+ *
605
+ * @param {number} length - Length of data in bytes to remove
606
+ * @param {boolean} consume - Move position to end of removed data (default false)
607
+ * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
608
+ */
609
+ drop(length, consume) {
610
+ return (0, common_1.remove)(this, this.offset, this.offset + (length || 0), consume || false, true);
611
+ }
612
+ //
613
+ //copy out
614
+ //
615
+ /**
616
+ * Returns part of data from current byte position to end of data unless supplied
617
+ *
618
+ * @param {number} startOffset - Start location (default current position)
619
+ * @param {number} endOffset - End location (default end of data)
620
+ * @param {boolean} consume - Move position to end of lifted data (default false)
621
+ * @param {number} fillValue - Byte value to to fill returned data (does NOT fill unless supplied)
622
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
623
+ */
624
+ lift(startOffset, endOffset, consume, fillValue) {
625
+ return (0, common_1.remove)(this, startOffset || this.offset, endOffset || this.size, consume || false, false, fillValue);
626
+ }
627
+ /**
628
+ * Returns part of data from current byte position to end of data unless supplied
629
+ *
630
+ * @param {number} startOffset - Start location (default current position)
631
+ * @param {number} endOffset - End location (default end of data)
632
+ * @param {boolean} consume - Move position to end of lifted data (default false)
633
+ * @param {number} fillValue - Byte value to to fill returned data (does NOT fill unless supplied)
634
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
635
+ */
636
+ fill(startOffset, endOffset, consume, fillValue) {
637
+ return (0, common_1.remove)(this, startOffset || this.offset, endOffset || this.size, consume || false, false, fillValue);
638
+ }
639
+ /**
640
+ * Extract data from current position to length supplied
346
641
  * Note: Does not affect supplied data
347
- * @param {number} length - length of data to copy from current offset
348
- * @param {number} consume - moves offset to end of length
349
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
642
+ *
643
+ * @param {number} length - Length of data in bytes to copy from current offset
644
+ * @param {number} consume - Moves offset to end of length
645
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
350
646
  */
351
- wrap(length, consume) {
352
- return this.extract(length, consume);
647
+ extract(length, consume) {
648
+ return (0, common_1.remove)(this, this.offset, length || 0, consume || false, false);
353
649
  }
354
650
  /**
355
- * Extract array from current position to length supplied
651
+ * Extract data from current position to length supplied
356
652
  * Note: Does not affect supplied data
357
- * @param {number} length - length of data to copy from current offset
358
- * @param {number} consume - moves offset to end of length
359
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
653
+ *
654
+ * @param {number} length - Length of data in bytes to copy from current offset
655
+ * @param {number} consume - Moves offset to end of length
656
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
657
+ */
658
+ slice(length, consume) {
659
+ return (0, common_1.remove)(this, this.offset, length || 0, consume || false, false);
660
+ }
661
+ /**
662
+ * Extract data from current position to length supplied
663
+ * Note: Does not affect supplied data
664
+ *
665
+ * @param {number} length - Length of data in bytes to copy from current offset
666
+ * @param {number} consume - Moves offset to end of length
667
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
668
+ */
669
+ wrap(length, consume) {
670
+ return (0, common_1.remove)(this, this.offset, length || 0, consume || false, false);
671
+ }
672
+ //
673
+ //insert
674
+ //
675
+ /**
676
+ * Inserts data into data
677
+ * Note: Must be same data type as supplied data. Errors on strict mode.
678
+ *
679
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
680
+ * @param {boolean} consume - Move current byte position to end of data (default false)
681
+ * @param {number} offset - Byte position to add at (defaults to current position)
682
+ */
683
+ insert(data, consume, offset) {
684
+ return (0, common_1.addData)(this, data, consume || false, offset || this.offset);
685
+ }
686
+ /**
687
+ * Inserts data into data
688
+ * Note: Must be same data type as supplied data. Errors on strict mode.
689
+ *
690
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
691
+ * @param {boolean} consume - Move current byte position to end of data (default false)
692
+ * @param {number} offset - Byte position to add at (defaults to current position)
693
+ */
694
+ place(data, consume, offset) {
695
+ return (0, common_1.addData)(this, data, consume || false, offset || this.offset);
696
+ }
697
+ /**
698
+ * Replaces data in data
699
+ * Note: Must be same data type as supplied data. Errors on strict mode.
700
+ *
701
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to replace in data
702
+ * @param {boolean} consume - Move current byte position to end of data (default false)
703
+ * @param {number} offset - Offset to add it at (defaults to current position)
704
+ */
705
+ replace(data, consume, offset) {
706
+ return (0, common_1.addData)(this, data, consume || false, offset || this.offset, true);
707
+ }
708
+ /**
709
+ * Replaces data in data
710
+ * Note: Must be same data type as supplied data. Errors on strict mode.
711
+ *
712
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to replace in data
713
+ * @param {boolean} consume - Move current byte position to end of data (default false)
714
+ * @param {number} offset - Offset to add it at (defaults to current position)
715
+ */
716
+ overwrite(data, consume, offset) {
717
+ return (0, common_1.addData)(this, data, consume || false, offset || this.offset, true);
718
+ }
719
+ /**
720
+ * Adds data to start of supplied data
721
+ * Note: Must be same data type as supplied data. Errors on strict mode.
722
+ *
723
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
724
+ * @param {boolean} consume - Move current write position to end of data (default false)
725
+ */
726
+ unshift(data, consume) {
727
+ return (0, common_1.addData)(this, data, consume || false, 0);
728
+ }
729
+ /**
730
+ * Adds data to start of supplied data
731
+ * Note: Must be same data type as supplied data. Errors on strict mode.
732
+ *
733
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
734
+ * @param {boolean} consume - Move current write position to end of data (default false)
360
735
  */
361
- lift(length, consume) {
362
- return this.extract(length, consume);
736
+ prepend(data, consume) {
737
+ return (0, common_1.addData)(this, data, consume || false, 0);
363
738
  }
364
739
  /**
740
+ * Adds data to end of supplied data
741
+ * Note: Must be same data type as supplied data. Errors on strict mode.
742
+ *
743
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
744
+ * @param {boolean} consume - Move current write position to end of data (default false)
745
+ */
746
+ push(data, consume) {
747
+ return (0, common_1.addData)(this, data, consume || false, this.size);
748
+ }
749
+ /**
750
+ * Adds data to end of supplied data
751
+ * Note: Must be same data type as supplied data. Errors on strict mode.
752
+ *
753
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
754
+ * @param {boolean} consume - Move current write position to end of data (default false)
755
+ */
756
+ append(data, consume) {
757
+ return (0, common_1.addData)(this, data, consume || false, this.size);
758
+ }
759
+ //
760
+ //finishing
761
+ //
762
+ /**
365
763
  * Returns current data
764
+ *
366
765
  * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
367
766
  */
368
767
  get() {
@@ -370,245 +769,81 @@ class bireader {
370
769
  }
371
770
  /**
372
771
  * Returns current data
772
+ *
373
773
  * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
374
774
  */
375
775
  return() {
376
776
  return this.data;
377
777
  }
378
778
  /**
379
- * removes reading data
779
+ * removes data
380
780
  */
381
781
  end() {
382
- this.data = [];
782
+ this.data = undefined;
383
783
  }
384
784
  /**
385
- * removes reading data
785
+ * removes data
386
786
  */
387
787
  close() {
388
- this.data = [];
788
+ this.data = undefined;
389
789
  }
390
790
  /**
391
- * removes reading data
791
+ * removes data
392
792
  */
393
793
  done() {
394
- this.data = [];
794
+ this.data = undefined;
395
795
  }
396
796
  /**
397
- * removes reading data
797
+ * removes data
398
798
  */
399
799
  finished() {
400
- this.data = [];
401
- }
402
- /**
403
- * Turn hexdump on error off, default on
404
- */
405
- errorDumpOff() {
406
- this.errorDump = false;
407
- }
408
- /**
409
- * Turn hexdump on error on, default on
410
- */
411
- errorDumpOn() {
412
- this.errorDump = true;
800
+ this.data = undefined;
413
801
  }
414
802
  /**
415
803
  * Console logs data as hex dump
416
804
  *
417
- * @param {object} options - options object
805
+ * @param {object} options
418
806
  * ```javascript
419
807
  * {
420
808
  * length: 192, // number of bytes to log, default 192 or end of data
421
- * startByte: 0, // byte to start dump, default current position
422
- * supressUnicode: false // Supress unicode character preview for cleaner columns
809
+ * startByte: 0, // byte to start dump (default current byte position)
810
+ * supressUnicode: false // Supress unicode character preview for even columns
423
811
  * }
424
812
  * ```
425
813
  */
426
814
  hexdump(options) {
427
- var length = options && options.length;
428
- var startByte = options && options.startByte;
429
- var supressUnicode = options && options.supressUnicode || false;
430
- if ((startByte || 0) > this.size) {
431
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
432
- throw new Error("Hexdump start is outside of data size: " + startByte + " of " + this.size);
433
- }
434
- const start = startByte || this.offset;
435
- const end = Math.min(start + (length || 192), this.size);
436
- if (start + (length || 0) > this.size) {
437
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
438
- throw new Error("Hexdump amount is outside of data size: " + (start + (length || 0)) + " of " + end);
439
- }
440
- function hex_check(byte, bits) {
441
- var value = 0;
442
- for (var i = 0; i < bits;) {
443
- var remaining = bits - i;
444
- var bitOffset = 0;
445
- var currentByte = byte;
446
- var read = Math.min(remaining, 8 - bitOffset);
447
- var mask, readBits;
448
- mask = ~(0xFF << read);
449
- readBits = (currentByte >> (8 - read - bitOffset)) & mask;
450
- value <<= read;
451
- value |= readBits;
452
- i += read;
453
- }
454
- value = value >>> 0;
455
- return value;
456
- }
457
- const rows = [];
458
- var header = " 0 1 2 3 4 5 6 7 8 9 A B C D E F ";
459
- var ending = "0123456789ABCDEF";
460
- var addr = "";
461
- for (let i = start; i < end; i += 16) {
462
- addr = i.toString(16).padStart(5, '0');
463
- var row = this.data?.slice(i, i + 16) || [];
464
- var hex = Array.from(row, (byte) => byte.toString(16).padStart(2, '0')).join(' ');
465
- rows.push(`${addr} ${hex.padEnd(47)} `);
466
- }
467
- let result = '';
468
- let make_wide = false;
469
- let i = start;
470
- while (i < end) {
471
- const byte = this.data[i];
472
- if (byte < 32 || byte == 127) {
473
- result += '.';
474
- }
475
- else if (byte < 127) {
476
- // Valid UTF-8 start byte or single-byte character
477
- // Convert the byte to a character and add it to the result
478
- result += String.fromCharCode(byte);
479
- }
480
- else if (supressUnicode) {
481
- result += '.';
482
- }
483
- else if (hex_check(byte, 1) == 0) {
484
- //Byte 1
485
- result += String.fromCharCode(byte);
486
- }
487
- else if (hex_check(byte, 3) == 6) {
488
- //Byte 2
489
- if (i + 1 <= end) {
490
- //check second byte
491
- const byte2 = this.data[i + 1];
492
- if (hex_check(byte2, 2) == 2) {
493
- const charCode = ((byte & 0x1f) << 6) | (byte2 & 0x3f);
494
- i++;
495
- make_wide = true;
496
- const read = " " + String.fromCharCode(charCode);
497
- result += read;
498
- }
499
- else {
500
- result += ".";
501
- }
502
- }
503
- else {
504
- result += ".";
505
- }
506
- }
507
- else if (hex_check(byte, 4) == 14) {
508
- //Byte 3
509
- if (i + 1 <= end) {
510
- //check second byte
511
- const byte2 = this.data[i + 1];
512
- if (hex_check(byte2, 2) == 2) {
513
- if (i + 2 <= end) {
514
- //check third byte
515
- const byte3 = this.data[i + 2];
516
- if (hex_check(byte3, 2) == 2) {
517
- const charCode = ((byte & 0x0f) << 12) |
518
- ((byte2 & 0x3f) << 6) |
519
- (byte3 & 0x3f);
520
- i += 2;
521
- make_wide = true;
522
- const read = " " + String.fromCharCode(charCode);
523
- result += read;
524
- }
525
- else {
526
- i++;
527
- result += " .";
528
- }
529
- }
530
- else {
531
- i++;
532
- result += " .";
533
- }
534
- }
535
- else {
536
- result += ".";
537
- }
538
- }
539
- else {
540
- result += ".";
541
- }
542
- }
543
- else if (hex_check(byte, 5) == 28) {
544
- //Byte 4
545
- if (i + 1 <= end) {
546
- //check second byte
547
- const byte2 = this.data[i + 1];
548
- if (hex_check(byte2, 2) == 2) {
549
- if (i + 2 <= end) {
550
- //check third byte
551
- const byte3 = this.data[i + 2];
552
- if (hex_check(byte3, 2) == 2) {
553
- if (i + 3 <= end) {
554
- //check fourth byte
555
- const byte4 = this.data[i + 2];
556
- if (hex_check(byte4, 2) == 2) {
557
- const charCode = (((byte4 & 0xFF) << 24) | ((byte3 & 0xFF) << 16) | ((byte2 & 0xFF) << 8) | (byte & 0xFF));
558
- i += 3;
559
- make_wide = true;
560
- const read = " " + String.fromCharCode(charCode);
561
- result += read;
562
- }
563
- else {
564
- i += 2;
565
- result += " .";
566
- }
567
- }
568
- else {
569
- i += 2;
570
- result += " .";
571
- }
572
- }
573
- else {
574
- i++;
575
- result += " .";
576
- }
577
- }
578
- else {
579
- i++;
580
- result += " .";
581
- }
582
- }
583
- else {
584
- result += ".";
585
- }
586
- }
587
- else {
588
- result += ".";
589
- }
590
- }
591
- else {
592
- // Invalid UTF-8 byte, add a period to the result
593
- result += '.';
594
- }
595
- i++;
596
- }
597
- const chunks = result.match(new RegExp(`.{1,${16}}`, 'g'));
598
- chunks?.forEach((self, i) => {
599
- rows[i] = rows[i] + (make_wide ? "|" + self + "|" : self);
600
- });
601
- header = "".padStart(addr.length) + header + (make_wide ? "" : ending);
602
- rows.unshift(header);
603
- if (make_wide) {
604
- rows.push("*Removed character byte header on unicode detection");
605
- }
606
- console.log(rows.join("\n"));
815
+ return (0, common_1.hexDump)(this, options);
816
+ }
817
+ /**
818
+ * Turn hexdump on error off (default on)
819
+ */
820
+ errorDumpOff() {
821
+ this.errorDump = false;
822
+ }
823
+ /**
824
+ * Turn hexdump on error on (default on)
825
+ */
826
+ errorDumpOn() {
827
+ this.errorDump = true;
607
828
  }
608
829
  //
609
830
  //bit reader
610
831
  //
611
832
  /**
833
+ *
834
+ * Write bits, must have at least value and number of bits
835
+ *
836
+ * ``Note``: When returning to a byte write, remaining bits are skipped
837
+ *
838
+ * @param {number} value - value as int
839
+ * @param {number} bits - number of bits to write
840
+ * @param {boolean} unsigned - if value is unsigned
841
+ * @param {string} endian - ``big`` or ``little``
842
+ */
843
+ writeBit(value, bits, unsigned, endian) {
844
+ return (0, common_1.wbit)(this, value, bits, unsigned, endian);
845
+ }
846
+ /**
612
847
  * Bit field reader
613
848
  *
614
849
  * Note: When returning to a byte read, remaining bits are dropped
@@ -619,48 +854,7 @@ class bireader {
619
854
  * @returns number
620
855
  */
621
856
  readBit(bits, unsigned, endian) {
622
- if (bits == undefined || typeof bits != "number") {
623
- throw new Error("Enter number of bits to read");
624
- }
625
- if (bits <= 0 || bits > 32) {
626
- throw new Error('Bit length must be between 1 and 32.');
627
- }
628
- const size_needed = ((((bits - 1) + this.bitoffset) / 8) + this.offset);
629
- if (bits <= 0 || size_needed > this.size) {
630
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
631
- throw new Error("Invalid number of bits to read: " + size_needed + " of " + this.size);
632
- }
633
- var off_in_bits = (this.offset * 8) + this.bitoffset;
634
- var value = 0;
635
- for (var i = 0; i < bits;) {
636
- var remaining = bits - i;
637
- var bitOffset = off_in_bits & 7;
638
- var currentByte = this.data[off_in_bits >> 3];
639
- var read = Math.min(remaining, 8 - bitOffset);
640
- var mask, readBits;
641
- if ((endian != undefined ? endian : this.endian) == "big") {
642
- mask = ~(0xFF << read);
643
- readBits = (currentByte >> (8 - read - bitOffset)) & mask;
644
- value <<= read;
645
- value |= readBits;
646
- }
647
- else {
648
- mask = ~(0xFF << read);
649
- readBits = (currentByte >> bitOffset) & mask;
650
- value |= readBits << i;
651
- }
652
- off_in_bits += read;
653
- i += read;
654
- }
655
- this.offset = this.offset + Math.floor(((bits) + this.bitoffset) / 8); //end byte
656
- this.bitoffset = ((bits) + this.bitoffset) % 8;
657
- if (unsigned == true || bits <= 7) {
658
- return value >>> 0;
659
- }
660
- if (bits !== 32 && value & (1 << (bits - 1))) {
661
- value |= -1 ^ ((1 << bits) - 1);
662
- }
663
- return value;
857
+ return (0, common_1.rbit)(this, bits, unsigned, endian);
664
858
  }
665
859
  /**
666
860
  * Bit field reader
@@ -673,7 +867,7 @@ class bireader {
673
867
  * @returns number
674
868
  */
675
869
  bit(bits, unsigned, endian) {
676
- return this.readBit(bits, unsigned, endian);
870
+ return this.bit(bits, unsigned, endian);
677
871
  }
678
872
  /**
679
873
  * Bit field reader
@@ -681,10 +875,11 @@ class bireader {
681
875
  * Note: When returning to a byte read, remaining bits are dropped
682
876
  *
683
877
  * @param {boolean} unsigned - if the value is unsigned
878
+ * @param {string} endian - ``big`` or ``little`
684
879
  * @returns number
685
880
  */
686
- bit1(unsigned) {
687
- return this.bit(1, unsigned);
881
+ bit1(unsigned, endian) {
882
+ return this.bit(1, unsigned, endian);
688
883
  }
689
884
  /**
690
885
  * Bit field reader
@@ -2700,7 +2895,7 @@ class bireader {
2700
2895
  * @returns number
2701
2896
  */
2702
2897
  readUBitBE(bits) {
2703
- return this.readBit(bits, true, "big");
2898
+ return this.bit(bits, true, "big");
2704
2899
  }
2705
2900
  /**
2706
2901
  * Bit field reader
@@ -2711,7 +2906,7 @@ class bireader {
2711
2906
  * @returns number
2712
2907
  */
2713
2908
  ubitbe(bits) {
2714
- return this.readBit(bits, true, "big");
2909
+ return this.bit(bits, true, "big");
2715
2910
  }
2716
2911
  /**
2717
2912
  * Bit field reader
@@ -2723,7 +2918,7 @@ class bireader {
2723
2918
  * @returns number
2724
2919
  */
2725
2920
  readBitBE(bits, unsigned) {
2726
- return this.readBit(bits, unsigned, "big");
2921
+ return this.bit(bits, unsigned, "big");
2727
2922
  }
2728
2923
  /**
2729
2924
  * Bit field reader
@@ -2735,7 +2930,7 @@ class bireader {
2735
2930
  * @returns number
2736
2931
  */
2737
2932
  bitbe(bits, unsigned) {
2738
- return this.readBit(bits, unsigned, "big");
2933
+ return this.bit(bits, unsigned, "big");
2739
2934
  }
2740
2935
  /**
2741
2936
  * Bit field reader
@@ -2746,7 +2941,7 @@ class bireader {
2746
2941
  * @returns number
2747
2942
  */
2748
2943
  readUBitLE(bits) {
2749
- return this.readBit(bits, true, "little");
2944
+ return this.bit(bits, true, "little");
2750
2945
  }
2751
2946
  /**
2752
2947
  * Bit field reader
@@ -2757,7 +2952,7 @@ class bireader {
2757
2952
  * @returns number
2758
2953
  */
2759
2954
  ubitle(bits) {
2760
- return this.readBit(bits, true, "little");
2955
+ return this.bit(bits, true, "little");
2761
2956
  }
2762
2957
  /**
2763
2958
  * Bit field reader
@@ -2769,7 +2964,7 @@ class bireader {
2769
2964
  * @returns number
2770
2965
  */
2771
2966
  readBitLE(bits, unsigned) {
2772
- return this.readBit(bits, unsigned, "little");
2967
+ return this.bit(bits, unsigned, "little");
2773
2968
  }
2774
2969
  /**
2775
2970
  * Bit field reader
@@ -2781,7 +2976,7 @@ class bireader {
2781
2976
  * @returns number
2782
2977
  */
2783
2978
  bitle(bits, unsigned) {
2784
- return this.readBit(bits, unsigned, "little");
2979
+ return this.bit(bits, unsigned, "little");
2785
2980
  }
2786
2981
  //
2787
2982
  //byte read
@@ -2793,15 +2988,16 @@ class bireader {
2793
2988
  * @returns number
2794
2989
  */
2795
2990
  readByte(unsigned) {
2796
- this.check_size(1);
2797
- var read = this.data[this.offset];
2798
- this.offset += 1;
2799
- if (unsigned == true) {
2800
- return read & 0xFF;
2801
- }
2802
- else {
2803
- return read > 127 ? read - 256 : read;
2804
- }
2991
+ return (0, common_1.rbyte)(this, unsigned);
2992
+ }
2993
+ /**
2994
+ * Write byte
2995
+ *
2996
+ * @param {number} value - value as int
2997
+ * @param {boolean} unsigned - if the value is unsigned
2998
+ */
2999
+ writeByte(value, unsigned) {
3000
+ return (0, common_1.wbyte)(this, value, unsigned);
2805
3001
  }
2806
3002
  /**
2807
3003
  * Read byte
@@ -2856,21 +3052,17 @@ class bireader {
2856
3052
  * @returns number
2857
3053
  */
2858
3054
  readInt16(unsigned, endian) {
2859
- this.check_size(2);
2860
- var read;
2861
- if ((endian != undefined ? endian : this.endian) == "little") {
2862
- read = (this.data[this.offset + 1] << 8) | this.data[this.offset];
2863
- }
2864
- else {
2865
- read = (this.data[this.offset] << 8) | this.data[this.offset + 1];
2866
- }
2867
- this.offset += 2;
2868
- if (unsigned == undefined || unsigned == false) {
2869
- return read & 0x8000 ? -(0x10000 - read) : read;
2870
- }
2871
- else {
2872
- return read & 0xFFFF;
2873
- }
3055
+ return (0, common_1.rint16)(this, unsigned, endian);
3056
+ }
3057
+ /**
3058
+ * Write int16
3059
+ *
3060
+ * @param {number} value - value as int
3061
+ * @param {boolean} unsigned - if the value is unsigned
3062
+ * @param {string} endian - ``big`` or ``little`
3063
+ */
3064
+ writeInt16(value, unsigned, endian) {
3065
+ return (0, common_1.wint16)(this, value, unsigned, endian);
2874
3066
  }
2875
3067
  /**
2876
3068
  * Read short
@@ -3080,34 +3272,16 @@ class bireader {
3080
3272
  * @returns number
3081
3273
  */
3082
3274
  readHalfFloat(endian) {
3083
- this.check_size(2);
3084
- var uint16Value = this.readInt16(true, (endian != undefined ? endian : this.endian));
3085
- const sign = (uint16Value & 0x8000) >> 15;
3086
- const exponent = (uint16Value & 0x7C00) >> 10;
3087
- const fraction = uint16Value & 0x03FF;
3088
- let floatValue;
3089
- if (exponent === 0) {
3090
- if (fraction === 0) {
3091
- floatValue = (sign === 0) ? 0 : -0; // +/-0
3092
- }
3093
- else {
3094
- // Denormalized number
3095
- floatValue = (sign === 0 ? 1 : -1) * Math.pow(2, -14) * (fraction / 0x0400);
3096
- }
3097
- }
3098
- else if (exponent === 0x1F) {
3099
- if (fraction === 0) {
3100
- floatValue = (sign === 0) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
3101
- }
3102
- else {
3103
- floatValue = Number.NaN;
3104
- }
3105
- }
3106
- else {
3107
- // Normalized number
3108
- floatValue = (sign === 0 ? 1 : -1) * Math.pow(2, exponent - 15) * (1 + fraction / 0x0400);
3109
- }
3110
- return floatValue;
3275
+ return (0, common_1.rhalffloat)(this, endian);
3276
+ }
3277
+ /**
3278
+ * Writes half float
3279
+ *
3280
+ * @param {number} value - value as int
3281
+ * @param {string} endian - ``big`` or ``little`
3282
+ */
3283
+ writeHalfFloat(value, endian) {
3284
+ return (0, common_1.whalffloat)(this, value, endian);
3111
3285
  }
3112
3286
  /**
3113
3287
  * Read half float
@@ -3186,21 +3360,17 @@ class bireader {
3186
3360
  * @returns number
3187
3361
  */
3188
3362
  readInt32(unsigned, endian) {
3189
- this.check_size(4);
3190
- var read;
3191
- if ((endian != undefined ? endian : this.endian) == "little") {
3192
- read = ((this.data[this.offset + 3] << 24) | (this.data[this.offset + 2] << 16) | (this.data[this.offset + 1] << 8) | this.data[this.offset]);
3193
- }
3194
- else {
3195
- read = (this.data[this.offset] << 24) | (this.data[this.offset + 1] << 16) | (this.data[this.offset + 2] << 8) | this.data[this.offset + 3];
3196
- }
3197
- this.offset += 4;
3198
- if (unsigned == undefined || unsigned == false) {
3199
- return read;
3200
- }
3201
- else {
3202
- return read >>> 0;
3203
- }
3363
+ return (0, common_1.rint32)(this, unsigned, endian);
3364
+ }
3365
+ /**
3366
+ * Write int32
3367
+ *
3368
+ * @param {number} value - value as int
3369
+ * @param {boolean} unsigned - if the value is unsigned
3370
+ * @param {string} endian - ``big`` or ``little`
3371
+ */
3372
+ writeInt32(value, unsigned, endian) {
3373
+ return (0, common_1.wint32)(this, value, unsigned, endian);
3204
3374
  }
3205
3375
  /**
3206
3376
  * Read 32 bit integer
@@ -3452,28 +3622,16 @@ class bireader {
3452
3622
  * @returns number
3453
3623
  */
3454
3624
  readFloat(endian) {
3455
- this.check_size(4);
3456
- var uint32Value = this.readInt32(true, (endian == undefined ? this.endian : endian));
3457
- // Check if the value is negative (i.e., the most significant bit is set)
3458
- const isNegative = (uint32Value & 0x80000000) !== 0 ? 1 : 0;
3459
- // Extract the exponent and fraction parts
3460
- const exponent = (uint32Value >> 23) & 0xFF;
3461
- const fraction = uint32Value & 0x7FFFFF;
3462
- // Calculate the float value
3463
- let floatValue;
3464
- if (exponent === 0) {
3465
- // Denormalized number (exponent is 0)
3466
- floatValue = Math.pow(-1, isNegative) * Math.pow(2, -126) * (fraction / Math.pow(2, 23));
3467
- }
3468
- else if (exponent === 0xFF) {
3469
- // Infinity or NaN (exponent is 255)
3470
- floatValue = fraction === 0 ? (isNegative ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY) : Number.NaN;
3471
- }
3472
- else {
3473
- // Normalized number
3474
- floatValue = Math.pow(-1, isNegative) * Math.pow(2, exponent - 127) * (1 + fraction / Math.pow(2, 23));
3475
- }
3476
- return floatValue;
3625
+ return (0, common_1.rfloat)(this, endian);
3626
+ }
3627
+ /**
3628
+ * Write float
3629
+ *
3630
+ * @param {number} value - value as int
3631
+ * @param {string} endian - ``big`` or ``little`
3632
+ */
3633
+ writeFloat(value, endian) {
3634
+ return (0, common_1.wfloat)(this, value, endian);
3477
3635
  }
3478
3636
  /**
3479
3637
  * Read float
@@ -3526,39 +3684,17 @@ class bireader {
3526
3684
  * @returns number
3527
3685
  */
3528
3686
  readInt64(unsigned, endian) {
3529
- this.check_size(8);
3530
- // Convert the byte array to a BigInt
3531
- let value = BigInt(0);
3532
- if ((endian == undefined ? this.endian : endian) == "little") {
3533
- for (let i = 0; i < 8; i++) {
3534
- value = value | BigInt(this.data[this.offset]) << BigInt(8 * i);
3535
- this.offset += 1;
3536
- }
3537
- if (unsigned == undefined || unsigned == false) {
3538
- if (value & (BigInt(1) << BigInt(63))) {
3539
- value -= BigInt(1) << BigInt(64);
3540
- }
3541
- return value;
3542
- }
3543
- else {
3544
- return value;
3545
- }
3546
- }
3547
- else {
3548
- for (let i = 0; i < 8; i++) {
3549
- value = (value << BigInt(8)) | BigInt(this.data[this.offset]);
3550
- this.offset += 1;
3551
- }
3552
- if (unsigned == undefined || unsigned == false) {
3553
- if (value & (BigInt(1) << BigInt(63))) {
3554
- value -= BigInt(1) << BigInt(64);
3555
- }
3556
- return value;
3557
- }
3558
- else {
3559
- return value;
3560
- }
3561
- }
3687
+ return (0, common_1.rint64)(this, unsigned, endian);
3688
+ }
3689
+ /**
3690
+ * Write 64 bit integer
3691
+ *
3692
+ * @param {number} value - value as int
3693
+ * @param {boolean} unsigned - if the value is unsigned
3694
+ * @param {string} endian - ``big`` or ``little`
3695
+ */
3696
+ writeInt64(value, unsigned, endian) {
3697
+ return (0, common_1.wint64)(this, value, unsigned, endian);
3562
3698
  }
3563
3699
  /**
3564
3700
  * Read signed 64 bit integer
@@ -3757,34 +3893,17 @@ class bireader {
3757
3893
  * @returns number
3758
3894
  */
3759
3895
  readDoubleFloat(endian) {
3760
- this.check_size(8);
3761
- var uint64Value = this.readInt64(true, (endian == undefined ? this.endian : endian));
3762
- const sign = (uint64Value & 0x8000000000000000n) >> 63n;
3763
- const exponent = Number((uint64Value & 0x7ff0000000000000n) >> 52n) - 1023;
3764
- const fraction = Number(uint64Value & 0x000fffffffffffffn) / Math.pow(2, 52);
3765
- var floatValue;
3766
- if (exponent == -1023) {
3767
- if (fraction == 0) {
3768
- floatValue = (sign == 0n) ? 0 : -0; // +/-0
3769
- }
3770
- else {
3771
- // Denormalized number
3772
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, -1022) * fraction;
3773
- }
3774
- }
3775
- else if (exponent == 1024) {
3776
- if (fraction == 0) {
3777
- floatValue = (sign == 0n) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
3778
- }
3779
- else {
3780
- floatValue = Number.NaN;
3781
- }
3782
- }
3783
- else {
3784
- // Normalized number
3785
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
3786
- }
3787
- return floatValue;
3896
+ return (0, common_1.rdfloat)(this, endian);
3897
+ }
3898
+ /**
3899
+ * Writes double float
3900
+ *
3901
+ * @param {number} value - value as int
3902
+ * @param {number} offset - byte offset (default last write position)
3903
+ * @param {string} endian - ``big`` or ``little`
3904
+ */
3905
+ writeDoubleFloat(value, endian) {
3906
+ return (0, common_1.wdfloat)(this, value, endian);
3788
3907
  }
3789
3908
  /**
3790
3909
  * Read double float
@@ -3873,127 +3992,45 @@ class bireader {
3873
3992
  * @return string
3874
3993
  */
3875
3994
  readString(options) {
3876
- var length = options && options.length;
3877
- var stringType = options && options.stringType || 'utf-8';
3878
- var terminateValue = options && options.terminateValue;
3879
- var lengthReadSize = options && options.lengthReadSize || 1;
3880
- var stripNull = options && options.stripNull || true;
3881
- var encoding = options && options.encoding || 'utf-8';
3882
- var endian = options && options.endian || this.endian;
3883
- var terminate = terminateValue;
3884
- if (length != undefined) {
3885
- this.check_size(length);
3886
- }
3887
- if (typeof terminateValue == "number") {
3888
- terminate = terminateValue & 0xFF;
3889
- }
3890
- else {
3891
- if (terminateValue != undefined) {
3892
- throw new Error("terminateValue must be a number");
3893
- }
3894
- }
3895
- if (stringType == 'utf-8' || stringType == 'utf-16') {
3896
- if (encoding == undefined) {
3897
- if (stringType == 'utf-8') {
3898
- encoding = 'utf-8';
3899
- }
3900
- if (stringType == 'utf-16') {
3901
- encoding = 'utf-16';
3902
- }
3903
- }
3904
- // Read the string as UTF-8 encoded untill 0 or terminateValue
3905
- const encodedBytes = [];
3906
- if (length == undefined && terminateValue == undefined) {
3907
- terminate = 0;
3908
- }
3909
- var read_length = 0;
3910
- if (length != undefined) {
3911
- read_length = length;
3912
- }
3913
- else {
3914
- read_length = this.data.length - this.offset;
3915
- }
3916
- for (let i = 0; i < read_length; i++) {
3917
- if (stringType === 'utf-8') {
3918
- var read = this.readUByte();
3919
- if (read == terminate) {
3920
- break;
3921
- }
3922
- else {
3923
- if (!(stripNull == true && read == 0)) {
3924
- encodedBytes.push(read);
3925
- }
3926
- }
3927
- }
3928
- else {
3929
- var read = this.readInt16(true, endian);
3930
- var read1 = read & 0xFF;
3931
- var read2 = (read >> 8) & 0xFF;
3932
- if (read == terminate) {
3933
- break;
3934
- }
3935
- else {
3936
- if (!(stripNull == true && read == 0)) {
3937
- encodedBytes.push(read1);
3938
- encodedBytes.push(read2);
3939
- }
3940
- }
3941
- }
3942
- }
3943
- return new TextDecoder(encoding).decode(new Uint8Array(encodedBytes));
3944
- }
3945
- else if (stringType == 'pascal' || stringType == 'wide-pascal') {
3946
- if (encoding == undefined) {
3947
- if (stringType == 'pascal') {
3948
- encoding = 'utf-8';
3949
- }
3950
- if (stringType == 'wide-pascal') {
3951
- encoding = 'utf-16';
3952
- }
3953
- }
3954
- var maxBytes;
3955
- if (lengthReadSize == 1) {
3956
- maxBytes = this.readUByte();
3957
- }
3958
- else if (lengthReadSize == 2) {
3959
- maxBytes = this.readInt16(true, endian);
3960
- }
3961
- else if (lengthReadSize == 4) {
3962
- maxBytes = this.readInt32(true, endian);
3963
- }
3964
- else {
3965
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
3966
- throw new Error("Invalid length read size: " + lengthReadSize);
3967
- }
3968
- // Read the string as Pascal or Delphi encoded
3969
- const encodedBytes = [];
3970
- for (let i = 0; i < maxBytes; i++) {
3971
- if (stringType == 'wide-pascal') {
3972
- const read = this.readInt16(true, endian);
3973
- if (!(stripNull == true && read == 0)) {
3974
- encodedBytes.push(read);
3975
- }
3976
- }
3977
- else {
3978
- const read = this.readUByte();
3979
- if (!(stripNull == true && read == 0)) {
3980
- encodedBytes.push(read);
3981
- }
3982
- }
3983
- }
3984
- var str_return;
3985
- if (stringType == 'wide-pascal') {
3986
- str_return = new TextDecoder(encoding).decode(new Uint16Array(encodedBytes));
3987
- }
3988
- else {
3989
- str_return = new TextDecoder(encoding).decode(new Uint8Array(encodedBytes));
3990
- }
3991
- return str_return;
3992
- }
3993
- else {
3994
- throw new Error('Unsupported string type: ' + stringType);
3995
- }
3995
+ return (0, common_1.rstring)(this, options);
3996
+ }
3997
+ /**
3998
+ * Writes string, use options object for different types
3999
+ *
4000
+ *
4001
+ * @param {string} string - text string
4002
+ * @param {object} options - options:
4003
+ * ```javascript
4004
+ * {
4005
+ * length: string.length, //for fixed length, non-terminate value utf strings
4006
+ * stringType: "utf-8", //utf-8, utf-16, pascal or wide-pascal
4007
+ * terminateValue: 0x00, // only with stringType: "utf"
4008
+ * lengthWriteSize: 1, //for pascal strings. 1, 2 or 4 byte length write size
4009
+ * encoding: "utf-8", //TextEncoder accepted types
4010
+ * endian: "little", //for wide-pascal and utf-16
4011
+ * }
4012
+ * ```
4013
+ */
4014
+ writeString(string, options) {
4015
+ return (0, common_1.wstring)(this, string, options);
3996
4016
  }
4017
+ /**
4018
+ * Reads string, use options object for different types
4019
+ *
4020
+ * @param {object} options
4021
+ * ```javascript
4022
+ * {
4023
+ * length: number, //for fixed length, non-terminate value utf strings
4024
+ * stringType: "utf-8", //utf-8, utf-16, pascal or wide-pascal
4025
+ * terminateValue: 0x00, // only for non-fixed length utf strings
4026
+ * lengthReadSize: 1, //for pascal strings. 1, 2 or 4 byte length read size
4027
+ * stripNull: true, // removes 0x00 characters
4028
+ * encoding: "utf-8", //TextEncoder accepted types
4029
+ * endian: "little", //for wide-pascal and utf-16
4030
+ * }
4031
+ * ```
4032
+ * @return string
4033
+ */
3997
4034
  string(options) {
3998
4035
  return this.readString(options);
3999
4036
  }