bireader 1.0.15 → 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,4 +1,4 @@
1
- import { skip, goto, remove, checkSize, addData, hexDump } from './common';
1
+ import { buffcheck, arraybuffcheck, extendarray, skip, goto, remove, checkSize, addData, hexDump, XOR, AND, OR, NOT, LSHIFT, RSHIFT, ADD, wbit, rbit, rbyte, wbyte, wint16, rint16, whalffloat, rhalffloat, rint32, wint32, rfloat, wfloat, wint64, rint64, rdfloat, wdfloat, wstring, rstring } from './common';
2
2
  /**
3
3
  * Binary reader, includes bitfields and strings
4
4
  *
@@ -10,23 +10,16 @@ import { skip, goto, remove, checkSize, addData, hexDump } from './common';
10
10
  */
11
11
  export class bireader {
12
12
  isBuffer(obj) {
13
- return (typeof Buffer !== 'undefined' && obj instanceof Buffer);
13
+ return buffcheck(obj);
14
14
  }
15
15
  isBufferOrUint8Array(obj) {
16
- return obj instanceof Uint8Array || this.isBuffer(obj);
16
+ return arraybuffcheck(this, obj);
17
17
  }
18
18
  extendArray(to_padd) {
19
- if ((typeof Buffer !== 'undefined' && this.data instanceof Buffer)) {
20
- var paddbuffer = Buffer.alloc(to_padd);
21
- this.data = Buffer.concat([this.data, paddbuffer]);
22
- }
23
- else {
24
- const addArray = new Array(to_padd);
25
- this.data = new Uint8Array([...this.data, ...addArray]);
26
- }
19
+ return extendarray(this, to_padd);
27
20
  }
28
- check_size(read_size, read_bits) {
29
- return checkSize(this, read_size || 0, read_bits || 0, this.offset);
21
+ check_size(write_bytes, write_bit, offset) {
22
+ return checkSize(this, write_bytes || 0, write_bit || 0, offset || this.offset);
30
23
  }
31
24
  /**
32
25
  * Binary reader, includes bitfields and strings
@@ -245,6 +238,54 @@ export class bireader {
245
238
  saveOffset() {
246
239
  return this.offset;
247
240
  }
241
+ /**
242
+ * Get the current bit position (0-7)
243
+ *
244
+ * @return {number} current bit position
245
+ */
246
+ tellB() {
247
+ return this.bitoffset;
248
+ }
249
+ /**
250
+ * Get the current bit position (0-7)
251
+ *
252
+ * @return {number} current bit position
253
+ */
254
+ getOffsetBit() {
255
+ return this.bitoffset;
256
+ }
257
+ /**
258
+ * Get the current bit position (0-7)
259
+ *
260
+ * @return {number} current bit position
261
+ */
262
+ saveOffsetAbsBit() {
263
+ return (this.offset * 8) + this.bitoffset;
264
+ }
265
+ /**
266
+ * Get the current absolute bit position (from start of data)
267
+ *
268
+ * @return {number} current absolute bit position
269
+ */
270
+ tellAbsB() {
271
+ return (this.offset * 8) + this.bitoffset;
272
+ }
273
+ /**
274
+ * Get the current absolute bit position (from start of data)
275
+ *
276
+ * @return {number} current absolute bit position
277
+ */
278
+ getOffsetAbsBit() {
279
+ return (this.offset * 8) + this.bitoffset;
280
+ }
281
+ /**
282
+ * Get the current absolute bit position (from start of data)
283
+ *
284
+ * @return {number} current absolute bit position
285
+ */
286
+ saveOffsetBit() {
287
+ return (this.offset * 8) + this.bitoffset;
288
+ }
248
289
  //
249
290
  //strict mode change
250
291
  //
@@ -261,6 +302,262 @@ export class bireader {
261
302
  this.strict = false;
262
303
  }
263
304
  //
305
+ //math
306
+ //
307
+ /**
308
+ * XOR data
309
+ *
310
+ * @param {number|string|Uint8Array|Buffer} xorKey - Value, string or array to XOR
311
+ * @param {number} startOffset - Start location (default current byte position)
312
+ * @param {number} endOffset - End location (default end of data)
313
+ * @param {boolean} consume - Move current position to end of data (default false)
314
+ */
315
+ xor(xorKey, startOffset, endOffset, consume) {
316
+ var XORKey = xorKey;
317
+ if (typeof xorKey == "number") {
318
+ //pass
319
+ }
320
+ else if (typeof xorKey == "string") {
321
+ //pass
322
+ }
323
+ else if (this.isBufferOrUint8Array(XORKey)) {
324
+ //pass
325
+ }
326
+ else {
327
+ throw new Error("XOR must be a number, string, Uint8Array or Buffer");
328
+ }
329
+ return XOR(this, xorKey, startOffset || this.offset, endOffset || this.size, consume || false);
330
+ }
331
+ /**
332
+ * XOR data
333
+ *
334
+ * @param {number|string|Uint8Array|Buffer} xorKey - Value, string or array to XOR
335
+ * @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)
336
+ * @param {boolean} consume - Move current position to end of data (default false)
337
+ */
338
+ xorThis(xorKey, length, consume) {
339
+ var Length = length || 1;
340
+ var XORKey = xorKey;
341
+ if (typeof xorKey == "number") {
342
+ Length = length || 1;
343
+ }
344
+ else if (typeof xorKey == "string") {
345
+ const encoder = new TextEncoder().encode(xorKey);
346
+ XORKey = encoder;
347
+ Length = length || encoder.length;
348
+ }
349
+ else if (this.isBufferOrUint8Array(XORKey)) {
350
+ Length = length || xorKey.length;
351
+ }
352
+ else {
353
+ throw new Error("XOR must be a number, string, Uint8Array or Buffer");
354
+ }
355
+ return XOR(this, XORKey, this.offset, this.offset + Length, consume || false);
356
+ }
357
+ /**
358
+ * OR data
359
+ *
360
+ * @param {number|string|Uint8Array|Buffer} orKey - Value, string or array to OR
361
+ * @param {number} startOffset - Start location (default current byte position)
362
+ * @param {number} endOffset - End location (default end of data)
363
+ * @param {boolean} consume - Move current position to end of data (default false)
364
+ */
365
+ or(orKey, startOffset, endOffset, consume) {
366
+ var ORKey = orKey;
367
+ if (typeof orKey == "number") {
368
+ //pass
369
+ }
370
+ else if (typeof orKey == "string") {
371
+ //pass
372
+ }
373
+ else if (this.isBufferOrUint8Array(ORKey)) {
374
+ //pass
375
+ }
376
+ else {
377
+ throw new Error("OR must be a number, string, Uint8Array or Buffer");
378
+ }
379
+ return OR(this, orKey, startOffset || this.offset, endOffset || this.size, consume || false);
380
+ }
381
+ /**
382
+ * OR data
383
+ *
384
+ * @param {number|string|Uint8Array|Buffer} orKey - Value, string or array to OR
385
+ * @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)
386
+ * @param {boolean} consume - Move current position to end of data (default false)
387
+ */
388
+ orThis(orKey, length, consume) {
389
+ var Length = length || 1;
390
+ var ORKey = orKey;
391
+ if (typeof orKey == "number") {
392
+ Length = length || 1;
393
+ }
394
+ else if (typeof orKey == "string") {
395
+ const encoder = new TextEncoder().encode(orKey);
396
+ ORKey = encoder;
397
+ Length = length || encoder.length;
398
+ }
399
+ else if (this.isBufferOrUint8Array(ORKey)) {
400
+ Length = length || orKey.length;
401
+ }
402
+ else {
403
+ throw new Error("OR must be a number, string, Uint8Array or Buffer");
404
+ }
405
+ return OR(this, ORKey, this.offset, this.offset + Length, consume || false);
406
+ }
407
+ /**
408
+ * AND data
409
+ *
410
+ * @param {number|string|Uint8Array|Buffer} andKey - Value, string or array to AND
411
+ * @param {number} startOffset - Start location (default current byte position)
412
+ * @param {number} endOffset - End location (default end of data)
413
+ * @param {boolean} consume - Move current position to end of data (default false)
414
+ */
415
+ and(andKey, startOffset, endOffset, consume) {
416
+ var ANDKey = andKey;
417
+ if (typeof andKey == "number") {
418
+ //pass
419
+ }
420
+ else if (typeof andKey == "string") {
421
+ //pass
422
+ }
423
+ else if (this.isBufferOrUint8Array(ANDKey)) {
424
+ //pass
425
+ }
426
+ else {
427
+ throw new Error("AND must be a number, string, Uint8Array or Buffer");
428
+ }
429
+ return AND(this, andKey, startOffset || this.offset, endOffset || this.size, consume || false);
430
+ }
431
+ /**
432
+ * AND data
433
+ *
434
+ * @param {number|string|Uint8Array|Buffer} andKey - Value, string or array to AND
435
+ * @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)
436
+ * @param {boolean} consume - Move current position to end of data (default false)
437
+ */
438
+ andThis(andKey, length, consume) {
439
+ var Length = length || 1;
440
+ var ANDKey = andKey;
441
+ if (typeof andKey == "number") {
442
+ Length = length || 1;
443
+ }
444
+ else if (typeof andKey == "string") {
445
+ const encoder = new TextEncoder().encode(andKey);
446
+ ANDKey = encoder;
447
+ Length = length || encoder.length;
448
+ }
449
+ else if (this.isBufferOrUint8Array(ANDKey)) {
450
+ Length = length || andKey.length;
451
+ }
452
+ else {
453
+ throw new Error("XOR must be a number, string, Uint8Array or Buffer");
454
+ }
455
+ return AND(this, ANDKey, this.offset, this.offset + Length, consume || false);
456
+ }
457
+ /**
458
+ * Not data
459
+ *
460
+ * @param {number} startOffset - Start location (default current byte position)
461
+ * @param {number} endOffset - End location (default end of data)
462
+ * @param {boolean} consume - Move current position to end of data (default false)
463
+ */
464
+ not(startOffset, endOffset, consume) {
465
+ return NOT(this, startOffset || this.offset, endOffset || this.size, consume || false);
466
+ }
467
+ /**
468
+ * Not data
469
+ *
470
+ * @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)
471
+ * @param {boolean} consume - Move current position to end of data (default false)
472
+ */
473
+ notThis(length, consume) {
474
+ return NOT(this, this.offset, this.offset + (length || 1), consume || false);
475
+ }
476
+ /**
477
+ * Left shift data
478
+ *
479
+ * @param {number} shiftValue - Value to left shift
480
+ * @param {number} startOffset - Start location (default current byte position)
481
+ * @param {number} endOffset - End location (default end of data)
482
+ * @param {boolean} consume - Move current position to end of data (default false)
483
+ */
484
+ lShift(shiftValue, startOffset, endOffset, consume) {
485
+ if (typeof shiftValue != "number") {
486
+ throw new Error("Shift value must be a number");
487
+ }
488
+ return LSHIFT(this, shiftValue, startOffset || this.offset, endOffset || this.size, consume || false);
489
+ }
490
+ /**
491
+ * Left shift data
492
+ *
493
+ * @param {number} shiftValue - Value to left shift
494
+ * @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)
495
+ * @param {boolean} consume - Move current position to end of data (default false)
496
+ */
497
+ lShiftThis(shiftValue, length, consume) {
498
+ var Length = length || 1;
499
+ if (typeof shiftValue != "number") {
500
+ throw new Error("Shift value must be a number");
501
+ }
502
+ return LSHIFT(this, shiftValue, this.offset, this.offset + Length, consume || false);
503
+ }
504
+ /**
505
+ * Right shift data
506
+ *
507
+ * @param {number} shiftValue - Value to right shift
508
+ * @param {number} startOffset - Start location (default current byte position)
509
+ * @param {number} endOffset - End location (default end of data)
510
+ * @param {boolean} consume - Move current position to end of data (default false)
511
+ */
512
+ rShift(shiftValue, startOffset, endOffset, consume) {
513
+ if (typeof shiftValue != "number") {
514
+ throw new Error("Shift value must be a number");
515
+ }
516
+ return RSHIFT(this, shiftValue, startOffset || this.offset, endOffset || this.size, consume || false);
517
+ }
518
+ /**
519
+ * Right shift data
520
+ *
521
+ * @param {number} shiftValue - Value to right shift
522
+ * @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)
523
+ * @param {boolean} consume - Move current position to end of data (default false)
524
+ */
525
+ rShiftThis(shiftValue, length, consume) {
526
+ var Length = length || 1;
527
+ if (typeof shiftValue != "number") {
528
+ throw new Error("Shift value must be a number");
529
+ }
530
+ return RSHIFT(this, shiftValue, this.offset, this.offset + Length, consume || false);
531
+ }
532
+ /**
533
+ * Add value to data
534
+ *
535
+ * @param {number} addValue - Value to add
536
+ * @param {number} startOffset - Start location (default current byte position)
537
+ * @param {number} endOffset - End location (default end of data)
538
+ * @param {boolean} consume - Move current position to end of data (default false)
539
+ */
540
+ add(addValue, startOffset, endOffset, consume) {
541
+ if (typeof addValue != "number") {
542
+ throw new Error("Add value must be a number");
543
+ }
544
+ return ADD(this, addValue, startOffset || this.offset, endOffset || this.size, consume || false);
545
+ }
546
+ /**
547
+ * Add value to data
548
+ *
549
+ * @param {number} addValue - Value to add
550
+ * @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)
551
+ * @param {boolean} consume - Move current position to end of data (default false)
552
+ */
553
+ addThis(addValue, length, consume) {
554
+ var Length = length || 1;
555
+ if (typeof addValue != "number") {
556
+ throw new Error("Add value must be a number");
557
+ }
558
+ return ADD(this, addValue, this.offset, this.offset + Length, consume || false);
559
+ }
560
+ //
264
561
  //remove part of data
265
562
  //
266
563
  /**
@@ -377,8 +674,8 @@ export class bireader {
377
674
  * Note: Must be same data type as supplied data. Errors on strict mode.
378
675
  *
379
676
  * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
380
- * @param {boolean} consume - Move current write position to end of data (default false)
381
- * @param {number} offset - Offset to add it at (defaults to current position)
677
+ * @param {boolean} consume - Move current byte position to end of data (default false)
678
+ * @param {number} offset - Byte position to add at (defaults to current position)
382
679
  */
383
680
  insert(data, consume, offset) {
384
681
  return addData(this, data, consume || false, offset || this.offset);
@@ -388,13 +685,35 @@ export class bireader {
388
685
  * Note: Must be same data type as supplied data. Errors on strict mode.
389
686
  *
390
687
  * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
391
- * @param {boolean} consume - Move current write position to end of data (default false)
392
- * @param {number} offset - Offset to add it at (defaults to current position)
688
+ * @param {boolean} consume - Move current byte position to end of data (default false)
689
+ * @param {number} offset - Byte position to add at (defaults to current position)
393
690
  */
394
691
  place(data, consume, offset) {
395
692
  return addData(this, data, consume || false, offset || this.offset);
396
693
  }
397
694
  /**
695
+ * Replaces data in data
696
+ * Note: Must be same data type as supplied data. Errors on strict mode.
697
+ *
698
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to replace in data
699
+ * @param {boolean} consume - Move current byte position to end of data (default false)
700
+ * @param {number} offset - Offset to add it at (defaults to current position)
701
+ */
702
+ replace(data, consume, offset) {
703
+ return addData(this, data, consume || false, offset || this.offset, true);
704
+ }
705
+ /**
706
+ * Replaces data in data
707
+ * Note: Must be same data type as supplied data. Errors on strict mode.
708
+ *
709
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to replace in data
710
+ * @param {boolean} consume - Move current byte position to end of data (default false)
711
+ * @param {number} offset - Offset to add it at (defaults to current position)
712
+ */
713
+ overwrite(data, consume, offset) {
714
+ return addData(this, data, consume || false, offset || this.offset, true);
715
+ }
716
+ /**
398
717
  * Adds data to start of supplied data
399
718
  * Note: Must be same data type as supplied data. Errors on strict mode.
400
719
  *
@@ -480,12 +799,12 @@ export class bireader {
480
799
  /**
481
800
  * Console logs data as hex dump
482
801
  *
483
- * @param {object} options - options object
802
+ * @param {object} options
484
803
  * ```javascript
485
804
  * {
486
805
  * length: 192, // number of bytes to log, default 192 or end of data
487
- * startByte: 0, // byte to start dump, default current position
488
- * supressUnicode: false // Supress unicode character preview for cleaner columns
806
+ * startByte: 0, // byte to start dump (default current byte position)
807
+ * supressUnicode: false // Supress unicode character preview for even columns
489
808
  * }
490
809
  * ```
491
810
  */
@@ -508,6 +827,20 @@ export class bireader {
508
827
  //bit reader
509
828
  //
510
829
  /**
830
+ *
831
+ * Write bits, must have at least value and number of bits
832
+ *
833
+ * ``Note``: When returning to a byte write, remaining bits are skipped
834
+ *
835
+ * @param {number} value - value as int
836
+ * @param {number} bits - number of bits to write
837
+ * @param {boolean} unsigned - if value is unsigned
838
+ * @param {string} endian - ``big`` or ``little``
839
+ */
840
+ writeBit(value, bits, unsigned, endian) {
841
+ return wbit(this, value, bits, unsigned, endian);
842
+ }
843
+ /**
511
844
  * Bit field reader
512
845
  *
513
846
  * Note: When returning to a byte read, remaining bits are dropped
@@ -518,48 +851,7 @@ export class bireader {
518
851
  * @returns number
519
852
  */
520
853
  readBit(bits, unsigned, endian) {
521
- if (bits == undefined || typeof bits != "number") {
522
- throw new Error("Enter number of bits to read");
523
- }
524
- if (bits <= 0 || bits > 32) {
525
- throw new Error('Bit length must be between 1 and 32.');
526
- }
527
- const size_needed = ((((bits - 1) + this.bitoffset) / 8) + this.offset);
528
- if (bits <= 0 || size_needed > this.size) {
529
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
530
- throw new Error("Invalid number of bits to read: " + size_needed + " of " + this.size);
531
- }
532
- var off_in_bits = (this.offset * 8) + this.bitoffset;
533
- var value = 0;
534
- for (var i = 0; i < bits;) {
535
- var remaining = bits - i;
536
- var bitOffset = off_in_bits & 7;
537
- var currentByte = this.data[off_in_bits >> 3];
538
- var read = Math.min(remaining, 8 - bitOffset);
539
- var mask, readBits;
540
- if ((endian != undefined ? endian : this.endian) == "big") {
541
- mask = ~(0xFF << read);
542
- readBits = (currentByte >> (8 - read - bitOffset)) & mask;
543
- value <<= read;
544
- value |= readBits;
545
- }
546
- else {
547
- mask = ~(0xFF << read);
548
- readBits = (currentByte >> bitOffset) & mask;
549
- value |= readBits << i;
550
- }
551
- off_in_bits += read;
552
- i += read;
553
- }
554
- this.offset = this.offset + Math.floor(((bits) + this.bitoffset) / 8); //end byte
555
- this.bitoffset = ((bits) + this.bitoffset) % 8;
556
- if (unsigned == true || bits <= 7) {
557
- return value >>> 0;
558
- }
559
- if (bits !== 32 && value & (1 << (bits - 1))) {
560
- value |= -1 ^ ((1 << bits) - 1);
561
- }
562
- return value;
854
+ return rbit(this, bits, unsigned, endian);
563
855
  }
564
856
  /**
565
857
  * Bit field reader
@@ -572,7 +864,7 @@ export class bireader {
572
864
  * @returns number
573
865
  */
574
866
  bit(bits, unsigned, endian) {
575
- return this.readBit(bits, unsigned, endian);
867
+ return this.bit(bits, unsigned, endian);
576
868
  }
577
869
  /**
578
870
  * Bit field reader
@@ -580,10 +872,11 @@ export class bireader {
580
872
  * Note: When returning to a byte read, remaining bits are dropped
581
873
  *
582
874
  * @param {boolean} unsigned - if the value is unsigned
875
+ * @param {string} endian - ``big`` or ``little`
583
876
  * @returns number
584
877
  */
585
- bit1(unsigned) {
586
- return this.bit(1, unsigned);
878
+ bit1(unsigned, endian) {
879
+ return this.bit(1, unsigned, endian);
587
880
  }
588
881
  /**
589
882
  * Bit field reader
@@ -2599,7 +2892,7 @@ export class bireader {
2599
2892
  * @returns number
2600
2893
  */
2601
2894
  readUBitBE(bits) {
2602
- return this.readBit(bits, true, "big");
2895
+ return this.bit(bits, true, "big");
2603
2896
  }
2604
2897
  /**
2605
2898
  * Bit field reader
@@ -2610,7 +2903,7 @@ export class bireader {
2610
2903
  * @returns number
2611
2904
  */
2612
2905
  ubitbe(bits) {
2613
- return this.readBit(bits, true, "big");
2906
+ return this.bit(bits, true, "big");
2614
2907
  }
2615
2908
  /**
2616
2909
  * Bit field reader
@@ -2622,7 +2915,7 @@ export class bireader {
2622
2915
  * @returns number
2623
2916
  */
2624
2917
  readBitBE(bits, unsigned) {
2625
- return this.readBit(bits, unsigned, "big");
2918
+ return this.bit(bits, unsigned, "big");
2626
2919
  }
2627
2920
  /**
2628
2921
  * Bit field reader
@@ -2634,7 +2927,7 @@ export class bireader {
2634
2927
  * @returns number
2635
2928
  */
2636
2929
  bitbe(bits, unsigned) {
2637
- return this.readBit(bits, unsigned, "big");
2930
+ return this.bit(bits, unsigned, "big");
2638
2931
  }
2639
2932
  /**
2640
2933
  * Bit field reader
@@ -2645,7 +2938,7 @@ export class bireader {
2645
2938
  * @returns number
2646
2939
  */
2647
2940
  readUBitLE(bits) {
2648
- return this.readBit(bits, true, "little");
2941
+ return this.bit(bits, true, "little");
2649
2942
  }
2650
2943
  /**
2651
2944
  * Bit field reader
@@ -2656,7 +2949,7 @@ export class bireader {
2656
2949
  * @returns number
2657
2950
  */
2658
2951
  ubitle(bits) {
2659
- return this.readBit(bits, true, "little");
2952
+ return this.bit(bits, true, "little");
2660
2953
  }
2661
2954
  /**
2662
2955
  * Bit field reader
@@ -2668,7 +2961,7 @@ export class bireader {
2668
2961
  * @returns number
2669
2962
  */
2670
2963
  readBitLE(bits, unsigned) {
2671
- return this.readBit(bits, unsigned, "little");
2964
+ return this.bit(bits, unsigned, "little");
2672
2965
  }
2673
2966
  /**
2674
2967
  * Bit field reader
@@ -2680,7 +2973,7 @@ export class bireader {
2680
2973
  * @returns number
2681
2974
  */
2682
2975
  bitle(bits, unsigned) {
2683
- return this.readBit(bits, unsigned, "little");
2976
+ return this.bit(bits, unsigned, "little");
2684
2977
  }
2685
2978
  //
2686
2979
  //byte read
@@ -2692,15 +2985,16 @@ export class bireader {
2692
2985
  * @returns number
2693
2986
  */
2694
2987
  readByte(unsigned) {
2695
- this.check_size(1);
2696
- var read = this.data[this.offset];
2697
- this.offset += 1;
2698
- if (unsigned == true) {
2699
- return read & 0xFF;
2700
- }
2701
- else {
2702
- return read > 127 ? read - 256 : read;
2703
- }
2988
+ return rbyte(this, unsigned);
2989
+ }
2990
+ /**
2991
+ * Write byte
2992
+ *
2993
+ * @param {number} value - value as int
2994
+ * @param {boolean} unsigned - if the value is unsigned
2995
+ */
2996
+ writeByte(value, unsigned) {
2997
+ return wbyte(this, value, unsigned);
2704
2998
  }
2705
2999
  /**
2706
3000
  * Read byte
@@ -2755,21 +3049,17 @@ export class bireader {
2755
3049
  * @returns number
2756
3050
  */
2757
3051
  readInt16(unsigned, endian) {
2758
- this.check_size(2);
2759
- var read;
2760
- if ((endian != undefined ? endian : this.endian) == "little") {
2761
- read = (this.data[this.offset + 1] << 8) | this.data[this.offset];
2762
- }
2763
- else {
2764
- read = (this.data[this.offset] << 8) | this.data[this.offset + 1];
2765
- }
2766
- this.offset += 2;
2767
- if (unsigned == undefined || unsigned == false) {
2768
- return read & 0x8000 ? -(0x10000 - read) : read;
2769
- }
2770
- else {
2771
- return read & 0xFFFF;
2772
- }
3052
+ return rint16(this, unsigned, endian);
3053
+ }
3054
+ /**
3055
+ * Write int16
3056
+ *
3057
+ * @param {number} value - value as int
3058
+ * @param {boolean} unsigned - if the value is unsigned
3059
+ * @param {string} endian - ``big`` or ``little`
3060
+ */
3061
+ writeInt16(value, unsigned, endian) {
3062
+ return wint16(this, value, unsigned, endian);
2773
3063
  }
2774
3064
  /**
2775
3065
  * Read short
@@ -2979,34 +3269,16 @@ export class bireader {
2979
3269
  * @returns number
2980
3270
  */
2981
3271
  readHalfFloat(endian) {
2982
- this.check_size(2);
2983
- var uint16Value = this.readInt16(true, (endian != undefined ? endian : this.endian));
2984
- const sign = (uint16Value & 0x8000) >> 15;
2985
- const exponent = (uint16Value & 0x7C00) >> 10;
2986
- const fraction = uint16Value & 0x03FF;
2987
- let floatValue;
2988
- if (exponent === 0) {
2989
- if (fraction === 0) {
2990
- floatValue = (sign === 0) ? 0 : -0; // +/-0
2991
- }
2992
- else {
2993
- // Denormalized number
2994
- floatValue = (sign === 0 ? 1 : -1) * Math.pow(2, -14) * (fraction / 0x0400);
2995
- }
2996
- }
2997
- else if (exponent === 0x1F) {
2998
- if (fraction === 0) {
2999
- floatValue = (sign === 0) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
3000
- }
3001
- else {
3002
- floatValue = Number.NaN;
3003
- }
3004
- }
3005
- else {
3006
- // Normalized number
3007
- floatValue = (sign === 0 ? 1 : -1) * Math.pow(2, exponent - 15) * (1 + fraction / 0x0400);
3008
- }
3009
- return floatValue;
3272
+ return rhalffloat(this, endian);
3273
+ }
3274
+ /**
3275
+ * Writes half float
3276
+ *
3277
+ * @param {number} value - value as int
3278
+ * @param {string} endian - ``big`` or ``little`
3279
+ */
3280
+ writeHalfFloat(value, endian) {
3281
+ return whalffloat(this, value, endian);
3010
3282
  }
3011
3283
  /**
3012
3284
  * Read half float
@@ -3085,21 +3357,17 @@ export class bireader {
3085
3357
  * @returns number
3086
3358
  */
3087
3359
  readInt32(unsigned, endian) {
3088
- this.check_size(4);
3089
- var read;
3090
- if ((endian != undefined ? endian : this.endian) == "little") {
3091
- read = ((this.data[this.offset + 3] << 24) | (this.data[this.offset + 2] << 16) | (this.data[this.offset + 1] << 8) | this.data[this.offset]);
3092
- }
3093
- else {
3094
- read = (this.data[this.offset] << 24) | (this.data[this.offset + 1] << 16) | (this.data[this.offset + 2] << 8) | this.data[this.offset + 3];
3095
- }
3096
- this.offset += 4;
3097
- if (unsigned == undefined || unsigned == false) {
3098
- return read;
3099
- }
3100
- else {
3101
- return read >>> 0;
3102
- }
3360
+ return rint32(this, unsigned, endian);
3361
+ }
3362
+ /**
3363
+ * Write int32
3364
+ *
3365
+ * @param {number} value - value as int
3366
+ * @param {boolean} unsigned - if the value is unsigned
3367
+ * @param {string} endian - ``big`` or ``little`
3368
+ */
3369
+ writeInt32(value, unsigned, endian) {
3370
+ return wint32(this, value, unsigned, endian);
3103
3371
  }
3104
3372
  /**
3105
3373
  * Read 32 bit integer
@@ -3351,28 +3619,16 @@ export class bireader {
3351
3619
  * @returns number
3352
3620
  */
3353
3621
  readFloat(endian) {
3354
- this.check_size(4);
3355
- var uint32Value = this.readInt32(true, (endian == undefined ? this.endian : endian));
3356
- // Check if the value is negative (i.e., the most significant bit is set)
3357
- const isNegative = (uint32Value & 0x80000000) !== 0 ? 1 : 0;
3358
- // Extract the exponent and fraction parts
3359
- const exponent = (uint32Value >> 23) & 0xFF;
3360
- const fraction = uint32Value & 0x7FFFFF;
3361
- // Calculate the float value
3362
- let floatValue;
3363
- if (exponent === 0) {
3364
- // Denormalized number (exponent is 0)
3365
- floatValue = Math.pow(-1, isNegative) * Math.pow(2, -126) * (fraction / Math.pow(2, 23));
3366
- }
3367
- else if (exponent === 0xFF) {
3368
- // Infinity or NaN (exponent is 255)
3369
- floatValue = fraction === 0 ? (isNegative ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY) : Number.NaN;
3370
- }
3371
- else {
3372
- // Normalized number
3373
- floatValue = Math.pow(-1, isNegative) * Math.pow(2, exponent - 127) * (1 + fraction / Math.pow(2, 23));
3374
- }
3375
- return floatValue;
3622
+ return rfloat(this, endian);
3623
+ }
3624
+ /**
3625
+ * Write float
3626
+ *
3627
+ * @param {number} value - value as int
3628
+ * @param {string} endian - ``big`` or ``little`
3629
+ */
3630
+ writeFloat(value, endian) {
3631
+ return wfloat(this, value, endian);
3376
3632
  }
3377
3633
  /**
3378
3634
  * Read float
@@ -3425,39 +3681,17 @@ export class bireader {
3425
3681
  * @returns number
3426
3682
  */
3427
3683
  readInt64(unsigned, endian) {
3428
- this.check_size(8);
3429
- // Convert the byte array to a BigInt
3430
- let value = BigInt(0);
3431
- if ((endian == undefined ? this.endian : endian) == "little") {
3432
- for (let i = 0; i < 8; i++) {
3433
- value = value | BigInt(this.data[this.offset]) << BigInt(8 * i);
3434
- this.offset += 1;
3435
- }
3436
- if (unsigned == undefined || unsigned == false) {
3437
- if (value & (BigInt(1) << BigInt(63))) {
3438
- value -= BigInt(1) << BigInt(64);
3439
- }
3440
- return value;
3441
- }
3442
- else {
3443
- return value;
3444
- }
3445
- }
3446
- else {
3447
- for (let i = 0; i < 8; i++) {
3448
- value = (value << BigInt(8)) | BigInt(this.data[this.offset]);
3449
- this.offset += 1;
3450
- }
3451
- if (unsigned == undefined || unsigned == false) {
3452
- if (value & (BigInt(1) << BigInt(63))) {
3453
- value -= BigInt(1) << BigInt(64);
3454
- }
3455
- return value;
3456
- }
3457
- else {
3458
- return value;
3459
- }
3460
- }
3684
+ return rint64(this, unsigned, endian);
3685
+ }
3686
+ /**
3687
+ * Write 64 bit integer
3688
+ *
3689
+ * @param {number} value - value as int
3690
+ * @param {boolean} unsigned - if the value is unsigned
3691
+ * @param {string} endian - ``big`` or ``little`
3692
+ */
3693
+ writeInt64(value, unsigned, endian) {
3694
+ return wint64(this, value, unsigned, endian);
3461
3695
  }
3462
3696
  /**
3463
3697
  * Read signed 64 bit integer
@@ -3656,34 +3890,17 @@ export class bireader {
3656
3890
  * @returns number
3657
3891
  */
3658
3892
  readDoubleFloat(endian) {
3659
- this.check_size(8);
3660
- var uint64Value = this.readInt64(true, (endian == undefined ? this.endian : endian));
3661
- const sign = (uint64Value & 0x8000000000000000n) >> 63n;
3662
- const exponent = Number((uint64Value & 0x7ff0000000000000n) >> 52n) - 1023;
3663
- const fraction = Number(uint64Value & 0x000fffffffffffffn) / Math.pow(2, 52);
3664
- var floatValue;
3665
- if (exponent == -1023) {
3666
- if (fraction == 0) {
3667
- floatValue = (sign == 0n) ? 0 : -0; // +/-0
3668
- }
3669
- else {
3670
- // Denormalized number
3671
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, -1022) * fraction;
3672
- }
3673
- }
3674
- else if (exponent == 1024) {
3675
- if (fraction == 0) {
3676
- floatValue = (sign == 0n) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
3677
- }
3678
- else {
3679
- floatValue = Number.NaN;
3680
- }
3681
- }
3682
- else {
3683
- // Normalized number
3684
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
3685
- }
3686
- return floatValue;
3893
+ return rdfloat(this, endian);
3894
+ }
3895
+ /**
3896
+ * Writes double float
3897
+ *
3898
+ * @param {number} value - value as int
3899
+ * @param {number} offset - byte offset (default last write position)
3900
+ * @param {string} endian - ``big`` or ``little`
3901
+ */
3902
+ writeDoubleFloat(value, endian) {
3903
+ return wdfloat(this, value, endian);
3687
3904
  }
3688
3905
  /**
3689
3906
  * Read double float
@@ -3772,126 +3989,27 @@ export class bireader {
3772
3989
  * @return string
3773
3990
  */
3774
3991
  readString(options) {
3775
- var length = options && options.length;
3776
- var stringType = options && options.stringType || 'utf-8';
3777
- var terminateValue = options && options.terminateValue;
3778
- var lengthReadSize = options && options.lengthReadSize || 1;
3779
- var stripNull = options && options.stripNull || true;
3780
- var encoding = options && options.encoding || 'utf-8';
3781
- var endian = options && options.endian || this.endian;
3782
- var terminate = terminateValue;
3783
- if (length != undefined) {
3784
- this.check_size(length);
3785
- }
3786
- if (typeof terminateValue == "number") {
3787
- terminate = terminateValue & 0xFF;
3788
- }
3789
- else {
3790
- if (terminateValue != undefined) {
3791
- throw new Error("terminateValue must be a number");
3792
- }
3793
- }
3794
- if (stringType == 'utf-8' || stringType == 'utf-16') {
3795
- if (encoding == undefined) {
3796
- if (stringType == 'utf-8') {
3797
- encoding = 'utf-8';
3798
- }
3799
- if (stringType == 'utf-16') {
3800
- encoding = 'utf-16';
3801
- }
3802
- }
3803
- // Read the string as UTF-8 encoded untill 0 or terminateValue
3804
- const encodedBytes = [];
3805
- if (length == undefined && terminateValue == undefined) {
3806
- terminate = 0;
3807
- }
3808
- var read_length = 0;
3809
- if (length != undefined) {
3810
- read_length = length;
3811
- }
3812
- else {
3813
- read_length = this.data.length - this.offset;
3814
- }
3815
- for (let i = 0; i < read_length; i++) {
3816
- if (stringType === 'utf-8') {
3817
- var read = this.readUByte();
3818
- if (read == terminate) {
3819
- break;
3820
- }
3821
- else {
3822
- if (!(stripNull == true && read == 0)) {
3823
- encodedBytes.push(read);
3824
- }
3825
- }
3826
- }
3827
- else {
3828
- var read = this.readInt16(true, endian);
3829
- var read1 = read & 0xFF;
3830
- var read2 = (read >> 8) & 0xFF;
3831
- if (read == terminate) {
3832
- break;
3833
- }
3834
- else {
3835
- if (!(stripNull == true && read == 0)) {
3836
- encodedBytes.push(read1);
3837
- encodedBytes.push(read2);
3838
- }
3839
- }
3840
- }
3841
- }
3842
- return new TextDecoder(encoding).decode(new Uint8Array(encodedBytes));
3843
- }
3844
- else if (stringType == 'pascal' || stringType == 'wide-pascal') {
3845
- if (encoding == undefined) {
3846
- if (stringType == 'pascal') {
3847
- encoding = 'utf-8';
3848
- }
3849
- if (stringType == 'wide-pascal') {
3850
- encoding = 'utf-16';
3851
- }
3852
- }
3853
- var maxBytes;
3854
- if (lengthReadSize == 1) {
3855
- maxBytes = this.readUByte();
3856
- }
3857
- else if (lengthReadSize == 2) {
3858
- maxBytes = this.readInt16(true, endian);
3859
- }
3860
- else if (lengthReadSize == 4) {
3861
- maxBytes = this.readInt32(true, endian);
3862
- }
3863
- else {
3864
- this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
3865
- throw new Error("Invalid length read size: " + lengthReadSize);
3866
- }
3867
- // Read the string as Pascal or Delphi encoded
3868
- const encodedBytes = [];
3869
- for (let i = 0; i < maxBytes; i++) {
3870
- if (stringType == 'wide-pascal') {
3871
- const read = this.readInt16(true, endian);
3872
- if (!(stripNull == true && read == 0)) {
3873
- encodedBytes.push(read);
3874
- }
3875
- }
3876
- else {
3877
- const read = this.readUByte();
3878
- if (!(stripNull == true && read == 0)) {
3879
- encodedBytes.push(read);
3880
- }
3881
- }
3882
- }
3883
- var str_return;
3884
- if (stringType == 'wide-pascal') {
3885
- str_return = new TextDecoder(encoding).decode(new Uint16Array(encodedBytes));
3886
- }
3887
- else {
3888
- str_return = new TextDecoder(encoding).decode(new Uint8Array(encodedBytes));
3889
- }
3890
- return str_return;
3891
- }
3892
- else {
3893
- throw new Error('Unsupported string type: ' + stringType);
3894
- }
3992
+ return rstring(this, options);
3993
+ }
3994
+ /**
3995
+ * Writes string, use options object for different types
3996
+ *
3997
+ *
3998
+ * @param {string} string - text string
3999
+ * @param {object} options - options:
4000
+ * ```javascript
4001
+ * {
4002
+ * length: string.length, //for fixed length, non-terminate value utf strings
4003
+ * stringType: "utf-8", //utf-8, utf-16, pascal or wide-pascal
4004
+ * terminateValue: 0x00, // only with stringType: "utf"
4005
+ * lengthWriteSize: 1, //for pascal strings. 1, 2 or 4 byte length write size
4006
+ * encoding: "utf-8", //TextEncoder accepted types
4007
+ * endian: "little", //for wide-pascal and utf-16
4008
+ * }
4009
+ * ```
4010
+ */
4011
+ writeString(string, options) {
4012
+ return wstring(this, string, options);
3895
4013
  }
3896
4014
  /**
3897
4015
  * Reads string, use options object for different types