bireader 3.1.15 → 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,27 +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
- // @ts-ignore
346
439
  ctx.data = Buffer.concat([ctx.data, paddbuffer]);
347
440
  }
348
441
  else {
349
- const addArray = new Array(to_padd);
350
- 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;
351
445
  }
352
446
  ctx.size = ctx.data.length;
353
447
  ctx.sizeB = ctx.data.length * 8;
448
+ return;
354
449
  }
355
450
  function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
451
+ ctx.open();
356
452
  const new_start = Math.abs(startOffset || 0);
357
453
  const new_offset = (endOffset || ctx.offset);
358
454
  if (new_offset > ctx.size) {
@@ -365,12 +461,12 @@ function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
365
461
  }
366
462
  }
367
463
  else {
368
- 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 })) : "";
369
465
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + endOffset + " of " + ctx.size);
370
466
  }
371
467
  }
372
468
  if (ctx.strict == true && remove == true) {
373
- 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 })) : "";
374
470
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: Can not remove data in strict mode: endOffset " + endOffset + " of " + ctx.size);
375
471
  }
376
472
  const data_removed = ctx.data.subarray(new_start, new_offset);
@@ -378,11 +474,13 @@ function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
378
474
  const part1 = ctx.data.subarray(0, new_start);
379
475
  const part2 = ctx.data.subarray(new_offset, ctx.size);
380
476
  if (isBuffer(ctx.data)) {
381
- // @ts-ignore
382
477
  ctx.data = Buffer.concat([part1, part2]);
383
478
  }
384
479
  else {
385
- 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;
386
484
  }
387
485
  ctx.size = ctx.data.length;
388
486
  ctx.sizeB = ctx.data.length * 8;
@@ -393,11 +491,14 @@ function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
393
491
  const replacement = new Array(data_removed.length).fill(fillValue & 0xff);
394
492
  if (isBuffer(ctx.data)) {
395
493
  const buff_placement = Buffer.from(replacement);
396
- // @ts-ignore
397
494
  ctx.data = Buffer.concat([part1, buff_placement, part2]);
398
495
  }
399
496
  else {
400
- 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;
401
502
  }
402
503
  ctx.size = ctx.data.length;
403
504
  ctx.sizeB = ctx.data.length * 8;
@@ -416,11 +517,11 @@ function remove(ctx, startOffset, endOffset, consume, remove, fillValue) {
416
517
  }
417
518
  function addData(ctx, data, consume, offset, replace) {
418
519
  if (ctx.strict == true) {
419
- 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 })) : "";
420
521
  throw new Error(`\x1b[33m[Strict mode]\x1b[0m: Can not insert data in strict mode. Use unrestrict() to enable.`);
421
522
  }
422
- if (typeof Buffer !== 'undefined' && data instanceof Buffer && !(ctx.data instanceof Buffer)) {
423
- // @ts-ignore
523
+ ctx.open();
524
+ if (isBuffer(data) && !isBuffer(ctx.data)) {
424
525
  data = Buffer.from(data);
425
526
  }
426
527
  if (data instanceof Uint8Array && !(ctx.data instanceof Uint8Array)) {
@@ -432,11 +533,14 @@ function addData(ctx, data, consume, offset, replace) {
432
533
  const part1 = ctx.data.subarray(0, needed_size - data.length);
433
534
  const part2 = ctx.data.subarray(needed_size, ctx.size);
434
535
  if (isBuffer(ctx.data)) {
435
- // @ts-ignore
436
536
  ctx.data = Buffer.concat([part1, data, part2]);
437
537
  }
438
538
  else {
439
- 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;
440
544
  }
441
545
  ctx.size = ctx.data.length;
442
546
  ctx.sizeB = ctx.data.length * 8;
@@ -445,11 +549,14 @@ function addData(ctx, data, consume, offset, replace) {
445
549
  const part1 = ctx.data.subarray(0, needed_size);
446
550
  const part2 = ctx.data.subarray(needed_size, ctx.size);
447
551
  if (isBuffer(ctx.data)) {
448
- // @ts-ignore
449
552
  ctx.data = Buffer.concat([part1, data, part2]);
450
553
  }
451
554
  else {
452
- 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;
453
560
  }
454
561
  ctx.size = ctx.data.length;
455
562
  ctx.sizeB = ctx.data.length * 8;
@@ -459,8 +566,8 @@ function addData(ctx, data, consume, offset, replace) {
459
566
  ctx.bitoffset = 0;
460
567
  }
461
568
  }
569
+ // #region Math
462
570
  function AND(ctx, and_key, start, end, consume) {
463
- const input = ctx.data;
464
571
  if ((end || 0) > ctx.size) {
465
572
  if (ctx.strict == false) {
466
573
  if (ctx.extendBufferSize != 0) {
@@ -471,13 +578,14 @@ function AND(ctx, and_key, start, end, consume) {
471
578
  }
472
579
  }
473
580
  else {
474
- 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 })) : "";
475
582
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
476
583
  }
477
584
  }
585
+ ctx.open();
478
586
  if (typeof and_key == "number") {
479
587
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
480
- input[i] = input[i] & (and_key & 0xff);
588
+ ctx.data[i] = ctx.data[i] & (and_key & 0xff);
481
589
  if (consume) {
482
590
  ctx.offset = i;
483
591
  ctx.bitoffset = 0;
@@ -485,8 +593,11 @@ function AND(ctx, and_key, start, end, consume) {
485
593
  }
486
594
  }
487
595
  else {
488
- if (arraybuffcheck(and_key)) {
489
- 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;
490
601
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
491
602
  if (number != and_key.length - 1) {
492
603
  number = number + 1;
@@ -494,7 +605,7 @@ function AND(ctx, and_key, start, end, consume) {
494
605
  else {
495
606
  number = 0;
496
607
  }
497
- input[i] = input[i] & and_key[number];
608
+ ctx.data[i] = ctx.data[i] & and_key[number];
498
609
  if (consume) {
499
610
  ctx.offset = i;
500
611
  ctx.bitoffset = 0;
@@ -507,7 +618,6 @@ function AND(ctx, and_key, start, end, consume) {
507
618
  }
508
619
  }
509
620
  function OR(ctx, or_key, start, end, consume) {
510
- const input = ctx.data;
511
621
  if ((end || 0) > ctx.size) {
512
622
  if (ctx.strict == false) {
513
623
  if (ctx.extendBufferSize != 0) {
@@ -518,13 +628,14 @@ function OR(ctx, or_key, start, end, consume) {
518
628
  }
519
629
  }
520
630
  else {
521
- 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 })) : "";
522
632
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
523
633
  }
524
634
  }
635
+ ctx.open();
525
636
  if (typeof or_key == "number") {
526
637
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
527
- input[i] = input[i] | (or_key & 0xff);
638
+ ctx.data[i] = ctx.data[i] | (or_key & 0xff);
528
639
  if (consume) {
529
640
  ctx.offset = i;
530
641
  ctx.bitoffset = 0;
@@ -532,8 +643,11 @@ function OR(ctx, or_key, start, end, consume) {
532
643
  }
533
644
  }
534
645
  else {
535
- if (arraybuffcheck(or_key)) {
536
- 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;
537
651
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
538
652
  if (number != or_key.length - 1) {
539
653
  number = number + 1;
@@ -541,7 +655,7 @@ function OR(ctx, or_key, start, end, consume) {
541
655
  else {
542
656
  number = 0;
543
657
  }
544
- input[i] = input[i] | or_key[number];
658
+ ctx.data[i] = ctx.data[i] | or_key[number];
545
659
  if (consume) {
546
660
  ctx.offset = i;
547
661
  ctx.bitoffset = 0;
@@ -554,7 +668,6 @@ function OR(ctx, or_key, start, end, consume) {
554
668
  }
555
669
  }
556
670
  function XOR(ctx, xor_key, start, end, consume) {
557
- const input = ctx.data;
558
671
  if ((end || 0) > ctx.size) {
559
672
  if (ctx.strict == false) {
560
673
  if (ctx.extendBufferSize != 0) {
@@ -565,13 +678,14 @@ function XOR(ctx, xor_key, start, end, consume) {
565
678
  }
566
679
  }
567
680
  else {
568
- 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 })) : "";
569
682
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
570
683
  }
571
684
  }
685
+ ctx.open();
572
686
  if (typeof xor_key == "number") {
573
687
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
574
- input[i] = input[i] ^ (xor_key & 0xff);
688
+ ctx.data[i] = ctx.data[i] ^ (xor_key & 0xff);
575
689
  if (consume) {
576
690
  ctx.offset = i;
577
691
  ctx.bitoffset = 0;
@@ -579,7 +693,10 @@ function XOR(ctx, xor_key, start, end, consume) {
579
693
  }
580
694
  }
581
695
  else {
582
- 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)) {
583
700
  let number = -1;
584
701
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
585
702
  if (number != xor_key.length - 1) {
@@ -588,7 +705,7 @@ function XOR(ctx, xor_key, start, end, consume) {
588
705
  else {
589
706
  number = 0;
590
707
  }
591
- input[i] = input[i] ^ xor_key[number];
708
+ ctx.data[i] = ctx.data[i] ^ xor_key[number];
592
709
  if (consume) {
593
710
  ctx.offset = i;
594
711
  ctx.bitoffset = 0;
@@ -611,10 +728,11 @@ function NOT(ctx, start, end, consume) {
611
728
  }
612
729
  }
613
730
  else {
614
- 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 })) : "";
615
732
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
616
733
  }
617
734
  }
735
+ ctx.open();
618
736
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
619
737
  ctx.data[i] = ~ctx.data[i];
620
738
  if (consume) {
@@ -624,7 +742,6 @@ function NOT(ctx, start, end, consume) {
624
742
  }
625
743
  }
626
744
  function LSHIFT(ctx, shift_key, start, end, consume) {
627
- const input = ctx.data;
628
745
  if ((end || 0) > ctx.size) {
629
746
  if (ctx.strict == false) {
630
747
  if (ctx.extendBufferSize != 0) {
@@ -635,13 +752,14 @@ function LSHIFT(ctx, shift_key, start, end, consume) {
635
752
  }
636
753
  }
637
754
  else {
638
- 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 })) : "";
639
756
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
640
757
  }
641
758
  }
759
+ ctx.open();
642
760
  if (typeof shift_key == "number") {
643
761
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
644
- input[i] = input[i] << shift_key;
762
+ ctx.data[i] = ctx.data[i] << shift_key;
645
763
  if (consume) {
646
764
  ctx.offset = i;
647
765
  ctx.bitoffset = 0;
@@ -649,8 +767,11 @@ function LSHIFT(ctx, shift_key, start, end, consume) {
649
767
  }
650
768
  }
651
769
  else {
652
- if (arraybuffcheck(shift_key)) {
653
- 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;
654
775
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
655
776
  if (number != shift_key.length - 1) {
656
777
  number = number + 1;
@@ -658,7 +779,7 @@ function LSHIFT(ctx, shift_key, start, end, consume) {
658
779
  else {
659
780
  number = 0;
660
781
  }
661
- input[i] = input[i] << shift_key[number];
782
+ ctx.data[i] = ctx.data[i] << shift_key[number];
662
783
  if (consume) {
663
784
  ctx.offset = i;
664
785
  ctx.bitoffset = 0;
@@ -671,7 +792,6 @@ function LSHIFT(ctx, shift_key, start, end, consume) {
671
792
  }
672
793
  }
673
794
  function RSHIFT(ctx, shift_key, start, end, consume) {
674
- const input = ctx.data;
675
795
  if ((end || 0) > ctx.size) {
676
796
  if (ctx.strict == false) {
677
797
  if (ctx.extendBufferSize != 0) {
@@ -682,13 +802,14 @@ function RSHIFT(ctx, shift_key, start, end, consume) {
682
802
  }
683
803
  }
684
804
  else {
685
- 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 })) : "";
686
806
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
687
807
  }
688
808
  }
809
+ ctx.open();
689
810
  if (typeof shift_key == "number") {
690
811
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
691
- input[i] = input[i] >> shift_key;
812
+ ctx.data[i] = ctx.data[i] >> shift_key;
692
813
  if (consume) {
693
814
  ctx.offset = i;
694
815
  ctx.bitoffset = 0;
@@ -696,8 +817,11 @@ function RSHIFT(ctx, shift_key, start, end, consume) {
696
817
  }
697
818
  }
698
819
  else {
699
- if (arraybuffcheck(shift_key)) {
700
- 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;
701
825
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
702
826
  if (number != shift_key.length - 1) {
703
827
  number = number + 1;
@@ -705,7 +829,7 @@ function RSHIFT(ctx, shift_key, start, end, consume) {
705
829
  else {
706
830
  number = 0;
707
831
  }
708
- input[i] = input[i] >> shift_key[number];
832
+ ctx.data[i] = ctx.data[i] >> shift_key[number];
709
833
  if (consume) {
710
834
  ctx.offset = i;
711
835
  ctx.bitoffset = 0;
@@ -718,7 +842,6 @@ function RSHIFT(ctx, shift_key, start, end, consume) {
718
842
  }
719
843
  }
720
844
  function ADD(ctx, add_key, start, end, consume) {
721
- const input = ctx.data;
722
845
  if ((end || 0) > ctx.size) {
723
846
  if (ctx.strict == false) {
724
847
  if (ctx.extendBufferSize != 0) {
@@ -729,13 +852,14 @@ function ADD(ctx, add_key, start, end, consume) {
729
852
  }
730
853
  }
731
854
  else {
732
- 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 })) : "";
733
856
  throw new Error("\x1b[33m[Strict mode]\x1b[0m: End offset outside of data: endOffset " + (end || 0) + " of " + ctx.size);
734
857
  }
735
858
  }
859
+ ctx.open();
736
860
  if (typeof add_key == "number") {
737
861
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
738
- input[i] = input[i] + add_key;
862
+ ctx.data[i] = ctx.data[i] + add_key;
739
863
  if (consume) {
740
864
  ctx.offset = i;
741
865
  ctx.bitoffset = 0;
@@ -743,8 +867,11 @@ function ADD(ctx, add_key, start, end, consume) {
743
867
  }
744
868
  }
745
869
  else {
746
- if (arraybuffcheck(add_key)) {
747
- 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;
748
875
  for (let i = (start || 0); i < Math.min(end || ctx.size, ctx.size); i++) {
749
876
  if (number != add_key.length - 1) {
750
877
  number = number + 1;
@@ -752,7 +879,7 @@ function ADD(ctx, add_key, start, end, consume) {
752
879
  else {
753
880
  number = 0;
754
881
  }
755
- input[i] = input[i] + add_key[number];
882
+ ctx.data[i] = ctx.data[i] + add_key[number];
756
883
  if (consume) {
757
884
  ctx.offset = i;
758
885
  ctx.bitoffset = 0;
@@ -764,11 +891,13 @@ function ADD(ctx, add_key, start, end, consume) {
764
891
  }
765
892
  }
766
893
  }
894
+ // #region Search
767
895
  function fString(ctx, searchString) {
896
+ ctx.open();
768
897
  // Convert the searchString to Uint8Array
769
898
  const searchArray = new TextEncoder().encode(searchString);
770
899
  for (let i = ctx.offset; i <= ctx.size - searchArray.length; i++) {
771
- let match = true;
900
+ var match = true;
772
901
  for (let j = 0; j < searchArray.length; j++) {
773
902
  if (ctx.data[i + j] !== searchArray[j]) {
774
903
  match = false;
@@ -782,25 +911,25 @@ function fString(ctx, searchString) {
782
911
  return -1; // String not found
783
912
  }
784
913
  function fNumber(ctx, targetNumber, bits, unsigned, endian) {
914
+ ctx.open();
785
915
  check_size(ctx, Math.floor(bits / 8), 0);
786
916
  for (let z = ctx.offset; z <= (ctx.size - (bits / 8)); z++) {
787
917
  var off_in_bits = 0;
788
918
  var value = 0;
789
919
  for (var i = 0; i < bits;) {
790
- var remaining = bits - i;
791
- var bitOffset = off_in_bits & 7;
792
- var currentByte = ctx.data[z + (off_in_bits >> 3)];
793
- var read = Math.min(remaining, 8 - bitOffset);
794
- 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);
795
924
  if ((endian != undefined ? endian : ctx.endian) == "big") {
796
- mask = ~(0xFF << read);
797
- readBits = (currentByte >> (8 - read - bitOffset)) & mask;
925
+ let mask = ~(0xFF << read);
926
+ let readBits = (currentByte >> (8 - read - bitOffset)) & mask;
798
927
  value <<= read;
799
928
  value |= readBits;
800
929
  }
801
930
  else {
802
- mask = ~(0xFF << read);
803
- readBits = (currentByte >> bitOffset) & mask;
931
+ let mask = ~(0xFF << read);
932
+ let readBits = (currentByte >> bitOffset) & mask;
804
933
  value |= readBits << i;
805
934
  }
806
935
  off_in_bits += read;
@@ -821,19 +950,20 @@ function fNumber(ctx, targetNumber, bits, unsigned, endian) {
821
950
  return -1; // number not found
822
951
  }
823
952
  function fHalfFloat(ctx, targetNumber, endian) {
953
+ ctx.open();
824
954
  check_size(ctx, 2, 0);
825
955
  for (let z = ctx.offset; z <= (ctx.size - 2); z++) {
826
956
  var value = 0;
827
957
  if ((endian != undefined ? endian : ctx.endian) == "little") {
828
- value = (ctx.data[z + 1] << 8) | ctx.data[z];
958
+ value = ((ctx.data[z + 1] & 0xFFFF) << 8) | (ctx.data[z] & 0xFFFF);
829
959
  }
830
960
  else {
831
- value = (ctx.data[z] << 8) | ctx.data[z + 1];
961
+ value = ((ctx.data[z] & 0xFFFF) << 8) | (ctx.data[z + 1] & 0xFFFF);
832
962
  }
833
963
  const sign = (value & 0x8000) >> 15;
834
964
  const exponent = (value & 0x7C00) >> 10;
835
965
  const fraction = value & 0x03FF;
836
- let floatValue;
966
+ var floatValue;
837
967
  if (exponent === 0) {
838
968
  if (fraction === 0) {
839
969
  floatValue = (sign === 0) ? 0 : -0; // +/-0
@@ -862,21 +992,28 @@ function fHalfFloat(ctx, targetNumber, endian) {
862
992
  return -1; // number not found
863
993
  }
864
994
  function fFloat(ctx, targetNumber, endian) {
995
+ ctx.open();
865
996
  check_size(ctx, 4, 0);
866
997
  for (let z = ctx.offset; z <= (ctx.size - 4); z++) {
867
998
  var value = 0;
868
999
  if ((endian != undefined ? endian : ctx.endian) == "little") {
869
- 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);
870
1004
  }
871
1005
  else {
872
- 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);
873
1010
  }
874
1011
  const isNegative = (value & 0x80000000) !== 0 ? 1 : 0;
875
1012
  // Extract the exponent and fraction parts
876
1013
  const exponent = (value >> 23) & 0xFF;
877
1014
  const fraction = value & 0x7FFFFF;
878
1015
  // Calculate the float value
879
- let floatValue;
1016
+ var floatValue;
880
1017
  if (exponent === 0) {
881
1018
  // Denormalized number (exponent is 0)
882
1019
  floatValue = Math.pow(-1, isNegative) * Math.pow(2, -126) * (fraction / Math.pow(2, 23));
@@ -896,12 +1033,16 @@ function fFloat(ctx, targetNumber, endian) {
896
1033
  return -1; // number not found
897
1034
  }
898
1035
  function fBigInt(ctx, targetNumber, unsigned, endian) {
1036
+ if (!hasBigInt) {
1037
+ throw new Error("System doesn't support BigInt values.");
1038
+ }
1039
+ ctx.open();
899
1040
  check_size(ctx, 8, 0);
900
1041
  for (let z = ctx.offset; z <= (ctx.size - 8); z++) {
901
- let value = BigInt(0);
1042
+ var value = BigInt(0);
902
1043
  if ((endian == undefined ? ctx.endian : endian) == "little") {
903
1044
  for (let i = 0; i < 8; i++) {
904
- value = value | BigInt(ctx.data[z + i]) << BigInt(8 * i);
1045
+ value = value | BigInt((ctx.data[z + i] & 0xFF)) << BigInt(8 * i);
905
1046
  }
906
1047
  if (unsigned == undefined || unsigned == false) {
907
1048
  if (value & (BigInt(1) << BigInt(63))) {
@@ -911,7 +1052,7 @@ function fBigInt(ctx, targetNumber, unsigned, endian) {
911
1052
  }
912
1053
  else {
913
1054
  for (let i = 0; i < 8; i++) {
914
- value = (value << BigInt(8)) | BigInt(ctx.data[z + i]);
1055
+ value = (value << BigInt(8)) | BigInt((ctx.data[z + i] & 0xFF));
915
1056
  }
916
1057
  if (unsigned == undefined || unsigned == false) {
917
1058
  if (value & (BigInt(1) << BigInt(63))) {
@@ -926,35 +1067,39 @@ function fBigInt(ctx, targetNumber, unsigned, endian) {
926
1067
  return -1; // number not found
927
1068
  }
928
1069
  function fDoubleFloat(ctx, targetNumber, endian) {
1070
+ if (!hasBigInt) {
1071
+ throw new Error("System doesn't support BigInt values.");
1072
+ }
1073
+ ctx.open();
929
1074
  check_size(ctx, 8, 0);
930
1075
  for (let z = ctx.offset; z <= (ctx.size - 8); z++) {
931
- let value = BigInt(0);
1076
+ var value = BigInt(0);
932
1077
  if ((endian == undefined ? ctx.endian : endian) == "little") {
933
1078
  for (let i = 0; i < 8; i++) {
934
- value = value | BigInt(ctx.data[z + i]) << BigInt(8 * i);
1079
+ value = value | BigInt((ctx.data[z + i] & 0xFF)) << BigInt(8 * i);
935
1080
  }
936
1081
  }
937
1082
  else {
938
1083
  for (let i = 0; i < 8; i++) {
939
- value = (value << BigInt(8)) | BigInt(ctx.data[z + i]);
1084
+ value = (value << BigInt(8)) | BigInt((ctx.data[z + i] & 0xFF));
940
1085
  }
941
1086
  }
942
- const sign = (value & 0x8000000000000000n) >> 63n;
943
- const exponent = Number((value & 0x7ff0000000000000n) >> 52n) - 1023;
944
- 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);
945
1090
  var floatValue;
946
1091
  if (exponent == -1023) {
947
1092
  if (fraction == 0) {
948
- floatValue = (sign == 0n) ? 0 : -0; // +/-0
1093
+ floatValue = (sign == BigInt(0)) ? 0 : -0; // +/-0
949
1094
  }
950
1095
  else {
951
1096
  // Denormalized number
952
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, -1022) * fraction;
1097
+ floatValue = (sign == BigInt(0) ? 1 : -1) * Math.pow(2, -1022) * fraction;
953
1098
  }
954
1099
  }
955
1100
  else if (exponent == 1024) {
956
1101
  if (fraction == 0) {
957
- floatValue = (sign == 0n) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
1102
+ floatValue = (sign == BigInt(0)) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
958
1103
  }
959
1104
  else {
960
1105
  floatValue = Number.NaN;
@@ -962,7 +1107,7 @@ function fDoubleFloat(ctx, targetNumber, endian) {
962
1107
  }
963
1108
  else {
964
1109
  // Normalized number
965
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
1110
+ floatValue = (sign == BigInt(0) ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
966
1111
  }
967
1112
  if (floatValue == targetNumber) {
968
1113
  return z;
@@ -970,7 +1115,9 @@ function fDoubleFloat(ctx, targetNumber, endian) {
970
1115
  }
971
1116
  return -1; // number not found
972
1117
  }
1118
+ // #region Write / Read Bits
973
1119
  function wbit(ctx, value, bits, unsigned, endian) {
1120
+ ctx.open();
974
1121
  if (value == undefined) {
975
1122
  throw new Error('Must supply value.');
976
1123
  }
@@ -985,7 +1132,7 @@ function wbit(ctx, value, bits, unsigned, endian) {
985
1132
  }
986
1133
  if (unsigned == true || bits == 1) {
987
1134
  if (value < 0 || value > Math.pow(2, bits)) {
988
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1135
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
989
1136
  throw new Error(`Value is out of range for the specified ${bits}bit length.` + " min: " + 0 + " max: " + Math.pow(2, bits) + " value: " + value);
990
1137
  }
991
1138
  }
@@ -993,7 +1140,7 @@ function wbit(ctx, value, bits, unsigned, endian) {
993
1140
  const maxValue = Math.pow(2, bits - 1) - 1;
994
1141
  const minValue = -maxValue - 1;
995
1142
  if (value < minValue || value > maxValue) {
996
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1143
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
997
1144
  throw new Error(`Value is out of range for the specified ${bits}bit length.` + " min: " + minValue + " max: " + maxValue + " value: " + value);
998
1145
  }
999
1146
  }
@@ -1013,23 +1160,22 @@ function wbit(ctx, value, bits, unsigned, endian) {
1013
1160
  }
1014
1161
  var off_in_bits = (ctx.offset * 8) + ctx.bitoffset;
1015
1162
  for (var i = 0; i < bits;) {
1016
- var remaining = bits - i;
1017
- var bitOffset = off_in_bits & 7;
1018
- var byteOffset = off_in_bits >> 3;
1019
- var written = Math.min(remaining, 8 - bitOffset);
1020
- 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);
1021
1167
  if ((endian != undefined ? endian : ctx.endian) == "big") {
1022
- mask = ~(-1 << written);
1023
- writeBits = (value >> (bits - i - written)) & mask;
1168
+ let mask = ~(-1 << written);
1169
+ let writeBits = (value >> (bits - i - written)) & mask;
1024
1170
  var destShift = 8 - bitOffset - written;
1025
- destMask = ~(mask << destShift);
1171
+ let destMask = ~(mask << destShift);
1026
1172
  ctx.data[byteOffset] = (ctx.data[byteOffset] & destMask) | (writeBits << destShift);
1027
1173
  }
1028
1174
  else {
1029
- mask = ~(0xFF << written);
1030
- writeBits = value & mask;
1175
+ let mask = ~(0xFF << written);
1176
+ let writeBits = value & mask;
1031
1177
  value >>= written;
1032
- destMask = ~(mask << bitOffset);
1178
+ let destMask = ~(mask << bitOffset);
1033
1179
  ctx.data[byteOffset] = (ctx.data[byteOffset] & destMask) | (writeBits << bitOffset);
1034
1180
  }
1035
1181
  off_in_bits += written;
@@ -1039,6 +1185,7 @@ function wbit(ctx, value, bits, unsigned, endian) {
1039
1185
  ctx.bitoffset = ((bits) + ctx.bitoffset) % 8;
1040
1186
  }
1041
1187
  function rbit(ctx, bits, unsigned, endian) {
1188
+ ctx.open();
1042
1189
  if (bits == undefined || typeof bits != "number") {
1043
1190
  throw new Error("Enter number of bits to read");
1044
1191
  }
@@ -1050,26 +1197,25 @@ function rbit(ctx, bits, unsigned, endian) {
1050
1197
  }
1051
1198
  const size_needed = ((((bits - 1) + ctx.bitoffset) / 8) + ctx.offset);
1052
1199
  if (bits <= 0 || size_needed > ctx.size) {
1053
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1200
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1054
1201
  throw new Error("Invalid number of bits to read: " + size_needed + " of " + ctx.size);
1055
1202
  }
1056
1203
  var off_in_bits = (ctx.offset * 8) + ctx.bitoffset;
1057
1204
  var value = 0;
1058
1205
  for (var i = 0; i < bits;) {
1059
- var remaining = bits - i;
1060
- var bitOffset = off_in_bits & 7;
1061
- var currentByte = ctx.data[off_in_bits >> 3];
1062
- var read = Math.min(remaining, 8 - bitOffset);
1063
- 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);
1064
1210
  if ((endian != undefined ? endian : ctx.endian) == "big") {
1065
- mask = ~(0xFF << read);
1066
- readBits = (currentByte >> (8 - read - bitOffset)) & mask;
1211
+ let mask = ~(0xFF << read);
1212
+ let readBits = (currentByte >> (8 - read - bitOffset)) & mask;
1067
1213
  value <<= read;
1068
1214
  value |= readBits;
1069
1215
  }
1070
1216
  else {
1071
- mask = ~(0xFF << read);
1072
- readBits = (currentByte >> bitOffset) & mask;
1217
+ let mask = ~(0xFF << read);
1218
+ let readBits = (currentByte >> bitOffset) & mask;
1073
1219
  value |= readBits << i;
1074
1220
  }
1075
1221
  off_in_bits += read;
@@ -1085,11 +1231,13 @@ function rbit(ctx, bits, unsigned, endian) {
1085
1231
  }
1086
1232
  return value;
1087
1233
  }
1234
+ // #region Write / Read Bytes
1088
1235
  function wbyte(ctx, value, unsigned) {
1236
+ ctx.open();
1089
1237
  check_size(ctx, 1, 0);
1090
1238
  if (unsigned == true) {
1091
1239
  if (value < 0 || value > 255) {
1092
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1240
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1093
1241
  throw new Error('Value is out of range for the specified 8bit length.' + " min: " + 0 + " max: " + 255 + " value: " + value);
1094
1242
  }
1095
1243
  }
@@ -1097,17 +1245,40 @@ function wbyte(ctx, value, unsigned) {
1097
1245
  const maxValue = Math.pow(2, 8 - 1) - 1;
1098
1246
  const minValue = -maxValue - 1;
1099
1247
  if (value < minValue || value > maxValue) {
1100
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1248
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1101
1249
  throw new Error('Value is out of range for the specified 8bit length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1102
1250
  }
1103
1251
  }
1104
- 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
+ }
1105
1263
  ctx.offset += 1;
1106
1264
  ctx.bitoffset = 0;
1107
1265
  }
1108
1266
  function rbyte(ctx, unsigned) {
1267
+ ctx.open();
1109
1268
  check_size(ctx, 1);
1110
- 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];
1111
1282
  ctx.offset += 1;
1112
1283
  ctx.bitoffset = 0;
1113
1284
  if (unsigned == true) {
@@ -1117,11 +1288,13 @@ function rbyte(ctx, unsigned) {
1117
1288
  return read > 127 ? read - 256 : read;
1118
1289
  }
1119
1290
  }
1291
+ // #region Write / Read Int16
1120
1292
  function wint16(ctx, value, unsigned, endian) {
1293
+ ctx.open();
1121
1294
  check_size(ctx, 2, 0);
1122
1295
  if (unsigned == true) {
1123
1296
  if (value < 0 || value > 65535) {
1124
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1297
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1125
1298
  throw new Error('Value is out of range for the specified 16bit length.' + " min: " + 0 + " max: " + 65535 + " value: " + value);
1126
1299
  }
1127
1300
  }
@@ -1129,29 +1302,53 @@ function wint16(ctx, value, unsigned, endian) {
1129
1302
  const maxValue = Math.pow(2, 16 - 1) - 1;
1130
1303
  const minValue = -maxValue - 1;
1131
1304
  if (value < minValue || value > maxValue) {
1132
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1305
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1133
1306
  throw new Error('Value is out of range for the specified 16bit length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1134
1307
  }
1135
1308
  }
1136
- if ((endian != undefined ? endian : ctx.endian) == "little") {
1137
- ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? value : value & 0xff;
1138
- 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
+ }
1139
1316
  }
1140
1317
  else {
1141
- ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xff;
1142
- 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
+ }
1143
1326
  }
1144
1327
  ctx.offset += 2;
1145
1328
  ctx.bitoffset = 0;
1146
1329
  }
1147
1330
  function rint16(ctx, unsigned, endian) {
1331
+ ctx.open();
1148
1332
  check_size(ctx, 2);
1149
1333
  var read;
1150
- if ((endian != undefined ? endian : ctx.endian) == "little") {
1151
- 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;
1152
1344
  }
1153
1345
  else {
1154
- 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
+ }
1155
1352
  }
1156
1353
  ctx.offset += 2;
1157
1354
  ctx.bitoffset = 0;
@@ -1162,12 +1359,21 @@ function rint16(ctx, unsigned, endian) {
1162
1359
  return read & 0xFFFF;
1163
1360
  }
1164
1361
  }
1362
+ // #region Write / Read Float16
1165
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
+ }
1166
1372
  var uint16Value = ctx.readInt16(true, (endian != undefined ? endian : ctx.endian));
1167
1373
  const sign = (uint16Value & 0x8000) >> 15;
1168
1374
  const exponent = (uint16Value & 0x7C00) >> 10;
1169
1375
  const fraction = uint16Value & 0x03FF;
1170
- let floatValue;
1376
+ var floatValue;
1171
1377
  if (exponent === 0) {
1172
1378
  if (fraction === 0) {
1173
1379
  floatValue = (sign === 0) ? 0 : -0; // +/-0
@@ -1192,36 +1398,54 @@ function rhalffloat(ctx, endian) {
1192
1398
  return floatValue;
1193
1399
  }
1194
1400
  function whalffloat(ctx, value, endian) {
1401
+ ctx.open();
1195
1402
  check_size(ctx, 2, 0);
1196
1403
  const maxValue = 65504;
1197
1404
  const minValue = 5.96e-08;
1198
1405
  if (value < minValue || value > maxValue) {
1199
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1406
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1200
1407
  throw new Error('Value is out of range for the specified half float length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1201
1408
  }
1202
- const signMask = 0x8000;
1203
- const exponentMask = 0x7C00;
1204
- const fractionMask = 0x03FF;
1205
- // Determine sign, exponent, and fraction bits
1206
- let signBit = (value & signMask) >> 15;
1207
- let exponentBits = (value & exponentMask) >> 10;
1208
- let fractionBits = value & fractionMask;
1209
- // Special cases for NaN and Infinity
1210
- if (exponentBits === 0x1F) {
1211
- // NaN or Infinity, copy exponent and fraction
1212
- exponentBits = 0xFF;
1213
- }
1214
- else if (exponentBits === 0x00) {
1215
- // Denormalized numbers, exponent is 0, adjust exponent bits
1216
- exponentBits = 0x00;
1217
- 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
+ }
1218
1442
  }
1219
1443
  else {
1220
- // Normalized number, subtract exponent bias
1221
- exponentBits -= 15;
1444
+ // Normalized
1445
+ exponent = exponent - 112;
1446
+ mantissa = mantissa >> 13;
1447
+ halfFloatBits = (sign << 15) | (exponent << 10) | mantissa;
1222
1448
  }
1223
- // Combine sign, exponent, and fraction bits into half float format
1224
- let halfFloatBits = (signBit << 15) | (exponentBits << 10) | fractionBits;
1225
1449
  // Write bytes based on endianness
1226
1450
  if ((endian == undefined ? ctx.endian : endian) == "little") {
1227
1451
  ctx.data[ctx.offset] = halfFloatBits & 0xFF;
@@ -1234,11 +1458,13 @@ function whalffloat(ctx, value, endian) {
1234
1458
  ctx.offset += 2;
1235
1459
  ctx.bitoffset = 0;
1236
1460
  }
1461
+ // #region Write / Read Int32
1237
1462
  function wint32(ctx, value, unsigned, endian) {
1463
+ ctx.open();
1238
1464
  check_size(ctx, 4, 0);
1239
1465
  if (unsigned == true) {
1240
1466
  if (value < 0 || value > 4294967295) {
1241
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1467
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1242
1468
  throw new Error('Value is out of range for the specified 32bit length.' + " min: " + 0 + " max: " + 4294967295 + " value: " + value);
1243
1469
  }
1244
1470
  }
@@ -1246,33 +1472,61 @@ function wint32(ctx, value, unsigned, endian) {
1246
1472
  const maxValue = Math.pow(2, 32 - 1) - 1;
1247
1473
  const minValue = -maxValue - 1;
1248
1474
  if (value < minValue || value > maxValue) {
1249
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1475
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1250
1476
  throw new Error('Value is out of range for the specified 32bit length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1251
1477
  }
1252
1478
  }
1253
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1254
- ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? value : value & 0xFF;
1255
- ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xFF;
1256
- ctx.data[ctx.offset + 2] = (unsigned == undefined || unsigned == false) ? (value >> 16) : (value >> 16) & 0xFF;
1257
- 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
+ }
1258
1486
  }
1259
1487
  else {
1260
- ctx.data[ctx.offset] = (unsigned == undefined || unsigned == false) ? (value >> 24) : (value >> 24) & 0xFF;
1261
- ctx.data[ctx.offset + 1] = (unsigned == undefined || unsigned == false) ? (value >> 16) : (value >> 16) & 0xFF;
1262
- ctx.data[ctx.offset + 2] = (unsigned == undefined || unsigned == false) ? (value >> 8) : (value >> 8) & 0xFF;
1263
- 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
+ }
1264
1500
  }
1265
1501
  ctx.offset += 4;
1266
1502
  ctx.bitoffset = 0;
1267
1503
  }
1268
1504
  function rint32(ctx, unsigned, endian) {
1505
+ ctx.open();
1269
1506
  check_size(ctx, 4);
1270
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
+ }
1271
1519
  if ((endian != undefined ? endian : ctx.endian) == "little") {
1272
- 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);
1273
1524
  }
1274
1525
  else {
1275
- 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);
1276
1530
  }
1277
1531
  ctx.offset += 4;
1278
1532
  ctx.bitoffset = 0;
@@ -1283,15 +1537,24 @@ function rint32(ctx, unsigned, endian) {
1283
1537
  return read >>> 0;
1284
1538
  }
1285
1539
  }
1540
+ // #region Write / Read Float32
1286
1541
  function rfloat(ctx, endian) {
1287
- 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));
1288
1551
  // Check if the value is negative (i.e., the most significant bit is set)
1289
1552
  const isNegative = (uint32Value & 0x80000000) !== 0 ? 1 : 0;
1290
1553
  // Extract the exponent and fraction parts
1291
1554
  const exponent = (uint32Value >> 23) & 0xFF;
1292
1555
  const fraction = uint32Value & 0x7FFFFF;
1293
1556
  // Calculate the float value
1294
- let floatValue;
1557
+ var floatValue;
1295
1558
  if (exponent === 0) {
1296
1559
  // Denormalized number (exponent is 0)
1297
1560
  floatValue = Math.pow(-1, isNegative) * Math.pow(2, -126) * (fraction / Math.pow(2, 23));
@@ -1307,6 +1570,7 @@ function rfloat(ctx, endian) {
1307
1570
  return floatValue;
1308
1571
  }
1309
1572
  function wfloat(ctx, value, endian) {
1573
+ ctx.open();
1310
1574
  check_size(ctx, 4, 0);
1311
1575
  const MIN_POSITIVE_FLOAT32 = Number.MIN_VALUE;
1312
1576
  const MAX_POSITIVE_FLOAT32 = 3.4028235e+38;
@@ -1315,67 +1579,94 @@ function wfloat(ctx, value, endian) {
1315
1579
  if (!((value === 0) ||
1316
1580
  (value >= MIN_POSITIVE_FLOAT32 && value <= MAX_POSITIVE_FLOAT32) ||
1317
1581
  (value >= MIN_NEGATIVE_FLOAT32 && value <= MAX_NEGATIVE_FLOAT32))) {
1318
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1582
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1319
1583
  throw new Error('Value is out of range for the specified float length.' + " min: " + MIN_NEGATIVE_FLOAT32 + " max: " + MAX_POSITIVE_FLOAT32 + " value: " + value);
1320
1584
  }
1321
- const dataView = new DataView(new Uint8Array(4).buffer);
1322
- dataView.setFloat32(0, value, true);
1323
- let intValue = dataView.getInt32(0, true);
1324
- let shift = 0;
1325
- for (let i = 0; i < 4; i++) {
1326
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1327
- 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];
1328
1596
  }
1329
1597
  else {
1330
- 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];
1331
1602
  }
1332
- shift += 8;
1333
1603
  }
1334
1604
  ctx.offset += 4;
1335
1605
  ctx.bitoffset = 0;
1336
1606
  }
1607
+ // #region Write / Read Int64
1337
1608
  function rint64(ctx, unsigned, endian) {
1609
+ if (!hasBigInt) {
1610
+ throw new Error("System doesn't support BigInt values.");
1611
+ }
1612
+ ctx.open();
1338
1613
  check_size(ctx, 8);
1339
- // Convert the byte array to a BigInt
1340
- let value = BigInt(0);
1341
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1342
- for (let i = 0; i < 8; i++) {
1343
- value = value | BigInt(ctx.data[ctx.offset]) << BigInt(8 * i);
1344
- ctx.offset += 1;
1345
- }
1614
+ var value = BigInt(0);
1615
+ if (canBigInt64) {
1346
1616
  if (unsigned == undefined || unsigned == false) {
1347
- if (value & (BigInt(1) << BigInt(63))) {
1348
- value -= BigInt(1) << BigInt(64);
1349
- }
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");
1350
1621
  }
1622
+ ctx.offset += 8;
1351
1623
  }
1352
1624
  else {
1353
- for (let i = 0; i < 8; i++) {
1354
- value = (value << BigInt(8)) | BigInt(ctx.data[ctx.offset]);
1355
- 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
+ }
1356
1635
  }
1357
- if (unsigned == undefined || unsigned == false) {
1358
- if (value & (BigInt(1) << BigInt(63))) {
1359
- 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
+ }
1360
1645
  }
1361
1646
  }
1362
1647
  }
1363
1648
  ctx.bitoffset = 0;
1364
- if (ctx.enforceBigInt) {
1649
+ if (ctx.enforceBigInt == true) {
1365
1650
  return value;
1366
1651
  }
1367
1652
  else {
1368
1653
  if (isSafeInt64(value)) {
1369
1654
  return Number(value);
1370
1655
  }
1656
+ else {
1657
+ throw new Error("Value is outside of number range and enforceBigInt is set to false. " + value);
1658
+ }
1371
1659
  }
1372
- return value;
1373
1660
  }
1374
1661
  function wint64(ctx, value, unsigned, endian) {
1662
+ if (!hasBigInt) {
1663
+ throw new Error("System doesn't support BigInt values.");
1664
+ }
1665
+ ctx.open();
1375
1666
  check_size(ctx, 8, 0);
1376
1667
  if (unsigned == true) {
1377
1668
  if (value < 0 || value > Math.pow(2, 64) - 1) {
1378
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1669
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1379
1670
  throw new Error('Value is out of range for the specified 64bit length.' + " min: " + 0 + " max: " + (Math.pow(2, 64) - 1) + " value: " + value);
1380
1671
  }
1381
1672
  }
@@ -1383,49 +1674,61 @@ function wint64(ctx, value, unsigned, endian) {
1383
1674
  const maxValue = Math.pow(2, 63) - 1;
1384
1675
  const minValue = -Math.pow(2, 63);
1385
1676
  if (value < minValue || value > maxValue) {
1386
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1677
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1387
1678
  throw new Error('Value is out of range for the specified 64bit length.' + " min: " + minValue + " max: " + maxValue + " value: " + value);
1388
1679
  }
1389
1680
  }
1390
- // Convert the BigInt to a 64-bit signed integer
1391
- const bigIntArray = new BigInt64Array(1);
1392
- bigIntArray[0] = BigInt(value);
1393
- // Use two 32-bit views to write the Int64
1394
- const int32Array = new Int32Array(bigIntArray.buffer);
1395
- for (let i = 0; i < 2; i++) {
1396
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1397
- if (unsigned == undefined || unsigned == false) {
1398
- ctx.data[ctx.offset + i * 4 + 0] = int32Array[i];
1399
- ctx.data[ctx.offset + i * 4 + 1] = (int32Array[i] >> 8);
1400
- ctx.data[ctx.offset + i * 4 + 2] = (int32Array[i] >> 16);
1401
- ctx.data[ctx.offset + i * 4 + 3] = (int32Array[i] >> 24);
1402
- }
1403
- else {
1404
- ctx.data[ctx.offset + i * 4 + 0] = int32Array[i] & 0xFF;
1405
- ctx.data[ctx.offset + i * 4 + 1] = (int32Array[i] >> 8) & 0xFF;
1406
- ctx.data[ctx.offset + i * 4 + 2] = (int32Array[i] >> 16) & 0xFF;
1407
- ctx.data[ctx.offset + i * 4 + 3] = (int32Array[i] >> 24) & 0xFF;
1408
- }
1681
+ if (canBigInt64) {
1682
+ if (unsigned == undefined || unsigned == false) {
1683
+ ctx.view.setBigInt64(ctx.offset, BigInt(value), endian != undefined ? endian == "little" : ctx.endian == "little");
1409
1684
  }
1410
1685
  else {
1411
- if (unsigned == undefined || unsigned == false) {
1412
- ctx.data[ctx.offset + (1 - i) * 4 + 3] = int32Array[i];
1413
- ctx.data[ctx.offset + (1 - i) * 4 + 2] = (int32Array[i] >> 8);
1414
- ctx.data[ctx.offset + (1 - i) * 4 + 1] = (int32Array[i] >> 16);
1415
- ctx.data[ctx.offset + (1 - i) * 4 + 0] = (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
+ }
1416
1709
  }
1417
1710
  else {
1418
- ctx.data[ctx.offset + (1 - i) * 4 + 3] = int32Array[i] & 0xFF;
1419
- ctx.data[ctx.offset + (1 - i) * 4 + 2] = (int32Array[i] >> 8) & 0xFF;
1420
- ctx.data[ctx.offset + (1 - i) * 4 + 1] = (int32Array[i] >> 16) & 0xFF;
1421
- ctx.data[ctx.offset + (1 - i) * 4 + 0] = (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
+ }
1422
1723
  }
1423
1724
  }
1424
1725
  }
1425
1726
  ctx.offset += 8;
1426
1727
  ctx.bitoffset = 0;
1427
1728
  }
1729
+ // #region Write / Read Float64
1428
1730
  function wdfloat(ctx, value, endian) {
1731
+ ctx.open();
1429
1732
  check_size(ctx, 8, 0);
1430
1733
  const MIN_POSITIVE_FLOAT64 = 2.2250738585072014e-308;
1431
1734
  const MAX_POSITIVE_FLOAT64 = Number.MAX_VALUE;
@@ -1434,43 +1737,56 @@ function wdfloat(ctx, value, endian) {
1434
1737
  if (!((value === 0) ||
1435
1738
  (value >= MIN_POSITIVE_FLOAT64 && value <= MAX_POSITIVE_FLOAT64) ||
1436
1739
  (value >= MIN_NEGATIVE_FLOAT64 && value <= MAX_NEGATIVE_FLOAT64))) {
1437
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1740
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1438
1741
  throw new Error('Value is out of range for the specified 64bit length.' + " min: " + MIN_NEGATIVE_FLOAT64 + " max: " + MAX_POSITIVE_FLOAT64 + " value: " + value);
1439
1742
  }
1440
- const intArray = new Int32Array(2);
1441
- const floatArray = new Float64Array(intArray.buffer);
1442
- floatArray[0] = value;
1443
- const bytes = new Uint8Array(intArray.buffer);
1444
- for (let i = 0; i < 8; i++) {
1445
- if ((endian == undefined ? ctx.endian : endian) == "little") {
1446
- ctx.data[ctx.offset + i] = bytes[i];
1447
- }
1448
- else {
1449
- 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
+ }
1450
1758
  }
1451
1759
  }
1452
1760
  ctx.offset += 8;
1453
1761
  ctx.bitoffset = 0;
1454
1762
  }
1455
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
+ }
1456
1772
  endian = (endian == undefined ? ctx.endian : endian);
1457
1773
  var uint64Value = ctx.readInt64(true, endian);
1458
- const sign = (BigInt(uint64Value) & 0x8000000000000000n) >> 63n;
1459
- const exponent = Number((BigInt(uint64Value) & 0x7ff0000000000000n) >> 52n) - 1023;
1460
- 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);
1461
1777
  var floatValue;
1462
1778
  if (exponent == -1023) {
1463
1779
  if (fraction == 0) {
1464
- floatValue = (sign == 0n) ? 0 : -0; // +/-0
1780
+ floatValue = (sign == BigInt(0)) ? 0 : -0; // +/-0
1465
1781
  }
1466
1782
  else {
1467
1783
  // Denormalized number
1468
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, -1022) * fraction;
1784
+ floatValue = (sign == BigInt(0) ? 1 : -1) * Math.pow(2, -1022) * fraction;
1469
1785
  }
1470
1786
  }
1471
1787
  else if (exponent == 1024) {
1472
1788
  if (fraction == 0) {
1473
- floatValue = (sign == 0n) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
1789
+ floatValue = (sign == BigInt(0)) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
1474
1790
  }
1475
1791
  else {
1476
1792
  floatValue = Number.NaN;
@@ -1478,11 +1794,13 @@ function rdfloat(ctx, endian) {
1478
1794
  }
1479
1795
  else {
1480
1796
  // Normalized number
1481
- floatValue = (sign == 0n ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
1797
+ floatValue = (sign == BigInt(0) ? 1 : -1) * Math.pow(2, exponent) * (1 + fraction);
1482
1798
  }
1483
1799
  return floatValue;
1484
1800
  }
1801
+ // #region Write / Read Strings
1485
1802
  function rstring(ctx, options) {
1803
+ ctx.open();
1486
1804
  var length = options && options.length;
1487
1805
  var stringType = options && options.stringType || 'utf-8';
1488
1806
  var terminateValue = options && options.terminateValue;
@@ -1572,7 +1890,7 @@ function rstring(ctx, options) {
1572
1890
  maxBytes = ctx.readInt32(true, endian);
1573
1891
  }
1574
1892
  else {
1575
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1893
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1576
1894
  throw new Error("Invalid length read size: " + lengthReadSize);
1577
1895
  }
1578
1896
  // Read the string as Pascal or Delphi encoded
@@ -1580,6 +1898,7 @@ function rstring(ctx, options) {
1580
1898
  for (let i = 0; i < maxBytes; i++) {
1581
1899
  if (stringType == 'wide-pascal') {
1582
1900
  const read = ctx.readInt16(true, endian);
1901
+ i++;
1583
1902
  if (!(stripNull == true && read == 0)) {
1584
1903
  encodedBytes.push(read);
1585
1904
  }
@@ -1593,10 +1912,12 @@ function rstring(ctx, options) {
1593
1912
  }
1594
1913
  var str_return;
1595
1914
  if (stringType == 'wide-pascal') {
1596
- str_return = new TextDecoder(encoding).decode(new Uint16Array(encodedBytes));
1915
+ const strBuffer = new Uint16Array(encodedBytes);
1916
+ str_return = new TextDecoder().decode(strBuffer.buffer);
1597
1917
  }
1598
1918
  else {
1599
- str_return = new TextDecoder(encoding).decode(new Uint8Array(encodedBytes));
1919
+ const strBuffer = new Uint8Array(encodedBytes);
1920
+ str_return = new TextDecoder(encoding).decode(strBuffer);
1600
1921
  }
1601
1922
  return str_return;
1602
1923
  }
@@ -1605,6 +1926,7 @@ function rstring(ctx, options) {
1605
1926
  }
1606
1927
  }
1607
1928
  function wstring(ctx, string, options) {
1929
+ ctx.open();
1608
1930
  var length = options && options.length;
1609
1931
  var stringType = options && options.stringType || 'utf-8';
1610
1932
  var terminateValue = options && options.terminateValue;
@@ -1617,9 +1939,9 @@ function wstring(ctx, string, options) {
1617
1939
  if (length == undefined && terminateValue == undefined) {
1618
1940
  terminateValue = 0;
1619
1941
  }
1620
- var totalLength = (length || encodedString.length) + (terminateValue != undefined ? 1 : 0);
1942
+ var totalLength = (length || encodedString.byteLength) + (terminateValue != undefined ? 1 : 0);
1621
1943
  if (stringType == 'utf-16') {
1622
- totalLength = (length || (encodedString.length * 2)) + (terminateValue != undefined ? 2 : 0);
1944
+ totalLength = (length || encodedString.byteLength) + (terminateValue != undefined ? 2 : 0);
1623
1945
  }
1624
1946
  check_size(ctx, totalLength, 0);
1625
1947
  // Write the string bytes to the Uint8Array
@@ -1666,41 +1988,38 @@ function wstring(ctx, string, options) {
1666
1988
  maxLength = 4294967295;
1667
1989
  }
1668
1990
  else {
1669
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1991
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1670
1992
  throw new Error("Invalid length write size: " + lengthWriteSize);
1671
1993
  }
1672
1994
  if (string.length > maxLength || (length || 0) > maxLength) {
1673
- ctx.errorDump ? "[Error], hexdump:\n" + ctx.hexdump() : "";
1995
+ ctx.errorDump ? console.log("\x1b[31m[Error]\x1b[0m hexdump:\n" + ctx.hexdump({ returnString: true })) : "";
1674
1996
  throw new Error("String outsize of max write length: " + maxLength);
1675
1997
  }
1676
- var maxBytes = Math.min(string.length, maxLength);
1998
+ const maxBytes = Math.min(string.length, maxLength);
1677
1999
  const encodedString = encoder.encode(string.substring(0, maxBytes));
1678
- var totalLength = (length || encodedString.length);
1679
- if (stringType == 'wide-pascal') {
1680
- totalLength = (length || (encodedString.length * 2));
1681
- }
2000
+ var totalLength = (length || encodedString.byteLength);
1682
2001
  if (lengthWriteSize == 1) {
1683
- ctx.writeUByte(maxBytes);
2002
+ ctx.writeUByte(totalLength);
1684
2003
  }
1685
2004
  else if (lengthWriteSize == 2) {
1686
- ctx.writeUInt16(maxBytes, endian);
2005
+ ctx.writeUInt16(totalLength, endian);
1687
2006
  }
1688
2007
  else if (lengthWriteSize == 4) {
1689
- ctx.writeUInt32(maxBytes, endian);
2008
+ ctx.writeUInt32(totalLength, endian);
1690
2009
  }
1691
2010
  check_size(ctx, totalLength, 0);
1692
2011
  // Write the string bytes to the Uint8Array
1693
- for (let i = 0; i < encodedString.length; i++) {
2012
+ for (let i = 0; i < totalLength; i++) {
1694
2013
  if (stringType == 'wide-pascal') {
1695
- const charCode = encodedString[i];
1696
2014
  if (endian == "little") {
1697
- ctx.data[ctx.offset + i * 2] = charCode & 0xFF;
1698
- 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];
1699
2017
  }
1700
2018
  else {
1701
- ctx.data[ctx.offset + i * 2 + 1] = charCode & 0xFF;
1702
- 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];
1703
2021
  }
2022
+ i++;
1704
2023
  }
1705
2024
  else {
1706
2025
  ctx.data[ctx.offset + i] = encodedString[i];
@@ -1713,8 +2032,33 @@ function wstring(ctx, string, options) {
1713
2032
  throw new Error('Unsupported string type: ' + stringType);
1714
2033
  }
1715
2034
  }
2035
+ // #region Class
2036
+ /**
2037
+ * Base class for BiReader and BiWriter
2038
+ */
1716
2039
  class BiBase {
1717
- 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) {
1718
2062
  /**
1719
2063
  * Endianness of default read.
1720
2064
  * @type {endian}
@@ -1743,12 +2087,8 @@ class BiBase {
1743
2087
  /**
1744
2088
  * Console log a hexdump on error.
1745
2089
  */
1746
- this.errorDump = true;
1747
- /**
1748
- * Current buffer data.
1749
- * @type {Buffer|Uint8Array|null}
1750
- */
1751
- this.data = null;
2090
+ this.errorDump = false;
2091
+ _BiBase_data.set(this, null);
1752
2092
  /**
1753
2093
  * When the data buffer needs to be extended while strict mode is ``false``, this will be the amount it extends.
1754
2094
  *
@@ -1760,14 +2100,39 @@ class BiBase {
1760
2100
  */
1761
2101
  this.extendBufferSize = 0;
1762
2102
  this.fd = null;
1763
- this.filePath = "";
1764
- this.fsMode = "";
2103
+ this.filePath = null;
2104
+ this.fsMode = "r";
1765
2105
  /**
1766
2106
  * The settings that used when using the .str getter / setter
1767
2107
  */
1768
2108
  this.strDefaults = { stringType: "utf-8", terminateValue: 0x0 };
2109
+ /**
2110
+ * Window size of the file data (largest amount it can read)
2111
+ */
1769
2112
  this.maxFileSize = null;
1770
- 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
+ }
1771
2136
  }
1772
2137
  ;
1773
2138
  /**
@@ -1794,67 +2159,227 @@ class BiBase {
1794
2159
  writeMode(mode) {
1795
2160
  if (mode) {
1796
2161
  this.strict = false;
2162
+ if (this.mode == "file") {
2163
+ this.fsMode = "w+";
2164
+ this.close();
2165
+ this.open();
2166
+ }
1797
2167
  return;
1798
2168
  }
1799
2169
  else {
1800
2170
  this.strict = true;
2171
+ if (this.mode == "file") {
2172
+ this.fsMode = "r";
2173
+ this.close();
2174
+ this.open();
2175
+ }
1801
2176
  return;
1802
2177
  }
1803
2178
  }
1804
2179
  ;
1805
2180
  /**
1806
- * 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
1807
2184
  */
1808
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
+ }
1809
2236
  return this.size;
1810
2237
  }
1811
2238
  ;
1812
2239
  /**
1813
- * Dummy function, not needed on Non-Stream
2240
+ * Internal update size
1814
2241
  */
1815
2242
  updateSize() {
1816
- 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
+ }
1817
2262
  }
1818
2263
  ;
1819
2264
  /**
1820
- * removes data.
2265
+ * commit data and removes it.
1821
2266
  */
1822
2267
  close() {
1823
- 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;
1824
2288
  }
1825
2289
  ;
1826
2290
  /**
1827
- * 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}
1828
2297
  */
1829
- read(start, length, consume = false) {
1830
- 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();
1831
2306
  }
1832
2307
  ;
1833
2308
  /**
1834
- * Dummy function, not needed on Non-Stream
2309
+ * Write data buffer back to file
2310
+ *
2311
+ * @returns {DataType}
1835
2312
  */
1836
- write(start, data, consume = false) {
1837
- this.insert(data, consume, start);
1838
- 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;
1839
2326
  }
1840
2327
  ;
1841
2328
  /**
1842
- * Dummy function, not needed on Non-Stream
2329
+ * syncs the data to file
1843
2330
  */
1844
- renameFile() {
2331
+ flush() {
2332
+ if (this.fd) {
2333
+ this.commit();
2334
+ }
1845
2335
  }
1846
2336
  ;
1847
2337
  /**
1848
- * 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.
1849
2347
  */
1850
- 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();
1851
2362
  }
1852
2363
  ;
1853
2364
  /**
1854
- * 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.
1855
2370
  */
1856
- commit(consume = true) {
1857
- 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
+ }
1858
2383
  }
1859
2384
  ;
1860
2385
  extendArray(to_padd) {
@@ -1862,11 +2387,20 @@ class BiBase {
1862
2387
  }
1863
2388
  ;
1864
2389
  isBufferOrUint8Array(obj) {
1865
- 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
+ }
1866
2400
  }
1867
2401
  ;
1868
2402
  ///////////////////////////////
1869
- // ENDIANNESS //
2403
+ // #region ENDIANNESS
1870
2404
  ///////////////////////////////
1871
2405
  /**
1872
2406
  *
@@ -1929,7 +2463,7 @@ class BiBase {
1929
2463
  }
1930
2464
  ;
1931
2465
  ///////////////////////////////
1932
- // SIZE //
2466
+ // #region SIZE
1933
2467
  ///////////////////////////////
1934
2468
  /**
1935
2469
  * Size in bytes of the current buffer.
@@ -1986,12 +2520,12 @@ class BiBase {
1986
2520
  }
1987
2521
  ;
1988
2522
  ///////////////////////////////
1989
- // POSITION //
2523
+ // #region POSITION
1990
2524
  ///////////////////////////////
1991
2525
  /**
1992
2526
  * Get the current byte position.
1993
2527
  *
1994
- * @return {number} current byte position
2528
+ * @returns {number} current byte position
1995
2529
  */
1996
2530
  get tell() {
1997
2531
  return this.offset;
@@ -2000,7 +2534,7 @@ class BiBase {
2000
2534
  /**
2001
2535
  * Get the current byte position.
2002
2536
  *
2003
- * @return {number} current byte position
2537
+ * @returns {number} current byte position
2004
2538
  */
2005
2539
  get FTell() {
2006
2540
  return this.offset;
@@ -2009,7 +2543,7 @@ class BiBase {
2009
2543
  /**
2010
2544
  * Get the current byte position.
2011
2545
  *
2012
- * @return {number} current byte position
2546
+ * @returns {number} current byte position
2013
2547
  */
2014
2548
  get getOffset() {
2015
2549
  return this.offset;
@@ -2018,7 +2552,7 @@ class BiBase {
2018
2552
  /**
2019
2553
  * Get the current byte position;
2020
2554
  *
2021
- * @return {number} current byte position
2555
+ * @returns {number} current byte position
2022
2556
  */
2023
2557
  get saveOffset() {
2024
2558
  return this.offset;
@@ -2027,7 +2561,7 @@ class BiBase {
2027
2561
  /**
2028
2562
  * Get the current byte position;
2029
2563
  *
2030
- * @return {number} current byte position
2564
+ * @returns {number} current byte position
2031
2565
  */
2032
2566
  get off() {
2033
2567
  return this.offset;
@@ -2036,7 +2570,7 @@ class BiBase {
2036
2570
  /**
2037
2571
  * Get the current bit position (0-7).
2038
2572
  *
2039
- * @return {number} current bit position
2573
+ * @returns {number} current bit position
2040
2574
  */
2041
2575
  get getOffsetBit() {
2042
2576
  return this.bitoffset;
@@ -2045,7 +2579,7 @@ class BiBase {
2045
2579
  /**
2046
2580
  * Get the current bit position (0-7).
2047
2581
  *
2048
- * @return {number} current bit position
2582
+ * @returns {number} current bit position
2049
2583
  */
2050
2584
  get tellB() {
2051
2585
  return this.bitoffset;
@@ -2054,7 +2588,7 @@ class BiBase {
2054
2588
  /**
2055
2589
  * Get the current bit position (0-7).
2056
2590
  *
2057
- * @return {number} current bit position
2591
+ * @returns {number} current bit position
2058
2592
  */
2059
2593
  get FTellB() {
2060
2594
  return this.bitoffset;
@@ -2063,7 +2597,7 @@ class BiBase {
2063
2597
  /**
2064
2598
  * Get the current bit position (0-7).
2065
2599
  *
2066
- * @return {number} current bit position
2600
+ * @returns {number} current bit position
2067
2601
  */
2068
2602
  get offb() {
2069
2603
  return this.bitoffset;
@@ -2072,7 +2606,7 @@ class BiBase {
2072
2606
  /**
2073
2607
  * Get the current absolute bit position (from start of data).
2074
2608
  *
2075
- * @return {number} current absolute bit position
2609
+ * @returns {number} current absolute bit position
2076
2610
  */
2077
2611
  get getOffsetAbsBit() {
2078
2612
  return (this.offset * 8) + this.bitoffset;
@@ -2081,7 +2615,7 @@ class BiBase {
2081
2615
  /**
2082
2616
  * Get the current absolute bit position (from start of data).
2083
2617
  *
2084
- * @return {number} current bit position
2618
+ * @returns {number} current bit position
2085
2619
  */
2086
2620
  get saveOffsetAbsBit() {
2087
2621
  return (this.offset * 8) + this.bitoffset;
@@ -2090,7 +2624,7 @@ class BiBase {
2090
2624
  /**
2091
2625
  * Get the current absolute bit position (from start of data).
2092
2626
  *
2093
- * @return {number} current absolute bit position
2627
+ * @returns {number} current absolute bit position
2094
2628
  */
2095
2629
  get tellAbsB() {
2096
2630
  return (this.offset * 8) + this.bitoffset;
@@ -2099,7 +2633,7 @@ class BiBase {
2099
2633
  /**
2100
2634
  * Get the current absolute bit position (from start of data).
2101
2635
  *
2102
- * @return {number} current absolute bit position
2636
+ * @returns {number} current absolute bit position
2103
2637
  */
2104
2638
  get saveOffsetBit() {
2105
2639
  return (this.offset * 8) + this.bitoffset;
@@ -2108,7 +2642,7 @@ class BiBase {
2108
2642
  /**
2109
2643
  * Get the current absolute bit position (from start of data).
2110
2644
  *
2111
- * @return {number} current absolute bit position
2645
+ * @returns {number} current absolute bit position
2112
2646
  */
2113
2647
  get offab() {
2114
2648
  return (this.offset * 8) + this.bitoffset;
@@ -2169,7 +2703,7 @@ class BiBase {
2169
2703
  }
2170
2704
  ;
2171
2705
  ///////////////////////////////
2172
- // FINISHING //
2706
+ // #region FINISHING
2173
2707
  ///////////////////////////////
2174
2708
  /**
2175
2709
  * Returns current data.
@@ -2178,9 +2712,9 @@ class BiBase {
2178
2712
  *
2179
2713
  * Use ``.data`` instead if you want the full buffer data.
2180
2714
  *
2181
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
2715
+ * @returns {DataType} ``Buffer`` or ``Uint8Array``
2182
2716
  */
2183
- get get() {
2717
+ get() {
2184
2718
  if (this.extendBufferSize != 0) {
2185
2719
  this.trim();
2186
2720
  }
@@ -2194,13 +2728,10 @@ class BiBase {
2194
2728
  *
2195
2729
  * Use ``.data`` instead if you want the full buffer data.
2196
2730
  *
2197
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
2731
+ * @returns {DataType} ``Buffer`` or ``Uint8Array``
2198
2732
  */
2199
- get return() {
2200
- if (this.extendBufferSize != 0) {
2201
- this.trim();
2202
- }
2203
- return this.data;
2733
+ return() {
2734
+ return this.get();
2204
2735
  }
2205
2736
  ;
2206
2737
  /**
@@ -2232,7 +2763,7 @@ class BiBase {
2232
2763
  }
2233
2764
  ;
2234
2765
  ///////////////////////////////
2235
- // STRICTMODE //
2766
+ // #region STRICT MODE
2236
2767
  ///////////////////////////////
2237
2768
  /**
2238
2769
  * Disallows extending data if position is outside of max size.
@@ -2250,27 +2781,39 @@ class BiBase {
2250
2781
  ;
2251
2782
  /**
2252
2783
  * removes data.
2784
+ *
2785
+ * Commits any changes to file when editing a file.
2253
2786
  */
2254
2787
  end() {
2255
- 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;
2256
2795
  }
2257
2796
  ;
2258
2797
  /**
2259
2798
  * removes data.
2799
+ *
2800
+ * Commits any changes to file when editing a file.
2260
2801
  */
2261
2802
  done() {
2262
- this.data = undefined;
2803
+ return this.end();
2263
2804
  }
2264
2805
  ;
2265
2806
  /**
2266
2807
  * removes data.
2808
+ *
2809
+ * Commits any changes to file when editing a file.
2267
2810
  */
2268
2811
  finished() {
2269
- this.data = undefined;
2812
+ return this.end();
2270
2813
  }
2271
2814
  ;
2272
2815
  ///////////////////////////////
2273
- // FIND //
2816
+ // #region FIND
2274
2817
  ///////////////////////////////
2275
2818
  /**
2276
2819
  * Searches for byte position of string from current read position.
@@ -2388,7 +2931,7 @@ class BiBase {
2388
2931
  }
2389
2932
  ;
2390
2933
  ///////////////////////////////
2391
- // MOVE TO //
2934
+ // #region MOVE TO
2392
2935
  ///////////////////////////////
2393
2936
  /**
2394
2937
  * Aligns current byte position.
@@ -2523,20 +3066,18 @@ class BiBase {
2523
3066
  * Set current byte and bit position to end of data.
2524
3067
  */
2525
3068
  gotoEnd() {
2526
- this.offset = this.size;
2527
- this.bitoffset = 0;
3069
+ this.last();
2528
3070
  }
2529
3071
  ;
2530
3072
  /**
2531
3073
  * Set byte and bit position to start of data.
2532
3074
  */
2533
3075
  EoF() {
2534
- this.offset = this.size;
2535
- this.bitoffset = 0;
3076
+ this.last();
2536
3077
  }
2537
3078
  ;
2538
3079
  ///////////////////////////////
2539
- // REMOVE //
3080
+ // #region REMOVE
2540
3081
  ///////////////////////////////
2541
3082
  /**
2542
3083
  * Deletes part of data from start to current byte position unless supplied, returns removed.
@@ -2546,7 +3087,7 @@ class BiBase {
2546
3087
  * @param {number} startOffset - Start location (default 0)
2547
3088
  * @param {number} endOffset - End location (default current position)
2548
3089
  * @param {boolean} consume - Move position to end of removed data (default false)
2549
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3090
+ * @returns {DataType} Removed data as ``Buffer`` or ``Uint8Array``
2550
3091
  */
2551
3092
  delete(startOffset, endOffset, consume) {
2552
3093
  return remove(this, startOffset || 0, endOffset || this.offset, consume || false, true);
@@ -2557,7 +3098,7 @@ class BiBase {
2557
3098
  *
2558
3099
  * Note: Errors in strict mode.
2559
3100
  *
2560
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3101
+ * @returns {DataType} Removed data as ``Buffer`` or ``Uint8Array``
2561
3102
  */
2562
3103
  clip() {
2563
3104
  return remove(this, this.offset, this.size, false, true);
@@ -2568,7 +3109,7 @@ class BiBase {
2568
3109
  *
2569
3110
  * Note: Errors in strict mode.
2570
3111
  *
2571
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3112
+ * @returns {DataType} Removed data as ``Buffer`` or ``Uint8Array``
2572
3113
  */
2573
3114
  trim() {
2574
3115
  return remove(this, this.offset, this.size, false, true);
@@ -2581,7 +3122,7 @@ class BiBase {
2581
3122
  *
2582
3123
  * @param {number} length - Length of data in bytes to remove
2583
3124
  * @param {boolean} consume - Move position to end of removed data (default false)
2584
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3125
+ * @returns {TemplateStringsArray} Removed data as ``Buffer`` or ``Uint8Array``
2585
3126
  */
2586
3127
  crop(length, consume) {
2587
3128
  return remove(this, this.offset, this.offset + (length || 0), consume || false, true);
@@ -2594,7 +3135,7 @@ class BiBase {
2594
3135
  *
2595
3136
  * @param {number} length - Length of data in bytes to remove
2596
3137
  * @param {boolean} consume - Move position to end of removed data (default false)
2597
- * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
3138
+ * @returns {DataType} Removed data as ``Buffer`` or ``Uint8Array``
2598
3139
  */
2599
3140
  drop(length, consume) {
2600
3141
  return remove(this, this.offset, this.offset + (length || 0), consume || false, true);
@@ -2605,7 +3146,7 @@ class BiBase {
2605
3146
  *
2606
3147
  * Note: Errors on strict mode.
2607
3148
  *
2608
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to replace in data
3149
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to replace in data
2609
3150
  * @param {boolean} consume - Move current byte position to end of data (default false)
2610
3151
  * @param {number} offset - Offset to add it at (defaults to current position)
2611
3152
  */
@@ -2618,7 +3159,7 @@ class BiBase {
2618
3159
  *
2619
3160
  * Note: Errors on strict mode.
2620
3161
  *
2621
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to replace in data
3162
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to replace in data
2622
3163
  * @param {boolean} consume - Move current byte position to end of data (default false)
2623
3164
  * @param {number} offset - Offset to add it at (defaults to current position)
2624
3165
  */
@@ -2627,7 +3168,7 @@ class BiBase {
2627
3168
  }
2628
3169
  ;
2629
3170
  ///////////////////////////////
2630
- // COPY OUT //
3171
+ // #region COPY OUT
2631
3172
  ///////////////////////////////
2632
3173
  /**
2633
3174
  * Returns part of data from current byte position to end of data unless supplied.
@@ -2636,7 +3177,7 @@ class BiBase {
2636
3177
  * @param {number} endOffset - End location (default end of data)
2637
3178
  * @param {boolean} consume - Move position to end of lifted data (default false)
2638
3179
  * @param {number} fillValue - Byte value to to fill returned data (does NOT fill unless supplied)
2639
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3180
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2640
3181
  */
2641
3182
  lift(startOffset, endOffset, consume, fillValue) {
2642
3183
  return remove(this, startOffset || this.offset, endOffset || this.size, consume || false, false, fillValue);
@@ -2649,7 +3190,7 @@ class BiBase {
2649
3190
  * @param {number} endOffset - End location (default end of data)
2650
3191
  * @param {boolean} consume - Move position to end of lifted data (default false)
2651
3192
  * @param {number} fillValue - Byte value to to fill returned data (does NOT fill unless supplied)
2652
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3193
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2653
3194
  */
2654
3195
  fill(startOffset, endOffset, consume, fillValue) {
2655
3196
  return remove(this, startOffset || this.offset, endOffset || this.size, consume || false, false, fillValue);
@@ -2662,7 +3203,7 @@ class BiBase {
2662
3203
  *
2663
3204
  * @param {number} length - Length of data in bytes to copy from current offset
2664
3205
  * @param {number} consume - Moves offset to end of length
2665
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3206
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2666
3207
  */
2667
3208
  extract(length, consume) {
2668
3209
  return remove(this, this.offset, this.offset + (length || 0), consume || false, false);
@@ -2675,7 +3216,7 @@ class BiBase {
2675
3216
  *
2676
3217
  * @param {number} length - Length of data in bytes to copy from current offset
2677
3218
  * @param {number} consume - Moves offset to end of length
2678
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3219
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2679
3220
  */
2680
3221
  slice(length, consume) {
2681
3222
  return remove(this, this.offset, this.offset + (length || 0), consume || false, false);
@@ -2688,21 +3229,21 @@ class BiBase {
2688
3229
  *
2689
3230
  * @param {number} length - Length of data in bytes to copy from current offset
2690
3231
  * @param {number} consume - Moves offset to end of length
2691
- * @returns {Buffer|Uint8Array} Selected data as ``Uint8Array`` or ``Buffer``
3232
+ * @returns {DataType} Selected data as ``Uint8Array`` or ``Buffer``
2692
3233
  */
2693
3234
  wrap(length, consume) {
2694
3235
  return remove(this, this.offset, this.offset + (length || 0), consume || false, false);
2695
3236
  }
2696
3237
  ;
2697
3238
  ///////////////////////////////
2698
- // INSERT //
3239
+ // #region INSERT
2699
3240
  ///////////////////////////////
2700
3241
  /**
2701
3242
  * Inserts data into data.
2702
3243
  *
2703
3244
  * Note: Errors on strict mode.
2704
3245
  *
2705
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3246
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2706
3247
  * @param {boolean} consume - Move current byte position to end of data (default false)
2707
3248
  * @param {number} offset - Byte position to add at (defaults to current position)
2708
3249
  */
@@ -2715,7 +3256,7 @@ class BiBase {
2715
3256
  *
2716
3257
  * Note: Errors on strict mode.
2717
3258
  *
2718
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3259
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2719
3260
  * @param {boolean} consume - Move current byte position to end of data (default false)
2720
3261
  * @param {number} offset - Byte position to add at (defaults to current position)
2721
3262
  */
@@ -2728,7 +3269,7 @@ class BiBase {
2728
3269
  *
2729
3270
  * Note: Errors on strict mode.
2730
3271
  *
2731
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3272
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2732
3273
  * @param {boolean} consume - Move current write position to end of data (default false)
2733
3274
  */
2734
3275
  unshift(data, consume) {
@@ -2740,7 +3281,7 @@ class BiBase {
2740
3281
  *
2741
3282
  * Note: Errors on strict mode.
2742
3283
  *
2743
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3284
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2744
3285
  * @param {boolean} consume - Move current write position to end of data (default false)
2745
3286
  */
2746
3287
  prepend(data, consume) {
@@ -2752,7 +3293,7 @@ class BiBase {
2752
3293
  *
2753
3294
  * Note: Errors on strict mode.
2754
3295
  *
2755
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3296
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2756
3297
  * @param {boolean} consume - Move current write position to end of data (default false)
2757
3298
  */
2758
3299
  push(data, consume) {
@@ -2764,7 +3305,7 @@ class BiBase {
2764
3305
  *
2765
3306
  * Note: Errors on strict mode.
2766
3307
  *
2767
- * @param {Buffer|Uint8Array} data - ``Uint8Array`` or ``Buffer`` to add to data
3308
+ * @param {DataType} data - ``Uint8Array`` or ``Buffer`` to add to data
2768
3309
  * @param {boolean} consume - Move current write position to end of data (default false)
2769
3310
  */
2770
3311
  append(data, consume) {
@@ -2772,7 +3313,7 @@ class BiBase {
2772
3313
  }
2773
3314
  ;
2774
3315
  ///////////////////////////////
2775
- // MATH //
3316
+ // #region MATH
2776
3317
  ///////////////////////////////
2777
3318
  /**
2778
3319
  * XOR data.
@@ -2784,12 +3325,10 @@ class BiBase {
2784
3325
  */
2785
3326
  xor(xorKey, startOffset, endOffset, consume) {
2786
3327
  var XORKey = xorKey;
2787
- if (typeof xorKey == "number") ;
2788
- else if (typeof xorKey == "string") {
3328
+ if (typeof xorKey == "string") {
2789
3329
  xorKey = new TextEncoder().encode(xorKey);
2790
3330
  }
2791
- else if (this.isBufferOrUint8Array(XORKey)) ;
2792
- else {
3331
+ else if (!(this.isBufferOrUint8Array(XORKey) || typeof xorKey == "number")) {
2793
3332
  throw new Error("XOR must be a number, string, Uint8Array or Buffer");
2794
3333
  }
2795
3334
  return XOR(this, xorKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -2832,12 +3371,10 @@ class BiBase {
2832
3371
  */
2833
3372
  or(orKey, startOffset, endOffset, consume) {
2834
3373
  var ORKey = orKey;
2835
- if (typeof orKey == "number") ;
2836
- else if (typeof orKey == "string") {
3374
+ if (typeof orKey == "string") {
2837
3375
  orKey = new TextEncoder().encode(orKey);
2838
3376
  }
2839
- else if (this.isBufferOrUint8Array(ORKey)) ;
2840
- else {
3377
+ else if (!(this.isBufferOrUint8Array(ORKey) || typeof orKey == "number")) {
2841
3378
  throw new Error("OR must be a number, string, Uint8Array or Buffer");
2842
3379
  }
2843
3380
  return OR(this, orKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -2873,19 +3410,17 @@ class BiBase {
2873
3410
  /**
2874
3411
  * AND data.
2875
3412
  *
2876
- * @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
2877
3414
  * @param {number} startOffset - Start location (default current byte position)
2878
3415
  * @param {number} endOffset - End location (default end of data)
2879
3416
  * @param {boolean} consume - Move current position to end of data (default false)
2880
3417
  */
2881
3418
  and(andKey, startOffset, endOffset, consume) {
2882
3419
  var ANDKey = andKey;
2883
- if (typeof ANDKey == "number") ;
2884
- else if (typeof ANDKey == "string") {
3420
+ if (typeof ANDKey == "string") {
2885
3421
  ANDKey = new TextEncoder().encode(ANDKey);
2886
3422
  }
2887
- else if (typeof ANDKey == "object") ;
2888
- else {
3423
+ else if (!(typeof ANDKey == "object" || typeof ANDKey == "number")) {
2889
3424
  throw new Error("AND must be a number, string, number array or Buffer");
2890
3425
  }
2891
3426
  return AND(this, andKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -2894,7 +3429,7 @@ class BiBase {
2894
3429
  /**
2895
3430
  * AND data.
2896
3431
  *
2897
- * @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
2898
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)
2899
3434
  * @param {boolean} consume - Move current position to end of data (default false)
2900
3435
  */
@@ -2921,19 +3456,17 @@ class BiBase {
2921
3456
  /**
2922
3457
  * Add value to data.
2923
3458
  *
2924
- * @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
2925
3460
  * @param {number} startOffset - Start location (default current byte position)
2926
3461
  * @param {number} endOffset - End location (default end of data)
2927
3462
  * @param {boolean} consume - Move current position to end of data (default false)
2928
3463
  */
2929
3464
  add(addKey, startOffset, endOffset, consume) {
2930
3465
  var addedKey = addKey;
2931
- if (typeof addedKey == "number") ;
2932
- else if (typeof addedKey == "string") {
3466
+ if (typeof addedKey == "string") {
2933
3467
  addedKey = new TextEncoder().encode(addedKey);
2934
3468
  }
2935
- else if (typeof addedKey == "object") ;
2936
- else {
3469
+ else if (!(typeof addedKey == "object" || typeof addedKey == "number")) {
2937
3470
  throw new Error("Add key must be a number, string, number array or Buffer");
2938
3471
  }
2939
3472
  return ADD(this, addedKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -2942,7 +3475,7 @@ class BiBase {
2942
3475
  /**
2943
3476
  * Add value to data.
2944
3477
  *
2945
- * @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
2946
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)
2947
3480
  * @param {boolean} consume - Move current position to end of data (default false)
2948
3481
  */
@@ -2990,19 +3523,17 @@ class BiBase {
2990
3523
  /**
2991
3524
  * Left shift data.
2992
3525
  *
2993
- * @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
2994
3527
  * @param {number} startOffset - Start location (default current byte position)
2995
3528
  * @param {number} endOffset - End location (default end of data)
2996
3529
  * @param {boolean} consume - Move current position to end of data (default false)
2997
3530
  */
2998
3531
  lShift(shiftKey, startOffset, endOffset, consume) {
2999
3532
  var lShiftKey = shiftKey;
3000
- if (typeof lShiftKey == "number") ;
3001
- else if (typeof lShiftKey == "string") {
3533
+ if (typeof lShiftKey == "string") {
3002
3534
  lShiftKey = new TextEncoder().encode(lShiftKey);
3003
3535
  }
3004
- else if (typeof lShiftKey == "object") ;
3005
- else {
3536
+ else if (!(typeof lShiftKey == "object" || typeof lShiftKey == "number")) {
3006
3537
  throw new Error("Left shift must be a number, string, number array or Buffer");
3007
3538
  }
3008
3539
  return LSHIFT(this, lShiftKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -3011,7 +3542,7 @@ class BiBase {
3011
3542
  /**
3012
3543
  * Left shift data.
3013
3544
  *
3014
- * @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
3015
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)
3016
3547
  * @param {boolean} consume - Move current position to end of data (default false)
3017
3548
  */
@@ -3038,19 +3569,17 @@ class BiBase {
3038
3569
  /**
3039
3570
  * Right shift data.
3040
3571
  *
3041
- * @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
3042
3573
  * @param {number} startOffset - Start location (default current byte position)
3043
3574
  * @param {number} endOffset - End location (default end of data)
3044
3575
  * @param {boolean} consume - Move current position to end of data (default false)
3045
3576
  */
3046
3577
  rShift(shiftKey, startOffset, endOffset, consume) {
3047
3578
  var rShiftKey = shiftKey;
3048
- if (typeof rShiftKey == "number") ;
3049
- else if (typeof rShiftKey == "string") {
3579
+ if (typeof rShiftKey == "string") {
3050
3580
  rShiftKey = new TextEncoder().encode(rShiftKey);
3051
3581
  }
3052
- else if (typeof rShiftKey == "object") ;
3053
- else {
3582
+ else if (!(typeof rShiftKey == "object" || typeof rShiftKey == "number")) {
3054
3583
  throw new Error("Right shift must be a number, string, number array or Buffer");
3055
3584
  }
3056
3585
  return RSHIFT(this, rShiftKey, startOffset || this.offset, endOffset || this.size, consume || false);
@@ -3059,7 +3588,7 @@ class BiBase {
3059
3588
  /**
3060
3589
  * Right shift data.
3061
3590
  *
3062
- * @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
3063
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)
3064
3593
  * @param {boolean} consume - Move current position to end of data (default false)
3065
3594
  */
@@ -3084,7 +3613,7 @@ class BiBase {
3084
3613
  }
3085
3614
  ;
3086
3615
  ///////////////////////////////
3087
- // BIT READER //
3616
+ // #region BIT READER
3088
3617
  ///////////////////////////////
3089
3618
  /**
3090
3619
  *
@@ -3219,6 +3748,9 @@ class BiBase {
3219
3748
  return this.readBit(bits, unsigned, "little");
3220
3749
  }
3221
3750
  ;
3751
+ ///////////////////////////////
3752
+ // #region BYTE READER
3753
+ ///////////////////////////////
3222
3754
  /**
3223
3755
  * Read byte.
3224
3756
  *
@@ -3280,6 +3812,9 @@ class BiBase {
3280
3812
  return this.readByte(true);
3281
3813
  }
3282
3814
  ;
3815
+ ///////////////////////////////
3816
+ // #region INT16 READER
3817
+ ///////////////////////////////
3283
3818
  /**
3284
3819
  * Read short.
3285
3820
  *
@@ -3386,6 +3921,9 @@ class BiBase {
3386
3921
  return this.readInt16(false, "big");
3387
3922
  }
3388
3923
  ;
3924
+ ///////////////////////////////
3925
+ // #region HALF FLOAT
3926
+ ///////////////////////////////
3389
3927
  /**
3390
3928
  * Read half float.
3391
3929
  *
@@ -3442,6 +3980,9 @@ class BiBase {
3442
3980
  return this.readHalfFloat("little");
3443
3981
  }
3444
3982
  ;
3983
+ ///////////////////////////////
3984
+ // #region INT32 READER
3985
+ ///////////////////////////////
3445
3986
  /**
3446
3987
  * Read 32 bit integer.
3447
3988
  *
@@ -3546,6 +4087,9 @@ class BiBase {
3546
4087
  return this.readInt32(true);
3547
4088
  }
3548
4089
  ;
4090
+ ///////////////////////////////
4091
+ // #region FLOAT32 READER
4092
+ ///////////////////////////////
3549
4093
  /**
3550
4094
  * Read float.
3551
4095
  *
@@ -3602,6 +4146,9 @@ class BiBase {
3602
4146
  return this.readFloat("little");
3603
4147
  }
3604
4148
  ;
4149
+ ///////////////////////////////
4150
+ // #region INT64 READER
4151
+ ///////////////////////////////
3605
4152
  /**
3606
4153
  * Read signed 64 bit integer.
3607
4154
  *
@@ -3609,7 +4156,6 @@ class BiBase {
3609
4156
  *
3610
4157
  * @param {boolean} unsigned - if value is unsigned or not
3611
4158
  * @param {endian?} endian - ``big`` or ``little``
3612
- * @returns {BigValue}
3613
4159
  */
3614
4160
  readInt64(unsigned, endian) {
3615
4161
  return rint64(this, unsigned, endian);
@@ -3727,6 +4273,9 @@ class BiBase {
3727
4273
  return this.readInt64(true, "little");
3728
4274
  }
3729
4275
  ;
4276
+ ///////////////////////////////
4277
+ // #region FLOAT64 READER
4278
+ ///////////////////////////////
3730
4279
  /**
3731
4280
  * Read double float.
3732
4281
  *
@@ -3783,6 +4332,9 @@ class BiBase {
3783
4332
  return this.readDoubleFloat("little");
3784
4333
  }
3785
4334
  ;
4335
+ ///////////////////////////////
4336
+ // #region STRING READER
4337
+ ///////////////////////////////
3786
4338
  /**
3787
4339
  * Reads string, use options object for different types.
3788
4340
  *
@@ -3793,7 +4345,7 @@ class BiBase {
3793
4345
  * @param {stringOptions["lengthReadSize"]?} options.lengthReadSize - for pascal strings. 1, 2 or 4 byte length read size
3794
4346
  * @param {stringOptions["encoding"]?} options.encoding - TextEncoder accepted types
3795
4347
  * @param {stringOptions["endian"]?} options.endian - for wide-pascal and utf-16
3796
- * @return {Promise<string>}
4348
+ * @returns {string}
3797
4349
  */
3798
4350
  readString(options) {
3799
4351
  return rstring(this, options);
@@ -3816,11 +4368,12 @@ class BiBase {
3816
4368
  }
3817
4369
  ;
3818
4370
  }
4371
+ _BiBase_data = new WeakMap();
3819
4372
 
3820
4373
  /**
3821
4374
  * Binary reader, includes bitfields and strings.
3822
4375
  *
3823
- * @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``
3824
4377
  * @param {BiOptions?} options - Any options to set at start
3825
4378
  * @param {BiOptions["byteOffset"]?} options.byteOffset - Byte offset to start writer (default ``0``)
3826
4379
  * @param {BiOptions["bitOffset"]?} options.bitOffset - Bit offset 0-7 to start writer (default ``0``)
@@ -3828,6 +4381,7 @@ class BiBase {
3828
4381
  * @param {BiOptions["strict"]?} options.strict - Strict mode: if ``true`` does not extend supplied array on outside write (default ``false``)
3829
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``.
3830
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)
3831
4385
  *
3832
4386
  * @since 2.0
3833
4387
  */
@@ -3835,7 +4389,7 @@ class BiReader extends BiBase {
3835
4389
  /**
3836
4390
  * Binary reader, includes bitfields and strings.
3837
4391
  *
3838
- * @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``
3839
4393
  * @param {BiOptions?} options - Any options to set at start
3840
4394
  * @param {BiOptions["byteOffset"]?} options.byteOffset - Byte offset to start writer (default ``0``)
3841
4395
  * @param {BiOptions["bitOffset"]?} options.bitOffset - Bit offset 0-7 to start writer (default ``0``)
@@ -3843,29 +4397,25 @@ class BiReader extends BiBase {
3843
4397
  * @param {BiOptions["strict"]?} options.strict - Strict mode: if ``true`` does not extend supplied array on outside write (default ``false``)
3844
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``.
3845
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)
3846
4401
  */
3847
- constructor(data, options = {}) {
3848
- super();
3849
- this.strict = true;
3850
- if (data == undefined) {
3851
- throw new Error("Data required");
3852
- }
3853
- else {
3854
- if (!this.isBufferOrUint8Array(data)) {
3855
- throw new Error("Write data must be Uint8Array or Buffer");
3856
- }
3857
- 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.");
3858
4406
  }
3859
- this.enforceBigInt = options?.enforceBigInt ?? false;
3860
- 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) {
3861
4411
  this.extendBufferSize = options.extendBufferSize;
3862
4412
  }
3863
- this.size = this.data.length;
3864
- this.sizeB = this.data.length * 8;
3865
- if (options.endianness != undefined && typeof options.endianness != "string") {
4413
+ if (options.endianness != undefined &&
4414
+ typeof options.endianness != "string") {
3866
4415
  throw new Error("Endian must be big or little");
3867
4416
  }
3868
- if (options.endianness != undefined && !(options.endianness == "big" || options.endianness == "little")) {
4417
+ if (options.endianness != undefined &&
4418
+ !(options.endianness == "big" || options.endianness == "little")) {
3869
4419
  throw new Error("Byte order must be big or little");
3870
4420
  }
3871
4421
  this.endian = options.endianness || "little";
@@ -3874,7 +4424,27 @@ class BiReader extends BiBase {
3874
4424
  }
3875
4425
  else {
3876
4426
  if (options.strict != undefined) {
3877
- 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");
3878
4448
  }
3879
4449
  }
3880
4450
  if (options.byteOffset != undefined || options.bitOffset != undefined) {
@@ -3882,7 +4452,7 @@ class BiReader extends BiBase {
3882
4452
  // Adjust byte offset based on bit overflow
3883
4453
  this.offset += Math.floor((Math.abs(options.bitOffset || 0)) / 8);
3884
4454
  // Adjust bit offset
3885
- this.bitoffset = (Math.abs(options.bitOffset || 0) + 64) % 8;
4455
+ this.bitoffset = Math.abs(normalizeBitOffset(options.bitOffset)) % 8;
3886
4456
  // Ensure bit offset stays between 0-7
3887
4457
  this.bitoffset = Math.min(Math.max(this.bitoffset, 0), 7);
3888
4458
  // Ensure offset doesn't go negative
@@ -3901,10 +4471,13 @@ class BiReader extends BiBase {
3901
4471
  }
3902
4472
  }
3903
4473
  }
4474
+ if (this.mode == "file") {
4475
+ this.open();
4476
+ }
3904
4477
  }
3905
4478
  ;
3906
4479
  //
3907
- // Bit Aliases
4480
+ // #region Bit Aliases
3908
4481
  //
3909
4482
  /**
3910
4483
  * Bit field reader.
@@ -6096,7 +6669,7 @@ class BiReader extends BiBase {
6096
6669
  }
6097
6670
  ;
6098
6671
  //
6099
- // byte read
6672
+ // #region byte read
6100
6673
  //
6101
6674
  /**
6102
6675
  * Read byte.
@@ -6135,7 +6708,7 @@ class BiReader extends BiBase {
6135
6708
  }
6136
6709
  ;
6137
6710
  //
6138
- //short16 read
6711
+ // #region short16 read
6139
6712
  //
6140
6713
  /**
6141
6714
  * Read short.
@@ -6300,7 +6873,7 @@ class BiReader extends BiBase {
6300
6873
  }
6301
6874
  ;
6302
6875
  //
6303
- //half float read
6876
+ // #region half float read
6304
6877
  //
6305
6878
  /**
6306
6879
  * Read half float.
@@ -6357,7 +6930,7 @@ class BiReader extends BiBase {
6357
6930
  }
6358
6931
  ;
6359
6932
  //
6360
- //int read
6933
+ // #region int read
6361
6934
  //
6362
6935
  /**
6363
6936
  * Read 32 bit integer.
@@ -6576,7 +7149,7 @@ class BiReader extends BiBase {
6576
7149
  }
6577
7150
  ;
6578
7151
  //
6579
- //float read
7152
+ // #region float read
6580
7153
  //
6581
7154
  /**
6582
7155
  * Read float.
@@ -6606,14 +7179,12 @@ class BiReader extends BiBase {
6606
7179
  }
6607
7180
  ;
6608
7181
  //
6609
- //int64 reader
7182
+ // #region int64 reader
6610
7183
  //
6611
7184
  /**
6612
7185
  * Read signed 64 bit integer
6613
7186
  *
6614
7187
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6615
- *
6616
- * @returns {BigValue}
6617
7188
  */
6618
7189
  get int64() {
6619
7190
  return this.readInt64();
@@ -6623,8 +7194,6 @@ class BiReader extends BiBase {
6623
7194
  * Read signed 64 bit integer.
6624
7195
  *
6625
7196
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6626
- *
6627
- * @returns {BigValue}
6628
7197
  */
6629
7198
  get bigint() {
6630
7199
  return this.readInt64();
@@ -6634,8 +7203,6 @@ class BiReader extends BiBase {
6634
7203
  * Read signed 64 bit integer.
6635
7204
  *
6636
7205
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6637
- *
6638
- * @returns {BigValue}
6639
7206
  */
6640
7207
  get quad() {
6641
7208
  return this.readInt64();
@@ -6645,8 +7212,6 @@ class BiReader extends BiBase {
6645
7212
  * Read unsigned 64 bit integer.
6646
7213
  *
6647
7214
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6648
- *
6649
- * @returns {BigValue}
6650
7215
  */
6651
7216
  get uint64() {
6652
7217
  return this.readInt64(true);
@@ -6656,8 +7221,6 @@ class BiReader extends BiBase {
6656
7221
  * Read unsigned 64 bit integer.
6657
7222
  *
6658
7223
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6659
- *
6660
- * @returns {BigValue}
6661
7224
  */
6662
7225
  get ubigint() {
6663
7226
  return this.readInt64(true);
@@ -6667,8 +7230,6 @@ class BiReader extends BiBase {
6667
7230
  * Read unsigned 64 bit integer.
6668
7231
  *
6669
7232
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6670
- *
6671
- * @returns {BigValue}
6672
7233
  */
6673
7234
  get uquad() {
6674
7235
  return this.readInt64(true);
@@ -6678,8 +7239,6 @@ class BiReader extends BiBase {
6678
7239
  * Read signed 64 bit integer.
6679
7240
  *
6680
7241
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6681
- *
6682
- * @returns {BigValue}
6683
7242
  */
6684
7243
  get int64be() {
6685
7244
  return this.readInt64(false, "big");
@@ -6689,8 +7248,6 @@ class BiReader extends BiBase {
6689
7248
  * Read signed 64 bit integer.
6690
7249
  *
6691
7250
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6692
- *
6693
- * @returns {BigValue}
6694
7251
  */
6695
7252
  get bigintbe() {
6696
7253
  return this.readInt64(false, "big");
@@ -6700,8 +7257,6 @@ class BiReader extends BiBase {
6700
7257
  * Read signed 64 bit integer.
6701
7258
  *
6702
7259
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6703
- *
6704
- * @returns {BigValue}
6705
7260
  */
6706
7261
  get quadbe() {
6707
7262
  return this.readInt64(false, "big");
@@ -6711,8 +7266,6 @@ class BiReader extends BiBase {
6711
7266
  * Read unsigned 64 bit integer.
6712
7267
  *
6713
7268
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6714
- *
6715
- * @returns {BigValue}
6716
7269
  */
6717
7270
  get uint64be() {
6718
7271
  return this.readInt64(true, "big");
@@ -6722,8 +7275,6 @@ class BiReader extends BiBase {
6722
7275
  * Read unsigned 64 bit integer.
6723
7276
  *
6724
7277
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6725
- *
6726
- * @returns {BigValue}
6727
7278
  */
6728
7279
  get ubigintbe() {
6729
7280
  return this.readInt64(true, "big");
@@ -6733,8 +7284,6 @@ class BiReader extends BiBase {
6733
7284
  * Read unsigned 64 bit integer.
6734
7285
  *
6735
7286
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6736
- *
6737
- * @returns {BigValue}
6738
7287
  */
6739
7288
  get uquadbe() {
6740
7289
  return this.readInt64(true, "big");
@@ -6744,8 +7293,6 @@ class BiReader extends BiBase {
6744
7293
  * Read signed 64 bit integer.
6745
7294
  *
6746
7295
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6747
- *
6748
- * @returns {BigValue}
6749
7296
  */
6750
7297
  get int64le() {
6751
7298
  return this.readInt64(false, "little");
@@ -6755,8 +7302,6 @@ class BiReader extends BiBase {
6755
7302
  * Read signed 64 bit integer.
6756
7303
  *
6757
7304
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6758
- *
6759
- * @returns {BigValue}
6760
7305
  */
6761
7306
  get bigintle() {
6762
7307
  return this.readInt64(false, "little");
@@ -6766,8 +7311,6 @@ class BiReader extends BiBase {
6766
7311
  * Read signed 64 bit integer.
6767
7312
  *
6768
7313
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6769
- *
6770
- * @returns {BigValue}
6771
7314
  */
6772
7315
  get quadle() {
6773
7316
  return this.readInt64(false, "little");
@@ -6777,8 +7320,6 @@ class BiReader extends BiBase {
6777
7320
  * Read unsigned 64 bit integer.
6778
7321
  *
6779
7322
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6780
- *
6781
- * @returns {BigValue}
6782
7323
  */
6783
7324
  get uint64le() {
6784
7325
  return this.readInt64(true, "little");
@@ -6788,8 +7329,6 @@ class BiReader extends BiBase {
6788
7329
  * Read unsigned 64 bit integer.
6789
7330
  *
6790
7331
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6791
- *
6792
- * @returns {BigValue}
6793
7332
  */
6794
7333
  get ubigintle() {
6795
7334
  return this.readInt64(true, "little");
@@ -6799,15 +7338,13 @@ class BiReader extends BiBase {
6799
7338
  * Read unsigned 64 bit integer.
6800
7339
  *
6801
7340
  * Note: If ``enforceBigInt`` was set to ``true``, this always returns a ``BigInt`` otherwise it will return a ``number`` if integer safe.
6802
- *
6803
- * @returns {BigValue}
6804
7341
  */
6805
7342
  get uquadle() {
6806
7343
  return this.readInt64(true, "little");
6807
7344
  }
6808
7345
  ;
6809
7346
  //
6810
- //doublefloat reader
7347
+ // #region doublefloat reader
6811
7348
  //
6812
7349
  /**
6813
7350
  * Read double float.
@@ -6864,7 +7401,7 @@ class BiReader extends BiBase {
6864
7401
  }
6865
7402
  ;
6866
7403
  //
6867
- //string reader
7404
+ // #region string reader
6868
7405
  //
6869
7406
  /**
6870
7407
  * Reads string, use options object for different types.
@@ -6877,7 +7414,7 @@ class BiReader extends BiBase {
6877
7414
  * @param {stringOptions["stripNull"]?} options.stripNull - removes 0x00 characters
6878
7415
  * @param {stringOptions["encoding"]?} options.encoding - TextEncoder accepted types
6879
7416
  * @param {stringOptions["endian"]?} options.endian - for wide-pascal and utf-16
6880
- * @return {string}
7417
+ * @returns {string}
6881
7418
  */
6882
7419
  string(options) {
6883
7420
  return this.readString(options);
@@ -6888,7 +7425,7 @@ class BiReader extends BiBase {
6888
7425
  *
6889
7426
  * Default is ``utf-8``
6890
7427
  *
6891
- * @return {string}
7428
+ * @returns {string}
6892
7429
  */
6893
7430
  get str() {
6894
7431
  return this.readString(this.strSettings);
@@ -6901,7 +7438,7 @@ class BiReader extends BiBase {
6901
7438
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6902
7439
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6903
7440
  *
6904
- * @return {string}
7441
+ * @returns {string}
6905
7442
  */
6906
7443
  utf8string(length, terminateValue, stripNull) {
6907
7444
  return this.string({ stringType: "utf-8", encoding: "utf-8", length: length, terminateValue: terminateValue, stripNull: stripNull });
@@ -6914,7 +7451,7 @@ class BiReader extends BiBase {
6914
7451
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6915
7452
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6916
7453
  *
6917
- * @return {string}
7454
+ * @returns {string}
6918
7455
  */
6919
7456
  cstring(length, terminateValue, stripNull) {
6920
7457
  return this.string({ stringType: "utf-8", encoding: "utf-8", length: length, terminateValue: terminateValue, stripNull: stripNull });
@@ -6927,7 +7464,7 @@ class BiReader extends BiBase {
6927
7464
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6928
7465
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6929
7466
  *
6930
- * @return {string}
7467
+ * @returns {string}
6931
7468
  */
6932
7469
  ansistring(length, terminateValue, stripNull) {
6933
7470
  return this.string({ stringType: "utf-8", encoding: "windows-1252", length: length, terminateValue: terminateValue, stripNull: stripNull });
@@ -6941,7 +7478,7 @@ class BiReader extends BiBase {
6941
7478
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6942
7479
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
6943
7480
  *
6944
- * @return {string}
7481
+ * @returns {string}
6945
7482
  */
6946
7483
  utf16string(length, terminateValue, stripNull, endian) {
6947
7484
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: endian, stripNull: stripNull });
@@ -6955,7 +7492,7 @@ class BiReader extends BiBase {
6955
7492
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6956
7493
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
6957
7494
  *
6958
- * @return {string}
7495
+ * @returns {string}
6959
7496
  */
6960
7497
  unistring(length, terminateValue, stripNull, endian) {
6961
7498
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: endian, stripNull: stripNull });
@@ -6968,7 +7505,7 @@ class BiReader extends BiBase {
6968
7505
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6969
7506
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6970
7507
  *
6971
- * @return {string}
7508
+ * @returns {string}
6972
7509
  */
6973
7510
  utf16stringle(length, terminateValue, stripNull) {
6974
7511
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: "little", stripNull: stripNull });
@@ -6981,7 +7518,7 @@ class BiReader extends BiBase {
6981
7518
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6982
7519
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6983
7520
  *
6984
- * @return {string}
7521
+ * @returns {string}
6985
7522
  */
6986
7523
  unistringle(length, terminateValue, stripNull) {
6987
7524
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: "little", stripNull: stripNull });
@@ -6994,7 +7531,7 @@ class BiReader extends BiBase {
6994
7531
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
6995
7532
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
6996
7533
  *
6997
- * @return {string}
7534
+ * @returns {string}
6998
7535
  */
6999
7536
  utf16stringbe(length, terminateValue, stripNull) {
7000
7537
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: "big", stripNull: stripNull });
@@ -7007,7 +7544,7 @@ class BiReader extends BiBase {
7007
7544
  * @param {stringOptions["terminateValue"]} terminateValue - for non-fixed length utf strings
7008
7545
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7009
7546
  *
7010
- * @return {string}
7547
+ * @returns {string}
7011
7548
  */
7012
7549
  unistringbe(length, terminateValue, stripNull) {
7013
7550
  return this.string({ stringType: "utf-16", encoding: "utf-16", length: length, terminateValue: terminateValue, endian: "big", stripNull: stripNull });
@@ -7020,7 +7557,7 @@ class BiReader extends BiBase {
7020
7557
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7021
7558
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7022
7559
  *
7023
- * @return {string}
7560
+ * @returns {string}
7024
7561
  */
7025
7562
  pstring(lengthReadSize, stripNull, endian) {
7026
7563
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: lengthReadSize, stripNull: stripNull, endian: endian });
@@ -7032,7 +7569,7 @@ class BiReader extends BiBase {
7032
7569
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7033
7570
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7034
7571
  *
7035
- * @return {string}
7572
+ * @returns {string}
7036
7573
  */
7037
7574
  pstring1(stripNull, endian) {
7038
7575
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 1, stripNull: stripNull, endian: endian });
@@ -7043,7 +7580,7 @@ class BiReader extends BiBase {
7043
7580
  *
7044
7581
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7045
7582
  *
7046
- * @return {string}
7583
+ * @returns {string}
7047
7584
  */
7048
7585
  pstring1le(stripNull) {
7049
7586
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 1, stripNull: stripNull, endian: "little" });
@@ -7054,7 +7591,7 @@ class BiReader extends BiBase {
7054
7591
  *
7055
7592
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7056
7593
  *
7057
- * @return {string}
7594
+ * @returns {string}
7058
7595
  */
7059
7596
  pstring1be(stripNull) {
7060
7597
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 1, stripNull: stripNull, endian: "big" });
@@ -7066,7 +7603,7 @@ class BiReader extends BiBase {
7066
7603
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7067
7604
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7068
7605
  *
7069
- * @return {string}
7606
+ * @returns {string}
7070
7607
  */
7071
7608
  pstring2(stripNull, endian) {
7072
7609
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 2, stripNull: stripNull, endian: endian });
@@ -7077,7 +7614,7 @@ class BiReader extends BiBase {
7077
7614
  *
7078
7615
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7079
7616
  *
7080
- * @return {string}
7617
+ * @returns {string}
7081
7618
  */
7082
7619
  pstring2le(stripNull) {
7083
7620
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 2, stripNull: stripNull, endian: "little" });
@@ -7088,7 +7625,7 @@ class BiReader extends BiBase {
7088
7625
  *
7089
7626
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7090
7627
  *
7091
- * @return {string}
7628
+ * @returns {string}
7092
7629
  */
7093
7630
  pstring2be(stripNull) {
7094
7631
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 2, stripNull: stripNull, endian: "big" });
@@ -7100,7 +7637,7 @@ class BiReader extends BiBase {
7100
7637
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7101
7638
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7102
7639
  *
7103
- * @return {string}
7640
+ * @returns {string}
7104
7641
  */
7105
7642
  pstring4(stripNull, endian) {
7106
7643
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 4, stripNull: stripNull, endian: endian });
@@ -7111,7 +7648,7 @@ class BiReader extends BiBase {
7111
7648
  *
7112
7649
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7113
7650
  *
7114
- * @return {string}
7651
+ * @returns {string}
7115
7652
  */
7116
7653
  pstring4le(stripNull) {
7117
7654
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 4, stripNull: stripNull, endian: "little" });
@@ -7122,7 +7659,7 @@ class BiReader extends BiBase {
7122
7659
  *
7123
7660
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7124
7661
  *
7125
- * @return {string}
7662
+ * @returns {string}
7126
7663
  */
7127
7664
  pstring4be(stripNull) {
7128
7665
  return this.string({ stringType: "pascal", encoding: "utf-8", lengthReadSize: 4, stripNull: stripNull, endian: "big" });
@@ -7135,7 +7672,7 @@ class BiReader extends BiBase {
7135
7672
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7136
7673
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7137
7674
  *
7138
- * @return {string}
7675
+ * @returns {string}
7139
7676
  */
7140
7677
  wpstring(lengthReadSize, stripNull, endian) {
7141
7678
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: lengthReadSize, endian: endian, stripNull: stripNull });
@@ -7147,19 +7684,41 @@ class BiReader extends BiBase {
7147
7684
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7148
7685
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7149
7686
  *
7150
- * @return {string}
7687
+ * @returns {string}
7151
7688
  */
7152
7689
  wpstring1(stripNull, endian) {
7153
7690
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 1, endian: endian, stripNull: stripNull });
7154
7691
  }
7155
7692
  ;
7156
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
+ /**
7157
7716
  * Reads Wide-Pascal string 2 byte length read.
7158
7717
  *
7159
7718
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7160
7719
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7161
7720
  *
7162
- * @return {string}
7721
+ * @returns {string}
7163
7722
  */
7164
7723
  wpstring2(stripNull, endian) {
7165
7724
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 2, endian: endian, stripNull: stripNull });
@@ -7170,7 +7729,7 @@ class BiReader extends BiBase {
7170
7729
  *
7171
7730
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7172
7731
  *
7173
- * @return {string}
7732
+ * @returns {string}
7174
7733
  */
7175
7734
  wpstring2le(stripNull) {
7176
7735
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 2, endian: "little", stripNull: stripNull });
@@ -7181,7 +7740,7 @@ class BiReader extends BiBase {
7181
7740
  *
7182
7741
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7183
7742
  *
7184
- * @return {string}
7743
+ * @returns {string}
7185
7744
  */
7186
7745
  wpstring2be(stripNull) {
7187
7746
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 2, endian: "big", stripNull: stripNull });
@@ -7193,7 +7752,7 @@ class BiReader extends BiBase {
7193
7752
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7194
7753
  * @param {stringOptions["endian"]} endian - ``big`` or ``little``
7195
7754
  *
7196
- * @return {string}
7755
+ * @returns {string}
7197
7756
  */
7198
7757
  wpstring4(stripNull, endian) {
7199
7758
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 4, endian: endian, stripNull: stripNull });
@@ -7204,7 +7763,7 @@ class BiReader extends BiBase {
7204
7763
  *
7205
7764
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7206
7765
  *
7207
- * @return {string}
7766
+ * @returns {string}
7208
7767
  */
7209
7768
  wpstring4be(stripNull) {
7210
7769
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 4, endian: "big", stripNull: stripNull });
@@ -7215,7 +7774,7 @@ class BiReader extends BiBase {
7215
7774
  *
7216
7775
  * @param {stringOptions["stripNull"]} stripNull - removes 0x00 characters
7217
7776
  *
7218
- * @return {string}
7777
+ * @returns {string}
7219
7778
  */
7220
7779
  wpstring4le(stripNull) {
7221
7780
  return this.string({ stringType: "wide-pascal", encoding: "utf-16", lengthReadSize: 4, endian: "little", stripNull: stripNull });
@@ -7226,7 +7785,7 @@ class BiReader extends BiBase {
7226
7785
  /**
7227
7786
  * Binary writer, includes bitfields and strings.
7228
7787
  *
7229
- * @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``
7230
7789
  * @param {BiOptions?} options - Any options to set at start
7231
7790
  * @param {BiOptions["byteOffset"]?} options.byteOffset - Byte offset to start writer (default ``0``)
7232
7791
  * @param {BiOptions["bitOffset"]?} options.bitOffset - Bit offset 0-7 to start writer (default ``0``)
@@ -7234,6 +7793,7 @@ class BiReader extends BiBase {
7234
7793
  * @param {BiOptions["strict"]?} options.strict - Strict mode: if ``true`` does not extend supplied array on outside write (default ``false``)
7235
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``.
7236
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)
7237
7797
  *
7238
7798
  * @since 2.0
7239
7799
  */
@@ -7241,7 +7801,7 @@ class BiWriter extends BiBase {
7241
7801
  /**
7242
7802
  * Binary writer, includes bitfields and strings.
7243
7803
  *
7244
- * @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``
7245
7805
  * @param {BiOptions?} options - Any options to set at start
7246
7806
  * @param {BiOptions["byteOffset"]?} options.byteOffset - Byte offset to start writer (default ``0``)
7247
7807
  * @param {BiOptions["bitOffset"]?} options.bitOffset - Bit offset 0-7 to start writer (default ``0``)
@@ -7249,51 +7809,63 @@ class BiWriter extends BiBase {
7249
7809
  * @param {BiOptions["strict"]?} options.strict - Strict mode: if ``true`` does not extend supplied array on outside write (default ``false``)
7250
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``.
7251
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)
7252
7813
  */
7253
- constructor(data, options = {}) {
7254
- super();
7814
+ constructor(input, options = {}) {
7815
+ super(input, options.writeable ?? true);
7255
7816
  this.strict = false;
7256
- if (data == undefined) {
7257
- if (typeof Buffer !== 'undefined') {
7258
- this.data = Buffer.alloc(this.offset || 1 + (this.bitoffset != 0 ? 1 : 0));
7259
- }
7260
- else {
7261
- this.data = new Uint8Array(this.offset || 1 + (this.bitoffset != 0 ? 1 : 0));
7262
- }
7817
+ this.enforceBigInt = (options?.enforceBigInt) ?? hasBigInt;
7818
+ if (options.extendBufferSize != undefined &&
7819
+ options.extendBufferSize != 0) {
7820
+ this.extendBufferSize = options.extendBufferSize;
7263
7821
  }
7264
- else {
7265
- if (!this.isBufferOrUint8Array(data)) {
7266
- throw new Error("Write data must be Uint8Array or Buffer.");
7267
- }
7268
- this.data = data;
7822
+ if (input == undefined) {
7823
+ input = new Uint8Array(this.extendBufferSize);
7824
+ console.warn(`BiWriter started without data. Creating Uint8Array with extendBufferSize.`);
7269
7825
  }
7270
- this.enforceBigInt = options?.enforceBigInt ?? false;
7271
- if (options.extendBufferSize != undefined && options.extendBufferSize != 0) {
7272
- 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.");
7273
7833
  }
7274
- this.size = this.data.length;
7275
- this.sizeB = this.data.length * 8;
7834
+ this.endian = options.endianness || "little";
7276
7835
  if (typeof options.strict == "boolean") {
7277
7836
  this.strict = options.strict;
7278
7837
  }
7279
7838
  else {
7280
7839
  if (options.strict != undefined) {
7281
- throw new Error("Strict mode must be true of false.");
7840
+ throw new Error("Strict mode must be true or false.");
7282
7841
  }
7283
7842
  }
7284
- if (options.endianness != undefined && typeof options.endianness != "string") {
7285
- throw new Error("endianness must be big or little.");
7843
+ if (input == undefined) {
7844
+ throw new Error("Data or file path required");
7286
7845
  }
7287
- if (options.endianness != undefined && !(options.endianness == "big" || options.endianness == "little")) {
7288
- 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
+ }
7289
7862
  }
7290
- this.endian = options.endianness || "little";
7291
7863
  if (options.byteOffset != undefined || options.bitOffset != undefined) {
7292
7864
  this.offset = ((Math.abs(options.byteOffset || 0)) + Math.ceil((Math.abs(options.bitOffset || 0)) / 8));
7293
7865
  // Adjust byte offset based on bit overflow
7294
7866
  this.offset += Math.floor((Math.abs(options.bitOffset || 0)) / 8);
7295
7867
  // Adjust bit offset
7296
- this.bitoffset = (Math.abs(options.bitOffset || 0) + 64) % 8;
7868
+ this.bitoffset = Math.abs(normalizeBitOffset(options.bitOffset)) % 8;
7297
7869
  // Ensure bit offset stays between 0-7
7298
7870
  this.bitoffset = Math.min(Math.max(this.bitoffset, 0), 7);
7299
7871
  // Ensure offset doesn't go negative
@@ -7312,10 +7884,13 @@ class BiWriter extends BiBase {
7312
7884
  }
7313
7885
  }
7314
7886
  }
7887
+ if (this.mode == "file") {
7888
+ this.open();
7889
+ }
7315
7890
  }
7316
7891
  ;
7317
7892
  //
7318
- // Bit Aliases
7893
+ // #region Bit Aliases
7319
7894
  //
7320
7895
  /**
7321
7896
  * Bit field writer.
@@ -9513,7 +10088,7 @@ class BiWriter extends BiBase {
9513
10088
  }
9514
10089
  ;
9515
10090
  //
9516
- // byte write
10091
+ // #region byte write
9517
10092
  //
9518
10093
  /**
9519
10094
  * Write byte.
@@ -9552,7 +10127,7 @@ class BiWriter extends BiBase {
9552
10127
  }
9553
10128
  ;
9554
10129
  //
9555
- // short writes
10130
+ // #region short writes
9556
10131
  //
9557
10132
  /**
9558
10133
  * Write int16.
@@ -9717,7 +10292,7 @@ class BiWriter extends BiBase {
9717
10292
  }
9718
10293
  ;
9719
10294
  //
9720
- // half float
10295
+ // #region half float
9721
10296
  //
9722
10297
  /**
9723
10298
  * Writes half float.
@@ -9774,7 +10349,7 @@ class BiWriter extends BiBase {
9774
10349
  }
9775
10350
  ;
9776
10351
  //
9777
- // int32 write
10352
+ // #region int32 write
9778
10353
  //
9779
10354
  /**
9780
10355
  * Write int32.
@@ -10002,7 +10577,7 @@ class BiWriter extends BiBase {
10002
10577
  }
10003
10578
  ;
10004
10579
  //
10005
- // float write
10580
+ // #region float write
10006
10581
  //
10007
10582
  /**
10008
10583
  * Write float.
@@ -10032,7 +10607,7 @@ class BiWriter extends BiBase {
10032
10607
  }
10033
10608
  ;
10034
10609
  //
10035
- // int64 write
10610
+ // #region int64 write
10036
10611
  //
10037
10612
  /**
10038
10613
  * Write 64 bit integer.
@@ -10197,7 +10772,7 @@ class BiWriter extends BiBase {
10197
10772
  }
10198
10773
  ;
10199
10774
  //
10200
- // doublefloat
10775
+ // #region doublefloat
10201
10776
  //
10202
10777
  /**
10203
10778
  * Writes double float.
@@ -10254,7 +10829,7 @@ class BiWriter extends BiBase {
10254
10829
  }
10255
10830
  ;
10256
10831
  //
10257
- // string
10832
+ // #region string
10258
10833
  //
10259
10834
  /**
10260
10835
  * Writes string, use options object for different types.
@@ -10606,6 +11181,16 @@ class BiReaderStream {
10606
11181
  throw new Error("BiReaderStream isn't usable in browser. Use BiReader instead.");
10607
11182
  }
10608
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
+ }
10609
11194
  /**
10610
11195
  * Isn't usable in browser.
10611
11196
  * @since 3.0
@@ -10636,6 +11221,16 @@ class biwriter {
10636
11221
  throw new Error("biwriter is deprecated. Use BiWriter instead.");
10637
11222
  }
10638
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
+ }
10639
11234
 
10640
- export { BiReader, BiReaderStream, BiWriter, BiWriterStream, bireader, biwriter, hexdump };
11235
+ export { BiBase, BiFileReader, BiFileWriter, BiReader, BiReaderStream, BiWriter, BiWriterStream, bireader, biwriter, hexdump };
10641
11236
  //# sourceMappingURL=index.browser.js.map