bireader 1.0.13 → 1.0.15

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,42 +1,53 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.bireader = void 0;
4
+ const common_1 = require("./common");
4
5
  /**
6
+ * Binary reader, includes bitfields and strings
5
7
  *
6
- * byte reader, includes bitfields and strings
7
- *
8
- * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```
9
- * @param {number} byteOffset - byte offset to start reader, default is 0
10
- * @param {number} bitOffset - bit offset to start reader, 0-7
11
- * @param {string} endianness - endianness ```big``` or ```little``` (default ```little```)
8
+ * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```. Always found in ``biwriter.data``
9
+ * @param {number} byteOffset - Byte offset to start reader (default 0)
10
+ * @param {number} bitOffset - Bit offset 0-7 to start reader (default 0)
11
+ * @param {string} endianness - Endianness ```big``` or ```little``` (default ```little```)
12
+ * @param {boolean} strict - Strict mode: if true does not extend supplied array on outside write (default true)
12
13
  */
13
14
  class bireader {
14
- check_size(read_size, read_bits) {
15
- const new_off = this.offset + (read_size || 0) + Math.ceil((this.bitoffset + (read_bits || 0)) / 8);
16
- if (new_off > this.size) {
17
- throw new Error(`Reader reached end of data.`);
18
- }
19
- }
20
15
  isBuffer(obj) {
21
16
  return (typeof Buffer !== 'undefined' && obj instanceof Buffer);
22
17
  }
23
18
  isBufferOrUint8Array(obj) {
24
19
  return obj instanceof Uint8Array || this.isBuffer(obj);
25
20
  }
21
+ extendArray(to_padd) {
22
+ if ((typeof Buffer !== 'undefined' && this.data instanceof Buffer)) {
23
+ var paddbuffer = Buffer.alloc(to_padd);
24
+ this.data = Buffer.concat([this.data, paddbuffer]);
25
+ }
26
+ else {
27
+ const addArray = new Array(to_padd);
28
+ this.data = new Uint8Array([...this.data, ...addArray]);
29
+ }
30
+ }
31
+ check_size(read_size, read_bits) {
32
+ return (0, common_1.checkSize)(this, read_size || 0, read_bits || 0, this.offset);
33
+ }
26
34
  /**
35
+ * Binary reader, includes bitfields and strings
27
36
  *
28
- * byte reader, includes bitfields and strings
29
- *
30
- * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```
31
- * @param {number} byteOffset - byte offset to start reader, default is 0
32
- * @param {number} bitOffset - bit offset to start reader, 0-7
33
- * @param {string} endianness - endianness ```big``` or ```little``` (default ```little```)
37
+ * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```. Always found in ``biwriter.data``
38
+ * @param {number} byteOffset - Byte offset to start reader (default 0)
39
+ * @param {number} bitOffset - Bit offset 0-7 to start reader (default 0)
40
+ * @param {string} endianness - Endianness ```big``` or ```little``` (default ```little```)
41
+ * @param {boolean} strict - Strict mode: if true does not extend supplied array on outside write (default true)
34
42
  */
35
- constructor(data, byteOffset, bitOffset, endianness) {
43
+ constructor(data, byteOffset, bitOffset, endianness, strict) {
36
44
  this.endian = "little";
37
45
  this.offset = 0;
38
46
  this.bitoffset = 0;
39
47
  this.size = 0;
48
+ this.strict = false;
49
+ this.errorDump = true;
50
+ this.data = [];
40
51
  if (endianness != undefined && typeof endianness != "string") {
41
52
  throw new Error("Endian must be big or little");
42
53
  }
@@ -55,6 +66,14 @@ class bireader {
55
66
  if (bitOffset != undefined) {
56
67
  this.bitoffset = bitOffset % 8;
57
68
  }
69
+ if (typeof strict == "boolean") {
70
+ this.strict = strict;
71
+ }
72
+ else {
73
+ if (strict != undefined) {
74
+ throw new Error("Strict mode must be true of false");
75
+ }
76
+ }
58
77
  if (data == undefined) {
59
78
  throw new Error("Data required");
60
79
  }
@@ -119,123 +138,98 @@ class bireader {
119
138
  le() {
120
139
  this.endianness("little");
121
140
  }
141
+ //
142
+ // move from current position
143
+ //
122
144
  /**
123
- * Move current read byte or bit position
145
+ * Offset current byte or bit position
146
+ * Note: Will extend array if strict mode is off and outside of max size
124
147
  *
125
- * @param {number} bytes - bytes to skip
126
- * @param {number} bits - bits to skip
148
+ * @param {number} bytes - Bytes to skip
149
+ * @param {number} bits - Bits to skip (0-7)
127
150
  */
128
151
  skip(bytes, bits) {
129
- this.check_size(bytes || 0);
130
- if ((((bytes || 0) + this.offset) + Math.ceil((this.bitoffset + (bits || 0)) / 8)) > this.size) {
131
- throw new Error("Seek outside of size of data: " + this.size);
132
- }
133
- this.bitoffset += (bits || 0) % 8;
134
- this.offset += (bytes || 0);
152
+ return (0, common_1.skip)(this, bytes, bits);
135
153
  }
136
154
  /**
137
- * Move current read byte or bit position
155
+ * Offset current byte or bit position
156
+ * Note: Will extend array if strict mode is off and outside of max size
138
157
  *
139
- * @param {number} bytes - bytes to skip
140
- * @param {number} bits - bits to skip
158
+ * @param {number} bytes - Bytes to skip
159
+ * @param {number} bits - Bits to skip (0-7)
141
160
  */
142
- fskip(bytes, bits) {
161
+ jump(bytes, bits) {
143
162
  this.skip(bytes, bits);
144
163
  }
164
+ //
165
+ // directly set current position
166
+ //
145
167
  /**
146
- * Change current byte or bit read position
168
+ * Change position directly to address
169
+ * Note: Will extend array if strict mode is off and outside of max size
147
170
  *
148
- * @param {number} byte - byte to jump to
149
- * @param {number} bit - bit to jump to (0-7)
171
+ * @param {number} byte - byte to set to
172
+ * @param {number} bit - bit to set to (0-7)
150
173
  */
151
174
  goto(byte, bit) {
152
- if ((byte + Math.ceil((bit || 0) / 8)) > this.size) {
153
- throw new Error("Goto outside of size of data: " + this.size);
154
- }
155
- this.offset = byte;
156
- this.bitoffset = (bit || 0) % 8;
175
+ return (0, common_1.goto)(this, byte, bit);
157
176
  }
158
177
  /**
159
- * Change current byte or bit read position
178
+ * Change position directly to address
179
+ * Note: Will extend array if strict mode is off and outside of max size
160
180
  *
161
- * @param {number} byte - byte to jump to
162
- * @param {number} bit - bit to jump to (0-7)
181
+ * @param {number} byte - byte to set to
182
+ * @param {number} bit - bit to set to (0-7)
163
183
  */
164
184
  seek(byte, bit) {
165
- this.goto(byte, bit);
166
- }
167
- /**
168
- * Change current byte or bit read position
169
- *
170
- * @param {number} byte - byte to jump to
171
- * @param {number} bit - bit to jump to (0-7)
172
- */
173
- fseek(byte, bit) {
174
- this.goto(byte, bit);
185
+ return this.goto(byte, bit);
175
186
  }
176
187
  /**
177
- * Change current byte or bit read position
188
+ * Change position directly to address
189
+ * Note: Will extend array if strict mode is off and outside of max size
178
190
  *
179
- * @param {number} byte - byte to jump to
180
- * @param {number} bit - bit to jump to (0-7)
181
- */
182
- jump(byte, bit) {
183
- this.goto(byte, bit);
184
- }
185
- /**
186
- * Change current byte or bit read position
187
- *
188
- * @param {number} byte - byte to jump to
189
- * @param {number} bit - bit to jump to (0-7)
191
+ * @param {number} byte - byte to set to
192
+ * @param {number} bit - bit to set to (0-7)
190
193
  */
191
194
  pointer(byte, bit) {
192
- this.goto(byte, bit);
195
+ return this.goto(byte, bit);
193
196
  }
194
197
  /**
195
- * Change current byte or bit read position
198
+ * Change position directly to address
199
+ * Note: Will extend array if strict mode is off and outside of max size
196
200
  *
197
- * @param {number} byte - byte to jump to
198
- * @param {number} bit - bit to jump to (0-7)
201
+ * @param {number} byte - byte to set to
202
+ * @param {number} bit - bit to set to (0-7)
199
203
  */
200
204
  warp(byte, bit) {
201
- this.goto(byte, bit);
202
- }
203
- /**
204
- * Change current byte or bit read position
205
- *
206
- * @param {number} byte - byte to jump to
207
- * @param {number} bit - bit to jump to (0-7)
208
- */
209
- fsetpos(byte, bit) {
210
- this.goto(byte, bit);
205
+ return this.goto(byte, bit);
211
206
  }
207
+ //
208
+ //go to start
209
+ //
212
210
  /**
213
- * Set offset to start of file
211
+ * Set byte and bit position to start of data
214
212
  */
215
213
  rewind() {
216
214
  this.offset = 0;
217
215
  this.bitoffset = 0;
218
216
  }
219
217
  /**
220
- * Set offset to start of file
218
+ * Set byte and bit position to start of data
221
219
  */
222
220
  gotostart() {
223
221
  this.offset = 0;
224
222
  this.bitoffset = 0;
225
223
  }
226
- /**
227
- * Set offset to start of file
228
- */
229
- tostart() {
230
- this.offset = 0;
231
- this.bitoffset = 0;
232
- }
224
+ //
225
+ //get position
226
+ //
233
227
  /**
234
228
  * Get the current byte position
235
229
  *
236
230
  * @return {number} current byte position
237
231
  */
238
- ftell() {
232
+ tell() {
239
233
  return this.offset;
240
234
  }
241
235
  /**
@@ -243,7 +237,7 @@ class bireader {
243
237
  *
244
238
  * @return {number} current byte position
245
239
  */
246
- tell() {
240
+ getOffset() {
247
241
  return this.offset;
248
242
  }
249
243
  /**
@@ -251,95 +245,204 @@ class bireader {
251
245
  *
252
246
  * @return {number} current byte position
253
247
  */
254
- fgetpos() {
248
+ saveOffset() {
255
249
  return this.offset;
256
250
  }
251
+ //
252
+ //strict mode change
253
+ //
257
254
  /**
258
- * Get the current byte position
255
+ * Disallows extending data if position is outside of max size
256
+ */
257
+ restrict() {
258
+ this.strict = true;
259
+ }
260
+ /**
261
+ * Allows extending data if position is outside of max size
262
+ */
263
+ unrestrict() {
264
+ this.strict = false;
265
+ }
266
+ //
267
+ //remove part of data
268
+ //
269
+ /**
270
+ * Deletes part of data from start to current byte position unless supplied, returns removed
271
+ * Note: Errors in strict mode
259
272
  *
260
- * @return {number} current byte position
273
+ * @param {number} startOffset - Start location (default 0)
274
+ * @param {number} endOffset - End location (default current position)
275
+ * @param {boolean} consume - Move position to end of removed data (default false)
276
+ * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
261
277
  */
262
- saveOffset() {
263
- return this.offset;
278
+ delete(startOffset, endOffset, consume) {
279
+ return (0, common_1.remove)(this, startOffset || 0, endOffset || this.offset, consume || false, true);
264
280
  }
265
281
  /**
266
- * Truncates array from start to current position unless supplied
267
- * Note: Does not affect supplied data
268
- * @param {number} startOffset - Start location, default 0
269
- * @param {number} endOffset - end location, default current write position
270
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
282
+ * Deletes part of data from start to current byte position unless supplied, returns removed
283
+ * Note: Errors in strict mode
284
+ *
285
+ * @param {number} startOffset - Start location (default 0)
286
+ * @param {number} endOffset - End location (default current position)
287
+ * @param {boolean} consume - Move position to end of removed data (default false)
288
+ * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
271
289
  */
272
- clip(startOffset, endOffset) {
273
- return this.data.slice(startOffset || 0, endOffset || this.offset);
290
+ clip(startOffset, endOffset, consume) {
291
+ return (0, common_1.remove)(this, startOffset || 0, endOffset || this.offset, consume || false, true);
274
292
  }
275
293
  /**
276
- * Truncates array from start to current position unless supplied
277
- * Note: Does not affect supplied data
278
- * @param {number} startOffset - Start location, default 0
279
- * @param {number} endOffset - end location, default current write position
280
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
294
+ * Deletes part of data from current byte position to supplied length, returns removed
295
+ * Note: Errors in strict mode
296
+ *
297
+ * @param {number} length - Length of data in bytes to remove
298
+ * @param {boolean} consume - Move position to end of removed data (default false)
299
+ * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
281
300
  */
282
- crop(startOffset, endOffset) {
283
- return this.data.slice(startOffset || 0, endOffset || this.offset);
301
+ crop(length, consume) {
302
+ return (0, common_1.remove)(this, this.offset, this.offset + (length || 0), consume || false, true);
284
303
  }
285
304
  /**
286
- * Truncates array from start to current position unless supplied
287
- * Note: Does not affect supplied data
288
- * @param {number} startOffset - Start location, default 0
289
- * @param {number} endOffset - end location, default current write position
290
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
305
+ * Deletes part of data from current position to supplied length, returns removed
306
+ * Note: Only works in strict mode
307
+ *
308
+ * @param {number} length - Length of data in bytes to remove
309
+ * @param {boolean} consume - Move position to end of removed data (default false)
310
+ * @returns {Buffer|Uint8Array} Removed data as ``Buffer`` or ``Uint8Array``
311
+ */
312
+ drop(length, consume) {
313
+ return (0, common_1.remove)(this, this.offset, this.offset + (length || 0), consume || false, true);
314
+ }
315
+ //
316
+ //copy out
317
+ //
318
+ /**
319
+ * Returns part of data from current byte position to end of data unless supplied
320
+ *
321
+ * @param {number} startOffset - Start location (default current position)
322
+ * @param {number} endOffset - End location (default end of data)
323
+ * @param {boolean} consume - Move position to end of lifted data (default false)
324
+ * @param {number} fillValue - Byte value to to fill returned data (does NOT fill unless supplied)
325
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
291
326
  */
292
- truncate(startOffset, endOffset) {
293
- return this.data.slice(startOffset || 0, endOffset || this.offset);
327
+ lift(startOffset, endOffset, consume, fillValue) {
328
+ return (0, common_1.remove)(this, startOffset || this.offset, endOffset || this.size, consume || false, false, fillValue);
294
329
  }
295
330
  /**
296
- * Truncates array from start to current position unless supplied
297
- * Note: Does not affect supplied data
298
- * @param {number} startOffset - Start location, default 0
299
- * @param {number} endOffset - end location, default current write position
300
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
331
+ * Returns part of data from current byte position to end of data unless supplied
332
+ *
333
+ * @param {number} startOffset - Start location (default current position)
334
+ * @param {number} endOffset - End location (default end of data)
335
+ * @param {boolean} consume - Move position to end of lifted data (default false)
336
+ * @param {number} fillValue - Byte value to to fill returned data (does NOT fill unless supplied)
337
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
301
338
  */
302
- slice(startOffset, endOffset) {
303
- return this.data.slice(startOffset || 0, endOffset || this.offset);
339
+ fill(startOffset, endOffset, consume, fillValue) {
340
+ return (0, common_1.remove)(this, startOffset || this.offset, endOffset || this.size, consume || false, false, fillValue);
304
341
  }
305
342
  /**
306
- * Extract array from current position to length supplied
343
+ * Extract data from current position to length supplied
307
344
  * Note: Does not affect supplied data
308
- * @param {number} length - length of data to copy from current offset
309
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
345
+ *
346
+ * @param {number} length - Length of data in bytes to copy from current offset
347
+ * @param {number} consume - Moves offset to end of length
348
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
310
349
  */
311
- extract(length) {
312
- if (this.offset + (length || 0) > this.size) {
313
- throw new Error("End offset outside of data: " + this.size);
314
- }
315
- return this.data.slice(this.offset, this.offset + (length || 0));
350
+ extract(length, consume) {
351
+ return (0, common_1.remove)(this, this.offset, length || 0, consume || false, false);
316
352
  }
317
353
  /**
318
- * Extract array from current position to length supplied
354
+ * Extract data from current position to length supplied
319
355
  * Note: Does not affect supplied data
320
- * @param {number} length - length of data to copy from current offset
321
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
356
+ *
357
+ * @param {number} length - Length of data in bytes to copy from current offset
358
+ * @param {number} consume - Moves offset to end of length
359
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
322
360
  */
323
- wrap(length) {
324
- if (this.offset + (length || 0) > this.size) {
325
- throw new Error("End offset outside of data: " + this.size);
326
- }
327
- return this.data.slice(this.offset, this.offset + (length || 0));
361
+ slice(length, consume) {
362
+ return (0, common_1.remove)(this, this.offset, length || 0, consume || false, false);
328
363
  }
329
364
  /**
330
- * Extract array from current position to length supplied
365
+ * Extract data from current position to length supplied
331
366
  * Note: Does not affect supplied data
332
- * @param {number} length - length of data to copy from current offset
333
- * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
367
+ *
368
+ * @param {number} length - Length of data in bytes to copy from current offset
369
+ * @param {number} consume - Moves offset to end of length
370
+ * @returns {Buffer|Uint8Array} Selected data as ```Uint8Array``` or ```Buffer```
334
371
  */
335
- lift(length) {
336
- if (this.offset + (length || 0) > this.size) {
337
- throw new Error("End offset outside of data: " + this.size);
338
- }
339
- return this.data.slice(this.offset, this.offset + (length || 0));
372
+ wrap(length, consume) {
373
+ return (0, common_1.remove)(this, this.offset, length || 0, consume || false, false);
374
+ }
375
+ //
376
+ //insert
377
+ //
378
+ /**
379
+ * Inserts data into data
380
+ * Note: Must be same data type as supplied data. Errors on strict mode.
381
+ *
382
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
383
+ * @param {boolean} consume - Move current write position to end of data (default false)
384
+ * @param {number} offset - Offset to add it at (defaults to current position)
385
+ */
386
+ insert(data, consume, offset) {
387
+ return (0, common_1.addData)(this, data, consume || false, offset || this.offset);
388
+ }
389
+ /**
390
+ * Inserts data into data
391
+ * Note: Must be same data type as supplied data. Errors on strict mode.
392
+ *
393
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
394
+ * @param {boolean} consume - Move current write position to end of data (default false)
395
+ * @param {number} offset - Offset to add it at (defaults to current position)
396
+ */
397
+ place(data, consume, offset) {
398
+ return (0, common_1.addData)(this, data, consume || false, offset || this.offset);
399
+ }
400
+ /**
401
+ * Adds data to start of supplied data
402
+ * Note: Must be same data type as supplied data. Errors on strict mode.
403
+ *
404
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
405
+ * @param {boolean} consume - Move current write position to end of data (default false)
406
+ */
407
+ unshift(data, consume) {
408
+ return (0, common_1.addData)(this, data, consume || false, 0);
340
409
  }
341
410
  /**
411
+ * Adds data to start of supplied data
412
+ * Note: Must be same data type as supplied data. Errors on strict mode.
413
+ *
414
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
415
+ * @param {boolean} consume - Move current write position to end of data (default false)
416
+ */
417
+ prepend(data, consume) {
418
+ return (0, common_1.addData)(this, data, consume || false, 0);
419
+ }
420
+ /**
421
+ * Adds data to end of supplied data
422
+ * Note: Must be same data type as supplied data. Errors on strict mode.
423
+ *
424
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
425
+ * @param {boolean} consume - Move current write position to end of data (default false)
426
+ */
427
+ push(data, consume) {
428
+ return (0, common_1.addData)(this, data, consume || false, this.size);
429
+ }
430
+ /**
431
+ * Adds data to end of supplied data
432
+ * Note: Must be same data type as supplied data. Errors on strict mode.
433
+ *
434
+ * @param {Buffer|Uint8Array} data - ```Uint8Array``` or ```Buffer``` to add to data
435
+ * @param {boolean} consume - Move current write position to end of data (default false)
436
+ */
437
+ append(data, consume) {
438
+ return (0, common_1.addData)(this, data, consume || false, this.size);
439
+ }
440
+ //
441
+ //finishing
442
+ //
443
+ /**
342
444
  * Returns current data
445
+ *
343
446
  * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
344
447
  */
345
448
  get() {
@@ -347,34 +450,62 @@ class bireader {
347
450
  }
348
451
  /**
349
452
  * Returns current data
453
+ *
350
454
  * @returns {Buffer|Uint8Array} ``Buffer`` or ``Uint8Array``
351
455
  */
352
456
  return() {
353
457
  return this.data;
354
458
  }
355
459
  /**
356
- * removes reading data
460
+ * removes data
357
461
  */
358
462
  end() {
359
- this.data = [];
463
+ this.data = undefined;
360
464
  }
361
465
  /**
362
- * removes reading data
466
+ * removes data
363
467
  */
364
468
  close() {
365
- this.data = [];
469
+ this.data = undefined;
366
470
  }
367
471
  /**
368
- * removes reading data
472
+ * removes data
369
473
  */
370
474
  done() {
371
- this.data = [];
475
+ this.data = undefined;
372
476
  }
373
477
  /**
374
- * removes reading data
478
+ * removes data
375
479
  */
376
480
  finished() {
377
- this.data = [];
481
+ this.data = undefined;
482
+ }
483
+ /**
484
+ * Console logs data as hex dump
485
+ *
486
+ * @param {object} options - options object
487
+ * ```javascript
488
+ * {
489
+ * length: 192, // number of bytes to log, default 192 or end of data
490
+ * startByte: 0, // byte to start dump, default current position
491
+ * supressUnicode: false // Supress unicode character preview for cleaner columns
492
+ * }
493
+ * ```
494
+ */
495
+ hexdump(options) {
496
+ return (0, common_1.hexDump)(this, options);
497
+ }
498
+ /**
499
+ * Turn hexdump on error off (default on)
500
+ */
501
+ errorDumpOff() {
502
+ this.errorDump = false;
503
+ }
504
+ /**
505
+ * Turn hexdump on error on (default on)
506
+ */
507
+ errorDumpOn() {
508
+ this.errorDump = true;
378
509
  }
379
510
  //
380
511
  //bit reader
@@ -398,6 +529,7 @@ class bireader {
398
529
  }
399
530
  const size_needed = ((((bits - 1) + this.bitoffset) / 8) + this.offset);
400
531
  if (bits <= 0 || size_needed > this.size) {
532
+ this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
401
533
  throw new Error("Invalid number of bits to read: " + size_needed + " of " + this.size);
402
534
  }
403
535
  var off_in_bits = (this.offset * 8) + this.bitoffset;
@@ -424,7 +556,7 @@ class bireader {
424
556
  }
425
557
  this.offset = this.offset + Math.floor(((bits) + this.bitoffset) / 8); //end byte
426
558
  this.bitoffset = ((bits) + this.bitoffset) % 8;
427
- if (unsigned == true) {
559
+ if (unsigned == true || bits <= 7) {
428
560
  return value >>> 0;
429
561
  }
430
562
  if (bits !== 32 && value & (1 << (bits - 1))) {
@@ -446,13 +578,13 @@ class bireader {
446
578
  return this.readBit(bits, unsigned, endian);
447
579
  }
448
580
  /**
449
- * Bit field reader
450
- *
451
- * Note: When returning to a byte read, remaining bits are dropped
452
- *
453
- * @param {boolean} unsigned - if the value is unsigned
454
- * @returns number
455
- */
581
+ * Bit field reader
582
+ *
583
+ * Note: When returning to a byte read, remaining bits are dropped
584
+ *
585
+ * @param {boolean} unsigned - if the value is unsigned
586
+ * @returns number
587
+ */
456
588
  bit1(unsigned) {
457
589
  return this.bit(1, unsigned);
458
590
  }
@@ -3732,6 +3864,7 @@ class bireader {
3732
3864
  maxBytes = this.readInt32(true, endian);
3733
3865
  }
3734
3866
  else {
3867
+ this.errorDump ? "[Error], hexdump:\n" + this.hexdump() : "";
3735
3868
  throw new Error("Invalid length read size: " + lengthReadSize);
3736
3869
  }
3737
3870
  // Read the string as Pascal or Delphi encoded
@@ -3763,6 +3896,23 @@ class bireader {
3763
3896
  throw new Error('Unsupported string type: ' + stringType);
3764
3897
  }
3765
3898
  }
3899
+ /**
3900
+ * Reads string, use options object for different types
3901
+ *
3902
+ * @param {object} options
3903
+ * ```javascript
3904
+ * {
3905
+ * length: number, //for fixed length, non-terminate value utf strings
3906
+ * stringType: "utf-8", //utf-8, utf-16, pascal or wide-pascal
3907
+ * terminateValue: 0x00, // only for non-fixed length utf strings
3908
+ * lengthReadSize: 1, //for pascal strings. 1, 2 or 4 byte length read size
3909
+ * stripNull: true, // removes 0x00 characters
3910
+ * encoding: "utf-8", //TextEncoder accepted types
3911
+ * endian: "little", //for wide-pascal and utf-16
3912
+ * }
3913
+ * ```
3914
+ * @return string
3915
+ */
3766
3916
  string(options) {
3767
3917
  return this.readString(options);
3768
3918
  }