1"use strict"; 2Object.defineProperty(exports, "__esModule", { value: true }); 3const utils_1 = require("./utils"); 4// The default Buffer size if one is not provided. 5const DEFAULT_SMARTBUFFER_SIZE = 4096; 6// The default string encoding to use for reading/writing strings. 7const DEFAULT_SMARTBUFFER_ENCODING = 'utf8'; 8class SmartBuffer { 9 /** 10 * Creates a new SmartBuffer instance. 11 * 12 * @param options { SmartBufferOptions } The SmartBufferOptions to apply to this instance. 13 */ 14 constructor(options) { 15 this.length = 0; 16 this._encoding = DEFAULT_SMARTBUFFER_ENCODING; 17 this._writeOffset = 0; 18 this._readOffset = 0; 19 if (SmartBuffer.isSmartBufferOptions(options)) { 20 // Checks for encoding 21 if (options.encoding) { 22 utils_1.checkEncoding(options.encoding); 23 this._encoding = options.encoding; 24 } 25 // Checks for initial size length 26 if (options.size) { 27 if (utils_1.isFiniteInteger(options.size) && options.size > 0) { 28 this._buff = Buffer.allocUnsafe(options.size); 29 } 30 else { 31 throw new Error(utils_1.ERRORS.INVALID_SMARTBUFFER_SIZE); 32 } 33 // Check for initial Buffer 34 } 35 else if (options.buff) { 36 if (options.buff instanceof Buffer) { 37 this._buff = options.buff; 38 this.length = options.buff.length; 39 } 40 else { 41 throw new Error(utils_1.ERRORS.INVALID_SMARTBUFFER_BUFFER); 42 } 43 } 44 else { 45 this._buff = Buffer.allocUnsafe(DEFAULT_SMARTBUFFER_SIZE); 46 } 47 } 48 else { 49 // If something was passed but it's not a SmartBufferOptions object 50 if (typeof options !== 'undefined') { 51 throw new Error(utils_1.ERRORS.INVALID_SMARTBUFFER_OBJECT); 52 } 53 // Otherwise default to sane options 54 this._buff = Buffer.allocUnsafe(DEFAULT_SMARTBUFFER_SIZE); 55 } 56 } 57 /** 58 * Creates a new SmartBuffer instance with the provided internal Buffer size and optional encoding. 59 * 60 * @param size { Number } The size of the internal Buffer. 61 * @param encoding { String } The BufferEncoding to use for strings. 62 * 63 * @return { SmartBuffer } 64 */ 65 static fromSize(size, encoding) { 66 return new this({ 67 size: size, 68 encoding: encoding 69 }); 70 } 71 /** 72 * Creates a new SmartBuffer instance with the provided Buffer and optional encoding. 73 * 74 * @param buffer { Buffer } The Buffer to use as the internal Buffer value. 75 * @param encoding { String } The BufferEncoding to use for strings. 76 * 77 * @return { SmartBuffer } 78 */ 79 static fromBuffer(buff, encoding) { 80 return new this({ 81 buff: buff, 82 encoding: encoding 83 }); 84 } 85 /** 86 * Creates a new SmartBuffer instance with the provided SmartBufferOptions options. 87 * 88 * @param options { SmartBufferOptions } The options to use when creating the SmartBuffer instance. 89 */ 90 static fromOptions(options) { 91 return new this(options); 92 } 93 /** 94 * Type checking function that determines if an object is a SmartBufferOptions object. 95 */ 96 static isSmartBufferOptions(options) { 97 const castOptions = options; 98 return (castOptions && 99 (castOptions.encoding !== undefined || castOptions.size !== undefined || castOptions.buff !== undefined)); 100 } 101 // Signed integers 102 /** 103 * Reads an Int8 value from the current read position or an optionally provided offset. 104 * 105 * @param offset { Number } The offset to read data from (optional) 106 * @return { Number } 107 */ 108 readInt8(offset) { 109 return this._readNumberValue(Buffer.prototype.readInt8, 1, offset); 110 } 111 /** 112 * Reads an Int16BE value from the current read position or an optionally provided offset. 113 * 114 * @param offset { Number } The offset to read data from (optional) 115 * @return { Number } 116 */ 117 readInt16BE(offset) { 118 return this._readNumberValue(Buffer.prototype.readInt16BE, 2, offset); 119 } 120 /** 121 * Reads an Int16LE value from the current read position or an optionally provided offset. 122 * 123 * @param offset { Number } The offset to read data from (optional) 124 * @return { Number } 125 */ 126 readInt16LE(offset) { 127 return this._readNumberValue(Buffer.prototype.readInt16LE, 2, offset); 128 } 129 /** 130 * Reads an Int32BE value from the current read position or an optionally provided offset. 131 * 132 * @param offset { Number } The offset to read data from (optional) 133 * @return { Number } 134 */ 135 readInt32BE(offset) { 136 return this._readNumberValue(Buffer.prototype.readInt32BE, 4, offset); 137 } 138 /** 139 * Reads an Int32LE value from the current read position or an optionally provided offset. 140 * 141 * @param offset { Number } The offset to read data from (optional) 142 * @return { Number } 143 */ 144 readInt32LE(offset) { 145 return this._readNumberValue(Buffer.prototype.readInt32LE, 4, offset); 146 } 147 /** 148 * Reads a BigInt64BE value from the current read position or an optionally provided offset. 149 * 150 * @param offset { Number } The offset to read data from (optional) 151 * @return { BigInt } 152 */ 153 readBigInt64BE(offset) { 154 utils_1.bigIntAndBufferInt64Check('readBigInt64BE'); 155 return this._readNumberValue(Buffer.prototype.readBigInt64BE, 8, offset); 156 } 157 /** 158 * Reads a BigInt64LE value from the current read position or an optionally provided offset. 159 * 160 * @param offset { Number } The offset to read data from (optional) 161 * @return { BigInt } 162 */ 163 readBigInt64LE(offset) { 164 utils_1.bigIntAndBufferInt64Check('readBigInt64LE'); 165 return this._readNumberValue(Buffer.prototype.readBigInt64LE, 8, offset); 166 } 167 /** 168 * Writes an Int8 value to the current write position (or at optional offset). 169 * 170 * @param value { Number } The value to write. 171 * @param offset { Number } The offset to write the value at. 172 * 173 * @return this 174 */ 175 writeInt8(value, offset) { 176 this._writeNumberValue(Buffer.prototype.writeInt8, 1, value, offset); 177 return this; 178 } 179 /** 180 * Inserts an Int8 value at the given offset value. 181 * 182 * @param value { Number } The value to insert. 183 * @param offset { Number } The offset to insert the value at. 184 * 185 * @return this 186 */ 187 insertInt8(value, offset) { 188 return this._insertNumberValue(Buffer.prototype.writeInt8, 1, value, offset); 189 } 190 /** 191 * Writes an Int16BE value to the current write position (or at optional offset). 192 * 193 * @param value { Number } The value to write. 194 * @param offset { Number } The offset to write the value at. 195 * 196 * @return this 197 */ 198 writeInt16BE(value, offset) { 199 return this._writeNumberValue(Buffer.prototype.writeInt16BE, 2, value, offset); 200 } 201 /** 202 * Inserts an Int16BE value at the given offset value. 203 * 204 * @param value { Number } The value to insert. 205 * @param offset { Number } The offset to insert the value at. 206 * 207 * @return this 208 */ 209 insertInt16BE(value, offset) { 210 return this._insertNumberValue(Buffer.prototype.writeInt16BE, 2, value, offset); 211 } 212 /** 213 * Writes an Int16LE value to the current write position (or at optional offset). 214 * 215 * @param value { Number } The value to write. 216 * @param offset { Number } The offset to write the value at. 217 * 218 * @return this 219 */ 220 writeInt16LE(value, offset) { 221 return this._writeNumberValue(Buffer.prototype.writeInt16LE, 2, value, offset); 222 } 223 /** 224 * Inserts an Int16LE value at the given offset value. 225 * 226 * @param value { Number } The value to insert. 227 * @param offset { Number } The offset to insert the value at. 228 * 229 * @return this 230 */ 231 insertInt16LE(value, offset) { 232 return this._insertNumberValue(Buffer.prototype.writeInt16LE, 2, value, offset); 233 } 234 /** 235 * Writes an Int32BE value to the current write position (or at optional offset). 236 * 237 * @param value { Number } The value to write. 238 * @param offset { Number } The offset to write the value at. 239 * 240 * @return this 241 */ 242 writeInt32BE(value, offset) { 243 return this._writeNumberValue(Buffer.prototype.writeInt32BE, 4, value, offset); 244 } 245 /** 246 * Inserts an Int32BE value at the given offset value. 247 * 248 * @param value { Number } The value to insert. 249 * @param offset { Number } The offset to insert the value at. 250 * 251 * @return this 252 */ 253 insertInt32BE(value, offset) { 254 return this._insertNumberValue(Buffer.prototype.writeInt32BE, 4, value, offset); 255 } 256 /** 257 * Writes an Int32LE value to the current write position (or at optional offset). 258 * 259 * @param value { Number } The value to write. 260 * @param offset { Number } The offset to write the value at. 261 * 262 * @return this 263 */ 264 writeInt32LE(value, offset) { 265 return this._writeNumberValue(Buffer.prototype.writeInt32LE, 4, value, offset); 266 } 267 /** 268 * Inserts an Int32LE value at the given offset value. 269 * 270 * @param value { Number } The value to insert. 271 * @param offset { Number } The offset to insert the value at. 272 * 273 * @return this 274 */ 275 insertInt32LE(value, offset) { 276 return this._insertNumberValue(Buffer.prototype.writeInt32LE, 4, value, offset); 277 } 278 /** 279 * Writes a BigInt64BE value to the current write position (or at optional offset). 280 * 281 * @param value { BigInt } The value to write. 282 * @param offset { Number } The offset to write the value at. 283 * 284 * @return this 285 */ 286 writeBigInt64BE(value, offset) { 287 utils_1.bigIntAndBufferInt64Check('writeBigInt64BE'); 288 return this._writeNumberValue(Buffer.prototype.writeBigInt64BE, 8, value, offset); 289 } 290 /** 291 * Inserts a BigInt64BE value at the given offset value. 292 * 293 * @param value { BigInt } The value to insert. 294 * @param offset { Number } The offset to insert the value at. 295 * 296 * @return this 297 */ 298 insertBigInt64BE(value, offset) { 299 utils_1.bigIntAndBufferInt64Check('writeBigInt64BE'); 300 return this._insertNumberValue(Buffer.prototype.writeBigInt64BE, 8, value, offset); 301 } 302 /** 303 * Writes a BigInt64LE value to the current write position (or at optional offset). 304 * 305 * @param value { BigInt } The value to write. 306 * @param offset { Number } The offset to write the value at. 307 * 308 * @return this 309 */ 310 writeBigInt64LE(value, offset) { 311 utils_1.bigIntAndBufferInt64Check('writeBigInt64LE'); 312 return this._writeNumberValue(Buffer.prototype.writeBigInt64LE, 8, value, offset); 313 } 314 /** 315 * Inserts a Int64LE value at the given offset value. 316 * 317 * @param value { BigInt } The value to insert. 318 * @param offset { Number } The offset to insert the value at. 319 * 320 * @return this 321 */ 322 insertBigInt64LE(value, offset) { 323 utils_1.bigIntAndBufferInt64Check('writeBigInt64LE'); 324 return this._insertNumberValue(Buffer.prototype.writeBigInt64LE, 8, value, offset); 325 } 326 // Unsigned Integers 327 /** 328 * Reads an UInt8 value from the current read position or an optionally provided offset. 329 * 330 * @param offset { Number } The offset to read data from (optional) 331 * @return { Number } 332 */ 333 readUInt8(offset) { 334 return this._readNumberValue(Buffer.prototype.readUInt8, 1, offset); 335 } 336 /** 337 * Reads an UInt16BE value from the current read position or an optionally provided offset. 338 * 339 * @param offset { Number } The offset to read data from (optional) 340 * @return { Number } 341 */ 342 readUInt16BE(offset) { 343 return this._readNumberValue(Buffer.prototype.readUInt16BE, 2, offset); 344 } 345 /** 346 * Reads an UInt16LE value from the current read position or an optionally provided offset. 347 * 348 * @param offset { Number } The offset to read data from (optional) 349 * @return { Number } 350 */ 351 readUInt16LE(offset) { 352 return this._readNumberValue(Buffer.prototype.readUInt16LE, 2, offset); 353 } 354 /** 355 * Reads an UInt32BE value from the current read position or an optionally provided offset. 356 * 357 * @param offset { Number } The offset to read data from (optional) 358 * @return { Number } 359 */ 360 readUInt32BE(offset) { 361 return this._readNumberValue(Buffer.prototype.readUInt32BE, 4, offset); 362 } 363 /** 364 * Reads an UInt32LE value from the current read position or an optionally provided offset. 365 * 366 * @param offset { Number } The offset to read data from (optional) 367 * @return { Number } 368 */ 369 readUInt32LE(offset) { 370 return this._readNumberValue(Buffer.prototype.readUInt32LE, 4, offset); 371 } 372 /** 373 * Reads a BigUInt64BE value from the current read position or an optionally provided offset. 374 * 375 * @param offset { Number } The offset to read data from (optional) 376 * @return { BigInt } 377 */ 378 readBigUInt64BE(offset) { 379 utils_1.bigIntAndBufferInt64Check('readBigUInt64BE'); 380 return this._readNumberValue(Buffer.prototype.readBigUInt64BE, 8, offset); 381 } 382 /** 383 * Reads a BigUInt64LE value from the current read position or an optionally provided offset. 384 * 385 * @param offset { Number } The offset to read data from (optional) 386 * @return { BigInt } 387 */ 388 readBigUInt64LE(offset) { 389 utils_1.bigIntAndBufferInt64Check('readBigUInt64LE'); 390 return this._readNumberValue(Buffer.prototype.readBigUInt64LE, 8, offset); 391 } 392 /** 393 * Writes an UInt8 value to the current write position (or at optional offset). 394 * 395 * @param value { Number } The value to write. 396 * @param offset { Number } The offset to write the value at. 397 * 398 * @return this 399 */ 400 writeUInt8(value, offset) { 401 return this._writeNumberValue(Buffer.prototype.writeUInt8, 1, value, offset); 402 } 403 /** 404 * Inserts an UInt8 value at the given offset value. 405 * 406 * @param value { Number } The value to insert. 407 * @param offset { Number } The offset to insert the value at. 408 * 409 * @return this 410 */ 411 insertUInt8(value, offset) { 412 return this._insertNumberValue(Buffer.prototype.writeUInt8, 1, value, offset); 413 } 414 /** 415 * Writes an UInt16BE value to the current write position (or at optional offset). 416 * 417 * @param value { Number } The value to write. 418 * @param offset { Number } The offset to write the value at. 419 * 420 * @return this 421 */ 422 writeUInt16BE(value, offset) { 423 return this._writeNumberValue(Buffer.prototype.writeUInt16BE, 2, value, offset); 424 } 425 /** 426 * Inserts an UInt16BE value at the given offset value. 427 * 428 * @param value { Number } The value to insert. 429 * @param offset { Number } The offset to insert the value at. 430 * 431 * @return this 432 */ 433 insertUInt16BE(value, offset) { 434 return this._insertNumberValue(Buffer.prototype.writeUInt16BE, 2, value, offset); 435 } 436 /** 437 * Writes an UInt16LE value to the current write position (or at optional offset). 438 * 439 * @param value { Number } The value to write. 440 * @param offset { Number } The offset to write the value at. 441 * 442 * @return this 443 */ 444 writeUInt16LE(value, offset) { 445 return this._writeNumberValue(Buffer.prototype.writeUInt16LE, 2, value, offset); 446 } 447 /** 448 * Inserts an UInt16LE value at the given offset value. 449 * 450 * @param value { Number } The value to insert. 451 * @param offset { Number } The offset to insert the value at. 452 * 453 * @return this 454 */ 455 insertUInt16LE(value, offset) { 456 return this._insertNumberValue(Buffer.prototype.writeUInt16LE, 2, value, offset); 457 } 458 /** 459 * Writes an UInt32BE value to the current write position (or at optional offset). 460 * 461 * @param value { Number } The value to write. 462 * @param offset { Number } The offset to write the value at. 463 * 464 * @return this 465 */ 466 writeUInt32BE(value, offset) { 467 return this._writeNumberValue(Buffer.prototype.writeUInt32BE, 4, value, offset); 468 } 469 /** 470 * Inserts an UInt32BE value at the given offset value. 471 * 472 * @param value { Number } The value to insert. 473 * @param offset { Number } The offset to insert the value at. 474 * 475 * @return this 476 */ 477 insertUInt32BE(value, offset) { 478 return this._insertNumberValue(Buffer.prototype.writeUInt32BE, 4, value, offset); 479 } 480 /** 481 * Writes an UInt32LE value to the current write position (or at optional offset). 482 * 483 * @param value { Number } The value to write. 484 * @param offset { Number } The offset to write the value at. 485 * 486 * @return this 487 */ 488 writeUInt32LE(value, offset) { 489 return this._writeNumberValue(Buffer.prototype.writeUInt32LE, 4, value, offset); 490 } 491 /** 492 * Inserts an UInt32LE value at the given offset value. 493 * 494 * @param value { Number } The value to insert. 495 * @param offset { Number } The offset to insert the value at. 496 * 497 * @return this 498 */ 499 insertUInt32LE(value, offset) { 500 return this._insertNumberValue(Buffer.prototype.writeUInt32LE, 4, value, offset); 501 } 502 /** 503 * Writes a BigUInt64BE value to the current write position (or at optional offset). 504 * 505 * @param value { Number } The value to write. 506 * @param offset { Number } The offset to write the value at. 507 * 508 * @return this 509 */ 510 writeBigUInt64BE(value, offset) { 511 utils_1.bigIntAndBufferInt64Check('writeBigUInt64BE'); 512 return this._writeNumberValue(Buffer.prototype.writeBigUInt64BE, 8, value, offset); 513 } 514 /** 515 * Inserts a BigUInt64BE value at the given offset value. 516 * 517 * @param value { Number } The value to insert. 518 * @param offset { Number } The offset to insert the value at. 519 * 520 * @return this 521 */ 522 insertBigUInt64BE(value, offset) { 523 utils_1.bigIntAndBufferInt64Check('writeBigUInt64BE'); 524 return this._insertNumberValue(Buffer.prototype.writeBigUInt64BE, 8, value, offset); 525 } 526 /** 527 * Writes a BigUInt64LE value to the current write position (or at optional offset). 528 * 529 * @param value { Number } The value to write. 530 * @param offset { Number } The offset to write the value at. 531 * 532 * @return this 533 */ 534 writeBigUInt64LE(value, offset) { 535 utils_1.bigIntAndBufferInt64Check('writeBigUInt64LE'); 536 return this._writeNumberValue(Buffer.prototype.writeBigUInt64LE, 8, value, offset); 537 } 538 /** 539 * Inserts a BigUInt64LE value at the given offset value. 540 * 541 * @param value { Number } The value to insert. 542 * @param offset { Number } The offset to insert the value at. 543 * 544 * @return this 545 */ 546 insertBigUInt64LE(value, offset) { 547 utils_1.bigIntAndBufferInt64Check('writeBigUInt64LE'); 548 return this._insertNumberValue(Buffer.prototype.writeBigUInt64LE, 8, value, offset); 549 } 550 // Floating Point 551 /** 552 * Reads an FloatBE value from the current read position or an optionally provided offset. 553 * 554 * @param offset { Number } The offset to read data from (optional) 555 * @return { Number } 556 */ 557 readFloatBE(offset) { 558 return this._readNumberValue(Buffer.prototype.readFloatBE, 4, offset); 559 } 560 /** 561 * Reads an FloatLE value from the current read position or an optionally provided offset. 562 * 563 * @param offset { Number } The offset to read data from (optional) 564 * @return { Number } 565 */ 566 readFloatLE(offset) { 567 return this._readNumberValue(Buffer.prototype.readFloatLE, 4, offset); 568 } 569 /** 570 * Writes a FloatBE value to the current write position (or at optional offset). 571 * 572 * @param value { Number } The value to write. 573 * @param offset { Number } The offset to write the value at. 574 * 575 * @return this 576 */ 577 writeFloatBE(value, offset) { 578 return this._writeNumberValue(Buffer.prototype.writeFloatBE, 4, value, offset); 579 } 580 /** 581 * Inserts a FloatBE value at the given offset value. 582 * 583 * @param value { Number } The value to insert. 584 * @param offset { Number } The offset to insert the value at. 585 * 586 * @return this 587 */ 588 insertFloatBE(value, offset) { 589 return this._insertNumberValue(Buffer.prototype.writeFloatBE, 4, value, offset); 590 } 591 /** 592 * Writes a FloatLE value to the current write position (or at optional offset). 593 * 594 * @param value { Number } The value to write. 595 * @param offset { Number } The offset to write the value at. 596 * 597 * @return this 598 */ 599 writeFloatLE(value, offset) { 600 return this._writeNumberValue(Buffer.prototype.writeFloatLE, 4, value, offset); 601 } 602 /** 603 * Inserts a FloatLE value at the given offset value. 604 * 605 * @param value { Number } The value to insert. 606 * @param offset { Number } The offset to insert the value at. 607 * 608 * @return this 609 */ 610 insertFloatLE(value, offset) { 611 return this._insertNumberValue(Buffer.prototype.writeFloatLE, 4, value, offset); 612 } 613 // Double Floating Point 614 /** 615 * Reads an DoublEBE value from the current read position or an optionally provided offset. 616 * 617 * @param offset { Number } The offset to read data from (optional) 618 * @return { Number } 619 */ 620 readDoubleBE(offset) { 621 return this._readNumberValue(Buffer.prototype.readDoubleBE, 8, offset); 622 } 623 /** 624 * Reads an DoubleLE value from the current read position or an optionally provided offset. 625 * 626 * @param offset { Number } The offset to read data from (optional) 627 * @return { Number } 628 */ 629 readDoubleLE(offset) { 630 return this._readNumberValue(Buffer.prototype.readDoubleLE, 8, offset); 631 } 632 /** 633 * Writes a DoubleBE value to the current write position (or at optional offset). 634 * 635 * @param value { Number } The value to write. 636 * @param offset { Number } The offset to write the value at. 637 * 638 * @return this 639 */ 640 writeDoubleBE(value, offset) { 641 return this._writeNumberValue(Buffer.prototype.writeDoubleBE, 8, value, offset); 642 } 643 /** 644 * Inserts a DoubleBE value at the given offset value. 645 * 646 * @param value { Number } The value to insert. 647 * @param offset { Number } The offset to insert the value at. 648 * 649 * @return this 650 */ 651 insertDoubleBE(value, offset) { 652 return this._insertNumberValue(Buffer.prototype.writeDoubleBE, 8, value, offset); 653 } 654 /** 655 * Writes a DoubleLE value to the current write position (or at optional offset). 656 * 657 * @param value { Number } The value to write. 658 * @param offset { Number } The offset to write the value at. 659 * 660 * @return this 661 */ 662 writeDoubleLE(value, offset) { 663 return this._writeNumberValue(Buffer.prototype.writeDoubleLE, 8, value, offset); 664 } 665 /** 666 * Inserts a DoubleLE value at the given offset value. 667 * 668 * @param value { Number } The value to insert. 669 * @param offset { Number } The offset to insert the value at. 670 * 671 * @return this 672 */ 673 insertDoubleLE(value, offset) { 674 return this._insertNumberValue(Buffer.prototype.writeDoubleLE, 8, value, offset); 675 } 676 // Strings 677 /** 678 * Reads a String from the current read position. 679 * 680 * @param arg1 { Number | String } The number of bytes to read as a String, or the BufferEncoding to use for 681 * the string (Defaults to instance level encoding). 682 * @param encoding { String } The BufferEncoding to use for the string (Defaults to instance level encoding). 683 * 684 * @return { String } 685 */ 686 readString(arg1, encoding) { 687 let lengthVal; 688 // Length provided 689 if (typeof arg1 === 'number') { 690 utils_1.checkLengthValue(arg1); 691 lengthVal = Math.min(arg1, this.length - this._readOffset); 692 } 693 else { 694 encoding = arg1; 695 lengthVal = this.length - this._readOffset; 696 } 697 // Check encoding 698 if (typeof encoding !== 'undefined') { 699 utils_1.checkEncoding(encoding); 700 } 701 const value = this._buff.slice(this._readOffset, this._readOffset + lengthVal).toString(encoding || this._encoding); 702 this._readOffset += lengthVal; 703 return value; 704 } 705 /** 706 * Inserts a String 707 * 708 * @param value { String } The String value to insert. 709 * @param offset { Number } The offset to insert the string at. 710 * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). 711 * 712 * @return this 713 */ 714 insertString(value, offset, encoding) { 715 utils_1.checkOffsetValue(offset); 716 return this._handleString(value, true, offset, encoding); 717 } 718 /** 719 * Writes a String 720 * 721 * @param value { String } The String value to write. 722 * @param arg2 { Number | String } The offset to write the string at, or the BufferEncoding to use. 723 * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). 724 * 725 * @return this 726 */ 727 writeString(value, arg2, encoding) { 728 return this._handleString(value, false, arg2, encoding); 729 } 730 /** 731 * Reads a null-terminated String from the current read position. 732 * 733 * @param encoding { String } The BufferEncoding to use for the string (Defaults to instance level encoding). 734 * 735 * @return { String } 736 */ 737 readStringNT(encoding) { 738 if (typeof encoding !== 'undefined') { 739 utils_1.checkEncoding(encoding); 740 } 741 // Set null character position to the end SmartBuffer instance. 742 let nullPos = this.length; 743 // Find next null character (if one is not found, default from above is used) 744 for (let i = this._readOffset; i < this.length; i++) { 745 if (this._buff[i] === 0x00) { 746 nullPos = i; 747 break; 748 } 749 } 750 // Read string value 751 const value = this._buff.slice(this._readOffset, nullPos); 752 // Increment internal Buffer read offset 753 this._readOffset = nullPos + 1; 754 return value.toString(encoding || this._encoding); 755 } 756 /** 757 * Inserts a null-terminated String. 758 * 759 * @param value { String } The String value to write. 760 * @param arg2 { Number | String } The offset to write the string to, or the BufferEncoding to use. 761 * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). 762 * 763 * @return this 764 */ 765 insertStringNT(value, offset, encoding) { 766 utils_1.checkOffsetValue(offset); 767 // Write Values 768 this.insertString(value, offset, encoding); 769 this.insertUInt8(0x00, offset + value.length); 770 return this; 771 } 772 /** 773 * Writes a null-terminated String. 774 * 775 * @param value { String } The String value to write. 776 * @param arg2 { Number | String } The offset to write the string to, or the BufferEncoding to use. 777 * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). 778 * 779 * @return this 780 */ 781 writeStringNT(value, arg2, encoding) { 782 // Write Values 783 this.writeString(value, arg2, encoding); 784 this.writeUInt8(0x00, typeof arg2 === 'number' ? arg2 + value.length : this.writeOffset); 785 return this; 786 } 787 // Buffers 788 /** 789 * Reads a Buffer from the internal read position. 790 * 791 * @param length { Number } The length of data to read as a Buffer. 792 * 793 * @return { Buffer } 794 */ 795 readBuffer(length) { 796 if (typeof length !== 'undefined') { 797 utils_1.checkLengthValue(length); 798 } 799 const lengthVal = typeof length === 'number' ? length : this.length; 800 const endPoint = Math.min(this.length, this._readOffset + lengthVal); 801 // Read buffer value 802 const value = this._buff.slice(this._readOffset, endPoint); 803 // Increment internal Buffer read offset 804 this._readOffset = endPoint; 805 return value; 806 } 807 /** 808 * Writes a Buffer to the current write position. 809 * 810 * @param value { Buffer } The Buffer to write. 811 * @param offset { Number } The offset to write the Buffer to. 812 * 813 * @return this 814 */ 815 insertBuffer(value, offset) { 816 utils_1.checkOffsetValue(offset); 817 return this._handleBuffer(value, true, offset); 818 } 819 /** 820 * Writes a Buffer to the current write position. 821 * 822 * @param value { Buffer } The Buffer to write. 823 * @param offset { Number } The offset to write the Buffer to. 824 * 825 * @return this 826 */ 827 writeBuffer(value, offset) { 828 return this._handleBuffer(value, false, offset); 829 } 830 /** 831 * Reads a null-terminated Buffer from the current read poisiton. 832 * 833 * @return { Buffer } 834 */ 835 readBufferNT() { 836 // Set null character position to the end SmartBuffer instance. 837 let nullPos = this.length; 838 // Find next null character (if one is not found, default from above is used) 839 for (let i = this._readOffset; i < this.length; i++) { 840 if (this._buff[i] === 0x00) { 841 nullPos = i; 842 break; 843 } 844 } 845 // Read value 846 const value = this._buff.slice(this._readOffset, nullPos); 847 // Increment internal Buffer read offset 848 this._readOffset = nullPos + 1; 849 return value; 850 } 851 /** 852 * Inserts a null-terminated Buffer. 853 * 854 * @param value { Buffer } The Buffer to write. 855 * @param offset { Number } The offset to write the Buffer to. 856 * 857 * @return this 858 */ 859 insertBufferNT(value, offset) { 860 utils_1.checkOffsetValue(offset); 861 // Write Values 862 this.insertBuffer(value, offset); 863 this.insertUInt8(0x00, offset + value.length); 864 return this; 865 } 866 /** 867 * Writes a null-terminated Buffer. 868 * 869 * @param value { Buffer } The Buffer to write. 870 * @param offset { Number } The offset to write the Buffer to. 871 * 872 * @return this 873 */ 874 writeBufferNT(value, offset) { 875 // Checks for valid numberic value; 876 if (typeof offset !== 'undefined') { 877 utils_1.checkOffsetValue(offset); 878 } 879 // Write Values 880 this.writeBuffer(value, offset); 881 this.writeUInt8(0x00, typeof offset === 'number' ? offset + value.length : this._writeOffset); 882 return this; 883 } 884 /** 885 * Clears the SmartBuffer instance to its original empty state. 886 */ 887 clear() { 888 this._writeOffset = 0; 889 this._readOffset = 0; 890 this.length = 0; 891 return this; 892 } 893 /** 894 * Gets the remaining data left to be read from the SmartBuffer instance. 895 * 896 * @return { Number } 897 */ 898 remaining() { 899 return this.length - this._readOffset; 900 } 901 /** 902 * Gets the current read offset value of the SmartBuffer instance. 903 * 904 * @return { Number } 905 */ 906 get readOffset() { 907 return this._readOffset; 908 } 909 /** 910 * Sets the read offset value of the SmartBuffer instance. 911 * 912 * @param offset { Number } - The offset value to set. 913 */ 914 set readOffset(offset) { 915 utils_1.checkOffsetValue(offset); 916 // Check for bounds. 917 utils_1.checkTargetOffset(offset, this); 918 this._readOffset = offset; 919 } 920 /** 921 * Gets the current write offset value of the SmartBuffer instance. 922 * 923 * @return { Number } 924 */ 925 get writeOffset() { 926 return this._writeOffset; 927 } 928 /** 929 * Sets the write offset value of the SmartBuffer instance. 930 * 931 * @param offset { Number } - The offset value to set. 932 */ 933 set writeOffset(offset) { 934 utils_1.checkOffsetValue(offset); 935 // Check for bounds. 936 utils_1.checkTargetOffset(offset, this); 937 this._writeOffset = offset; 938 } 939 /** 940 * Gets the currently set string encoding of the SmartBuffer instance. 941 * 942 * @return { BufferEncoding } The string Buffer encoding currently set. 943 */ 944 get encoding() { 945 return this._encoding; 946 } 947 /** 948 * Sets the string encoding of the SmartBuffer instance. 949 * 950 * @param encoding { BufferEncoding } The string Buffer encoding to set. 951 */ 952 set encoding(encoding) { 953 utils_1.checkEncoding(encoding); 954 this._encoding = encoding; 955 } 956 /** 957 * Gets the underlying internal Buffer. (This includes unmanaged data in the Buffer) 958 * 959 * @return { Buffer } The Buffer value. 960 */ 961 get internalBuffer() { 962 return this._buff; 963 } 964 /** 965 * Gets the value of the internal managed Buffer (Includes managed data only) 966 * 967 * @param { Buffer } 968 */ 969 toBuffer() { 970 return this._buff.slice(0, this.length); 971 } 972 /** 973 * Gets the String value of the internal managed Buffer 974 * 975 * @param encoding { String } The BufferEncoding to display the Buffer as (defaults to instance level encoding). 976 */ 977 toString(encoding) { 978 const encodingVal = typeof encoding === 'string' ? encoding : this._encoding; 979 // Check for invalid encoding. 980 utils_1.checkEncoding(encodingVal); 981 return this._buff.toString(encodingVal, 0, this.length); 982 } 983 /** 984 * Destroys the SmartBuffer instance. 985 */ 986 destroy() { 987 this.clear(); 988 return this; 989 } 990 /** 991 * Handles inserting and writing strings. 992 * 993 * @param value { String } The String value to insert. 994 * @param isInsert { Boolean } True if inserting a string, false if writing. 995 * @param arg2 { Number | String } The offset to insert the string at, or the BufferEncoding to use. 996 * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). 997 */ 998 _handleString(value, isInsert, arg3, encoding) { 999 let offsetVal = this._writeOffset; 1000 let encodingVal = this._encoding; 1001 // Check for offset 1002 if (typeof arg3 === 'number') { 1003 offsetVal = arg3; 1004 // Check for encoding 1005 } 1006 else if (typeof arg3 === 'string') { 1007 utils_1.checkEncoding(arg3); 1008 encodingVal = arg3; 1009 } 1010 // Check for encoding (third param) 1011 if (typeof encoding === 'string') { 1012 utils_1.checkEncoding(encoding); 1013 encodingVal = encoding; 1014 } 1015 // Calculate bytelength of string. 1016 const byteLength = Buffer.byteLength(value, encodingVal); 1017 // Ensure there is enough internal Buffer capacity. 1018 if (isInsert) { 1019 this.ensureInsertable(byteLength, offsetVal); 1020 } 1021 else { 1022 this._ensureWriteable(byteLength, offsetVal); 1023 } 1024 // Write value 1025 this._buff.write(value, offsetVal, byteLength, encodingVal); 1026 // Increment internal Buffer write offset; 1027 if (isInsert) { 1028 this._writeOffset += byteLength; 1029 } 1030 else { 1031 // If an offset was given, check to see if we wrote beyond the current writeOffset. 1032 if (typeof arg3 === 'number') { 1033 this._writeOffset = Math.max(this._writeOffset, offsetVal + byteLength); 1034 } 1035 else { 1036 // If no offset was given, we wrote to the end of the SmartBuffer so increment writeOffset. 1037 this._writeOffset += byteLength; 1038 } 1039 } 1040 return this; 1041 } 1042 /** 1043 * Handles writing or insert of a Buffer. 1044 * 1045 * @param value { Buffer } The Buffer to write. 1046 * @param offset { Number } The offset to write the Buffer to. 1047 */ 1048 _handleBuffer(value, isInsert, offset) { 1049 const offsetVal = typeof offset === 'number' ? offset : this._writeOffset; 1050 // Ensure there is enough internal Buffer capacity. 1051 if (isInsert) { 1052 this.ensureInsertable(value.length, offsetVal); 1053 } 1054 else { 1055 this._ensureWriteable(value.length, offsetVal); 1056 } 1057 // Write buffer value 1058 value.copy(this._buff, offsetVal); 1059 // Increment internal Buffer write offset; 1060 if (isInsert) { 1061 this._writeOffset += value.length; 1062 } 1063 else { 1064 // If an offset was given, check to see if we wrote beyond the current writeOffset. 1065 if (typeof offset === 'number') { 1066 this._writeOffset = Math.max(this._writeOffset, offsetVal + value.length); 1067 } 1068 else { 1069 // If no offset was given, we wrote to the end of the SmartBuffer so increment writeOffset. 1070 this._writeOffset += value.length; 1071 } 1072 } 1073 return this; 1074 } 1075 /** 1076 * Ensures that the internal Buffer is large enough to read data. 1077 * 1078 * @param length { Number } The length of the data that needs to be read. 1079 * @param offset { Number } The offset of the data that needs to be read. 1080 */ 1081 ensureReadable(length, offset) { 1082 // Offset value defaults to managed read offset. 1083 let offsetVal = this._readOffset; 1084 // If an offset was provided, use it. 1085 if (typeof offset !== 'undefined') { 1086 // Checks for valid numberic value; 1087 utils_1.checkOffsetValue(offset); 1088 // Overide with custom offset. 1089 offsetVal = offset; 1090 } 1091 // Checks if offset is below zero, or the offset+length offset is beyond the total length of the managed data. 1092 if (offsetVal < 0 || offsetVal + length > this.length) { 1093 throw new Error(utils_1.ERRORS.INVALID_READ_BEYOND_BOUNDS); 1094 } 1095 } 1096 /** 1097 * Ensures that the internal Buffer is large enough to insert data. 1098 * 1099 * @param dataLength { Number } The length of the data that needs to be written. 1100 * @param offset { Number } The offset of the data to be written. 1101 */ 1102 ensureInsertable(dataLength, offset) { 1103 // Checks for valid numberic value; 1104 utils_1.checkOffsetValue(offset); 1105 // Ensure there is enough internal Buffer capacity. 1106 this._ensureCapacity(this.length + dataLength); 1107 // If an offset was provided and its not the very end of the buffer, copy data into appropriate location in regards to the offset. 1108 if (offset < this.length) { 1109 this._buff.copy(this._buff, offset + dataLength, offset, this._buff.length); 1110 } 1111 // Adjust tracked smart buffer length 1112 if (offset + dataLength > this.length) { 1113 this.length = offset + dataLength; 1114 } 1115 else { 1116 this.length += dataLength; 1117 } 1118 } 1119 /** 1120 * Ensures that the internal Buffer is large enough to write data. 1121 * 1122 * @param dataLength { Number } The length of the data that needs to be written. 1123 * @param offset { Number } The offset of the data to be written (defaults to writeOffset). 1124 */ 1125 _ensureWriteable(dataLength, offset) { 1126 const offsetVal = typeof offset === 'number' ? offset : this._writeOffset; 1127 // Ensure enough capacity to write data. 1128 this._ensureCapacity(offsetVal + dataLength); 1129 // Adjust SmartBuffer length (if offset + length is larger than managed length, adjust length) 1130 if (offsetVal + dataLength > this.length) { 1131 this.length = offsetVal + dataLength; 1132 } 1133 } 1134 /** 1135 * Ensures that the internal Buffer is large enough to write at least the given amount of data. 1136 * 1137 * @param minLength { Number } The minimum length of the data needs to be written. 1138 */ 1139 _ensureCapacity(minLength) { 1140 const oldLength = this._buff.length; 1141 if (minLength > oldLength) { 1142 let data = this._buff; 1143 let newLength = (oldLength * 3) / 2 + 1; 1144 if (newLength < minLength) { 1145 newLength = minLength; 1146 } 1147 this._buff = Buffer.allocUnsafe(newLength); 1148 data.copy(this._buff, 0, 0, oldLength); 1149 } 1150 } 1151 /** 1152 * Reads a numeric number value using the provided function. 1153 * 1154 * @typeparam T { number | bigint } The type of the value to be read 1155 * 1156 * @param func { Function(offset: number) => number } The function to read data on the internal Buffer with. 1157 * @param byteSize { Number } The number of bytes read. 1158 * @param offset { Number } The offset to read from (optional). When this is not provided, the managed readOffset is used instead. 1159 * 1160 * @returns { T } the number value 1161 */ 1162 _readNumberValue(func, byteSize, offset) { 1163 this.ensureReadable(byteSize, offset); 1164 // Call Buffer.readXXXX(); 1165 const value = func.call(this._buff, typeof offset === 'number' ? offset : this._readOffset); 1166 // Adjust internal read offset if an optional read offset was not provided. 1167 if (typeof offset === 'undefined') { 1168 this._readOffset += byteSize; 1169 } 1170 return value; 1171 } 1172 /** 1173 * Inserts a numeric number value based on the given offset and value. 1174 * 1175 * @typeparam T { number | bigint } The type of the value to be written 1176 * 1177 * @param func { Function(offset: T, offset?) => number} The function to write data on the internal Buffer with. 1178 * @param byteSize { Number } The number of bytes written. 1179 * @param value { T } The number value to write. 1180 * @param offset { Number } the offset to write the number at (REQUIRED). 1181 * 1182 * @returns SmartBuffer this buffer 1183 */ 1184 _insertNumberValue(func, byteSize, value, offset) { 1185 // Check for invalid offset values. 1186 utils_1.checkOffsetValue(offset); 1187 // Ensure there is enough internal Buffer capacity. (raw offset is passed) 1188 this.ensureInsertable(byteSize, offset); 1189 // Call buffer.writeXXXX(); 1190 func.call(this._buff, value, offset); 1191 // Adjusts internally managed write offset. 1192 this._writeOffset += byteSize; 1193 return this; 1194 } 1195 /** 1196 * Writes a numeric number value based on the given offset and value. 1197 * 1198 * @typeparam T { number | bigint } The type of the value to be written 1199 * 1200 * @param func { Function(offset: T, offset?) => number} The function to write data on the internal Buffer with. 1201 * @param byteSize { Number } The number of bytes written. 1202 * @param value { T } The number value to write. 1203 * @param offset { Number } the offset to write the number at (REQUIRED). 1204 * 1205 * @returns SmartBuffer this buffer 1206 */ 1207 _writeNumberValue(func, byteSize, value, offset) { 1208 // If an offset was provided, validate it. 1209 if (typeof offset === 'number') { 1210 // Check if we're writing beyond the bounds of the managed data. 1211 if (offset < 0) { 1212 throw new Error(utils_1.ERRORS.INVALID_WRITE_BEYOND_BOUNDS); 1213 } 1214 utils_1.checkOffsetValue(offset); 1215 } 1216 // Default to writeOffset if no offset value was given. 1217 const offsetVal = typeof offset === 'number' ? offset : this._writeOffset; 1218 // Ensure there is enough internal Buffer capacity. (raw offset is passed) 1219 this._ensureWriteable(byteSize, offsetVal); 1220 func.call(this._buff, value, offsetVal); 1221 // If an offset was given, check to see if we wrote beyond the current writeOffset. 1222 if (typeof offset === 'number') { 1223 this._writeOffset = Math.max(this._writeOffset, offsetVal + byteSize); 1224 } 1225 else { 1226 // If no numeric offset was given, we wrote to the end of the SmartBuffer so increment writeOffset. 1227 this._writeOffset += byteSize; 1228 } 1229 return this; 1230 } 1231} 1232exports.SmartBuffer = SmartBuffer; 1233//# sourceMappingURL=smartbuffer.js.map