bireader 3.1.14 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,25 @@
1
+ const canInt8 = "getUint8" in DataView.prototype && "getInt8" in DataView.prototype && "setUint8" in DataView.prototype && "setInt8" in DataView.prototype;
2
+ const canInt16 = "getUint16" in DataView.prototype && "getInt16" in DataView.prototype && "setUint16" in DataView.prototype && "setInt16" in DataView.prototype;
3
+ const canFloat16 = 'getFloat16' in DataView.prototype && 'setFloat16' in DataView.prototype;
4
+ const canInt32 = 'getInt32' in DataView.prototype && 'getUint32' in DataView.prototype && 'setInt32' in DataView.prototype && 'setUint32' in DataView.prototype;
5
+ const canFloat32 = "getFloat32" in DataView.prototype && "setFloat32" in DataView.prototype;
6
+ const canBigInt64 = "getBigUint64" in DataView.prototype && "getBigInt64" in DataView.prototype && "setBigUint64" in DataView.prototype && "setBigInt64" in DataView.prototype;
7
+ const canFloat64 = "getFloat64" in DataView.prototype && "setFloat64" in DataView.prototype;
8
+ const hasBigInt = typeof BigInt === 'function';
1
9
  const MIN_SAFE = BigInt(Number.MIN_SAFE_INTEGER);
2
10
  const MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);
3
11
  function isSafeInt64(big) {
4
12
  return big >= MIN_SAFE && big <= MAX_SAFE;
5
13
  }
6
14
  function isBuffer(obj) {
7
- return buffcheck(obj);
15
+ return (typeof Buffer !== 'undefined' && Buffer.isBuffer(obj));
8
16
  }
9
- function buffcheck(obj) {
10
- return (typeof Buffer !== 'undefined' && obj instanceof Buffer);
11
- }
12
- function arraybuffcheck(obj) {
17
+ function arrayBufferCheck(obj) {
13
18
  return obj instanceof Uint8Array || isBuffer(obj);
14
19
  }
20
+ function normalizeBitOffset(bit) {
21
+ return ((bit % 8) + 8) % 8;
22
+ }
15
23
  /**
16
24
  * Creates hex dump string. Will console log or return string if set in options.
17
25
  *
@@ -47,13 +55,12 @@ function _hexDump(data, options = {}, start, end) {
47
55
  function hex_check(byte, bits) {
48
56
  var value = 0;
49
57
  for (var i = 0; i < bits;) {
50
- var remaining = bits - i;
51
- var bitOffset = 0;
52
- var currentByte = byte;
53
- var read = Math.min(remaining, 8 - bitOffset);
54
- var mask, readBits;
55
- mask = ~(0xFF << read);
56
- readBits = (currentByte >> (8 - read - bitOffset)) & mask;
58
+ const remaining = bits - i;
59
+ const bitOffset = 0;
60
+ const currentByte = byte;
61
+ const read = Math.min(remaining, 8 - bitOffset);
62
+ const mask = ~(0xFF << read);
63
+ const readBits = (currentByte >> (8 - read - bitOffset)) & mask;
57
64
  value <<= read;
58
65
  value |= readBits;
59
66
  i += read;
@@ -61,10 +68,10 @@ function _hexDump(data, options = {}, start, end) {
61
68
  value = value >>> 0;
62
69
  return value;
63
70
  }
64
- var suppressUnicode = options && options.suppressUnicode || false;
71
+ const suppressUnicode = options && options.suppressUnicode || false;
65
72
  const rows = [];
66
73
  var header = " 0 1 2 3 4 5 6 7 8 9 A B C D E F ";
67
- var ending = "0123456789ABCDEF";
74
+ const ending = "0123456789ABCDEF";
68
75
  var addr = "";
69
76
  for (let i = start; i < end; i += 16) {
70
77
  addr = i.toString(16).padStart(5, '0');
@@ -221,22 +228,87 @@ function _hexDump(data, options = {}, start, end) {
221
228
  }
222
229
  }
223
230
 
231
+ /******************************************************************************
232
+ Copyright (c) Microsoft Corporation.
233
+
234
+ Permission to use, copy, modify, and/or distribute this software for any
235
+ purpose with or without fee is hereby granted.
236
+
237
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
238
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
239
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
240
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
241
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
242
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
243
+ PERFORMANCE OF THIS SOFTWARE.
244
+ ***************************************************************************** */
245
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
246
+
247
+
248
+ function __classPrivateFieldGet(receiver, state, kind, f) {
249
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
250
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
251
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
252
+ }
253
+
254
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
255
+ if (kind === "m") throw new TypeError("Private method is not writable");
256
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
257
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
258
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
259
+ }
260
+
261
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
262
+ var e = new Error(message);
263
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
264
+ };
265
+
266
+ var _BiBase_data;
267
+ const bufferConstants = { MAX_LENGTH: 2147483647 }; // 2 gigs
268
+ var fs;
269
+ (async function () {
270
+ if (typeof process !== 'undefined' && process.versions && process.versions.node) {
271
+ // We are in Node.js
272
+ try {
273
+ if (typeof require !== 'undefined') {
274
+ fs = require('fs');
275
+ const buffer = require("buffer");
276
+ bufferConstants.MAX_LENGTH = buffer.constants.MAX_LENGTH;
277
+ }
278
+ else {
279
+ fs = await import('fs');
280
+ const buffer = await import('buffer');
281
+ bufferConstants.MAX_LENGTH = buffer.constants.MAX_LENGTH;
282
+ }
283
+ }
284
+ catch (error) {
285
+ console.error('Failed to load fs and buffer module:', error);
286
+ }
287
+ }
288
+ })();
289
+ function MAX_LENGTH() {
290
+ return bufferConstants.MAX_LENGTH;
291
+ }
224
292
  function hexDumpBase(ctx, options = {}) {
225
293
  var length = options && options.length;
226
294
  var startByte = options && options.startByte;
227
295
  if ((startByte || 0) > ctx.size) {
228
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
296
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
229
297
  throw new Error("Hexdump start is outside of data size: " + startByte + " of " + ctx.size);
230
298
  }
231
299
  const start = startByte || ctx.offset;
232
300
  const end = Math.min(start + (length || 192), ctx.size);
233
301
  if (start + (length || 0) > ctx.size) {
234
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
302
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
235
303
  throw new Error("Hexdump amount is outside of data size: " + (start + (length || 0)) + " of " + end);
236
304
  }
237
- const data = ctx.data;
305
+ var data = ctx.data;
306
+ if (ctx.mode == "file") {
307
+ data = ctx.lift(start, start + length, false);
308
+ }
238
309
  return _hexDump(data, options, start, end);
239
310
  }
311
+ // #region Movement
240
312
  function skip(ctx, bytes, bits) {
241
313
  var new_size = (((bytes || 0) + ctx.offset) + Math.ceil((ctx.bitoffset + (bits || 0)) / 8));
242
314
  if (bits && bits < 0) {
@@ -252,29 +324,30 @@ function skip(ctx, bytes, bits) {
252
324
  }
253
325
  }
254
326
  else {
255
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
327
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
256
328
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: Seek of range of data: seek " + new_size + " of " + ctx.size);
257
329
  }
258
330
  }
259
331
  // Adjust byte offset based on bit overflow
260
332
  ctx.offset += Math.floor((ctx.bitoffset + (bits || 0)) / 8);
261
333
  // Adjust bit offset
262
- ctx.bitoffset = (ctx.bitoffset + (bits || 0) + 64) % 8;
334
+ ctx.bitoffset = (ctx.bitoffset + normalizeBitOffset(bits)) % 8;
263
335
  // Adjust byte offset based on byte overflow
264
336
  ctx.offset += bytes;
265
337
  // Ensure bit offset stays between 0-7
266
338
  ctx.bitoffset = Math.min(Math.max(ctx.bitoffset, 0), 7);
267
339
  // Ensure offset doesn't go negative
268
340
  ctx.offset = Math.max(ctx.offset, 0);
341
+ return;
269
342
  }
270
343
  function align(ctx, n) {
271
- var a = ctx.offset % n;
344
+ const a = ctx.offset % n;
272
345
  if (a) {
273
346
  ctx.skip(n - a);
274
347
  }
275
348
  }
276
349
  function alignRev(ctx, n) {
277
- var a = ctx.offset % n;
350
+ const a = ctx.offset % n;
278
351
  if (a) {
279
352
  ctx.skip(a * -1);
280
353
  }
@@ -294,32 +367,31 @@ function goto(ctx, bytes, bits) {
294
367
  }
295
368
  }
296
369
  else {
297
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
298
- throw new Error("\x1b[33m[Strict mode]\x1b[0m: Goto utside of range of data: goto " + new_size + " of " + ctx.size);
370
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
371
+ throw new Error("\x1b[33m[Strict mode]\x1b[0m: Goto outside of range of data: goto " + new_size + " of " + ctx.size);
299
372
  }
300
373
  }
301
374
  ctx.offset = bytes;
302
375
  // Adjust byte offset based on bit overflow
303
376
  ctx.offset += Math.floor(((bits || 0)) / 8);
304
377
  // Adjust bit offset
305
- ctx.bitoffset = ((bits || 0) + 64) % 8;
378
+ ctx.bitoffset = normalizeBitOffset(bits) % 8;
306
379
  // Ensure bit offset stays between 0-7
307
380
  ctx.bitoffset = Math.min(Math.max(ctx.bitoffset, 0), 7);
308
381
  // Ensure offset doesn't go negative
309
382
  ctx.offset = Math.max(ctx.offset, 0);
383
+ return;
310
384
  }
385
+ // #region Manipulation
311
386
  function check_size(ctx, write_bytes, write_bit, offset) {
312
- return checkSize(ctx, write_bytes || 0, write_bit || 0, ctx.offset);
313
- }
314
- function checkSize(ctx, write_bytes, write_bit, offset) {
315
387
  const bits = (write_bit || 0) + ctx.bitoffset;
316
- var new_off = (offset || ctx.offset);
388
+ var new_off = (ctx.offset);
317
389
  var writesize = write_bytes || 0;
318
390
  if (bits != 0) {
319
391
  //add bits
320
392
  writesize += Math.ceil(bits / 8);
321
393
  }
322
- //if biger extend
394
+ //if bigger extend
323
395
  const needed_size = new_off + writesize;
324
396
  if (needed_size > ctx.size) {
325
397
  const dif = needed_size - ctx.size;
@@ -332,26 +404,51 @@ function checkSize(ctx, write_bytes, write_bit, offset) {
332
404
  }
333
405
  }
334
406
  else {
335
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
336
- throw new Error(`\x1b[33m[Strict mode]\x1b[0m: Reached end of data: writing to ` + needed_size + " at " + ctx.offset + " of " + ctx.size);
407
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
408
+ throw new Error(`\x1b[33m[Strict mode]\x1b[0m: Reached end of data: ` + needed_size + " at " + ctx.offset + " of " + ctx.size);
337
409
  }
338
410
  }
339
411
  //start read location
340
412
  return new_off;
341
413
  }
342
414
  function extendarray(ctx, to_padd) {
343
- if ((typeof Buffer !== 'undefined' && ctx.data instanceof Buffer)) {
415
+ ctx.open();
416
+ if (ctx.strict) {
417
+ throw new Error('File position is outside of file size while in strict mode.');
418
+ }
419
+ if (ctx.size + to_padd > ctx.maxFileSize) {
420
+ throw new Error("buffer extend outside of max: " + (ctx.size + to_padd) + " to " + ctx.maxFileSize);
421
+ }
422
+ if (ctx.mode == "file") {
423
+ if (ctx.extendBufferSize != 0) {
424
+ if (ctx.extendBufferSize > to_padd) {
425
+ to_padd = ctx.extendBufferSize;
426
+ }
427
+ }
428
+ try {
429
+ fs.ftruncateSync(ctx.fd, ctx.size + to_padd);
430
+ }
431
+ catch (error) {
432
+ throw new Error(error);
433
+ }
434
+ ctx.updateSize();
435
+ return;
436
+ }
437
+ if (isBuffer(ctx.data)) {
344
438
  var paddbuffer = Buffer.alloc(to_padd);
345
439
  ctx.data = Buffer.concat([ctx.data, paddbuffer]);
346
440
  }
347
441
  else {
348
- const addArray = new Array(to_padd);
349
- ctx.data = new Uint8Array([...ctx.data, ...addArray]);
442
+ const newBuf = new Uint8Array(ctx.size + to_padd);
443
+ newBuf.set(ctx.data);
444
+ ctx.data = newBuf;
350
445
  }
351
446
  ctx.size = ctx.data.length;
352
447
  ctx.sizeB = ctx.data.length * 8;
448
+ return;
353
449
  }
354
450
  function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
451
+ ctx.open();
355
452
  const new_start = Math.abs(startOffset || 0);
356
453
  const new_offset = (endOffset || ctx.offset);
357
454
  if (new_offset > ctx.size) {
@@ -364,12 +461,12 @@ function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
364
461
  }
365
462
  }
366
463
  else {
367
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
464
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
368
465
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + endOffset + " of " + ctx.size);
369
466
  }
370
467
  }
371
468
  if (ctx.strict == true && remove == true) {
372
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
469
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
373
470
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: Can not remove data in strict mode: endOffset " + endOffset + " of " + ctx.size);
374
471
  }
375
472
  const data_removed = ctx.data.subarray(new_start, new_offset);
@@ -380,7 +477,10 @@ function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
380
477
  ctx.data = Buffer.concat([part1, part2]);
381
478
  }
382
479
  else {
383
- ctx.data = new Uint8Array([...part1, ...part2]);
480
+ const newBuf = new Uint8Array(part1.byteLength + part2.byteLength);
481
+ newBuf.set(part1, 0);
482
+ newBuf.set(part2, part1.byteLength);
483
+ ctx.data = newBuf;
384
484
  }
385
485
  ctx.size = ctx.data.length;
386
486
  ctx.sizeB = ctx.data.length * 8;
@@ -394,7 +494,11 @@ function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
394
494
  ctx.data = Buffer.concat([part1, buff_placement, part2]);
395
495
  }
396
496
  else {
397
- ctx.data = new Uint8Array([...part1, ...replacement, ...part2]);
497
+ const newBuf = new Uint8Array(part1.byteLength + replacement.length + part2.byteLength);
498
+ newBuf.set(part1, 0);
499
+ newBuf.set(replacement, part1.byteLength);
500
+ newBuf.set(part2, part1.byteLength + replacement.length);
501
+ ctx.data = newBuf;
398
502
  }
399
503
  ctx.size = ctx.data.length;
400
504
  ctx.sizeB = ctx.data.length * 8;
@@ -413,10 +517,11 @@ function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
413
517
  }
414
518
  function addData(ctx, data, consume, offset, replace) {
415
519
  if (ctx.strict == true) {
416
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
520
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
417
521
  throw new Error(`\x1b[33m[Strict mode]\x1b[0m: Can not insert data in strict mode. Use unrestrict() to enable.`);
418
522
  }
419
- if (typeof Buffer !== 'undefined' && data instanceof Buffer && !(ctx.data instanceof Buffer)) {
523
+ ctx.open();
524
+ if (isBuffer(data) && !isBuffer(ctx.data)) {
420
525
  data = Buffer.from(data);
421
526
  }
422
527
  if (data instanceof Uint8Array && !(ctx.data instanceof Uint8Array)) {
@@ -431,7 +536,11 @@ function addData(ctx, data, consume, offset, replace) {
431
536
  ctx.data = Buffer.concat([part1, data, part2]);
432
537
  }
433
538
  else {
434
- ctx.data = new Uint8Array([...part1, ...data, ...part2]);
539
+ const newBuf = new Uint8Array(part1.byteLength + data.byteLength + part2.byteLength);
540
+ newBuf.set(part1, 0);
541
+ newBuf.set(data, part1.byteLength);
542
+ newBuf.set(part2, part1.byteLength + data.byteLength);
543
+ ctx.data = newBuf;
435
544
  }
436
545
  ctx.size = ctx.data.length;
437
546
  ctx.sizeB = ctx.data.length * 8;
@@ -443,7 +552,11 @@ function addData(ctx, data, consume, offset, replace) {
443
552
  ctx.data = Buffer.concat([part1, data, part2]);
444
553
  }
445
554
  else {
446
- ctx.data = new Uint8Array([...part1, ...data, ...part2]);
555
+ const newBuf = new Uint8Array(part1.byteLength + data.byteLength + part2.byteLength);
556
+ newBuf.set(part1, 0);
557
+ newBuf.set(data, part1.byteLength);
558
+ newBuf.set(part2, part1.byteLength + data.byteLength);
559
+ ctx.data = newBuf;
447
560
  }
448
561
  ctx.size = ctx.data.length;
449
562
  ctx.sizeB = ctx.data.length * 8;
@@ -453,8 +566,8 @@ function addData(ctx, data, consume, offset, replace) {
453
566
  ctx.bitoffset = 0;
454
567
  }
455
568
  }
569
+ // #region Math
456
570
  function AND(ctx, and_key, start, end, consume) {
457
- const input = ctx.data;
458
571
  if ((end || 0) > ctx.size) {
459
572
  if (ctx.strict == false) {
460
573
  if (ctx.extendBufferSize != 0) {
@@ -465,13 +578,14 @@ function AND(ctx, and_key, start, end, consume) {
465
578
  }
466
579
  }
467
580
  else {
468
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
581
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
469
582
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
470
583
  }
471
584
  }
585
+ ctx.open();
472
586
  if (typeof and_key == "number") {
473
587
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
474
- input[i] = input[i] & (and_key & 0xff);
588
+ ctx.data[i] = ctx.data[i] & (and_key & 0xff);
475
589
  if (consume) {
476
590
  ctx.offset = i;
477
591
  ctx.bitoffset = 0;
@@ -479,8 +593,11 @@ function AND(ctx, and_key, start, end, consume) {
479
593
  }
480
594
  }
481
595
  else {
482
- if (arraybuffcheck(and_key)) {
483
- let number = -1;
596
+ if (typeof and_key == "string") {
597
+ and_key = Uint8Array.from(Array.from(and_key).map(letter => letter.charCodeAt(0)));
598
+ }
599
+ if (arrayBufferCheck(and_key)) {
600
+ var number = -1;
484
601
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
485
602
  if (number != and_key.length - 1) {
486
603
  number = number + 1;
@@ -488,7 +605,7 @@ function AND(ctx, and_key, start, end, consume) {
488
605
  else {
489
606
  number = 0;
490
607
  }
491
- input[i] = input[i] & and_key[number];
608
+ ctx.data[i] = ctx.data[i] & and_key[number];
492
609
  if (consume) {
493
610
  ctx.offset = i;
494
611
  ctx.bitoffset = 0;
@@ -501,7 +618,6 @@ function AND(ctx, and_key, start, end, consume) {
501
618
  }
502
619
  }
503
620
  function OR(ctx, or_key, start, end, consume) {
504
- const input = ctx.data;
505
621
  if ((end || 0) > ctx.size) {
506
622
  if (ctx.strict == false) {
507
623
  if (ctx.extendBufferSize != 0) {
@@ -512,13 +628,14 @@ function OR(ctx, or_key, start, end, consume) {
512
628
  }
513
629
  }
514
630
  else {
515
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
631
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
516
632
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
517
633
  }
518
634
  }
635
+ ctx.open();
519
636
  if (typeof or_key == "number") {
520
637
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
521
- input[i] = input[i] | (or_key & 0xff);
638
+ ctx.data[i] = ctx.data[i] | (or_key & 0xff);
522
639
  if (consume) {
523
640
  ctx.offset = i;
524
641
  ctx.bitoffset = 0;
@@ -526,8 +643,11 @@ function OR(ctx, or_key, start, end, consume) {
526
643
  }
527
644
  }
528
645
  else {
529
- if (arraybuffcheck(or_key)) {
530
- let number = -1;
646
+ if (typeof or_key == "string") {
647
+ or_key = Uint8Array.from(Array.from(or_key).map(letter => letter.charCodeAt(0)));
648
+ }
649
+ if (arrayBufferCheck(or_key)) {
650
+ var number = -1;
531
651
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
532
652
  if (number != or_key.length - 1) {
533
653
  number = number + 1;
@@ -535,7 +655,7 @@ function OR(ctx, or_key, start, end, consume) {
535
655
  else {
536
656
  number = 0;
537
657
  }
538
- input[i] = input[i] | or_key[number];
658
+ ctx.data[i] = ctx.data[i] | or_key[number];
539
659
  if (consume) {
540
660
  ctx.offset = i;
541
661
  ctx.bitoffset = 0;
@@ -548,7 +668,6 @@ function OR(ctx, or_key, start, end, consume) {
548
668
  }
549
669
  }
550
670
  function XOR(ctx, xor_key, start, end, consume) {
551
- const input = ctx.data;
552
671
  if ((end || 0) > ctx.size) {
553
672
  if (ctx.strict == false) {
554
673
  if (ctx.extendBufferSize != 0) {
@@ -559,13 +678,14 @@ function XOR(ctx, xor_key, start, end, consume) {
559
678
  }
560
679
  }
561
680
  else {
562
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
681
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
563
682
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
564
683
  }
565
684
  }
685
+ ctx.open();
566
686
  if (typeof xor_key == "number") {
567
687
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
568
- input[i] = input[i] ^ (xor_key & 0xff);
688
+ ctx.data[i] = ctx.data[i] ^ (xor_key & 0xff);
569
689
  if (consume) {
570
690
  ctx.offset = i;
571
691
  ctx.bitoffset = 0;
@@ -573,7 +693,10 @@ function XOR(ctx, xor_key, start, end, consume) {
573
693
  }
574
694
  }
575
695
  else {
576
- if (arraybuffcheck(xor_key)) {
696
+ if (typeof xor_key == "string") {
697
+ xor_key = Uint8Array.from(Array.from(xor_key).map(letter => letter.charCodeAt(0)));
698
+ }
699
+ if (arrayBufferCheck(xor_key)) {
577
700
  let number = -1;
578
701
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
579
702
  if (number != xor_key.length - 1) {
@@ -582,7 +705,7 @@ function XOR(ctx, xor_key, start, end, consume) {
582
705
  else {
583
706
  number = 0;
584
707
  }
585
- input[i] = input[i] ^ xor_key[number];
708
+ ctx.data[i] = ctx.data[i] ^ xor_key[number];
586
709
  if (consume) {
587
710
  ctx.offset = i;
588
711
  ctx.bitoffset = 0;
@@ -605,10 +728,11 @@ function NOT(ctx, start, end, consume) {
605
728
  }
606
729
  }
607
730
  else {
608
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
731
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
609
732
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
610
733
  }
611
734
  }
735
+ ctx.open();
612
736
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
613
737
  ctx.data[i] = ~ctx.data[i];
614
738
  if (consume) {
@@ -618,7 +742,6 @@ function NOT(ctx, start, end, consume) {
618
742
  }
619
743
  }
620
744
  function LSHIFT(ctx, shift_key, start, end, consume) {
621
- const input = ctx.data;
622
745
  if ((end || 0) > ctx.size) {
623
746
  if (ctx.strict == false) {
624
747
  if (ctx.extendBufferSize != 0) {
@@ -629,13 +752,14 @@ function LSHIFT(ctx, shift_key, start, end, consume) {
629
752
  }
630
753
  }
631
754
  else {
632
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
755
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
633
756
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
634
757
  }
635
758
  }
759
+ ctx.open();
636
760
  if (typeof shift_key == "number") {
637
761
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
638
- input[i] = input[i] << shift_key;
762
+ ctx.data[i] = ctx.data[i] << shift_key;
639
763
  if (consume) {
640
764
  ctx.offset = i;
641
765
  ctx.bitoffset = 0;
@@ -643,8 +767,11 @@ function LSHIFT(ctx, shift_key, start, end, consume) {
643
767
  }
644
768
  }
645
769
  else {
646
- if (arraybuffcheck(shift_key)) {
647
- let number = -1;
770
+ if (typeof shift_key == "string") {
771
+ shift_key = Uint8Array.from(Array.from(shift_key).map(letter => letter.charCodeAt(0)));
772
+ }
773
+ if (arrayBufferCheck(shift_key)) {
774
+ var number = -1;
648
775
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
649
776
  if (number != shift_key.length - 1) {
650
777
  number = number + 1;
@@ -652,7 +779,7 @@ function LSHIFT(ctx, shift_key, start, end, consume) {
652
779
  else {
653
780
  number = 0;
654
781
  }
655
- input[i] = input[i] << shift_key[number];
782
+ ctx.data[i] = ctx.data[i] << shift_key[number];
656
783
  if (consume) {
657
784
  ctx.offset = i;
658
785
  ctx.bitoffset = 0;
@@ -665,7 +792,6 @@ function LSHIFT(ctx, shift_key, start, end, consume) {
665
792
  }
666
793
  }
667
794
  function RSHIFT(ctx, shift_key, start, end, consume) {
668
- const input = ctx.data;
669
795
  if ((end || 0) > ctx.size) {
670
796
  if (ctx.strict == false) {
671
797
  if (ctx.extendBufferSize != 0) {
@@ -676,13 +802,14 @@ function RSHIFT(ctx, shift_key, start, end, consume) {
676
802
  }
677
803
  }
678
804
  else {
679
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
805
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
680
806
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
681
807
  }
682
808
  }
809
+ ctx.open();
683
810
  if (typeof shift_key == "number") {
684
811
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
685
- input[i] = input[i] >> shift_key;
812
+ ctx.data[i] = ctx.data[i] >> shift_key;
686
813
  if (consume) {
687
814
  ctx.offset = i;
688
815
  ctx.bitoffset = 0;
@@ -690,8 +817,11 @@ function RSHIFT(ctx, shift_key, start, end, consume) {
690
817
  }
691
818
  }
692
819
  else {
693
- if (arraybuffcheck(shift_key)) {
694
- let number = -1;
820
+ if (typeof shift_key == "string") {
821
+ shift_key = Uint8Array.from(Array.from(shift_key).map(letter => letter.charCodeAt(0)));
822
+ }
823
+ if (arrayBufferCheck(shift_key)) {
824
+ var number = -1;
695
825
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
696
826
  if (number != shift_key.length - 1) {
697
827
  number = number + 1;
@@ -699,7 +829,7 @@ function RSHIFT(ctx, shift_key, start, end, consume) {
699
829
  else {
700
830
  number = 0;
701
831
  }
702
- input[i] = input[i] >> shift_key[number];
832
+ ctx.data[i] = ctx.data[i] >> shift_key[number];
703
833
  if (consume) {
704
834
  ctx.offset = i;
705
835
  ctx.bitoffset = 0;
@@ -712,7 +842,6 @@ function RSHIFT(ctx, shift_key, start, end, consume) {
712
842
  }
713
843
  }
714
844
  function ADD(ctx, add_key, start, end, consume) {
715
- const input = ctx.data;
716
845
  if ((end || 0) > ctx.size) {
717
846
  if (ctx.strict == false) {
718
847
  if (ctx.extendBufferSize != 0) {
@@ -723,13 +852,14 @@ function ADD(ctx, add_key, start, end, consume) {
723
852
  }
724
853
  }
725
854
  else {
726
- ctx.errorDump ? console.log("[Error], hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
855
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
727
856
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
728
857
  }
729
858
  }
859
+ ctx.open();
730
860
  if (typeof add_key == "number") {
731
861
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
732
- input[i] = input[i] + add_key;
862
+ ctx.data[i] = ctx.data[i] + add_key;
733
863
  if (consume) {
734
864
  ctx.offset = i;
735
865
  ctx.bitoffset = 0;
@@ -737,8 +867,11 @@ function ADD(ctx, add_key, start, end, consume) {
737
867
  }
738
868
  }
739
869
  else {
740
- if (arraybuffcheck(add_key)) {
741
- let number = -1;
870
+ if (typeof add_key == "string") {
871
+ add_key = Uint8Array.from(Array.from(add_key).map(letter => letter.charCodeAt(0)));
872
+ }
873
+ if (arrayBufferCheck(add_key)) {
874
+ var number = -1;
742
875
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
743
876
  if (number != add_key.length - 1) {
744
877
  number = number + 1;
@@ -746,7 +879,7 @@ function ADD(ctx, add_key, start, end, consume) {
746
879
  else {
747
880
  number = 0;
748
881
  }
749
- input[i] = input[i] + add_key[number];
882
+ ctx.data[i] = ctx.data[i] + add_key[number];
750
883
  if (consume) {
751
884
  ctx.offset = i;
752
885
  ctx.bitoffset = 0;
@@ -758,11 +891,13 @@ function ADD(ctx, add_key, start, end, consume) {
758
891
  }
759
892
  }
760
893
  }
894
+ // #region Search
761
895
  function fString(ctx, searchString) {
896
+ ctx.open();
762
897
  // Convert the searchString to Uint8Array
763
898
  const searchArray = new TextEncoder().encode(searchString);
764
899
  for (let i = ctx.offset; i <= ctx.size - searchArray.length; i++) {
765
- let match = true;
900
+ var match = true;
766
901
  for (let j = 0; j < searchArray.length; j++) {
767
902
  if (ctx.data[i + j] !== searchArray[j]) {
768
903
  match = false;
@@ -776,25 +911,25 @@ function fString(ctx, searchString) {
776
911
  return -1; // String not found
777
912
  }
778
913
  function fNumber(ctx, targetNumber, bits, unsigned, endian) {
914
+ ctx.open();
779
915
  check_size(ctx, Math.floor(bits / 8), 0);
780
916
  for (let z = ctx.offset; z <= (ctx.size - (bits / 8)); z++) {
781
917
  var off_in_bits = 0;
782
918
  var value = 0;
783
919
  for (var i = 0; i < bits;) {
784
- var remaining = bits - i;
785
- var bitOffset = off_in_bits & 7;
786
- var currentByte = ctx.data[z + (off_in_bits >> 3)];
787
- var read = Math.min(remaining, 8 - bitOffset);
788
- var mask, readBits;
920
+ const remaining = bits - i;
921
+ const bitOffset = off_in_bits & 7;
922
+ const currentByte = ctx.data[z + (off_in_bits >> 3)];
923
+ const read = Math.min(remaining, 8 - bitOffset);
789
924
  if ((endian != undefined ? endian : ctx.endian) == "big") {
790
- mask = ~(0xFF << read);
791
- readBits = (currentByte >> (8 - read - bitOffset)) & mask;
925
+ let mask = ~(0xFF << read);
926
+ let readBits = (currentByte >> (8 - read - bitOffset)) & mask;
792
927
  value <<= read;
793
928
  value |= readBits;
794
929
  }
795
930
  else {
796
- mask = ~(0xFF << read);
797
- readBits = (currentByte >> bitOffset) & mask;
931
+ let mask = ~(0xFF << read);
932
+ let readBits = (currentByte >> bitOffset) & mask;
798
933
  value |= readBits << i;
799
934
  }
800
935
  off_in_bits += read;
@@ -815,19 +950,20 @@ function fNumber(ctx, targetNumber, bits, unsigned, endian) {
815
950
  return -1; // number not found
816
951
  }
817
952
  function fHalfFloat(ctx, targetNumber, endian) {
953
+ ctx.open();
818
954
  check_size(ctx, 2, 0);
819
955
  for (let z = ctx.offset; z <= (ctx.size - 2); z++) {
820
956
  var value = 0;
821
957
  if ((endian != undefined ? endian : ctx.endian) == "little") {
822
- value = (ctx.data[z + 1] << 8) | ctx.data[z];
958
+ value = ((ctx.data[z + 1] & 0xFFFF) << 8) | (ctx.data[z] & 0xFFFF);
823
959
  }
824
960
  else {
825
- value = (ctx.data[z] << 8) | ctx.data[z + 1];
961
+ value = ((ctx.data[z] & 0xFFFF) << 8) | (ctx.data[z + 1] & 0xFFFF);
826
962
  }
827
963
  const sign = (value & 0x8000) >> 15;
828
964
  const exponent = (value & 0x7C00) >> 10;
829
965
  const fraction = value & 0x03FF;
830
- let floatValue;
966
+ var floatValue;
831
967
  if (exponent === 0) {
832
968
  if (fraction === 0) {
833
969
  floatValue = (sign === 0) ? 0 : -0; // +/-0
@@ -856,21 +992,28 @@ function fHalfFloat(ctx, targetNumber, endian) {
856
992
  return -1; // number not found
857
993
  }
858
994
  function fFloat(ctx, targetNumber, endian) {
995
+ ctx.open();
859
996
  check_size(ctx, 4, 0);
860
997
  for (let z = ctx.offset; z <= (ctx.size - 4); z++) {
861
998
  var value = 0;
862
999
  if ((endian != undefined ? endian : ctx.endian) == "little") {
863
- value = ((ctx.data[z + 3] << 24) | (ctx.data[z + 2] << 16) | (ctx.data[z + 1] << 8) | ctx.data[z]);
1000
+ value = ((ctx.data[z + 3] & 0xFF) << 24) |
1001
+ ((ctx.data[z + 2] & 0xFF) << 16) |
1002
+ ((ctx.data[z + 1] & 0xFF) << 8) |
1003
+ (ctx.data[z] & 0xFF);
864
1004
  }
865
1005
  else {
866
- value = (ctx.data[z] << 24) | (ctx.data[z + 1] << 16) | (ctx.data[z + 2] << 8) | ctx.data[z + 3];
1006
+ value = ((ctx.data[z] & 0xFF) << 24) |
1007
+ ((ctx.data[z + 1] & 0xFF) << 16) |
1008
+ ((ctx.data[z + 2] & 0xFF) << 8) |
1009
+ (ctx.data[z + 3] & 0xFF);
867
1010
  }
868
1011
  const isNegative = (value & 0x80000000) !== 0 ? 1 : 0;
869
1012
  // Extract the exponent and fraction parts
870
1013
  const exponent = (value >> 23) & 0xFF;
871
1014
  const fraction = value & 0x7FFFFF;
872
1015
  // Calculate the float value
873
- let floatValue;
1016
+ var floatValue;
874
1017
  if (exponent === 0) {
875
1018
  // Denormalized number (exponent is 0)
876
1019
  floatValue = Math.pow(-1, isNegative) * Math.pow(2, -126) * (fraction / Math.pow(2, 23));
@@ -890,12 +1033,16 @@ function fFloat(ctx, targetNumber, endian) {
890
1033
  return -1; // number not found
891
1034
  }
892
1035
  function fBigInt(ctx, targetNumber, unsigned, endian) {
1036
+ if (!hasBigInt) {
1037
+ throw new Error("System doesn't support BigInt values.");
1038
+ }
1039
+ ctx.open();
893
1040
  check_size(ctx, 8, 0);
894
1041
  for (let z = ctx.offset; z <= (ctx.size - 8); z++) {
895
- let value = BigInt(0);
1042
+ var value = BigInt(0);
896
1043
  if ((endian == undefined ? ctx.endian : endian) == "little") {
897
1044
  for (let i = 0; i < 8; i++) {
898
- value = value | BigInt(ctx.data[z + i]) << BigInt(8 * i);
1045
+ value = value | BigInt((ctx.data[z + i] & 0xFF)) << BigInt(8 * i);
899
1046
  }
900
1047
  if (unsigned == undefined || unsigned == false) {
901
1048
  if (value & (BigInt(1) << BigInt(63))) {
@@ -905,7 +1052,7 @@ function fBigInt(ctx, targetNumber, unsigned, endian) {
905
1052
  }
906
1053
  else {
907
1054
  for (let i = 0; i < 8; i++) {
908
- value = (value << BigInt(8)) | BigInt(ctx.data[z + i]);
1055
+ value = (value << BigInt(8)) | BigInt((ctx.data[z + i] & 0xFF));
909
1056
  }
910
1057
  if (unsigned == undefined || unsigned == false) {
911
1058
  if (value & (BigInt(1) << BigInt(63))) {
@@ -920,35 +1067,39 @@ function fBigInt(ctx, targetNumber, unsigned, endian) {
920
1067
  return -1; // number not found
921
1068
  }
922
1069
  function fDoubleFloat(ctx, targetNumber, endian) {
1070
+ if (!hasBigInt) {
1071
+ throw new Error("System doesn't support BigInt values.");
1072
+ }
1073
+ ctx.open();
923
1074
  check_size(ctx, 8, 0);
924
1075
  for (let z = ctx.offset; z <= (ctx.size - 8); z++) {
925
- let value = BigInt(0);
1076
+ var value = BigInt(0);
926
1077
  if ((endian == undefined ? ctx.endian : endian) == "little") {
927
1078
  for (let i = 0; i < 8; i++) {
928
- value = value | BigInt(ctx.data[z + i]) << BigInt(8 * i);
1079
+ value = value | BigInt((ctx.data[z + i] & 0xFF)) << BigInt(8 * i);
929
1080
  }
930
1081
  }
931
1082
  else {
932
1083
  for (let i = 0; i < 8; i++) {
933
- value = (value << BigInt(8)) | BigInt(ctx.data[z + i]);
1084
+ value = (value << BigInt(8)) | BigInt((ctx.data[z + i] & 0xFF));
934
1085
  }
935
1086
  }
936
- const sign = (value & 0x8000000000000000n) >> 63n;
937
- const exponent = Number((value & 0x7ff0000000000000n) >> 52n) - 1023;
938
- const fraction = Number(value & 0x000fffffffffffffn) / Math.pow(2, 52);
1087
+ const sign = (value & BigInt("9223372036854775808")) >> BigInt(63);
1088
+ const exponent = Number((value & BigInt("9218868437227405312")) >> BigInt(52)) - 1023;
1089
+ const fraction = Number(value & BigInt("4503599627370495")) / Math.pow(2, 52);
939
1090
  var floatValue;
940
1091
  if (exponent == -1023) {
941
1092
  if (fraction == 0) {
942
- floatValue = (sign == 0n) ? 0 : -0; // +/-0
1093
+ floatValue = (sign == BigInt(0)) ? 0 : -0; // +/-0
943
1094
  }
944
1095
  else {
945
1096
  // Denormalized number
946
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, -1022) * fraction;
1097
+ floatValue = (sign == BigInt(0) ? 1 : -1) * Math.pow(2, -1022) * fraction;
947
1098
  }
948
1099
  }
949
1100
  else if (exponent == 1024) {
950
1101
  if (fraction == 0) {
951
- floatValue = (sign == 0n) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
1102
+ floatValue = (sign == BigInt(0)) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
952
1103
  }
953
1104
  else {
954
1105
  floatValue = Number.NaN;
@@ -956,7 +1107,7 @@ function fDoubleFloat(ctx, targetNumber, endian) {
956
1107
  }
957
1108
  else {
958
1109
  // Normalized number
959
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
1110
+ floatValue = (sign == BigInt(0) ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
960
1111
  }
961
1112
  if (floatValue == targetNumber) {
962
1113
  return z;
@@ -964,7 +1115,9 @@ function fDoubleFloat(ctx, targetNumber, endian) {
964
1115
  }
965
1116
  return -1; // number not found
966
1117
  }
1118
+ // #region Write / Read Bits
967
1119
  function wbit(ctx, value, bits, unsigned, endian) {
1120
+ ctx.open();
968
1121
  if (value == undefined) {
969
1122
  throw new Error('Must supply value.');
970
1123
  }
@@ -979,7 +1132,7 @@ function wbit(ctx, value, bits, unsigned, endian) {
979
1132
  }
980
1133
  if (unsigned == true || bits == 1) {
981
1134
  if (value < 0 || value > Math.pow(2, bits)) {
982
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1135
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
983
1136
  throw new Error(`Value is out of range for the specified ${bits}bit length.` + " min: " + 0 + " max: " + Math.pow(2, bits) + " value: " + value);
984
1137
  }
985
1138
  }
@@ -987,7 +1140,7 @@ function wbit(ctx, value, bits, unsigned, endian) {
987
1140
  const maxValue = Math.pow(2, bits - 1) - 1;
988
1141
  const minValue = -maxValue - 1;
989
1142
  if (value < minValue || value > maxValue) {
990
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1143
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
991
1144
  throw new Error(`Value is out of range for the specified ${bits}bit length.` + " min: " + minValue + " max: " + maxValue + " value: " + value);
992
1145
  }
993
1146
  }
@@ -1007,23 +1160,22 @@ function wbit(ctx, value, bits, unsigned, endian) {
1007
1160
  }
1008
1161
  var off_in_bits = (ctx.offset * 8) + ctx.bitoffset;
1009
1162
  for (var i = 0; i < bits;) {
1010
- var remaining = bits - i;
1011
- var bitOffset = off_in_bits & 7;
1012
- var byteOffset = off_in_bits >> 3;
1013
- var written = Math.min(remaining, 8 - bitOffset);
1014
- var mask, writeBits, destMask;
1163
+ const remaining = bits - i;
1164
+ const bitOffset = off_in_bits & 7;
1165
+ const byteOffset = off_in_bits >> 3;
1166
+ const written = Math.min(remaining, 8 - bitOffset);
1015
1167
  if ((endian != undefined ? endian : ctx.endian) == "big") {
1016
- mask = ~(-1 << written);
1017
- writeBits = (value >> (bits - i - written)) & mask;
1168
+ let mask = ~(-1 << written);
1169
+ let writeBits = (value >> (bits - i - written)) & mask;
1018
1170
  var destShift = 8 - bitOffset - written;
1019
- destMask = ~(mask << destShift);
1171
+ let destMask = ~(mask << destShift);
1020
1172
  ctx.data[byteOffset] = (ctx.data[byteOffset] & destMask) | (writeBits << destShift);
1021
1173
  }
1022
1174
  else {
1023
- mask = ~(0xFF << written);
1024
- writeBits = value & mask;
1175
+ let mask = ~(0xFF << written);
1176
+ let writeBits = value & mask;
1025
1177
  value >>= written;
1026
- destMask = ~(mask << bitOffset);
1178
+ let destMask = ~(mask << bitOffset);
1027
1179
  ctx.data[byteOffset] = (ctx.data[byteOffset] & destMask) | (writeBits << bitOffset);
1028
1180
  }
1029
1181
  off_in_bits += written;
@@ -1033,6 +1185,7 @@ function wbit(ctx, value, bits, unsigned, endian) {
1033
1185
  ctx.bitoffset = ((bits) + ctx.bitoffset) % 8;
1034
1186
  }
1035
1187
  function rbit(ctx, bits, unsigned, endian) {
1188
+ ctx.open();
1036
1189
  if (bits == undefined || typeof bits != "number") {
1037
1190
  throw new Error("Enter number of bits to read");
1038
1191
  }
@@ -1044,26 +1197,25 @@ function rbit(ctx, bits, unsigned, endian) {
1044
1197
  }
1045
1198
  const size_needed = ((((bits - 1) + ctx.bitoffset) / 8) + ctx.offset);
1046
1199
  if (bits <= 0 || size_needed > ctx.size) {
1047
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1200
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1048
1201
  throw new Error("Invalid number of bits to read: " + size_needed + " of " + ctx.size);
1049
1202
  }
1050
1203
  var off_in_bits = (ctx.offset * 8) + ctx.bitoffset;
1051
1204
  var value = 0;
1052
1205
  for (var i = 0; i < bits;) {
1053
- var remaining = bits - i;
1054
- var bitOffset = off_in_bits & 7;
1055
- var currentByte = ctx.data[off_in_bits >> 3];
1056
- var read = Math.min(remaining, 8 - bitOffset);
1057
- var mask, readBits;
1206
+ const remaining = bits - i;
1207
+ const bitOffset = off_in_bits & 7;
1208
+ const currentByte = ctx.data[off_in_bits >> 3];
1209
+ const read = Math.min(remaining, 8 - bitOffset);
1058
1210
  if ((endian != undefined ? endian : ctx.endian) == "big") {
1059
- mask = ~(0xFF << read);
1060
- readBits = (currentByte >> (8 - read - bitOffset)) & mask;
1211
+ let mask = ~(0xFF << read);
1212
+ let readBits = (currentByte >> (8 - read - bitOffset)) & mask;
1061
1213
  value <<= read;
1062
1214
  value |= readBits;
1063
1215
  }
1064
1216
  else {
1065
- mask = ~(0xFF << read);
1066
- readBits = (currentByte >> bitOffset) & mask;
1217
+ let mask = ~(0xFF << read);
1218
+ let readBits = (currentByte >> bitOffset) & mask;
1067
1219
  value |= readBits << i;
1068
1220
  }
1069
1221
  off_in_bits += read;
@@ -1079,11 +1231,13 @@ function rbit(ctx, bits, unsigned, endian) {
1079
1231
  }
1080
1232
  return value;
1081
1233
  }
1234
+ // #region Write / Read Bytes
1082
1235
  function wbyte(ctx, value, unsigned) {
1236
+ ctx.open();
1083
1237
  check_size(ctx, 1, 0);
1084
1238
  if (unsigned == true) {
1085
1239
  if (value < 0 || value > 255) {
1086
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1240
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1087
1241
  throw new Error('Value is out of range for the specified 8bit length.' + " min: " + 0 + " max: " + 255 + " value: " + value);
1088
1242
  }
1089
1243
  }
@@ -1091,17 +1245,40 @@ function wbyte(ctx, value, unsigned) {
1091
1245
  const maxValue = Math.pow(2, 8 - 1) - 1;
1092
1246
  const minValue = -maxValue - 1;
1093
1247
  if (value < minValue || value > maxValue) {
1094
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1248
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1095
1249
  throw new Error('Value is out of range for the specified 8bit length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1096
1250
  }
1097
1251
  }
1098
- ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? value : value & 0xFF;
1252
+ if (canInt8) {
1253
+ if ((unsigned == undefined || unsigned == false)) {
1254
+ ctx.view.setInt8(ctx.offset, value);
1255
+ }
1256
+ else {
1257
+ ctx.view.setUint8(ctx.offset, value);
1258
+ }
1259
+ }
1260
+ else {
1261
+ ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? value : value & 0xFF;
1262
+ }
1099
1263
  ctx.offset += 1;
1100
1264
  ctx.bitoffset = 0;
1101
1265
  }
1102
1266
  function rbyte(ctx, unsigned) {
1267
+ ctx.open();
1103
1268
  check_size(ctx, 1);
1104
- const read = ctx.data[ctx.offset];
1269
+ var read;
1270
+ if (canInt8) {
1271
+ if ((unsigned == undefined || unsigned == false)) {
1272
+ read = ctx.view.getInt8(ctx.offset);
1273
+ }
1274
+ else {
1275
+ read = ctx.view.getUint8(ctx.offset);
1276
+ }
1277
+ ctx.offset += 1;
1278
+ ctx.bitoffset = 0;
1279
+ return read;
1280
+ }
1281
+ read = ctx.data[ctx.offset];
1105
1282
  ctx.offset += 1;
1106
1283
  ctx.bitoffset = 0;
1107
1284
  if (unsigned == true) {
@@ -1111,11 +1288,13 @@ function rbyte(ctx, unsigned) {
1111
1288
  return read > 127 ? read - 256 : read;
1112
1289
  }
1113
1290
  }
1291
+ // #region Write / Read Int16
1114
1292
  function wint16(ctx, value, unsigned, endian) {
1293
+ ctx.open();
1115
1294
  check_size(ctx, 2, 0);
1116
1295
  if (unsigned == true) {
1117
1296
  if (value < 0 || value > 65535) {
1118
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1297
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1119
1298
  throw new Error('Value is out of range for the specified 16bit length.' + " min: " + 0 + " max: " + 65535 + " value: " + value);
1120
1299
  }
1121
1300
  }
@@ -1123,29 +1302,53 @@ function wint16(ctx, value, unsigned, endian) {
1123
1302
  const maxValue = Math.pow(2, 16 - 1) - 1;
1124
1303
  const minValue = -maxValue - 1;
1125
1304
  if (value < minValue || value > maxValue) {
1126
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1305
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1127
1306
  throw new Error('Value is out of range for the specified 16bit length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1128
1307
  }
1129
1308
  }
1130
- if ((endian != undefined ? endian : ctx.endian) == "little") {
1131
- ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? value : value & 0xff;
1132
- ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xff;
1309
+ if (canInt16) {
1310
+ if ((unsigned == undefined || unsigned == false)) {
1311
+ ctx.view.setInt16(ctx.offset, value, endian != undefined ? endian == "little" : ctx.endian == "little");
1312
+ }
1313
+ else {
1314
+ ctx.view.setUint16(ctx.offset, value, endian != undefined ? endian == "little" : ctx.endian == "little");
1315
+ }
1133
1316
  }
1134
1317
  else {
1135
- ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xff;
1136
- ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? value : value & 0xff;
1318
+ if ((endian != undefined ? endian : ctx.endian) == "little") {
1319
+ ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? value : value & 0xff;
1320
+ ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xff;
1321
+ }
1322
+ else {
1323
+ ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xff;
1324
+ ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? value : value & 0xff;
1325
+ }
1137
1326
  }
1138
1327
  ctx.offset += 2;
1139
1328
  ctx.bitoffset = 0;
1140
1329
  }
1141
1330
  function rint16(ctx, unsigned, endian) {
1331
+ ctx.open();
1142
1332
  check_size(ctx, 2);
1143
1333
  var read;
1144
- if ((endian != undefined ? endian : ctx.endian) == "little") {
1145
- read = (ctx.data[ctx.offset + 1] << 8) | ctx.data[ctx.offset];
1334
+ if (canInt16) {
1335
+ if (unsigned == undefined || unsigned == false) {
1336
+ read = ctx.view.getInt16(ctx.offset, endian != undefined ? endian == "little" : ctx.endian == "little");
1337
+ }
1338
+ else {
1339
+ read = ctx.view.getUint16(ctx.offset, endian != undefined ? endian == "little" : ctx.endian == "little");
1340
+ }
1341
+ ctx.offset += 2;
1342
+ ctx.bitoffset = 0;
1343
+ return read;
1146
1344
  }
1147
1345
  else {
1148
- read = (ctx.data[ctx.offset] << 8) | ctx.data[ctx.offset + 1];
1346
+ if ((endian != undefined ? endian : ctx.endian) == "little") {
1347
+ read = ((ctx.data[ctx.offset + 1] & 0xFFFF) << 8) | (ctx.data[ctx.offset] & 0xFFFF);
1348
+ }
1349
+ else {
1350
+ read = ((ctx.data[ctx.offset] & 0xFFFF) << 8) | (ctx.data[ctx.offset + 1] & 0xFFFF);
1351
+ }
1149
1352
  }
1150
1353
  ctx.offset += 2;
1151
1354
  ctx.bitoffset = 0;
@@ -1156,12 +1359,21 @@ function rint16(ctx, unsigned, endian) {
1156
1359
  return read & 0xFFFF;
1157
1360
  }
1158
1361
  }
1362
+ // #region Write / Read Float16
1159
1363
  function rhalffloat(ctx, endian) {
1364
+ if (canFloat16) {
1365
+ ctx.open();
1366
+ check_size(ctx, 2);
1367
+ const float16Value = ctx.view.getFloat16(ctx.offset, endian != undefined ? endian == "little" : ctx.endian == "little");
1368
+ ctx.offset += 2;
1369
+ ctx.bitoffset = 0;
1370
+ return float16Value;
1371
+ }
1160
1372
  var uint16Value = ctx.readInt16(true, (endian != undefined ? endian : ctx.endian));
1161
1373
  const sign = (uint16Value & 0x8000) >> 15;
1162
1374
  const exponent = (uint16Value & 0x7C00) >> 10;
1163
1375
  const fraction = uint16Value & 0x03FF;
1164
- let floatValue;
1376
+ var floatValue;
1165
1377
  if (exponent === 0) {
1166
1378
  if (fraction === 0) {
1167
1379
  floatValue = (sign === 0) ? 0 : -0; // +/-0
@@ -1186,36 +1398,54 @@ function rhalffloat(ctx, endian) {
1186
1398
  return floatValue;
1187
1399
  }
1188
1400
  function whalffloat(ctx, value, endian) {
1401
+ ctx.open();
1189
1402
  check_size(ctx, 2, 0);
1190
1403
  const maxValue = 65504;
1191
1404
  const minValue = 5.96e-08;
1192
1405
  if (value < minValue || value > maxValue) {
1193
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1406
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1194
1407
  throw new Error('Value is out of range for the specified half float length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1195
1408
  }
1196
- const signMask = 0x8000;
1197
- const exponentMask = 0x7C00;
1198
- const fractionMask = 0x03FF;
1199
- // Determine sign, exponent, and fraction bits
1200
- let signBit = (value & signMask) >> 15;
1201
- let exponentBits = (value & exponentMask) >> 10;
1202
- let fractionBits = value & fractionMask;
1203
- // Special cases for NaN and Infinity
1204
- if (exponentBits === 0x1F) {
1205
- // NaN or Infinity, copy exponent and fraction
1206
- exponentBits = 0xFF;
1207
- }
1208
- else if (exponentBits === 0x00) {
1209
- // Denormalized numbers, exponent is 0, adjust exponent bits
1210
- exponentBits = 0x00;
1211
- fractionBits = 0x00; // Clear fraction for denormals
1409
+ if (canFloat16) {
1410
+ ctx.view.setFloat16(ctx.offset, value, endian != undefined ? endian == "little" : ctx.endian == "little");
1411
+ ctx.offset += 2;
1412
+ ctx.bitoffset = 0;
1413
+ return;
1414
+ }
1415
+ const floatView = new Float32Array(1);
1416
+ const intView = new Uint32Array(floatView.buffer);
1417
+ floatView[0] = value;
1418
+ const x = intView[0];
1419
+ const sign = (x >> 31) & 0x1;
1420
+ var exponent = (x >> 23) & 0xff;
1421
+ var mantissa = x & 0x7fffff;
1422
+ var halfFloatBits;
1423
+ if (exponent === 0xff) {
1424
+ // NaN or Infinity
1425
+ halfFloatBits = (sign << 15) | (0x1f << 10) | (mantissa ? 0x200 : 0);
1426
+ }
1427
+ else if (exponent > 142) {
1428
+ // Overflow → Infinity
1429
+ halfFloatBits = (sign << 15) | (0x1f << 10);
1430
+ }
1431
+ else if (exponent < 113) {
1432
+ // Subnormal or zero
1433
+ if (exponent < 103) {
1434
+ halfFloatBits = sign << 15;
1435
+ }
1436
+ else {
1437
+ mantissa |= 0x800000;
1438
+ const shift = 125 - exponent;
1439
+ mantissa = mantissa >> shift;
1440
+ halfFloatBits = (sign << 15) | (mantissa >> 13);
1441
+ }
1212
1442
  }
1213
1443
  else {
1214
- // Normalized number, subtract exponent bias
1215
- exponentBits -= 15;
1444
+ // Normalized
1445
+ exponent = exponent - 112;
1446
+ mantissa = mantissa >> 13;
1447
+ halfFloatBits = (sign << 15) | (exponent << 10) | mantissa;
1216
1448
  }
1217
- // Combine sign, exponent, and fraction bits into half float format
1218
- let halfFloatBits = (signBit << 15) | (exponentBits << 10) | fractionBits;
1219
1449
  // Write bytes based on endianness
1220
1450
  if ((endian == undefined ? ctx.endian : endian) == "little") {
1221
1451
  ctx.data[ctx.offset] = halfFloatBits & 0xFF;
@@ -1228,11 +1458,13 @@ function whalffloat(ctx, value, endian) {
1228
1458
  ctx.offset += 2;
1229
1459
  ctx.bitoffset = 0;
1230
1460
  }
1461
+ // #region Write / Read Int32
1231
1462
  function wint32(ctx, value, unsigned, endian) {
1463
+ ctx.open();
1232
1464
  check_size(ctx, 4, 0);
1233
1465
  if (unsigned == true) {
1234
1466
  if (value < 0 || value > 4294967295) {
1235
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1467
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1236
1468
  throw new Error('Value is out of range for the specified 32bit length.' + " min: " + 0 + " max: " + 4294967295 + " value: " + value);
1237
1469
  }
1238
1470
  }
@@ -1240,33 +1472,61 @@ function wint32(ctx, value, unsigned, endian) {
1240
1472
  const maxValue = Math.pow(2, 32 - 1) - 1;
1241
1473
  const minValue = -maxValue - 1;
1242
1474
  if (value < minValue || value > maxValue) {
1243
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1475
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1244
1476
  throw new Error('Value is out of range for the specified 32bit length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1245
1477
  }
1246
1478
  }
1247
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1248
- ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? value : value & 0xFF;
1249
- ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xFF;
1250
- ctx.data[ctx.offset + 2] = (unsigned == undefined || unsigned == false) ? (value >> 16) : (value >> 16) & 0xFF;
1251
- ctx.data[ctx.offset + 3] = (unsigned == undefined || unsigned == false) ? (value >> 24) : (value >> 24) & 0xFF;
1479
+ if (canInt32) {
1480
+ if ((unsigned == undefined || unsigned == false)) {
1481
+ ctx.view.setInt32(ctx.offset, value, endian != undefined ? endian == "little" : ctx.endian == "little");
1482
+ }
1483
+ else {
1484
+ ctx.view.setUint32(ctx.offset, value, endian != undefined ? endian == "little" : ctx.endian == "little");
1485
+ }
1252
1486
  }
1253
1487
  else {
1254
- ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? (value >> 24) : (value >> 24) & 0xFF;
1255
- ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? (value >> 16) : (value >> 16) & 0xFF;
1256
- ctx.data[ctx.offset + 2] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xFF;
1257
- ctx.data[ctx.offset + 3] = (unsigned == undefined || unsigned == false) ? value : value & 0xFF;
1488
+ if ((endian == undefined ? ctx.endian : endian) == "little") {
1489
+ ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? value : value & 0xFF;
1490
+ ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xFF;
1491
+ ctx.data[ctx.offset + 2] = (unsigned == undefined || unsigned == false) ? (value >> 16) : (value >> 16) & 0xFF;
1492
+ ctx.data[ctx.offset + 3] = (unsigned == undefined || unsigned == false) ? (value >> 24) : (value >> 24) & 0xFF;
1493
+ }
1494
+ else {
1495
+ ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? (value >> 24) : (value >> 24) & 0xFF;
1496
+ ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? (value >> 16) : (value >> 16) & 0xFF;
1497
+ ctx.data[ctx.offset + 2] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xFF;
1498
+ ctx.data[ctx.offset + 3] = (unsigned == undefined || unsigned == false) ? value : value & 0xFF;
1499
+ }
1258
1500
  }
1259
1501
  ctx.offset += 4;
1260
1502
  ctx.bitoffset = 0;
1261
1503
  }
1262
1504
  function rint32(ctx, unsigned, endian) {
1505
+ ctx.open();
1263
1506
  check_size(ctx, 4);
1264
1507
  var read;
1508
+ if (canInt32) {
1509
+ if ((unsigned == undefined || unsigned == false)) {
1510
+ read = ctx.view.getInt32(ctx.offset, endian != undefined ? endian == "little" : ctx.endian == "little");
1511
+ }
1512
+ else {
1513
+ read = ctx.view.getUint32(ctx.offset, endian != undefined ? endian == "little" : ctx.endian == "little");
1514
+ }
1515
+ ctx.offset += 4;
1516
+ ctx.bitoffset = 0;
1517
+ return read;
1518
+ }
1265
1519
  if ((endian != undefined ? endian : ctx.endian) == "little") {
1266
- read = ((ctx.data[ctx.offset + 3] << 24) | (ctx.data[ctx.offset + 2] << 16) | (ctx.data[ctx.offset + 1] << 8) | ctx.data[ctx.offset]);
1520
+ read = ((ctx.data[ctx.offset + 3] & 0xFF) << 24) |
1521
+ ((ctx.data[ctx.offset + 2] & 0xFF) << 16) |
1522
+ ((ctx.data[ctx.offset + 1] & 0xFF) << 8) |
1523
+ (ctx.data[ctx.offset] & 0xFF);
1267
1524
  }
1268
1525
  else {
1269
- read = (ctx.data[ctx.offset] << 24) | (ctx.data[ctx.offset + 1] << 16) | (ctx.data[ctx.offset + 2] << 8) | ctx.data[ctx.offset + 3];
1526
+ read = ((ctx.data[ctx.offset] & 0xFF) << 24) |
1527
+ ((ctx.data[ctx.offset + 1] & 0xFF) << 16) |
1528
+ ((ctx.data[ctx.offset + 2] & 0xFF) << 8) |
1529
+ (ctx.data[ctx.offset + 3] & 0xFF);
1270
1530
  }
1271
1531
  ctx.offset += 4;
1272
1532
  ctx.bitoffset = 0;
@@ -1277,15 +1537,24 @@ function rint32(ctx, unsigned, endian) {
1277
1537
  return read >>> 0;
1278
1538
  }
1279
1539
  }
1540
+ // #region Write / Read Float32
1280
1541
  function rfloat(ctx, endian) {
1281
- var uint32Value = ctx.readInt32(true, (endian == undefined ? ctx.endian : endian));
1542
+ if (canFloat32) {
1543
+ ctx.open();
1544
+ check_size(ctx, 4);
1545
+ const float32Value = ctx.view.getFloat32(ctx.offset, endian != undefined ? endian == "little" : ctx.endian == "little");
1546
+ ctx.offset += 4;
1547
+ ctx.bitoffset = 0;
1548
+ return float32Value;
1549
+ }
1550
+ const uint32Value = ctx.readInt32(true, (endian == undefined ? ctx.endian : endian));
1282
1551
  // Check if the value is negative (i.e., the most significant bit is set)
1283
1552
  const isNegative = (uint32Value & 0x80000000) !== 0 ? 1 : 0;
1284
1553
  // Extract the exponent and fraction parts
1285
1554
  const exponent = (uint32Value >> 23) & 0xFF;
1286
1555
  const fraction = uint32Value & 0x7FFFFF;
1287
1556
  // Calculate the float value
1288
- let floatValue;
1557
+ var floatValue;
1289
1558
  if (exponent === 0) {
1290
1559
  // Denormalized number (exponent is 0)
1291
1560
  floatValue = Math.pow(-1, isNegative) * Math.pow(2, -126) * (fraction / Math.pow(2, 23));
@@ -1301,6 +1570,7 @@ function rfloat(ctx, endian) {
1301
1570
  return floatValue;
1302
1571
  }
1303
1572
  function wfloat(ctx, value, endian) {
1573
+ ctx.open();
1304
1574
  check_size(ctx, 4, 0);
1305
1575
  const MIN_POSITIVE_FLOAT32 = Number.MIN_VALUE;
1306
1576
  const MAX_POSITIVE_FLOAT32 = 3.4028235e+38;
@@ -1309,67 +1579,94 @@ function wfloat(ctx, value, endian) {
1309
1579
  if (!((value === 0) ||
1310
1580
  (value >= MIN_POSITIVE_FLOAT32 && value <= MAX_POSITIVE_FLOAT32) ||
1311
1581
  (value >= MIN_NEGATIVE_FLOAT32 && value <= MAX_NEGATIVE_FLOAT32))) {
1312
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1582
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1313
1583
  throw new Error('Value is out of range for the specified float length.' + " min: " + MIN_NEGATIVE_FLOAT32 + " max: " + MAX_POSITIVE_FLOAT32 + " value: " + value);
1314
1584
  }
1315
- const dataView = new DataView(new Uint8Array(4).buffer);
1316
- dataView.setFloat32(0, value, true);
1317
- let intValue = dataView.getInt32(0, true);
1318
- let shift = 0;
1319
- for (let i = 0; i < 4; i++) {
1320
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1321
- ctx.data[ctx.offset + i] = (intValue >> shift) & 0xFF;
1585
+ if (canFloat32) {
1586
+ ctx.view.setFloat32(ctx.offset, value, endian != undefined ? endian == "little" : ctx.endian == "little");
1587
+ }
1588
+ else {
1589
+ const arrayFloat = new Float32Array(1);
1590
+ arrayFloat[0] = value;
1591
+ if (endian != undefined ? endian == "little" : ctx.endian == "little") {
1592
+ ctx.data[ctx.offset] = arrayFloat.buffer[0];
1593
+ ctx.data[ctx.offset + 1] = arrayFloat.buffer[1];
1594
+ ctx.data[ctx.offset + 2] = arrayFloat.buffer[2];
1595
+ ctx.data[ctx.offset + 3] = arrayFloat.buffer[3];
1322
1596
  }
1323
1597
  else {
1324
- ctx.data[ctx.offset + (3 - i)] = (intValue >> shift) & 0xFF;
1598
+ ctx.data[ctx.offset] = arrayFloat.buffer[3];
1599
+ ctx.data[ctx.offset + 1] = arrayFloat.buffer[2];
1600
+ ctx.data[ctx.offset + 2] = arrayFloat.buffer[1];
1601
+ ctx.data[ctx.offset + 3] = arrayFloat.buffer[0];
1325
1602
  }
1326
- shift += 8;
1327
1603
  }
1328
1604
  ctx.offset += 4;
1329
1605
  ctx.bitoffset = 0;
1330
1606
  }
1607
+ // #region Write / Read Int64
1331
1608
  function rint64(ctx, unsigned, endian) {
1609
+ if (!hasBigInt) {
1610
+ throw new Error("System doesn't support BigInt values.");
1611
+ }
1612
+ ctx.open();
1332
1613
  check_size(ctx, 8);
1333
- // Convert the byte array to a BigInt
1334
- let value = BigInt(0);
1335
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1336
- for (let i = 0; i < 8; i++) {
1337
- value = value | BigInt(ctx.data[ctx.offset]) << BigInt(8 * i);
1338
- ctx.offset += 1;
1339
- }
1614
+ var value = BigInt(0);
1615
+ if (canBigInt64) {
1340
1616
  if (unsigned == undefined || unsigned == false) {
1341
- if (value & (BigInt(1) << BigInt(63))) {
1342
- value -= BigInt(1) << BigInt(64);
1343
- }
1617
+ value = ctx.view.getBigInt64(ctx.offset, endian != undefined ? endian == "little" : ctx.endian == "little");
1618
+ }
1619
+ else {
1620
+ value = ctx.view.getBigUint64(ctx.offset, endian != undefined ? endian == "little" : ctx.endian == "little");
1344
1621
  }
1622
+ ctx.offset += 8;
1345
1623
  }
1346
1624
  else {
1347
- for (let i = 0; i < 8; i++) {
1348
- value = (value << BigInt(8)) | BigInt(ctx.data[ctx.offset]);
1349
- ctx.offset += 1;
1625
+ if ((endian == undefined ? ctx.endian : endian) == "little") {
1626
+ for (let i = 0; i < 8; i++) {
1627
+ value = value | BigInt((ctx.data[ctx.offset] & 0xFF)) << BigInt(8 * i);
1628
+ ctx.offset += 1;
1629
+ }
1630
+ if (unsigned == undefined || unsigned == false) {
1631
+ if (value & (BigInt(1) << BigInt(63))) {
1632
+ value -= BigInt(1) << BigInt(64);
1633
+ }
1634
+ }
1350
1635
  }
1351
- if (unsigned == undefined || unsigned == false) {
1352
- if (value & (BigInt(1) << BigInt(63))) {
1353
- value -= BigInt(1) << BigInt(64);
1636
+ else {
1637
+ for (let i = 0; i < 8; i++) {
1638
+ value = (value << BigInt(8)) | BigInt((ctx.data[ctx.offset] & 0xFF));
1639
+ ctx.offset += 1;
1640
+ }
1641
+ if (unsigned == undefined || unsigned == false) {
1642
+ if (value & (BigInt(1) << BigInt(63))) {
1643
+ value -= BigInt(1) << BigInt(64);
1644
+ }
1354
1645
  }
1355
1646
  }
1356
1647
  }
1357
1648
  ctx.bitoffset = 0;
1358
- if (ctx.enforceBigInt) {
1649
+ if (ctx.enforceBigInt == true) {
1359
1650
  return value;
1360
1651
  }
1361
1652
  else {
1362
1653
  if (isSafeInt64(value)) {
1363
1654
  return Number(value);
1364
1655
  }
1656
+ else {
1657
+ throw new Error("Value is outside of number range and enforceBigInt is set to false. " + value);
1658
+ }
1365
1659
  }
1366
- return value;
1367
1660
  }
1368
1661
  function wint64(ctx, value, unsigned, endian) {
1662
+ if (!hasBigInt) {
1663
+ throw new Error("System doesn't support BigInt values.");
1664
+ }
1665
+ ctx.open();
1369
1666
  check_size(ctx, 8, 0);
1370
1667
  if (unsigned == true) {
1371
1668
  if (value < 0 || value > Math.pow(2, 64) - 1) {
1372
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1669
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1373
1670
  throw new Error('Value is out of range for the specified 64bit length.' + " min: " + 0 + " max: " + (Math.pow(2, 64) - 1) + " value: " + value);
1374
1671
  }
1375
1672
  }
@@ -1377,49 +1674,61 @@ function wint64(ctx, value, unsigned, endian) {
1377
1674
  const maxValue = Math.pow(2, 63) - 1;
1378
1675
  const minValue = -Math.pow(2, 63);
1379
1676
  if (value < minValue || value > maxValue) {
1380
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1677
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1381
1678
  throw new Error('Value is out of range for the specified 64bit length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1382
1679
  }
1383
1680
  }
1384
- // Convert the BigInt to a 64-bit signed integer
1385
- const bigIntArray = new BigInt64Array(1);
1386
- bigIntArray[0] = BigInt(value);
1387
- // Use two 32-bit views to write the Int64
1388
- const int32Array = new Int32Array(bigIntArray.buffer);
1389
- for (let i = 0; i < 2; i++) {
1390
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1391
- if (unsigned == undefined || unsigned == false) {
1392
- ctx.data[ctx.offset + i * 4 + 0] = int32Array[i];
1393
- ctx.data[ctx.offset + i * 4 + 1] = (int32Array[i] >> 8);
1394
- ctx.data[ctx.offset + i * 4 + 2] = (int32Array[i] >> 16);
1395
- ctx.data[ctx.offset + i * 4 + 3] = (int32Array[i] >> 24);
1396
- }
1397
- else {
1398
- ctx.data[ctx.offset + i * 4 + 0] = int32Array[i] & 0xFF;
1399
- ctx.data[ctx.offset + i * 4 + 1] = (int32Array[i] >> 8) & 0xFF;
1400
- ctx.data[ctx.offset + i * 4 + 2] = (int32Array[i] >> 16) & 0xFF;
1401
- ctx.data[ctx.offset + i * 4 + 3] = (int32Array[i] >> 24) & 0xFF;
1402
- }
1681
+ if (canBigInt64) {
1682
+ if (unsigned == undefined || unsigned == false) {
1683
+ ctx.view.setBigInt64(ctx.offset, BigInt(value), endian != undefined ? endian == "little" : ctx.endian == "little");
1403
1684
  }
1404
1685
  else {
1405
- if (unsigned == undefined || unsigned == false) {
1406
- ctx.data[ctx.offset + (1 - i) * 4 + 0] = int32Array[i];
1407
- ctx.data[ctx.offset + (1 - i) * 4 + 1] = (int32Array[i] >> 8);
1408
- ctx.data[ctx.offset + (1 - i) * 4 + 2] = (int32Array[i] >> 16);
1409
- ctx.data[ctx.offset + (1 - i) * 4 + 3] = (int32Array[i] >> 24);
1686
+ ctx.view.setBigUint64(ctx.offset, BigInt(value), endian != undefined ? endian == "little" : ctx.endian == "little");
1687
+ }
1688
+ }
1689
+ else {
1690
+ // Convert the BigInt to a 64-bit signed integer
1691
+ const bigIntArray = new BigInt64Array(1);
1692
+ bigIntArray[0] = BigInt(value);
1693
+ // Use two 32-bit views to write the Int64
1694
+ const int32Array = new Int32Array(bigIntArray.buffer);
1695
+ for (let i = 0; i < 2; i++) {
1696
+ if ((endian == undefined ? ctx.endian : endian) == "little") {
1697
+ if (unsigned == undefined || unsigned == false) {
1698
+ ctx.data[ctx.offset + i * 4 + 0] = int32Array[i];
1699
+ ctx.data[ctx.offset + i * 4 + 1] = (int32Array[i] >> 8);
1700
+ ctx.data[ctx.offset + i * 4 + 2] = (int32Array[i] >> 16);
1701
+ ctx.data[ctx.offset + i * 4 + 3] = (int32Array[i] >> 24);
1702
+ }
1703
+ else {
1704
+ ctx.data[ctx.offset + i * 4 + 0] = int32Array[i] & 0xFF;
1705
+ ctx.data[ctx.offset + i * 4 + 1] = (int32Array[i] >> 8) & 0xFF;
1706
+ ctx.data[ctx.offset + i * 4 + 2] = (int32Array[i] >> 16) & 0xFF;
1707
+ ctx.data[ctx.offset + i * 4 + 3] = (int32Array[i] >> 24) & 0xFF;
1708
+ }
1410
1709
  }
1411
1710
  else {
1412
- ctx.data[ctx.offset + (1 - i) * 4 + 0] = int32Array[i] & 0xFF;
1413
- ctx.data[ctx.offset + (1 - i) * 4 + 1] = (int32Array[i] >> 8) & 0xFF;
1414
- ctx.data[ctx.offset + (1 - i) * 4 + 2] = (int32Array[i] >> 16) & 0xFF;
1415
- ctx.data[ctx.offset + (1 - i) * 4 + 3] = (int32Array[i] >> 24) & 0xFF;
1711
+ if (unsigned == undefined || unsigned == false) {
1712
+ ctx.data[ctx.offset + (1 - i) * 4 + 3] = int32Array[i];
1713
+ ctx.data[ctx.offset + (1 - i) * 4 + 2] = (int32Array[i] >> 8);
1714
+ ctx.data[ctx.offset + (1 - i) * 4 + 1] = (int32Array[i] >> 16);
1715
+ ctx.data[ctx.offset + (1 - i) * 4 + 0] = (int32Array[i] >> 24);
1716
+ }
1717
+ else {
1718
+ ctx.data[ctx.offset + (1 - i) * 4 + 3] = int32Array[i] & 0xFF;
1719
+ ctx.data[ctx.offset + (1 - i) * 4 + 2] = (int32Array[i] >> 8) & 0xFF;
1720
+ ctx.data[ctx.offset + (1 - i) * 4 + 1] = (int32Array[i] >> 16) & 0xFF;
1721
+ ctx.data[ctx.offset + (1 - i) * 4 + 0] = (int32Array[i] >> 24) & 0xFF;
1722
+ }
1416
1723
  }
1417
1724
  }
1418
1725
  }
1419
1726
  ctx.offset += 8;
1420
1727
  ctx.bitoffset = 0;
1421
1728
  }
1729
+ // #region Write / Read Float64
1422
1730
  function wdfloat(ctx, value, endian) {
1731
+ ctx.open();
1423
1732
  check_size(ctx, 8, 0);
1424
1733
  const MIN_POSITIVE_FLOAT64 = 2.2250738585072014e-308;
1425
1734
  const MAX_POSITIVE_FLOAT64 = Number.MAX_VALUE;
@@ -1428,43 +1737,56 @@ function wdfloat(ctx, value, endian) {
1428
1737
  if (!((value === 0) ||
1429
1738
  (value >= MIN_POSITIVE_FLOAT64 && value <= MAX_POSITIVE_FLOAT64) ||
1430
1739
  (value >= MIN_NEGATIVE_FLOAT64 && value <= MAX_NEGATIVE_FLOAT64))) {
1431
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1740
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1432
1741
  throw new Error('Value is out of range for the specified 64bit length.' + " min: " + MIN_NEGATIVE_FLOAT64 + " max: " + MAX_POSITIVE_FLOAT64 + " value: " + value);
1433
1742
  }
1434
- const intArray = new Int32Array(2);
1435
- const floatArray = new Float64Array(intArray.buffer);
1436
- floatArray[0] = value;
1437
- const bytes = new Uint8Array(intArray.buffer);
1438
- for (let i = 0; i < 8; i++) {
1439
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1440
- ctx.data[ctx.offset + i] = bytes[i];
1441
- }
1442
- else {
1443
- ctx.data[ctx.offset + (7 - i)] = bytes[i];
1743
+ if (canFloat64) {
1744
+ ctx.view.setFloat64(ctx.offset, value, endian != undefined ? endian == "little" : ctx.endian == "little");
1745
+ }
1746
+ else {
1747
+ const intArray = new Int32Array(2);
1748
+ const floatArray = new Float64Array(intArray.buffer);
1749
+ floatArray[0] = value;
1750
+ const bytes = new Uint8Array(intArray.buffer);
1751
+ for (let i = 0; i < 8; i++) {
1752
+ if ((endian == undefined ? ctx.endian : endian) == "little") {
1753
+ ctx.data[ctx.offset + i] = bytes[i];
1754
+ }
1755
+ else {
1756
+ ctx.data[ctx.offset + (7 - i)] = bytes[i];
1757
+ }
1444
1758
  }
1445
1759
  }
1446
1760
  ctx.offset += 8;
1447
1761
  ctx.bitoffset = 0;
1448
1762
  }
1449
1763
  function rdfloat(ctx, endian) {
1764
+ if (canFloat64) {
1765
+ ctx.open();
1766
+ check_size(ctx, 8, 0);
1767
+ const floatValue = ctx.view.getFloat64(ctx.offset, endian != undefined ? endian == "little" : ctx.endian == "little");
1768
+ ctx.offset += 8;
1769
+ ctx.bitoffset = 0;
1770
+ return floatValue;
1771
+ }
1450
1772
  endian = (endian == undefined ? ctx.endian : endian);
1451
1773
  var uint64Value = ctx.readInt64(true, endian);
1452
- const sign = (BigInt(uint64Value) & 0x8000000000000000n) >> 63n;
1453
- const exponent = Number((BigInt(uint64Value) & 0x7ff0000000000000n) >> 52n) - 1023;
1454
- const fraction = Number(BigInt(uint64Value) & 0x000fffffffffffffn) / Math.pow(2, 52);
1774
+ const sign = (BigInt(uint64Value) & BigInt("9223372036854775808")) >> BigInt(63);
1775
+ const exponent = Number((BigInt(uint64Value) & BigInt("9218868437227405312")) >> BigInt(52)) - 1023;
1776
+ const fraction = Number(BigInt(uint64Value) & BigInt("4503599627370495")) / Math.pow(2, 52);
1455
1777
  var floatValue;
1456
1778
  if (exponent == -1023) {
1457
1779
  if (fraction == 0) {
1458
- floatValue = (sign == 0n) ? 0 : -0; // +/-0
1780
+ floatValue = (sign == BigInt(0)) ? 0 : -0; // +/-0
1459
1781
  }
1460
1782
  else {
1461
1783
  // Denormalized number
1462
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, -1022) * fraction;
1784
+ floatValue = (sign == BigInt(0) ? 1 : -1) * Math.pow(2, -1022) * fraction;
1463
1785
  }
1464
1786
  }
1465
1787
  else if (exponent == 1024) {
1466
1788
  if (fraction == 0) {
1467
- floatValue = (sign == 0n) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
1789
+ floatValue = (sign == BigInt(0)) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
1468
1790
  }
1469
1791
  else {
1470
1792
  floatValue = Number.NaN;
@@ -1472,11 +1794,13 @@ function rdfloat(ctx, endian) {
1472
1794
  }
1473
1795
  else {
1474
1796
  // Normalized number
1475
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
1797
+ floatValue = (sign == BigInt(0) ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
1476
1798
  }
1477
1799
  return floatValue;
1478
1800
  }
1801
+ // #region Write / Read Strings
1479
1802
  function rstring(ctx, options) {
1803
+ ctx.open();
1480
1804
  var length = options && options.length;
1481
1805
  var stringType = options && options.stringType || 'utf-8';
1482
1806
  var terminateValue = options && options.terminateValue;
@@ -1566,7 +1890,7 @@ function rstring(ctx, options) {
1566
1890
  maxBytes = ctx.readInt32(true, endian);
1567
1891
  }
1568
1892
  else {
1569
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1893
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1570
1894
  throw new Error("Invalid length read size: " + lengthReadSize);
1571
1895
  }
1572
1896
  // Read the string as Pascal or Delphi encoded
@@ -1574,6 +1898,7 @@ function rstring(ctx, options) {
1574
1898
  for (let i = 0; i < maxBytes; i++) {
1575
1899
  if (stringType == 'wide-pascal') {
1576
1900
  const read = ctx.readInt16(true, endian);
1901
+ i++;
1577
1902
  if (!(stripNull == true && read == 0)) {
1578
1903
  encodedBytes.push(read);
1579
1904
  }
@@ -1587,10 +1912,12 @@ function rstring(ctx, options) {
1587
1912
  }
1588
1913
  var str_return;
1589
1914
  if (stringType == 'wide-pascal') {
1590
- str_return = new TextDecoder(encoding).decode(new Uint16Array(encodedBytes));
1915
+ const strBuffer = new Uint16Array(encodedBytes);
1916
+ str_return = new TextDecoder().decode(strBuffer.buffer);
1591
1917
  }
1592
1918
  else {
1593
- str_return = new TextDecoder(encoding).decode(new Uint8Array(encodedBytes));
1919
+ const strBuffer = new Uint8Array(encodedBytes);
1920
+ str_return = new TextDecoder(encoding).decode(strBuffer);
1594
1921
  }
1595
1922
  return str_return;
1596
1923
  }
@@ -1599,6 +1926,7 @@ function rstring(ctx, options) {
1599
1926
  }
1600
1927
  }
1601
1928
  function wstring(ctx, string, options) {
1929
+ ctx.open();
1602
1930
  var length = options && options.length;
1603
1931
  var stringType = options && options.stringType || 'utf-8';
1604
1932
  var terminateValue = options && options.terminateValue;
@@ -1611,9 +1939,9 @@ function wstring(ctx, string, options) {
1611
1939
  if (length == undefined && terminateValue == undefined) {
1612
1940
  terminateValue = 0;
1613
1941
  }
1614
- var totalLength = (length || encodedString.length) + (terminateValue != undefined ? 1 : 0);
1942
+ var totalLength = (length || encodedString.byteLength) + (terminateValue != undefined ? 1 : 0);
1615
1943
  if (stringType == 'utf-16') {
1616
- totalLength = (length || (encodedString.length * 2)) + (terminateValue != undefined ? 2 : 0);
1944
+ totalLength = (length || encodedString.byteLength) + (terminateValue != undefined ? 2 : 0);
1617
1945
  }
1618
1946
  check_size(ctx, totalLength, 0);
1619
1947
  // Write the string bytes to the Uint8Array
@@ -1660,41 +1988,38 @@ function wstring(ctx, string, options) {
1660
1988
  maxLength = 4294967295;
1661
1989
  }
1662
1990
  else {
1663
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1991
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1664
1992
  throw new Error("Invalid length write size: " + lengthWriteSize);
1665
1993
  }
1666
1994
  if (string.length > maxLength || (length || 0) > maxLength) {
1667
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1995
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1668
1996
  throw new Error("String outsize of max write length: " + maxLength);
1669
1997
  }
1670
- var maxBytes = Math.min(string.length, maxLength);
1998
+ const maxBytes = Math.min(string.length, maxLength);
1671
1999
  const encodedString = encoder.encode(string.substring(0, maxBytes));
1672
- var totalLength = (length || encodedString.length);
1673
- if (stringType == 'wide-pascal') {
1674
- totalLength = (length || (encodedString.length * 2));
1675
- }
2000
+ var totalLength = (length || encodedString.byteLength);
1676
2001
  if (lengthWriteSize == 1) {
1677
- ctx.writeUByte(maxBytes);
2002
+ ctx.writeUByte(totalLength);
1678
2003
  }
1679
2004
  else if (lengthWriteSize == 2) {
1680
- ctx.writeUInt16(maxBytes, endian);
2005
+ ctx.writeUInt16(totalLength, endian);
1681
2006
  }
1682
2007
  else if (lengthWriteSize == 4) {
1683
- ctx.writeUInt32(maxBytes, endian);
2008
+ ctx.writeUInt32(totalLength, endian);
1684
2009
  }
1685
2010
  check_size(ctx, totalLength, 0);
1686
2011
  // Write the string bytes to the Uint8Array
1687
- for (let i = 0; i < encodedString.length; i++) {
2012
+ for (let i = 0; i < totalLength; i++) {
1688
2013
  if (stringType == 'wide-pascal') {
1689
- const charCode = encodedString[i];
1690
2014
  if (endian == "little") {
1691
- ctx.data[ctx.offset + i * 2] = charCode & 0xFF;
1692
- ctx.data[ctx.offset + i * 2 + 1] = (charCode >> 8) & 0xFF;
2015
+ ctx.data[ctx.offset + i] = encodedString[i];
2016
+ ctx.data[ctx.offset + i + 1] = encodedString[i + 1];
1693
2017
  }
1694
2018
  else {
1695
- ctx.data[ctx.offset + i * 2 + 1] = charCode & 0xFF;
1696
- ctx.data[ctx.offset + i * 2] = (charCode >> 8) & 0xFF;
2019
+ ctx.data[ctx.offset + i + 1] = encodedString[i];
2020
+ ctx.data[ctx.offset + i] = encodedString[i + 1];
1697
2021
  }
2022
+ i++;
1698
2023
  }
1699
2024
  else {
1700
2025
  ctx.data[ctx.offset + i] = encodedString[i];
@@ -1707,8 +2032,33 @@ function wstring(ctx, string, options) {
1707
2032
  throw new Error('Unsupported string type: ' + stringType);
1708
2033
  }
1709
2034
  }
2035
+ // #region Class
2036
+ /**
2037
+ * Base class for BiReader and BiWriter
2038
+ */
1710
2039
  class BiBase {
1711
- constructor() {
2040
+ /**
2041
+ * Get the current buffer data.
2042
+ *
2043
+ * @type {DataType}
2044
+ */
2045
+ get data() {
2046
+ return __classPrivateFieldGet(this, _BiBase_data, "f");
2047
+ }
2048
+ ;
2049
+ /**
2050
+ * Set the current buffer data.
2051
+ *
2052
+ * @param {DataType} data
2053
+ */
2054
+ set data(data) {
2055
+ if (this.isBufferOrUint8Array(data)) {
2056
+ __classPrivateFieldSet(this, _BiBase_data, data, "f");
2057
+ this.updateView();
2058
+ }
2059
+ }
2060
+ ;
2061
+ constructor(input, writeable) {
1712
2062
  /**
1713
2063
  * Endianness of default read.
1714
2064
  * @type {endian}
@@ -1737,12 +2087,8 @@ class BiBase {
1737
2087
  /**
1738
2088
  * Console log a hexdump on error.
1739
2089
  */
1740
- this.errorDump = true;
1741
- /**
1742
- * Current buffer data.
1743
- * @type {Buffer|Uint8Array|null}
1744
- */
1745
- this.data = null;
2090
+ this.errorDump = false;
2091
+ _BiBase_data.set(this, null);
1746
2092
  /**
1747
2093
  * When the data buffer needs to be extended while strict mode is ``false``, this will be the amount it extends.
1748
2094
  *
@@ -1754,14 +2100,39 @@ class BiBase {
1754
2100
  */
1755
2101
  this.extendBufferSize = 0;
1756
2102
  this.fd = null;
1757
- this.filePath = "";
1758
- this.fsMode = "";
2103
+ this.filePath = null;
2104
+ this.fsMode = "r";
1759
2105
  /**
1760
2106
  * The settings that used when using the .str getter / setter
1761
2107
  */
1762
2108
  this.strDefaults = { stringType: "utf-8", terminateValue: 0x0 };
2109
+ /**
2110
+ * Window size of the file data (largest amount it can read)
2111
+ */
1763
2112
  this.maxFileSize = null;
1764
- this.enforceBigInt = false;
2113
+ this.enforceBigInt = null;
2114
+ this.mode = 'memory';
2115
+ if (typeof input == "string") {
2116
+ if (typeof Buffer === 'undefined' || typeof fs == "undefined") {
2117
+ throw new Error("Need node to read or write files.");
2118
+ }
2119
+ this.filePath = input;
2120
+ this.mode = "file";
2121
+ }
2122
+ else {
2123
+ this.mode = "memory";
2124
+ }
2125
+ if (this.maxFileSize == null) {
2126
+ this.maxFileSize = MAX_LENGTH() || 0x80000000;
2127
+ }
2128
+ if (writeable != undefined) {
2129
+ if (writeable == true) {
2130
+ this.fsMode = "w+";
2131
+ }
2132
+ else {
2133
+ this.fsMode = "r";
2134
+ }
2135
+ }
1765
2136
  }
1766
2137
  ;
1767
2138
  /**
@@ -1788,67 +2159,227 @@ class BiBase {
1788
2159
  writeMode(mode) {
1789
2160
  if (mode) {
1790
2161
  this.strict = false;
2162
+ if (this.mode == "file") {
2163
+ this.fsMode = "w+";
2164
+ this.close();
2165
+ this.open();
2166
+ }
1791
2167
  return;
1792
2168
  }
1793
2169
  else {
1794
2170
  this.strict = true;
2171
+ if (this.mode == "file") {
2172
+ this.fsMode = "r";
2173
+ this.close();
2174
+ this.open();
2175
+ }
1795
2176
  return;
1796
2177
  }
1797
2178
  }
1798
2179
  ;
1799
2180
  /**
1800
- * Dummy function, not needed on Non-Stream
2181
+ * Opens the file in `file` mode. Must be run before reading or writing.
2182
+ *
2183
+ * @returns {number} file size
1801
2184
  */
1802
2185
  open() {
2186
+ if (this.mode == "memory") {
2187
+ return this.size;
2188
+ }
2189
+ if (this.fd != null) {
2190
+ return this.size;
2191
+ }
2192
+ if (fs == undefined) {
2193
+ throw new Error("Can't load file without Node.");
2194
+ }
2195
+ if (this.maxFileSize == null) {
2196
+ this.maxFileSize = MAX_LENGTH();
2197
+ }
2198
+ try {
2199
+ this.fd = fs.openSync(this.filePath, this.fsMode);
2200
+ }
2201
+ catch (error) {
2202
+ throw new Error(error);
2203
+ }
2204
+ this.updateSize();
2205
+ this.data = Buffer.alloc(this.size);
2206
+ try {
2207
+ fs.readSync(this.fd, this.data, 0, this.data.length, null);
2208
+ }
2209
+ catch (error) {
2210
+ throw new Error(error);
2211
+ }
2212
+ if (this.offset != undefined || this.bitoffset != undefined) {
2213
+ this.offset = ((Math.abs(this.offset || 0)) + Math.ceil((Math.abs(this.bitoffset || 0)) / 8));
2214
+ // Adjust byte offset based on bit overflow
2215
+ this.offset += Math.floor((Math.abs(this.bitoffset || 0)) / 8);
2216
+ // Adjust bit offset
2217
+ this.bitoffset = Math.abs(normalizeBitOffset(this.bitoffset)) % 8;
2218
+ // Ensure bit offset stays between 0-7
2219
+ this.bitoffset = Math.min(Math.max(this.bitoffset, 0), 7);
2220
+ // Ensure offset doesn't go negative
2221
+ this.offset = Math.max(this.offset, 0);
2222
+ if (this.offset > this.size) {
2223
+ if (this.strict == false) {
2224
+ if (this.extendBufferSize != 0) {
2225
+ this.extendArray(this.extendBufferSize);
2226
+ }
2227
+ else {
2228
+ this.extendArray(this.offset - this.size);
2229
+ }
2230
+ }
2231
+ else {
2232
+ throw new Error(`Starting offset outside of size: ${this.offset} of ${this.size}`);
2233
+ }
2234
+ }
2235
+ }
1803
2236
  return this.size;
1804
2237
  }
1805
2238
  ;
1806
2239
  /**
1807
- * Dummy function, not needed on Non-Stream
2240
+ * Internal update size
1808
2241
  */
1809
2242
  updateSize() {
1810
- this.return;
2243
+ if (this.mode == "memory") {
2244
+ return;
2245
+ }
2246
+ if (fs == undefined) {
2247
+ throw new Error("Can't read file without Node.");
2248
+ }
2249
+ if (this.fd !== null) {
2250
+ try {
2251
+ const stat = fs.fstatSync(this.fd);
2252
+ this.size = stat.size;
2253
+ this.sizeB = this.size * 8;
2254
+ }
2255
+ catch (error) {
2256
+ throw new Error(error);
2257
+ }
2258
+ if (this.size > this.maxFileSize) {
2259
+ throw new Error("File too large to load.");
2260
+ }
2261
+ }
1811
2262
  }
1812
2263
  ;
1813
2264
  /**
1814
- * removes data.
2265
+ * commit data and removes it.
1815
2266
  */
1816
2267
  close() {
1817
- this.data = undefined;
2268
+ if (this.mode == "memory") {
2269
+ __classPrivateFieldSet(this, _BiBase_data, undefined, "f");
2270
+ this.view = undefined;
2271
+ return;
2272
+ }
2273
+ if (this.fd === null) {
2274
+ return; // Already closed / or not open
2275
+ }
2276
+ if (fs == undefined) {
2277
+ throw new Error("Can't use BitFile without Node.");
2278
+ }
2279
+ this.commit();
2280
+ try {
2281
+ fs.closeSync(this.fd);
2282
+ }
2283
+ catch (error) {
2284
+ throw new Error(error);
2285
+ }
2286
+ this.fd = null;
2287
+ return;
1818
2288
  }
1819
2289
  ;
1820
2290
  /**
1821
- * Dummy function, not needed on Non-Stream
2291
+ * Write buffer to data
2292
+ *
2293
+ * @param {DataType} data
2294
+ * @param {boolean} consume
2295
+ * @param {number} start - likely this.offset
2296
+ * @returns {Buffer | Uint8Array}
1822
2297
  */
1823
- read(start, length, consume = false) {
1824
- return this.lift(start, start + length, consume);
2298
+ write(data, consume = false, start = this.offset) {
2299
+ if (this.mode == "memory") {
2300
+ this.insert(data, consume, start);
2301
+ return data;
2302
+ }
2303
+ this.open();
2304
+ this.insert(data, consume, start);
2305
+ return this.commit();
1825
2306
  }
1826
2307
  ;
1827
2308
  /**
1828
- * Dummy function, not needed on Non-Stream
2309
+ * Write data buffer back to file
2310
+ *
2311
+ * @returns {DataType}
1829
2312
  */
1830
- write(start, data, consume = false) {
1831
- this.insert(data, consume, start);
1832
- return data.length;
2313
+ commit() {
2314
+ if (this.mode == "memory") {
2315
+ return this.data;
2316
+ }
2317
+ this.open();
2318
+ try {
2319
+ fs.writeSync(this.fd, this.data, 0, this.data.length);
2320
+ }
2321
+ catch (error) {
2322
+ throw new Error(error);
2323
+ }
2324
+ this.updateSize();
2325
+ return this.data;
1833
2326
  }
1834
2327
  ;
1835
2328
  /**
1836
- * Dummy function, not needed on Non-Stream
2329
+ * syncs the data to file
1837
2330
  */
1838
- renameFile() {
2331
+ flush() {
2332
+ if (this.fd) {
2333
+ this.commit();
2334
+ }
1839
2335
  }
1840
2336
  ;
1841
2337
  /**
1842
- * Dummy function, not needed on Non-Stream
2338
+ * Renames the file you are working on.
2339
+ *
2340
+ * Must be full file path and file name.
2341
+ *
2342
+ * Keeps write / read position.
2343
+ *
2344
+ * Note: This is permanent and can't be undone.
2345
+ *
2346
+ * @param {string} newFilePath - New full file path and name.
1843
2347
  */
1844
- deleteFile() {
2348
+ renameFile(newFilePath) {
2349
+ if (this.mode == "memory") {
2350
+ return;
2351
+ }
2352
+ try {
2353
+ fs.closeSync(this.fd);
2354
+ this.fd = null;
2355
+ fs.renameSync(this.filePath, newFilePath);
2356
+ }
2357
+ catch (error) {
2358
+ throw new Error(error);
2359
+ }
2360
+ this.filePath = newFilePath;
2361
+ this.open();
1845
2362
  }
1846
2363
  ;
1847
2364
  /**
1848
- * Dummy function, not needed on Non-Stream
2365
+ * Deletes the working file.
2366
+ *
2367
+ * Note: This is permanentand can't be undone.
2368
+ *
2369
+ * It doesn't send the file to the recycling bin for recovery.
1849
2370
  */
1850
- commit(consume = true) {
1851
- return consume ? 0 : 1;
2371
+ deleteFile() {
2372
+ if (this.mode == "memory") {
2373
+ return;
2374
+ }
2375
+ try {
2376
+ fs.closeSync(this.fd);
2377
+ this.fd = null;
2378
+ fs.unlinkSync(this.filePath);
2379
+ }
2380
+ catch (error) {
2381
+ throw new Error(error);
2382
+ }
1852
2383
  }
1853
2384
  ;
1854
2385
  extendArray(to_padd) {
@@ -1856,11 +2387,20 @@ class BiBase {
1856
2387
  }
1857
2388
  ;
1858
2389
  isBufferOrUint8Array(obj) {
1859
- return arraybuffcheck(obj);
2390
+ return arrayBufferCheck(obj);
2391
+ }
2392
+ ;
2393
+ /**
2394
+ * Call this after everytime we set/replace `this.data`
2395
+ */
2396
+ updateView() {
2397
+ if (__classPrivateFieldGet(this, _BiBase_data, "f")) {
2398
+ this.view = new DataView(__classPrivateFieldGet(this, _BiBase_data, "f").buffer, __classPrivateFieldGet(this, _BiBase_data, "f").byteOffset ?? 0, __classPrivateFieldGet(this, _BiBase_data, "f").byteLength);
2399
+ }
1860
2400
  }
1861
2401
  ;
1862
2402
  ///////////////////////////////
1863
- // ENDIANNESS //
2403
+ // #region ENDIANNESS
1864
2404
  ///////////////////////////////
1865
2405
  /**
1866
2406
  *
@@ -1923,7 +2463,7 @@ class BiBase {
1923
2463
  }
1924
2464
  ;
1925
2465
  ///////////////////////////////
1926
- // SIZE //
2466
+ // #region SIZE
1927
2467
  ///////////////////////////////
1928
2468
  /**
1929
2469
  * Size in bytes of the current buffer.
@@ -1980,12 +2520,12 @@ class BiBase {
1980
2520
  }
1981
2521
  ;
1982
2522
  ///////////////////////////////
1983
- // POSITION //
2523
+ // #region POSITION
1984
2524
  ///////////////////////////////
1985
2525
  /**
1986
2526
  * Get the current byte position.
1987
2527
  *
1988
- * @return {number} current byte position
2528
+ * @returns {number} current byte position
1989
2529
  */
1990
2530
  get tell() {
1991
2531
  return this.offset;
@@ -1994,7 +2534,7 @@ class BiBase {
1994
2534
  /**
1995
2535
  * Get the current byte position.
1996
2536
  *
1997
- * @return {number} current byte position
2537
+ * @returns {number} current byte position
1998
2538
  */
1999
2539
  get FTell() {
2000
2540
  return this.offset;
@@ -2003,7 +2543,7 @@ class BiBase {
2003
2543
  /**
2004
2544
  * Get the current byte position.
2005
2545
  *
2006
- * @return {number} current byte position
2546
+ * @returns {number} current byte position
2007
2547
  */
2008
2548
  get getOffset() {
2009
2549
  return this.offset;
@@ -2012,7 +2552,7 @@ class BiBase {
2012
2552
  /**
2013
2553
  * Get the current byte position;
2014
2554
  *
2015
- * @return {number} current byte position
2555
+ * @returns {number} current byte position
2016
2556
  */
2017
2557
  get saveOffset() {
2018
2558
  return this.offset;
@@ -2021,7 +2561,7 @@ class BiBase {
2021
2561
  /**
2022
2562
  * Get the current byte position;
2023
2563
  *
2024
- * @return {number} current byte position
2564
+ * @returns {number} current byte position
2025
2565
  */
2026
2566
  get off() {
2027
2567
  return this.offset;
@@ -2030,7 +2570,7 @@ class BiBase {
2030
2570
  /**
2031
2571
  * Get the current bit position (0-7).
2032
2572
  *
2033
- * @return {number} current bit position
2573
+ * @returns {number} current bit position
2034
2574
  */
2035
2575
  get getOffsetBit() {
2036
2576
  return this.bitoffset;
@@ -2039,7 +2579,7 @@ class BiBase {
2039
2579
  /**
2040
2580
  * Get the current bit position (0-7).
2041
2581
  *
2042
- * @return {number} current bit position
2582
+ * @returns {number} current bit position
2043
2583
  */
2044
2584
  get tellB() {
2045
2585
  return this.bitoffset;
@@ -2048,7 +2588,7 @@ class BiBase {
2048
2588
  /**
2049
2589
  * Get the current bit position (0-7).
2050
2590
  *
2051
- * @return {number} current bit position
2591
+ * @returns {number} current bit position
2052
2592
  */
2053
2593
  get FTellB() {
2054
2594
  return this.bitoffset;
@@ -2057,7 +2597,7 @@ class BiBase {
2057
2597
  /**
2058
2598
  * Get the current bit position (0-7).
2059
2599
  *
2060
- * @return {number} current bit position
2600
+ * @returns {number} current bit position
2061
2601
  */
2062
2602
  get offb() {
2063
2603
  return this.bitoffset;
@@ -2066,7 +2606,7 @@ class BiBase {
2066
2606
  /**
2067
2607
  * Get the current absolute bit position (from start of data).
2068
2608
  *
2069
- * @return {number} current absolute bit position
2609
+ * @returns {number} current absolute bit position
2070
2610
  */
2071
2611
  get getOffsetAbsBit() {
2072
2612
  return (this.offset * 8) + this.bitoffset;
@@ -2075,7 +2615,7 @@ class BiBase {
2075
2615
  /**
2076
2616
  * Get the current absolute bit position (from start of data).
2077
2617
  *
2078
- * @return {number} current bit position
2618
+ * @returns {number} current bit position
2079
2619
  */
2080
2620
  get saveOffsetAbsBit() {
2081
2621
  return (this.offset * 8) + this.bitoffset;
@@ -2084,7 +2624,7 @@ class BiBase {
2084
2624
  /**
2085
2625
  * Get the current absolute bit position (from start of data).
2086
2626
  *
2087
- * @return {number} current absolute bit position
2627
+ * @returns {number} current absolute bit position
2088
2628
  */
2089
2629
  get tellAbsB() {
2090
2630
  return (this.offset * 8) + this.bitoffset;
@@ -2093,7 +2633,7 @@ class BiBase {
2093
2633
  /**
2094
2634
  * Get the current absolute bit position (from start of data).
2095
2635
  *
2096
- * @return {number} current absolute bit position
2636
+ * @returns {number} current absolute bit position
2097
2637
  */
2098
2638
  get saveOffsetBit() {
2099
2639
  return (this.offset * 8) + this.bitoffset;
@@ -2102,7 +2642,7 @@ class BiBase {
2102
2642
  /**
2103
2643
  * Get the current absolute bit position (from start of data).
2104
2644
  *
2105
- * @return {number} current absolute bit position
2645
+ * @returns {number} current absolute bit position
2106
2646
  */
2107
2647
  get offab() {
2108
2648
  return (this.offset * 8) + this.bitoffset;
@@ -2163,7 +2703,7 @@ class BiBase {
2163
2703
  }
2164
2704
  ;
2165
2705
  ///////////////////////////////
2166
- // FINISHING //
2706
+ // #region FINISHING
2167
2707
  ///////////////////////////////
2168
2708
  /**
2169
2709
  * Returns current data.
@@ -2172,9 +2712,9 @@ class BiBase {
2172
2712
  *
2173
2713
  * Use ``.data`` instead if you want the full buffer data.
2174
2714
  *
2175
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
2715
+ * @returns {DataType} ``Buffer`` or ``Uint8Array``
2176
2716
  */
2177
- get get() {
2717
+ get() {
2178
2718
  if (this.extendBufferSize != 0) {
2179
2719
  this.trim();
2180
2720
  }
@@ -2188,13 +2728,10 @@ class BiBase {
2188
2728
  *
2189
2729
  * Use ``.data`` instead if you want the full buffer data.
2190
2730
  *
2191
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
2731
+ * @returns {DataType} ``Buffer`` or ``Uint8Array``
2192
2732
  */
2193
- get return() {
2194
- if (this.extendBufferSize != 0) {
2195
- this.trim();
2196
- }
2197
- return this.data;
2733
+ return() {
2734
+ return this.get();
2198
2735
  }
2199
2736
  ;
2200
2737
  /**
@@ -2226,7 +2763,7 @@ class BiBase {
2226
2763
  }
2227
2764
  ;
2228
2765
  ///////////////////////////////
2229
- // STRICTMODE //
2766
+ // #region STRICT MODE
2230
2767
  ///////////////////////////////
2231
2768
  /**
2232
2769
  * Disallows extending data if position is outside of max size.
@@ -2244,27 +2781,39 @@ class BiBase {
2244
2781
  ;
2245
2782
  /**
2246
2783
  * removes data.
2784
+ *
2785
+ * Commits any changes to file when editing a file.
2247
2786
  */
2248
2787
  end() {
2249
- this.data = undefined;
2788
+ if (this.mode == "memory") {
2789
+ __classPrivateFieldSet(this, _BiBase_data, undefined, "f");
2790
+ this.view = undefined;
2791
+ return;
2792
+ }
2793
+ this.commit();
2794
+ return;
2250
2795
  }
2251
2796
  ;
2252
2797
  /**
2253
2798
  * removes data.
2799
+ *
2800
+ * Commits any changes to file when editing a file.
2254
2801
  */
2255
2802
  done() {
2256
- this.data = undefined;
2803
+ return this.end();
2257
2804
  }
2258
2805
  ;
2259
2806
  /**
2260
2807
  * removes data.
2808
+ *
2809
+ * Commits any changes to file when editing a file.
2261
2810
  */
2262
2811
  finished() {
2263
- this.data = undefined;
2812
+ return this.end();
2264
2813
  }
2265
2814
  ;
2266
2815
  ///////////////////////////////
2267
- // FIND //
2816
+ // #region FIND
2268
2817
  ///////////////////////////////
2269
2818
  /**
2270
2819
  * Searches for byte position of string from current read position.
@@ -2382,7 +2931,7 @@ class BiBase {
2382
2931
  }
2383
2932
  ;
2384
2933
  ///////////////////////////////
2385
- // MOVE TO //
2934
+ // #region MOVE TO
2386
2935
  ///////////////////////////////
2387
2936
  /**
2388
2937
  * Aligns current byte position.
@@ -2517,20 +3066,18 @@ class BiBase {
2517
3066
  * Set current byte and bit position to end of data.
2518
3067
  */
2519
3068
  gotoEnd() {
2520
- this.offset = this.size;
2521
- this.bitoffset = 0;
3069
+ this.last();
2522
3070
  }
2523
3071
  ;
2524
3072
  /**
2525
3073
  * Set byte and bit position to start of data.
2526
3074
  */
2527
3075
  EoF() {
2528
- this.offset = this.size;
2529
- this.bitoffset = 0;
3076
+ this.last();
2530
3077
  }
2531
3078
  ;
2532
3079
  ///////////////////////////////
2533
- // REMOVE //
3080
+ // #region REMOVE
2534
3081
  ///////////////////////////////
2535
3082
  /**
2536
3083
  * Deletes part of data from start to current byte position unless supplied, returns removed.
@@ -2540,7 +3087,7 @@ class BiBase {
2540
3087
  * @param {number} startOffset - Start location (default 0)
2541
3088
  * @param {number} endOffset - End location (default current position)
2542
3089
  * @param {boolean} consume - Move position to end of removed data (default false)
2543
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3090
+ * @returns {DataType} Removed data as ``Buffer`` or ``Uint8Array``
2544
3091
  */
2545
3092
  delete(startOffset, endOffset, consume) {
2546
3093
  return remove(this, startOffset || 0, endOffset || this.offset, consume || false, true);
@@ -2551,7 +3098,7 @@ class BiBase {
2551
3098
  *
2552
3099
  * Note: Errors in strict mode.
2553
3100
  *
2554
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3101
+ * @returns {DataType} Removed data as ``Buffer`` or ``Uint8Array``
2555
3102
  */
2556
3103
  clip() {
2557
3104
  return remove(this, this.offset, this.size, false, true);
@@ -2562,7 +3109,7 @@ class BiBase {
2562
3109
  *
2563
3110
  * Note: Errors in strict mode.
2564
3111
  *
2565
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3112
+ * @returns {DataType} Removed data as ``Buffer`` or ``Uint8Array``
2566
3113
  */
2567
3114
  trim() {
2568
3115
  return remove(this, this.offset, this.size, false, true);
@@ -2575,7 +3122,7 @@ class BiBase {
2575
3122
  *
2576
3123
  * @param {number} length - Length of data in bytes to remove
2577
3124
  * @param {boolean} consume - Move position to end of removed data (default false)
2578
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3125
+ * @returns {TemplateStringsArray} Removed data as ``Buffer`` or ``Uint8Array``
2579
3126
  */
2580
3127
  crop(length, consume) {
2581
3128
  return remove(this, this.offset, this.offset + (length || 0), consume || false, true);
@@ -2588,7 +3135,7 @@ class BiBase {
2588
3135
  *
2589
3136
  * @param {number} length - Length of data in bytes to remove
2590
3137
  * @param {boolean} consume - Move position to end of removed data (default false)
2591
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3138
+ * @returns {DataType} Removed data as ``Buffer`` or ``Uint8Array``
2592
3139
  */
2593
3140
  drop(length, consume) {
2594
3141
  return remove(this, this.offset, this.offset + (length || 0), consume || false, true);
@@ -2599,7 +3146,7 @@ class BiBase {
2599
3146
  *
2600
3147
  * Note: Errors on strict mode.
2601
3148
  *
2602
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to replace in data
3149
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to replace in data
2603
3150
  * @param {boolean} consume - Move current byte position to end of data (default false)
2604
3151
  * @param {number} offset - Offset to add it at (defaults to current position)
2605
3152
  */
@@ -2612,7 +3159,7 @@ class BiBase {
2612
3159
  *
2613
3160
  * Note: Errors on strict mode.
2614
3161
  *
2615
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to replace in data
3162
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to replace in data
2616
3163
  * @param {boolean} consume - Move current byte position to end of data (default false)
2617
3164
  * @param {number} offset - Offset to add it at (defaults to current position)
2618
3165
  */
@@ -2621,7 +3168,7 @@ class BiBase {
2621
3168
  }
2622
3169
  ;
2623
3170
  ///////////////////////////////
2624
- // COPY OUT //
3171
+ // #region COPY OUT
2625
3172
  ///////////////////////////////
2626
3173
  /**
2627
3174
  * Returns part of data from current byte position to end of data unless supplied.
@@ -2630,7 +3177,7 @@ class BiBase {
2630
3177
  * @param {number} endOffset - End location (default end of data)
2631
3178
  * @param {boolean} consume - Move position to end of lifted data (default false)
2632
3179
  * @param {number} fillValue - Byte value to to fill returned data (does NOT fill unless supplied)
2633
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3180
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2634
3181
  */
2635
3182
  lift(startOffset, endOffset, consume, fillValue) {
2636
3183
  return remove(this, startOffset || this.offset, endOffset || this.size, consume || false, false, fillValue);
@@ -2643,7 +3190,7 @@ class BiBase {
2643
3190
  * @param {number} endOffset - End location (default end of data)
2644
3191
  * @param {boolean} consume - Move position to end of lifted data (default false)
2645
3192
  * @param {number} fillValue - Byte value to to fill returned data (does NOT fill unless supplied)
2646
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3193
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2647
3194
  */
2648
3195
  fill(startOffset, endOffset, consume, fillValue) {
2649
3196
  return remove(this, startOffset || this.offset, endOffset || this.size, consume || false, false, fillValue);
@@ -2656,7 +3203,7 @@ class BiBase {
2656
3203
  *
2657
3204
  * @param {number} length - Length of data in bytes to copy from current offset
2658
3205
  * @param {number} consume - Moves offset to end of length
2659
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3206
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2660
3207
  */
2661
3208
  extract(length, consume) {
2662
3209
  return remove(this, this.offset, this.offset + (length || 0), consume || false, false);
@@ -2669,7 +3216,7 @@ class BiBase {
2669
3216
  *
2670
3217
  * @param {number} length - Length of data in bytes to copy from current offset
2671
3218
  * @param {number} consume - Moves offset to end of length
2672
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3219
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2673
3220
  */
2674
3221
  slice(length, consume) {
2675
3222
  return remove(this, this.offset, this.offset + (length || 0), consume || false, false);
@@ -2682,21 +3229,21 @@ class BiBase {
2682
3229
  *
2683
3230
  * @param {number} length - Length of data in bytes to copy from current offset
2684
3231
  * @param {number} consume - Moves offset to end of length
2685
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3232
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2686
3233
  */
2687
3234
  wrap(length, consume) {
2688
3235
  return remove(this, this.offset, this.offset + (length || 0), consume || false, false);
2689
3236
  }
2690
3237
  ;
2691
3238
  ///////////////////////////////
2692
- // INSERT //
3239
+ // #region INSERT
2693
3240
  ///////////////////////////////
2694
3241
  /**
2695
3242
  * Inserts data into data.
2696
3243
  *
2697
3244
  * Note: Errors on strict mode.
2698
3245
  *
2699
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3246
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2700
3247
  * @param {boolean} consume - Move current byte position to end of data (default false)
2701
3248
  * @param {number} offset - Byte position to add at (defaults to current position)
2702
3249
  */
@@ -2709,7 +3256,7 @@ class BiBase {
2709
3256
  *
2710
3257
  * Note: Errors on strict mode.
2711
3258
  *
2712
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3259
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2713
3260
  * @param {boolean} consume - Move current byte position to end of data (default false)
2714
3261
  * @param {number} offset - Byte position to add at (defaults to current position)
2715
3262
  */
@@ -2722,7 +3269,7 @@ class BiBase {
2722
3269
  *
2723
3270
  * Note: Errors on strict mode.
2724
3271
  *
2725
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3272
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2726
3273
  * @param {boolean} consume - Move current write position to end of data (default false)
2727
3274
  */
2728
3275
  unshift(data, consume) {
@@ -2734,7 +3281,7 @@ class BiBase {
2734
3281
  *
2735
3282
  * Note: Errors on strict mode.
2736
3283
  *
2737
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3284
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2738
3285
  * @param {boolean} consume - Move current write position to end of data (default false)
2739
3286
  */
2740
3287
  prepend(data, consume) {
@@ -2746,7 +3293,7 @@ class BiBase {
2746
3293
  *
2747
3294
  * Note: Errors on strict mode.
2748
3295
  *
2749
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3296
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2750
3297
  * @param {boolean} consume - Move current write position to end of data (default false)
2751
3298
  */
2752
3299
  push(data, consume) {
@@ -2758,7 +3305,7 @@ class BiBase {
2758
3305
  *
2759
3306
  * Note: Errors on strict mode.
2760
3307
  *
2761
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3308
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2762
3309
  * @param {boolean} consume - Move current write position to end of data (default false)
2763
3310
  */
2764
3311
  append(data, consume) {
@@ -2766,7 +3313,7 @@ class BiBase {
2766
3313
  }
2767
3314
  ;
2768
3315
  ///////////////////////////////
2769
- // MATH //
3316
+ // #region MATH
2770
3317
  ///////////////////////////////
2771
3318
  /**
2772
3319
  * XOR data.
@@ -2778,12 +3325,10 @@ class BiBase {
2778
3325
  */
2779
3326
  xor(xorKey, startOffset, endOffset, consume) {
2780
3327
  var XORKey = xorKey;
2781
- if (typeof xorKey == "number") ;
2782
- else if (typeof xorKey == "string") {
3328
+ if (typeof xorKey == "string") {
2783
3329
  xorKey = new TextEncoder().encode(xorKey);
2784
3330
  }
2785
- else if (this.isBufferOrUint8Array(XORKey)) ;
2786
- else {
3331
+ else if (!(this.isBufferOrUint8Array(XORKey) || typeof xorKey == "number")) {
2787
3332
  throw new Error("XOR must be a number, string, Uint8Array or Buffer");
2788
3333
  }
2789
3334
  return XOR(this, xorKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -2826,12 +3371,10 @@ class BiBase {
2826
3371
  */
2827
3372
  or(orKey, startOffset, endOffset, consume) {
2828
3373
  var ORKey = orKey;
2829
- if (typeof orKey == "number") ;
2830
- else if (typeof orKey == "string") {
3374
+ if (typeof orKey == "string") {
2831
3375
  orKey = new TextEncoder().encode(orKey);
2832
3376
  }
2833
- else if (this.isBufferOrUint8Array(ORKey)) ;
2834
- else {
3377
+ else if (!(this.isBufferOrUint8Array(ORKey) || typeof orKey == "number")) {
2835
3378
  throw new Error("OR must be a number, string, Uint8Array or Buffer");
2836
3379
  }
2837
3380
  return OR(this, orKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -2867,19 +3410,17 @@ class BiBase {
2867
3410
  /**
2868
3411
  * AND data.
2869
3412
  *
2870
- * @param {number|string|Array<number>|Buffer} andKey - Value, string or array to AND
3413
+ * @param {number|string|Uint8Array|Buffer} andKey - Value, string or array to AND
2871
3414
  * @param {number} startOffset - Start location (default current byte position)
2872
3415
  * @param {number} endOffset - End location (default end of data)
2873
3416
  * @param {boolean} consume - Move current position to end of data (default false)
2874
3417
  */
2875
3418
  and(andKey, startOffset, endOffset, consume) {
2876
3419
  var ANDKey = andKey;
2877
- if (typeof ANDKey == "number") ;
2878
- else if (typeof ANDKey == "string") {
3420
+ if (typeof ANDKey == "string") {
2879
3421
  ANDKey = new TextEncoder().encode(ANDKey);
2880
3422
  }
2881
- else if (typeof ANDKey == "object") ;
2882
- else {
3423
+ else if (!(typeof ANDKey == "object" || typeof ANDKey == "number")) {
2883
3424
  throw new Error("AND must be a number, string, number array or Buffer");
2884
3425
  }
2885
3426
  return AND(this, andKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -2888,7 +3429,7 @@ class BiBase {
2888
3429
  /**
2889
3430
  * AND data.
2890
3431
  *
2891
- * @param {number|string|Array<number>|Buffer} andKey - Value, string or array to AND
3432
+ * @param {number|string|Uint8Array|Buffer} andKey - Value, string or array to AND
2892
3433
  * @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)
2893
3434
  * @param {boolean} consume - Move current position to end of data (default false)
2894
3435
  */
@@ -2915,19 +3456,17 @@ class BiBase {
2915
3456
  /**
2916
3457
  * Add value to data.
2917
3458
  *
2918
- * @param {number|string|Array<number>|Buffer} addKey - Value, string or array to add to data
3459
+ * @param {number|string|Uint8Array|Buffer} addKey - Value, string or array to add to data
2919
3460
  * @param {number} startOffset - Start location (default current byte position)
2920
3461
  * @param {number} endOffset - End location (default end of data)
2921
3462
  * @param {boolean} consume - Move current position to end of data (default false)
2922
3463
  */
2923
3464
  add(addKey, startOffset, endOffset, consume) {
2924
3465
  var addedKey = addKey;
2925
- if (typeof addedKey == "number") ;
2926
- else if (typeof addedKey == "string") {
3466
+ if (typeof addedKey == "string") {
2927
3467
  addedKey = new TextEncoder().encode(addedKey);
2928
3468
  }
2929
- else if (typeof addedKey == "object") ;
2930
- else {
3469
+ else if (!(typeof addedKey == "object" || typeof addedKey == "number")) {
2931
3470
  throw new Error("Add key must be a number, string, number array or Buffer");
2932
3471
  }
2933
3472
  return ADD(this, addedKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -2936,7 +3475,7 @@ class BiBase {
2936
3475
  /**
2937
3476
  * Add value to data.
2938
3477
  *
2939
- * @param {number|string|Array<number>|Buffer} addKey - Value, string or array to add to data
3478
+ * @param {number|string|Uint8Array|Buffer} addKey - Value, string or array to add to data
2940
3479
  * @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)
2941
3480
  * @param {boolean} consume - Move current position to end of data (default false)
2942
3481
  */
@@ -2984,19 +3523,17 @@ class BiBase {
2984
3523
  /**
2985
3524
  * Left shift data.
2986
3525
  *
2987
- * @param {number|string|Array<number>|Buffer} shiftKey - Value, string or array to left shift data
3526
+ * @param {number|string|Uint8Array|Buffer} shiftKey - Value, string or array to left shift data
2988
3527
  * @param {number} startOffset - Start location (default current byte position)
2989
3528
  * @param {number} endOffset - End location (default end of data)
2990
3529
  * @param {boolean} consume - Move current position to end of data (default false)
2991
3530
  */
2992
3531
  lShift(shiftKey, startOffset, endOffset, consume) {
2993
3532
  var lShiftKey = shiftKey;
2994
- if (typeof lShiftKey == "number") ;
2995
- else if (typeof lShiftKey == "string") {
3533
+ if (typeof lShiftKey == "string") {
2996
3534
  lShiftKey = new TextEncoder().encode(lShiftKey);
2997
3535
  }
2998
- else if (typeof lShiftKey == "object") ;
2999
- else {
3536
+ else if (!(typeof lShiftKey == "object" || typeof lShiftKey == "number")) {
3000
3537
  throw new Error("Left shift must be a number, string, number array or Buffer");
3001
3538
  }
3002
3539
  return LSHIFT(this, lShiftKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -3005,7 +3542,7 @@ class BiBase {
3005
3542
  /**
3006
3543
  * Left shift data.
3007
3544
  *
3008
- * @param {number|string|Array<number>|Buffer} shiftKey - Value, string or array to left shift data
3545
+ * @param {number|string|Uint8Array|Buffer} shiftKey - Value, string or array to left shift data
3009
3546
  * @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)
3010
3547
  * @param {boolean} consume - Move current position to end of data (default false)
3011
3548
  */
@@ -3032,19 +3569,17 @@ class BiBase {
3032
3569
  /**
3033
3570
  * Right shift data.
3034
3571
  *
3035
- * @param {number|string|Array<number>|Buffer} shiftKey - Value, string or array to right shift data
3572
+ * @param {number|string|Uint8Array|Buffer} shiftKey - Value, string or array to right shift data
3036
3573
  * @param {number} startOffset - Start location (default current byte position)
3037
3574
  * @param {number} endOffset - End location (default end of data)
3038
3575
  * @param {boolean} consume - Move current position to end of data (default false)
3039
3576
  */
3040
3577
  rShift(shiftKey, startOffset, endOffset, consume) {
3041
3578
  var rShiftKey = shiftKey;
3042
- if (typeof rShiftKey == "number") ;
3043
- else if (typeof rShiftKey == "string") {
3579
+ if (typeof rShiftKey == "string") {
3044
3580
  rShiftKey = new TextEncoder().encode(rShiftKey);
3045
3581
  }
3046
- else if (typeof rShiftKey == "object") ;
3047
- else {
3582
+ else if (!(typeof rShiftKey == "object" || typeof rShiftKey == "number")) {
3048
3583
  throw new Error("Right shift must be a number, string, number array or Buffer");
3049
3584
  }
3050
3585
  return RSHIFT(this, rShiftKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -3053,7 +3588,7 @@ class BiBase {
3053
3588
  /**
3054
3589
  * Right shift data.
3055
3590
  *
3056
- * @param {number|string|Array<number>|Buffer} shiftKey - Value, string or array to right shift data
3591
+ * @param {number|string|Uint8Array|Buffer} shiftKey - Value, string or array to right shift data
3057
3592
  * @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)
3058
3593
  * @param {boolean} consume - Move current position to end of data (default false)
3059
3594
  */
@@ -3078,7 +3613,7 @@ class BiBase {
3078
3613
  }
3079
3614
  ;
3080
3615
  ///////////////////////////////
3081
- // BIT READER //
3616
+ // #region BIT READER
3082
3617
  ///////////////////////////////
3083
3618
  /**
3084
3619
  *
@@ -3213,6 +3748,9 @@ class BiBase {
3213
3748
  return this.readBit(bits, unsigned, "little");
3214
3749
  }
3215
3750
  ;
3751
+ ///////////////////////////////
3752
+ // #region BYTE READER
3753
+ ///////////////////////////////
3216
3754
  /**
3217
3755
  * Read byte.
3218
3756
  *
@@ -3274,6 +3812,9 @@ class BiBase {
3274
3812
  return this.readByte(true);
3275
3813
  }
3276
3814
  ;
3815
+ ///////////////////////////////
3816
+ // #region INT16 READER
3817
+ ///////////////////////////////
3277
3818
  /**
3278
3819
  * Read short.
3279
3820
  *
@@ -3380,6 +3921,9 @@ class BiBase {
3380
3921
  return this.readInt16(false, "big");
3381
3922
  }
3382
3923
  ;
3924
+ ///////////////////////////////
3925
+ // #region HALF FLOAT
3926
+ ///////////////////////////////
3383
3927
  /**
3384
3928
  * Read half float.
3385
3929
  *
@@ -3436,6 +3980,9 @@ class BiBase {
3436
3980
  return this.readHalfFloat("little");
3437
3981
  }
3438
3982
  ;
3983
+ ///////////////////////////////
3984
+ // #region INT32 READER
3985
+ ///////////////////////////////
3439
3986
  /**
3440
3987
  * Read 32 bit integer.
3441
3988
  *
@@ -3540,6 +4087,9 @@ class BiBase {
3540
4087
  return this.readInt32(true);
3541
4088
  }
3542
4089
  ;
4090
+ ///////////////////////////////
4091
+ // #region FLOAT32 READER
4092
+ ///////////////////////////////
3543
4093
  /**
3544
4094
  * Read float.
3545
4095
  *
@@ -3596,6 +4146,9 @@ class BiBase {
3596
4146
  return this.readFloat("little");
3597
4147
  }
3598
4148
  ;
4149
+ ///////////////////////////////
4150
+ // #region INT64 READER
4151
+ ///////////////////////////////
3599
4152
  /**
3600
4153
  * Read signed 64 bit integer.
3601
4154
  *
@@ -3603,7 +4156,6 @@ class BiBase {
3603
4156
  *
3604
4157
  * @param {boolean} unsigned - if value is unsigned or not
3605
4158
  * @param {endian?} endian - ``big`` or ``little``
3606
- * @returns {BigValue}
3607
4159
  */
3608
4160
  readInt64(unsigned, endian) {
3609
4161
  return rint64(this, unsigned, endian);
@@ -3721,6 +4273,9 @@ class BiBase {
3721
4273
  return this.readInt64(true, "little");
3722
4274
  }
3723
4275
  ;
4276
+ ///////////////////////////////
4277
+ // #region FLOAT64 READER
4278
+ ///////////////////////////////
3724
4279
  /**
3725
4280
  * Read double float.
3726
4281
  *
@@ -3777,6 +4332,9 @@ class BiBase {
3777
4332
  return this.readDoubleFloat("little");
3778
4333
  }
3779
4334
  ;
4335
+ ///////////////////////////////
4336
+ // #region STRING READER
4337
+ ///////////////////////////////
3780
4338
  /**
3781
4339
  * Reads string, use options object for different types.
3782
4340
  *
@@ -3787,7 +4345,7 @@ class BiBase {
3787
4345
  * @param {stringOptions["lengthReadSize"]?} options.lengthReadSize - for pascal strings. 1, 2 or 4 byte length read size
3788
4346
  * @param {stringOptions["encoding"]?} options.encoding - TextEncoder accepted types
3789
4347
  * @param {stringOptions["endian"]?} options.endian - for wide-pascal and utf-16
3790
- * @return {Promise<string>}
4348
+ * @returns {string}
3791
4349
  */
3792
4350
  readString(options) {
3793
4351
  return rstring(this, options);
@@ -3810,11 +4368,12 @@ class BiBase {
3810
4368
  }
3811
4369
  ;
3812
4370
  }
4371
+ _BiBase_data = new WeakMap();
3813
4372
 
3814
4373
  /**
3815
4374
  * Binary reader, includes bitfields and strings.
3816
4375
  *
3817
- * @param {Buffer|Uint8Array} data - ``Buffer`` or ``Uint8Array``. Always found in ``BiReader.data``
4376
+ * @param {string|Buffer|Uint8Array} input - File path or a ``Buffer`` or ``Uint8Array``. Always found in ``BiReader.data``
3818
4377
  * @param {BiOptions?} options - Any options to set at start
3819
4378
  * @param {BiOptions["byteOffset"]?} options.byteOffset - Byte offset to start writer (default ``0``)
3820
4379
  * @param {BiOptions["bitOffset"]?} options.bitOffset - Bit offset 0-7 to start writer (default ``0``)
@@ -3822,6 +4381,7 @@ class BiBase {
3822
4381
  * @param {BiOptions["strict"]?} options.strict - Strict mode: if ``true`` does not extend supplied array on outside write (default ``false``)
3823
4382
  * @param {BiOptions["extendBufferSize"]?} options.extendBufferSize - Amount of data to add when extending the buffer array when strict mode is false. Note: Changes logic in ``.get`` and ``.return``.
3824
4383
  * @param {BiOptions["enforceBigInt"]?} options.enforceBigInt - 64 bit value reads will always stay ``BigInt``.
4384
+ * @param {BiOptions["writeable"]} options.writeable - Allow data writes when reading a file (default false in reader)
3825
4385
  *
3826
4386
  * @since 2.0
3827
4387
  */
@@ -3829,7 +4389,7 @@ class BiReader extends BiBase {
3829
4389
  /**
3830
4390
  * Binary reader, includes bitfields and strings.
3831
4391
  *
3832
- * @param {Buffer|Uint8Array} data - ``Buffer`` or ``Uint8Array``. Always found in ``BiReader.data``
4392
+ * @param {string|Buffer|Uint8Array} input - File path or a ``Buffer`` or ``Uint8Array``. Always found in ``BiReader.data``
3833
4393
  * @param {BiOptions?} options - Any options to set at start
3834
4394
  * @param {BiOptions["byteOffset"]?} options.byteOffset - Byte offset to start writer (default ``0``)
3835
4395
  * @param {BiOptions["bitOffset"]?} options.bitOffset - Bit offset 0-7 to start writer (default ``0``)
@@ -3837,29 +4397,25 @@ class BiReader extends BiBase {
3837
4397
  * @param {BiOptions["strict"]?} options.strict - Strict mode: if ``true`` does not extend supplied array on outside write (default ``false``)
3838
4398
  * @param {BiOptions["extendBufferSize"]?} options.extendBufferSize - Amount of data to add when extending the buffer array when strict mode is false. Note: Changes logic in ``.get`` and ``.return``.
3839
4399
  * @param {BiOptions["enforceBigInt"]?} options.enforceBigInt - 64 bit value reads will always stay ``BigInt``.
4400
+ * @param {BiOptions["writeable"]} options.writeable - Allow data writes when reading a file (default false in reader)
3840
4401
  */
3841
- constructor(data, options = {}) {
3842
- super();
3843
- this.strict = true;
3844
- if (data == undefined) {
3845
- throw new Error("Data required");
3846
- }
3847
- else {
3848
- if (!this.isBufferOrUint8Array(data)) {
3849
- throw new Error("Write data must be Uint8Array or Buffer");
3850
- }
3851
- this.data = data;
4402
+ constructor(input, options = {}) {
4403
+ super(input, options.writeable ?? false);
4404
+ if (input == undefined) {
4405
+ throw new Error("Can not start BiReader without data.");
3852
4406
  }
3853
- this.enforceBigInt = options?.enforceBigInt ?? false;
3854
- if (options.extendBufferSize != undefined && options.extendBufferSize != 0) {
4407
+ this.strict = true;
4408
+ this.enforceBigInt = (options?.enforceBigInt) ?? hasBigInt;
4409
+ if (options.extendBufferSize != undefined &&
4410
+ options.extendBufferSize != 0) {
3855
4411
  this.extendBufferSize = options.extendBufferSize;
3856
4412
  }
3857
- this.size = this.data.length;
3858
- this.sizeB = this.data.length * 8;
3859
- if (options.endianness != undefined && typeof options.endianness != "string") {
4413
+ if (options.endianness != undefined &&
4414
+ typeof options.endianness != "string") {
3860
4415
  throw new Error("Endian must be big or little");
3861
4416
  }
3862
- if (options.endianness != undefined && !(options.endianness == "big" || options.endianness == "little")) {
4417
+ if (options.endianness != undefined &&
4418
+ !(options.endianness == "big" || options.endianness == "little")) {
3863
4419
  throw new Error("Byte order must be big or little");
3864
4420
  }
3865
4421
  this.endian = options.endianness || "little";
@@ -3868,7 +4424,27 @@ class BiReader extends BiBase {
3868
4424
  }
3869
4425
  else {
3870
4426
  if (options.strict != undefined) {
3871
- throw new Error("Strict mode must be true of false");
4427
+ throw new Error("Strict mode must be true or false");
4428
+ }
4429
+ }
4430
+ if (input == undefined) {
4431
+ throw new Error("Data or file path required");
4432
+ }
4433
+ else {
4434
+ if (typeof input == "string") {
4435
+ this.filePath = input;
4436
+ this.mode = "file";
4437
+ this.offset = options.byteOffset ?? 0;
4438
+ this.bitoffset = options.bitOffset ?? 0;
4439
+ }
4440
+ else if (this.isBufferOrUint8Array(input)) {
4441
+ this.data = input;
4442
+ this.mode = "memory";
4443
+ this.size = this.data.length;
4444
+ this.sizeB = this.data.length * 8;
4445
+ }
4446
+ else {
4447
+ throw new Error("Write data must be Uint8Array or Buffer");
3872
4448
  }
3873
4449
  }
3874
4450
  if (options.byteOffset != undefined || options.bitOffset != undefined) {
@@ -3876,7 +4452,7 @@ class BiReader extends BiBase {
3876
4452
  // Adjust byte offset based on bit overflow
3877
4453
  this.offset += Math.floor((Math.abs(options.bitOffset || 0)) / 8);
3878
4454
  // Adjust bit offset
3879
- this.bitoffset = (Math.abs(options.bitOffset || 0) + 64) % 8;
4455
+ this.bitoffset = Math.abs(normalizeBitOffset(options.bitOffset)) % 8;
3880
4456
  // Ensure bit offset stays between 0-7
3881
4457
  this.bitoffset = Math.min(Math.max(this.bitoffset, 0), 7);
3882
4458
  // Ensure offset doesn't go negative
@@ -3895,10 +4471,13 @@ class BiReader extends BiBase {
3895
4471
  }
3896
4472
  }
3897
4473
  }
4474
+ if (this.mode == "file") {
4475
+ this.open();
4476
+ }
3898
4477
  }
3899
4478
  ;
3900
4479
  //
3901
- // Bit Aliases
4480
+ // #region Bit Aliases
3902
4481
  //
3903
4482
  /**
3904
4483
  * Bit field reader.
@@ -6090,7 +6669,7 @@ class BiReader extends BiBase {
6090
6669
  }
6091
6670
  ;
6092
6671
  //
6093
- // byte read
6672
+ // #region byte read
6094
6673
  //
6095
6674
  /**
6096
6675
  * Read byte.
@@ -6129,7 +6708,7 @@ class BiReader extends BiBase {
6129
6708
  }
6130
6709
  ;
6131
6710
  //
6132
- //short16 read
6711
+ // #region short16 read
6133
6712
  //
6134
6713
  /**
6135
6714
  * Read short.
@@ -6294,7 +6873,7 @@ class BiReader extends BiBase {
6294
6873
  }
6295
6874
  ;
6296
6875
  //
6297
- //half float read
6876
+ // #region half float read
6298
6877
  //
6299
6878
  /**
6300
6879
  * Read half float.
@@ -6351,7 +6930,7 @@ class BiReader extends BiBase {
6351
6930
  }
6352
6931
  ;
6353
6932
  //
6354
- //int read
6933
+ // #region int read
6355
6934
  //
6356
6935
  /**
6357
6936
  * Read 32 bit integer.
@@ -6570,7 +7149,7 @@ class BiReader extends BiBase {
6570
7149
  }
6571
7150
  ;
6572
7151
  //
6573
- //float read
7152
+ // #region float read
6574
7153
  //
6575
7154
  /**
6576
7155
  * Read float.
@@ -6600,14 +7179,12 @@ class BiReader extends BiBase {
6600
7179
  }
6601
7180
  ;
6602
7181
  //
6603
- //int64 reader
7182
+ // #region int64 reader
6604
7183
  //
6605
7184
  /**
6606
7185
  * Read signed 64 bit integer
6607
7186
  *
6608
7187
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6609
- *
6610
- * @returns {BigValue}
6611
7188
  */
6612
7189
  get int64() {
6613
7190
  return this.readInt64();
@@ -6617,8 +7194,6 @@ class BiReader extends BiBase {
6617
7194
  * Read signed 64 bit integer.
6618
7195
  *
6619
7196
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6620
- *
6621
- * @returns {BigValue}
6622
7197
  */
6623
7198
  get bigint() {
6624
7199
  return this.readInt64();
@@ -6628,8 +7203,6 @@ class BiReader extends BiBase {
6628
7203
  * Read signed 64 bit integer.
6629
7204
  *
6630
7205
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6631
- *
6632
- * @returns {BigValue}
6633
7206
  */
6634
7207
  get quad() {
6635
7208
  return this.readInt64();
@@ -6639,8 +7212,6 @@ class BiReader extends BiBase {
6639
7212
  * Read unsigned 64 bit integer.
6640
7213
  *
6641
7214
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6642
- *
6643
- * @returns {BigValue}
6644
7215
  */
6645
7216
  get uint64() {
6646
7217
  return this.readInt64(true);
@@ -6650,8 +7221,6 @@ class BiReader extends BiBase {
6650
7221
  * Read unsigned 64 bit integer.
6651
7222
  *
6652
7223
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6653
- *
6654
- * @returns {BigValue}
6655
7224
  */
6656
7225
  get ubigint() {
6657
7226
  return this.readInt64(true);
@@ -6661,8 +7230,6 @@ class BiReader extends BiBase {
6661
7230
  * Read unsigned 64 bit integer.
6662
7231
  *
6663
7232
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6664
- *
6665
- * @returns {BigValue}
6666
7233
  */
6667
7234
  get uquad() {
6668
7235
  return this.readInt64(true);
@@ -6672,8 +7239,6 @@ class BiReader extends BiBase {
6672
7239
  * Read signed 64 bit integer.
6673
7240
  *
6674
7241
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6675
- *
6676
- * @returns {BigValue}
6677
7242
  */
6678
7243
  get int64be() {
6679
7244
  return this.readInt64(false, "big");
@@ -6683,8 +7248,6 @@ class BiReader extends BiBase {
6683
7248
  * Read signed 64 bit integer.
6684
7249
  *
6685
7250
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6686
- *
6687
- * @returns {BigValue}
6688
7251
  */
6689
7252
  get bigintbe() {
6690
7253
  return this.readInt64(false, "big");
@@ -6694,8 +7257,6 @@ class BiReader extends BiBase {
6694
7257
  * Read signed 64 bit integer.
6695
7258
  *
6696
7259
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6697
- *
6698
- * @returns {BigValue}
6699
7260
  */
6700
7261
  get quadbe() {
6701
7262
  return this.readInt64(false, "big");
@@ -6705,8 +7266,6 @@ class BiReader extends BiBase {
6705
7266
  * Read unsigned 64 bit integer.
6706
7267
  *
6707
7268
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6708
- *
6709
- * @returns {BigValue}
6710
7269
  */
6711
7270
  get uint64be() {
6712
7271
  return this.readInt64(true, "big");
@@ -6716,8 +7275,6 @@ class BiReader extends BiBase {
6716
7275
  * Read unsigned 64 bit integer.
6717
7276
  *
6718
7277
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6719
- *
6720
- * @returns {BigValue}
6721
7278
  */
6722
7279
  get ubigintbe() {
6723
7280
  return this.readInt64(true, "big");
@@ -6727,8 +7284,6 @@ class BiReader extends BiBase {
6727
7284
  * Read unsigned 64 bit integer.
6728
7285
  *
6729
7286
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6730
- *
6731
- * @returns {BigValue}
6732
7287
  */
6733
7288
  get uquadbe() {
6734
7289
  return this.readInt64(true, "big");
@@ -6738,8 +7293,6 @@ class BiReader extends BiBase {
6738
7293
  * Read signed 64 bit integer.
6739
7294
  *
6740
7295
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6741
- *
6742
- * @returns {BigValue}
6743
7296
  */
6744
7297
  get int64le() {
6745
7298
  return this.readInt64(false, "little");
@@ -6749,8 +7302,6 @@ class BiReader extends BiBase {
6749
7302
  * Read signed 64 bit integer.
6750
7303
  *
6751
7304
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6752
- *
6753
- * @returns {BigValue}
6754
7305
  */
6755
7306
  get bigintle() {
6756
7307
  return this.readInt64(false, "little");
@@ -6760,8 +7311,6 @@ class BiReader extends BiBase {
6760
7311
  * Read signed 64 bit integer.
6761
7312
  *
6762
7313
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6763
- *
6764
- * @returns {BigValue}
6765
7314
  */
6766
7315
  get quadle() {
6767
7316
  return this.readInt64(false, "little");
@@ -6771,8 +7320,6 @@ class BiReader extends BiBase {
6771
7320
  * Read unsigned 64 bit integer.
6772
7321
  *
6773
7322
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6774
- *
6775
- * @returns {BigValue}
6776
7323
  */
6777
7324
  get uint64le() {
6778
7325
  return this.readInt64(true, "little");
@@ -6782,8 +7329,6 @@ class BiReader extends BiBase {
6782
7329
  * Read unsigned 64 bit integer.
6783
7330
  *
6784
7331
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6785
- *
6786
- * @returns {BigValue}
6787
7332
  */
6788
7333
  get ubigintle() {
6789
7334
  return this.readInt64(true, "little");
@@ -6793,15 +7338,13 @@ class BiReader extends BiBase {
6793
7338
  * Read unsigned 64 bit integer.
6794
7339
  *
6795
7340
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6796
- *
6797
- * @returns {BigValue}
6798
7341
  */
6799
7342
  get uquadle() {
6800
7343
  return this.readInt64(true, "little");
6801
7344
  }
6802
7345
  ;
6803
7346
  //
6804
- //doublefloat reader
7347
+ // #region doublefloat reader
6805
7348
  //
6806
7349
  /**
6807
7350
  * Read double float.
@@ -6858,7 +7401,7 @@ class BiReader extends BiBase {
6858
7401
  }
6859
7402
  ;
6860
7403
  //
6861
- //string reader
7404
+ // #region string reader
6862
7405
  //
6863
7406
  /**
6864
7407
  * Reads string, use options object for different types.
@@ -6871,7 +7414,7 @@ class BiReader extends BiBase {
6871
7414
  * @param {stringOptions["stripNull"]?} options.stripNull - removes 0x00 characters
6872
7415
  * @param {stringOptions["encoding"]?} options.encoding - TextEncoder accepted types
6873
7416
  * @param {stringOptions["endian"]?} options.endian - for wide-pascal and utf-16
6874
- * @return {string}
7417
+ * @returns {string}
6875
7418
  */
6876
7419
  string(options) {
6877
7420
  return this.readString(options);
@@ -6882,7 +7425,7 @@ class BiReader extends BiBase {
6882
7425
  *
6883
7426
  * Default is ``utf-8``
6884
7427
  *
6885
- * @return {string}
7428
+ * @returns {string}
6886
7429
  */
6887
7430
  get str() {
6888
7431
  return this.readString(this.strSettings);
@@ -6895,7 +7438,7 @@ class BiReader extends BiBase {
6895
7438
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6896
7439
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6897
7440
  *
6898
- * @return {string}
7441
+ * @returns {string}
6899
7442
  */
6900
7443
  utf8string(length, terminateValue, stripNull) {
6901
7444
  return this.string({ stringType: "utf-8", encoding: "utf-8", length: length, terminateValue: terminateValue, stripNull: stripNull });
@@ -6908,7 +7451,7 @@ class BiReader extends BiBase {
6908
7451
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6909
7452
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6910
7453
  *
6911
- * @return {string}
7454
+ * @returns {string}
6912
7455
  */
6913
7456
  cstring(length, terminateValue, stripNull) {
6914
7457
  return this.string({ stringType: "utf-8", encoding: "utf-8", length: length, terminateValue: terminateValue, stripNull: stripNull });
@@ -6921,7 +7464,7 @@ class BiReader extends BiBase {
6921
7464
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6922
7465
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6923
7466
  *
6924
- * @return {string}
7467
+ * @returns {string}
6925
7468
  */
6926
7469
  ansistring(length, terminateValue, stripNull) {
6927
7470
  return this.string({ stringType: "utf-8", encoding: "windows-1252", length: length, terminateValue: terminateValue, stripNull: stripNull });
@@ -6935,7 +7478,7 @@ class BiReader extends BiBase {
6935
7478
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6936
7479
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
6937
7480
  *
6938
- * @return {string}
7481
+ * @returns {string}
6939
7482
  */
6940
7483
  utf16string(length, terminateValue, stripNull, endian) {
6941
7484
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: endian, stripNull: stripNull });
@@ -6949,7 +7492,7 @@ class BiReader extends BiBase {
6949
7492
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6950
7493
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
6951
7494
  *
6952
- * @return {string}
7495
+ * @returns {string}
6953
7496
  */
6954
7497
  unistring(length, terminateValue, stripNull, endian) {
6955
7498
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: endian, stripNull: stripNull });
@@ -6962,7 +7505,7 @@ class BiReader extends BiBase {
6962
7505
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6963
7506
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6964
7507
  *
6965
- * @return {string}
7508
+ * @returns {string}
6966
7509
  */
6967
7510
  utf16stringle(length, terminateValue, stripNull) {
6968
7511
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: "little", stripNull: stripNull });
@@ -6975,7 +7518,7 @@ class BiReader extends BiBase {
6975
7518
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6976
7519
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6977
7520
  *
6978
- * @return {string}
7521
+ * @returns {string}
6979
7522
  */
6980
7523
  unistringle(length, terminateValue, stripNull) {
6981
7524
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: "little", stripNull: stripNull });
@@ -6988,7 +7531,7 @@ class BiReader extends BiBase {
6988
7531
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6989
7532
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6990
7533
  *
6991
- * @return {string}
7534
+ * @returns {string}
6992
7535
  */
6993
7536
  utf16stringbe(length, terminateValue, stripNull) {
6994
7537
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: "big", stripNull: stripNull });
@@ -7001,7 +7544,7 @@ class BiReader extends BiBase {
7001
7544
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
7002
7545
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7003
7546
  *
7004
- * @return {string}
7547
+ * @returns {string}
7005
7548
  */
7006
7549
  unistringbe(length, terminateValue, stripNull) {
7007
7550
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: "big", stripNull: stripNull });
@@ -7014,7 +7557,7 @@ class BiReader extends BiBase {
7014
7557
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7015
7558
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7016
7559
  *
7017
- * @return {string}
7560
+ * @returns {string}
7018
7561
  */
7019
7562
  pstring(lengthReadSize, stripNull, endian) {
7020
7563
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: lengthReadSize, stripNull: stripNull, endian: endian });
@@ -7026,7 +7569,7 @@ class BiReader extends BiBase {
7026
7569
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7027
7570
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7028
7571
  *
7029
- * @return {string}
7572
+ * @returns {string}
7030
7573
  */
7031
7574
  pstring1(stripNull, endian) {
7032
7575
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 1, stripNull: stripNull, endian: endian });
@@ -7037,7 +7580,7 @@ class BiReader extends BiBase {
7037
7580
  *
7038
7581
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7039
7582
  *
7040
- * @return {string}
7583
+ * @returns {string}
7041
7584
  */
7042
7585
  pstring1le(stripNull) {
7043
7586
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 1, stripNull: stripNull, endian: "little" });
@@ -7048,7 +7591,7 @@ class BiReader extends BiBase {
7048
7591
  *
7049
7592
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7050
7593
  *
7051
- * @return {string}
7594
+ * @returns {string}
7052
7595
  */
7053
7596
  pstring1be(stripNull) {
7054
7597
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 1, stripNull: stripNull, endian: "big" });
@@ -7060,7 +7603,7 @@ class BiReader extends BiBase {
7060
7603
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7061
7604
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7062
7605
  *
7063
- * @return {string}
7606
+ * @returns {string}
7064
7607
  */
7065
7608
  pstring2(stripNull, endian) {
7066
7609
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 2, stripNull: stripNull, endian: endian });
@@ -7071,7 +7614,7 @@ class BiReader extends BiBase {
7071
7614
  *
7072
7615
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7073
7616
  *
7074
- * @return {string}
7617
+ * @returns {string}
7075
7618
  */
7076
7619
  pstring2le(stripNull) {
7077
7620
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 2, stripNull: stripNull, endian: "little" });
@@ -7082,7 +7625,7 @@ class BiReader extends BiBase {
7082
7625
  *
7083
7626
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7084
7627
  *
7085
- * @return {string}
7628
+ * @returns {string}
7086
7629
  */
7087
7630
  pstring2be(stripNull) {
7088
7631
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 2, stripNull: stripNull, endian: "big" });
@@ -7094,7 +7637,7 @@ class BiReader extends BiBase {
7094
7637
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7095
7638
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7096
7639
  *
7097
- * @return {string}
7640
+ * @returns {string}
7098
7641
  */
7099
7642
  pstring4(stripNull, endian) {
7100
7643
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 4, stripNull: stripNull, endian: endian });
@@ -7105,7 +7648,7 @@ class BiReader extends BiBase {
7105
7648
  *
7106
7649
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7107
7650
  *
7108
- * @return {string}
7651
+ * @returns {string}
7109
7652
  */
7110
7653
  pstring4le(stripNull) {
7111
7654
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 4, stripNull: stripNull, endian: "little" });
@@ -7116,7 +7659,7 @@ class BiReader extends BiBase {
7116
7659
  *
7117
7660
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7118
7661
  *
7119
- * @return {string}
7662
+ * @returns {string}
7120
7663
  */
7121
7664
  pstring4be(stripNull) {
7122
7665
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 4, stripNull: stripNull, endian: "big" });
@@ -7129,7 +7672,7 @@ class BiReader extends BiBase {
7129
7672
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7130
7673
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7131
7674
  *
7132
- * @return {string}
7675
+ * @returns {string}
7133
7676
  */
7134
7677
  wpstring(lengthReadSize, stripNull, endian) {
7135
7678
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: lengthReadSize, endian: endian, stripNull: stripNull });
@@ -7141,19 +7684,41 @@ class BiReader extends BiBase {
7141
7684
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7142
7685
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7143
7686
  *
7144
- * @return {string}
7687
+ * @returns {string}
7145
7688
  */
7146
7689
  wpstring1(stripNull, endian) {
7147
7690
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 1, endian: endian, stripNull: stripNull });
7148
7691
  }
7149
7692
  ;
7150
7693
  /**
7694
+ * Reads Wide-Pascal string 1 byte length read in little endian order.
7695
+ *
7696
+ * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7697
+ *
7698
+ * @returns {string}
7699
+ */
7700
+ wpstring1le(stripNull) {
7701
+ return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 1, endian: "little", stripNull: stripNull });
7702
+ }
7703
+ ;
7704
+ /**
7705
+ * Reads Wide-Pascal string 1 byte length read in big endian order.
7706
+ *
7707
+ * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7708
+ *
7709
+ * @returns {string}
7710
+ */
7711
+ wpstring1be(stripNull) {
7712
+ return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 1, endian: "big", stripNull: stripNull });
7713
+ }
7714
+ ;
7715
+ /**
7151
7716
  * Reads Wide-Pascal string 2 byte length read.
7152
7717
  *
7153
7718
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7154
7719
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7155
7720
  *
7156
- * @return {string}
7721
+ * @returns {string}
7157
7722
  */
7158
7723
  wpstring2(stripNull, endian) {
7159
7724
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 2, endian: endian, stripNull: stripNull });
@@ -7164,7 +7729,7 @@ class BiReader extends BiBase {
7164
7729
  *
7165
7730
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7166
7731
  *
7167
- * @return {string}
7732
+ * @returns {string}
7168
7733
  */
7169
7734
  wpstring2le(stripNull) {
7170
7735
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 2, endian: "little", stripNull: stripNull });
@@ -7175,7 +7740,7 @@ class BiReader extends BiBase {
7175
7740
  *
7176
7741
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7177
7742
  *
7178
- * @return {string}
7743
+ * @returns {string}
7179
7744
  */
7180
7745
  wpstring2be(stripNull) {
7181
7746
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 2, endian: "big", stripNull: stripNull });
@@ -7187,7 +7752,7 @@ class BiReader extends BiBase {
7187
7752
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7188
7753
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7189
7754
  *
7190
- * @return {string}
7755
+ * @returns {string}
7191
7756
  */
7192
7757
  wpstring4(stripNull, endian) {
7193
7758
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 4, endian: endian, stripNull: stripNull });
@@ -7198,7 +7763,7 @@ class BiReader extends BiBase {
7198
7763
  *
7199
7764
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7200
7765
  *
7201
- * @return {string}
7766
+ * @returns {string}
7202
7767
  */
7203
7768
  wpstring4be(stripNull) {
7204
7769
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 4, endian: "big", stripNull: stripNull });
@@ -7209,7 +7774,7 @@ class BiReader extends BiBase {
7209
7774
  *
7210
7775
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7211
7776
  *
7212
- * @return {string}
7777
+ * @returns {string}
7213
7778
  */
7214
7779
  wpstring4le(stripNull) {
7215
7780
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 4, endian: "little", stripNull: stripNull });
@@ -7220,7 +7785,7 @@ class BiReader extends BiBase {
7220
7785
  /**
7221
7786
  * Binary writer, includes bitfields and strings.
7222
7787
  *
7223
- * @param {Buffer|Uint8Array} data - ``Buffer`` or ``Uint8Array``. Always found in ``BiWriter.data``
7788
+ * @param {string|Buffer|Uint8Array} input - File path or a ``Buffer`` or ``Uint8Array``. Always found in ``BiWriter.data``
7224
7789
  * @param {BiOptions?} options - Any options to set at start
7225
7790
  * @param {BiOptions["byteOffset"]?} options.byteOffset - Byte offset to start writer (default ``0``)
7226
7791
  * @param {BiOptions["bitOffset"]?} options.bitOffset - Bit offset 0-7 to start writer (default ``0``)
@@ -7228,6 +7793,7 @@ class BiReader extends BiBase {
7228
7793
  * @param {BiOptions["strict"]?} options.strict - Strict mode: if ``true`` does not extend supplied array on outside write (default ``false``)
7229
7794
  * @param {BiOptions["extendBufferSize"]?} options.extendBufferSize - Amount of data to add when extending the buffer array when strict mode is false. Note: Changes logic in ``.get`` and ``.return``.
7230
7795
  * @param {BiOptions["enforceBigInt"]?} options.enforceBigInt - 64 bit value reads will always stay ``BigInt``.
7796
+ * @param {BiOptions["writeable"]} options.writeable - Allow data writes when reading a file (default true in writer)
7231
7797
  *
7232
7798
  * @since 2.0
7233
7799
  */
@@ -7235,7 +7801,7 @@ class BiWriter extends BiBase {
7235
7801
  /**
7236
7802
  * Binary writer, includes bitfields and strings.
7237
7803
  *
7238
- * @param {Buffer|Uint8Array} data - ``Buffer`` or ``Uint8Array``. Always found in ``BiWriter.data``
7804
+ * @param {string|Buffer|Uint8Array} input - ``Buffer`` or ``Uint8Array``. Always found in ``BiWriter.data``
7239
7805
  * @param {BiOptions?} options - Any options to set at start
7240
7806
  * @param {BiOptions["byteOffset"]?} options.byteOffset - Byte offset to start writer (default ``0``)
7241
7807
  * @param {BiOptions["bitOffset"]?} options.bitOffset - Bit offset 0-7 to start writer (default ``0``)
@@ -7243,51 +7809,63 @@ class BiWriter extends BiBase {
7243
7809
  * @param {BiOptions["strict"]?} options.strict - Strict mode: if ``true`` does not extend supplied array on outside write (default ``false``)
7244
7810
  * @param {BiOptions["extendBufferSize"]?} options.extendBufferSize - Amount of data to add when extending the buffer array when strict mode is false. Note: Changes logic in ``.get`` and ``.return``.
7245
7811
  * @param {BiOptions["enforceBigInt"]?} options.enforceBigInt - 64 bit value reads will always stay ``BigInt``.
7812
+ * @param {BiOptions["writeable"]} options.writeable - Allow data writes when reading a file (default true in writer)
7246
7813
  */
7247
- constructor(data, options = {}) {
7248
- super();
7814
+ constructor(input, options = {}) {
7815
+ super(input, options.writeable ?? true);
7249
7816
  this.strict = false;
7250
- if (data == undefined) {
7251
- if (typeof Buffer !== 'undefined') {
7252
- this.data = Buffer.alloc(this.offset || 1 + (this.bitoffset != 0 ? 1 : 0));
7253
- }
7254
- else {
7255
- this.data = new Uint8Array(this.offset || 1 + (this.bitoffset != 0 ? 1 : 0));
7256
- }
7817
+ this.enforceBigInt = (options?.enforceBigInt) ?? hasBigInt;
7818
+ if (options.extendBufferSize != undefined &&
7819
+ options.extendBufferSize != 0) {
7820
+ this.extendBufferSize = options.extendBufferSize;
7257
7821
  }
7258
- else {
7259
- if (!this.isBufferOrUint8Array(data)) {
7260
- throw new Error("Write data must be Uint8Array or Buffer.");
7261
- }
7262
- this.data = data;
7822
+ if (input == undefined) {
7823
+ input = new Uint8Array(this.extendBufferSize);
7824
+ console.warn(`BiWriter started without data. Creating Uint8Array with extendBufferSize.`);
7263
7825
  }
7264
- this.enforceBigInt = options?.enforceBigInt ?? false;
7265
- if (options.extendBufferSize != undefined && options.extendBufferSize != 0) {
7266
- this.extendBufferSize = options.extendBufferSize;
7826
+ if (options.endianness != undefined &&
7827
+ typeof options.endianness != "string") {
7828
+ throw new Error("endianness must be big or little.");
7829
+ }
7830
+ if (options.endianness != undefined &&
7831
+ !(options.endianness == "big" || options.endianness == "little")) {
7832
+ throw new Error("Endianness must be big or little.");
7267
7833
  }
7268
- this.size = this.data.length;
7269
- this.sizeB = this.data.length * 8;
7834
+ this.endian = options.endianness || "little";
7270
7835
  if (typeof options.strict == "boolean") {
7271
7836
  this.strict = options.strict;
7272
7837
  }
7273
7838
  else {
7274
7839
  if (options.strict != undefined) {
7275
- throw new Error("Strict mode must be true of false.");
7840
+ throw new Error("Strict mode must be true or false.");
7276
7841
  }
7277
7842
  }
7278
- if (options.endianness != undefined && typeof options.endianness != "string") {
7279
- throw new Error("endianness must be big or little.");
7843
+ if (input == undefined) {
7844
+ throw new Error("Data or file path required");
7280
7845
  }
7281
- if (options.endianness != undefined && !(options.endianness == "big" || options.endianness == "little")) {
7282
- throw new Error("Endianness must be big or little.");
7846
+ else {
7847
+ if (typeof input == "string") {
7848
+ this.filePath = input;
7849
+ this.mode = "file";
7850
+ this.offset = options.byteOffset ?? 0;
7851
+ this.bitoffset = options.bitOffset ?? 0;
7852
+ }
7853
+ else if (this.isBufferOrUint8Array(input)) {
7854
+ this.data = input;
7855
+ this.mode = "memory";
7856
+ this.size = this.data.length;
7857
+ this.sizeB = this.data.length * 8;
7858
+ }
7859
+ else {
7860
+ throw new Error("Write data must be Uint8Array or Buffer");
7861
+ }
7283
7862
  }
7284
- this.endian = options.endianness || "little";
7285
7863
  if (options.byteOffset != undefined || options.bitOffset != undefined) {
7286
7864
  this.offset = ((Math.abs(options.byteOffset || 0)) + Math.ceil((Math.abs(options.bitOffset || 0)) / 8));
7287
7865
  // Adjust byte offset based on bit overflow
7288
7866
  this.offset += Math.floor((Math.abs(options.bitOffset || 0)) / 8);
7289
7867
  // Adjust bit offset
7290
- this.bitoffset = (Math.abs(options.bitOffset || 0) + 64) % 8;
7868
+ this.bitoffset = Math.abs(normalizeBitOffset(options.bitOffset)) % 8;
7291
7869
  // Ensure bit offset stays between 0-7
7292
7870
  this.bitoffset = Math.min(Math.max(this.bitoffset, 0), 7);
7293
7871
  // Ensure offset doesn't go negative
@@ -7306,10 +7884,13 @@ class BiWriter extends BiBase {
7306
7884
  }
7307
7885
  }
7308
7886
  }
7887
+ if (this.mode == "file") {
7888
+ this.open();
7889
+ }
7309
7890
  }
7310
7891
  ;
7311
7892
  //
7312
- // Bit Aliases
7893
+ // #region Bit Aliases
7313
7894
  //
7314
7895
  /**
7315
7896
  * Bit field writer.
@@ -9507,7 +10088,7 @@ class BiWriter extends BiBase {
9507
10088
  }
9508
10089
  ;
9509
10090
  //
9510
- // byte write
10091
+ // #region byte write
9511
10092
  //
9512
10093
  /**
9513
10094
  * Write byte.
@@ -9546,7 +10127,7 @@ class BiWriter extends BiBase {
9546
10127
  }
9547
10128
  ;
9548
10129
  //
9549
- // short writes
10130
+ // #region short writes
9550
10131
  //
9551
10132
  /**
9552
10133
  * Write int16.
@@ -9711,7 +10292,7 @@ class BiWriter extends BiBase {
9711
10292
  }
9712
10293
  ;
9713
10294
  //
9714
- // half float
10295
+ // #region half float
9715
10296
  //
9716
10297
  /**
9717
10298
  * Writes half float.
@@ -9768,7 +10349,7 @@ class BiWriter extends BiBase {
9768
10349
  }
9769
10350
  ;
9770
10351
  //
9771
- // int32 write
10352
+ // #region int32 write
9772
10353
  //
9773
10354
  /**
9774
10355
  * Write int32.
@@ -9996,7 +10577,7 @@ class BiWriter extends BiBase {
9996
10577
  }
9997
10578
  ;
9998
10579
  //
9999
- // float write
10580
+ // #region float write
10000
10581
  //
10001
10582
  /**
10002
10583
  * Write float.
@@ -10026,7 +10607,7 @@ class BiWriter extends BiBase {
10026
10607
  }
10027
10608
  ;
10028
10609
  //
10029
- // int64 write
10610
+ // #region int64 write
10030
10611
  //
10031
10612
  /**
10032
10613
  * Write 64 bit integer.
@@ -10191,7 +10772,7 @@ class BiWriter extends BiBase {
10191
10772
  }
10192
10773
  ;
10193
10774
  //
10194
- // doublefloat
10775
+ // #region doublefloat
10195
10776
  //
10196
10777
  /**
10197
10778
  * Writes double float.
@@ -10248,7 +10829,7 @@ class BiWriter extends BiBase {
10248
10829
  }
10249
10830
  ;
10250
10831
  //
10251
- // string
10832
+ // #region string
10252
10833
  //
10253
10834
  /**
10254
10835
  * Writes string, use options object for different types.
@@ -10600,6 +11181,16 @@ class BiReaderStream {
10600
11181
  throw new Error("BiReaderStream isn't usable in browser. Use BiReader instead.");
10601
11182
  }
10602
11183
  }
11184
+ /**
11185
+ * Isn't usable in browser.
11186
+ * @since 4.0
11187
+ * @deprecated Use ``BiReader`` instead.
11188
+ */
11189
+ class BiFileReader {
11190
+ constructor() {
11191
+ throw new Error("BiFileReader isn't usable in browser. Use BiReader instead.");
11192
+ }
11193
+ }
10603
11194
  /**
10604
11195
  * Isn't usable in browser.
10605
11196
  * @since 3.0
@@ -10630,6 +11221,16 @@ class biwriter {
10630
11221
  throw new Error("biwriter is deprecated. Use BiWriter instead.");
10631
11222
  }
10632
11223
  }
11224
+ /**
11225
+ * Isn't usable in browser.
11226
+ * @since 4.0
11227
+ * @deprecated Use ``BiWriter`` instead.
11228
+ */
11229
+ class BiFileWriter {
11230
+ constructor() {
11231
+ throw new Error("BiWriterStream isn't usable in browser. Use BiWriter instead.");
11232
+ }
11233
+ }
10633
11234
 
10634
- export { BiReader, BiReaderStream, BiWriter, BiWriterStream, bireader, biwriter, hexdump };
11235
+ export { BiBase, BiFileReader, BiFileWriter, BiReader, BiReaderStream, BiWriter, BiWriterStream, bireader, biwriter, hexdump };
10635
11236
  //# sourceMappingURL=index.browser.js.map