smartbuffer.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. "use strict";
  2. // The default Buffer size if one is not provided.
  3. const DEFAULT_SMARTBUFFER_SIZE = 4096;
  4. // The default string encoding to use for reading/writing strings.
  5. const DEFAULT_SMARTBUFFER_ENCODING = 'utf8';
  6. class SmartBuffer {
  7. /**
  8. * Creates a new SmartBuffer instance.
  9. *
  10. * @param arg1 { Number | BufferEncoding | Buffer | SmartBufferOptions }
  11. * @param arg2 { BufferEncoding }
  12. */
  13. constructor(arg1, arg2) {
  14. this.length = 0;
  15. this.encoding = DEFAULT_SMARTBUFFER_ENCODING;
  16. this.writeOffset = 0;
  17. this.readOffset = 0;
  18. // Initial buffer size provided
  19. if (typeof arg1 === 'number') {
  20. if (Number.isFinite(arg1) && Number.isInteger(arg1) && arg1 > 0) {
  21. this.buff = Buffer.allocUnsafe(arg1);
  22. }
  23. else {
  24. throw new Error('Invalid size provided. Size must be a valid integer greater than zero.');
  25. }
  26. }
  27. else if (typeof arg1 === 'string') {
  28. if (Buffer.isEncoding(arg1)) {
  29. this.buff = Buffer.allocUnsafe(DEFAULT_SMARTBUFFER_SIZE);
  30. this.encoding = arg1;
  31. }
  32. else {
  33. throw new Error('Invalid encoding provided. Please specify a valid encoding the internal Node.js Buffer supports.');
  34. }
  35. }
  36. else if (arg1 instanceof Buffer) {
  37. this.buff = arg1;
  38. this.length = arg1.length;
  39. }
  40. else if (SmartBuffer.isSmartBufferOptions(arg1)) {
  41. // Checks for encoding
  42. if (arg1.encoding) {
  43. if (Buffer.isEncoding(arg1.encoding)) {
  44. this.encoding = arg1.encoding;
  45. }
  46. else {
  47. throw new Error('Invalid encoding provided. Please specify a valid encoding the internal Node.js Buffer supports.');
  48. }
  49. }
  50. // Checks for initial size length
  51. if (arg1.size) {
  52. if (Number.isFinite(arg1.size) && Number.isInteger(arg1.size) && arg1.size > 0) {
  53. this.buff = Buffer.allocUnsafe(arg1.size);
  54. }
  55. else {
  56. throw new Error('Invalid size provided. Size must be a valid integer greater than zero.');
  57. }
  58. }
  59. else if (arg1.buff) {
  60. if (arg1.buff instanceof Buffer) {
  61. this.buff = arg1.buff;
  62. this.length = arg1.buff.length;
  63. }
  64. else {
  65. throw new Error('Invalid buffer provided in SmartBufferOptions.');
  66. }
  67. }
  68. else {
  69. this.buff = Buffer.allocUnsafe(DEFAULT_SMARTBUFFER_SIZE);
  70. }
  71. }
  72. else if (typeof arg1 === 'object') {
  73. throw new Error('Invalid object supplied to SmartBuffer constructor.');
  74. }
  75. else {
  76. this.buff = Buffer.allocUnsafe(DEFAULT_SMARTBUFFER_SIZE);
  77. }
  78. // Check for encoding (Buffer, Encoding) constructor.
  79. if (typeof arg2 === 'string') {
  80. if (Buffer.isEncoding(arg2)) {
  81. this.encoding = arg2;
  82. }
  83. else {
  84. throw new Error('Invalid encoding provided. Please specify a valid encoding the internal Node.js Buffer supports.');
  85. }
  86. }
  87. }
  88. /**
  89. * Creates a new SmartBuffer instance with the provided internal Buffer size and optional encoding.
  90. *
  91. * @param size { Number } The size of the internal Buffer.
  92. * @param encoding { String } The BufferEncoding to use for strings.
  93. *
  94. * @return { SmartBuffer }
  95. */
  96. static fromSize(size, encoding) {
  97. return new this({
  98. size: size,
  99. encoding: encoding
  100. });
  101. }
  102. /**
  103. * Creates a new SmartBuffer instance with the provided Buffer and optional encoding.
  104. *
  105. * @param buffer { Buffer } The Buffer to use as the internal Buffer value.
  106. * @param encoding { String } The BufferEncoding to use for strings.
  107. *
  108. * @return { SmartBuffer }
  109. */
  110. static fromBuffer(buff, encoding) {
  111. return new this({
  112. buff: buff,
  113. encoding: encoding
  114. });
  115. }
  116. /**
  117. * Creates a new SmartBuffer instance with the provided SmartBufferOptions options.
  118. *
  119. * @param options { SmartBufferOptions } The options to use when creating the SmartBuffer instance.
  120. */
  121. static fromOptions(options) {
  122. return new this(options);
  123. }
  124. /**
  125. * Ensures that the internal Buffer is large enough to write data.
  126. *
  127. * @param minLength { Number } The minimum length of the data that needs to be written.
  128. * @param offset { Number } The offset of the data to be written.
  129. */
  130. ensureWriteable(minLength, offset) {
  131. const offsetVal = typeof offset === 'number' ? offset : 0;
  132. // Ensure there is enough internal Buffer capacity.
  133. this.ensureCapacity(this.length + minLength + offsetVal);
  134. // If offset is provided, copy data into appropriate location in regards to the offset.
  135. if (typeof offset === 'number') {
  136. this.buff.copy(this.buff, offsetVal + minLength, offsetVal, this.buff.length);
  137. }
  138. // Adjust instance length.
  139. this.length = Math.max(this.length + minLength, offsetVal + minLength);
  140. }
  141. /**
  142. * Ensures that the internal Buffer is large enough to write at least the given amount of data.
  143. *
  144. * @param minLength { Number } The minimum length of the data needs to be written.
  145. */
  146. ensureCapacity(minLength) {
  147. const oldLength = this.buff.length;
  148. if (minLength > oldLength) {
  149. let data = this.buff;
  150. let newLength = (oldLength * 3) / 2 + 1;
  151. if (newLength < minLength) {
  152. newLength = minLength;
  153. }
  154. this.buff = Buffer.allocUnsafe(newLength);
  155. data.copy(this.buff, 0, 0, oldLength);
  156. }
  157. }
  158. /**
  159. * Reads a numeric number value using the provided function.
  160. *
  161. * @param func { Function(offset: number) => number } The function to read data on the internal Buffer with.
  162. * @param byteSize { Number } The number of bytes read.
  163. *
  164. * @param { Number }
  165. */
  166. readNumberValue(func, byteSize) {
  167. // Call Buffer.readXXXX();
  168. const value = func.call(this.buff, this.readOffset);
  169. // Adjust internal read offset
  170. this.readOffset += byteSize;
  171. return value;
  172. }
  173. /**
  174. * Writes a numeric number value using the provided function.
  175. *
  176. * @param func { Function(offset: number, offset?) => number} The function to write data on the internal Buffer with.
  177. * @param byteSize { Number } The number of bytes written.
  178. * @param value { Number } The number value to write.
  179. * @param offset { Number } the offset to write the number at.
  180. *
  181. */
  182. writeNumberValue(func, byteSize, value, offset) {
  183. const offsetVal = typeof offset === 'number' ? offset : this.writeOffset;
  184. // Ensure there is enough internal Buffer capacity. (raw offset is passed)
  185. this.ensureWriteable(byteSize, offset);
  186. // Call buffer.writeXXXX();
  187. func.call(this.buff, value, offsetVal);
  188. // Adjusts internal write offset
  189. this.writeOffset += byteSize;
  190. }
  191. // Signed integers
  192. /**
  193. * Reads an Int8 value from the current read position.
  194. *
  195. * @return { Number }
  196. */
  197. readInt8() {
  198. return this.readNumberValue(Buffer.prototype.readUInt8, 1);
  199. }
  200. /**
  201. * Reads an Int16BE value from the current read position.
  202. *
  203. * @return { Number }
  204. */
  205. readInt16BE() {
  206. return this.readNumberValue(Buffer.prototype.readUInt16BE, 2);
  207. }
  208. /**
  209. * Reads an Int16LE value from the current read position.
  210. *
  211. * @return { Number }
  212. */
  213. readInt16LE() {
  214. return this.readNumberValue(Buffer.prototype.readUInt16LE, 2);
  215. }
  216. /**
  217. * Reads an Int32BE value from the current read position.
  218. *
  219. * @return { Number }
  220. */
  221. readInt32BE() {
  222. return this.readNumberValue(Buffer.prototype.readUInt32BE, 4);
  223. }
  224. /**
  225. * Reads an Int32LE value from the current read position.
  226. *
  227. * @return { Number }
  228. */
  229. readInt32LE() {
  230. return this.readNumberValue(Buffer.prototype.readUInt32LE, 4);
  231. }
  232. /**
  233. * Writes an Int8 value to the current write position (or at optional offset).
  234. *
  235. * @param value { Number } The value to write.
  236. * @param offset { Number } The offset to write the value at.
  237. *
  238. * @return this
  239. */
  240. writeInt8(value, offset) {
  241. this.writeNumberValue(Buffer.prototype.writeInt8, 1, value, offset);
  242. return this;
  243. }
  244. /**
  245. * Writes an Int16BE value to the current write position (or at optional offset).
  246. *
  247. * @param value { Number } The value to write.
  248. * @param offset { Number } The offset to write the value at.
  249. *
  250. * @return this
  251. */
  252. writeInt16BE(value, offset) {
  253. this.writeNumberValue(Buffer.prototype.writeInt16BE, 2, value, offset);
  254. return this;
  255. }
  256. /**
  257. * Writes an Int16LE 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. writeInt16LE(value, offset) {
  265. this.writeNumberValue(Buffer.prototype.writeInt16LE, 2, value, offset);
  266. return this;
  267. }
  268. /**
  269. * Writes an Int32BE value to the current write position (or at optional offset).
  270. *
  271. * @param value { Number } The value to write.
  272. * @param offset { Number } The offset to write the value at.
  273. *
  274. * @return this
  275. */
  276. writeInt32BE(value, offset) {
  277. this.writeNumberValue(Buffer.prototype.writeInt32BE, 4, value, offset);
  278. return this;
  279. }
  280. /**
  281. * Writes an Int32LE value to the current write position (or at optional offset).
  282. *
  283. * @param value { Number } The value to write.
  284. * @param offset { Number } The offset to write the value at.
  285. *
  286. * @return this
  287. */
  288. writeInt32LE(value, offset) {
  289. this.writeNumberValue(Buffer.prototype.writeInt32LE, 4, value, offset);
  290. return this;
  291. }
  292. // Unsigned Integers
  293. /**
  294. * Reads an UInt8 value from the current read position.
  295. *
  296. * @return { Number }
  297. */
  298. readUInt8() {
  299. return this.readNumberValue(Buffer.prototype.readUInt8, 1);
  300. }
  301. /**
  302. * Reads an UInt16BE value from the current read position.
  303. *
  304. * @return { Number }
  305. */
  306. readUInt16BE() {
  307. return this.readNumberValue(Buffer.prototype.readUInt16BE, 2);
  308. }
  309. /**
  310. * Reads an UInt16LE value from the current read position.
  311. *
  312. * @return { Number }
  313. */
  314. readUInt16LE() {
  315. return this.readNumberValue(Buffer.prototype.readUInt16LE, 2);
  316. }
  317. /**
  318. * Reads an UInt32BE value from the current read position.
  319. *
  320. * @return { Number }
  321. */
  322. readUInt32BE() {
  323. return this.readNumberValue(Buffer.prototype.readUInt32BE, 4);
  324. }
  325. /**
  326. * Reads an UInt32LE value from the current read position.
  327. *
  328. * @return { Number }
  329. */
  330. readUInt32LE() {
  331. return this.readNumberValue(Buffer.prototype.readUInt32LE, 4);
  332. }
  333. /**
  334. * Writes an UInt8 value to the current write position (or at optional offset).
  335. *
  336. * @param value { Number } The value to write.
  337. * @param offset { Number } The offset to write the value at.
  338. *
  339. * @return this
  340. */
  341. writeUInt8(value, offset) {
  342. this.writeNumberValue(Buffer.prototype.writeUInt8, 1, value, offset);
  343. return this;
  344. }
  345. /**
  346. * Writes an UInt16BE value to the current write position (or at optional offset).
  347. *
  348. * @param value { Number } The value to write.
  349. * @param offset { Number } The offset to write the value at.
  350. *
  351. * @return this
  352. */
  353. writeUInt16BE(value, offset) {
  354. this.writeNumberValue(Buffer.prototype.writeUInt16BE, 2, value, offset);
  355. return this;
  356. }
  357. /**
  358. * Writes an UInt16LE value to the current write position (or at optional offset).
  359. *
  360. * @param value { Number } The value to write.
  361. * @param offset { Number } The offset to write the value at.
  362. *
  363. * @return this
  364. */
  365. writeUInt16LE(value, offset) {
  366. this.writeNumberValue(Buffer.prototype.writeUInt16LE, 2, value, offset);
  367. return this;
  368. }
  369. /**
  370. * Writes an UInt32BE value to the current write position (or at optional offset).
  371. *
  372. * @param value { Number } The value to write.
  373. * @param offset { Number } The offset to write the value at.
  374. *
  375. * @return this
  376. */
  377. writeUInt32BE(value, offset) {
  378. this.writeNumberValue(Buffer.prototype.writeUInt32BE, 4, value, offset);
  379. return this;
  380. }
  381. /**
  382. * Writes an UInt32LE value to the current write position (or at optional offset).
  383. *
  384. * @param value { Number } The value to write.
  385. * @param offset { Number } The offset to write the value at.
  386. *
  387. * @return this
  388. */
  389. writeUInt32LE(value, offset) {
  390. this.writeNumberValue(Buffer.prototype.writeUInt32LE, 4, value, offset);
  391. return this;
  392. }
  393. // Floating Point
  394. /**
  395. * Reads an FloatBE value from the current read position.
  396. *
  397. * @return { Number }
  398. */
  399. readFloatBE() {
  400. return this.readNumberValue(Buffer.prototype.readFloatBE, 4);
  401. }
  402. /**
  403. * Reads an FloatLE value from the current read position.
  404. *
  405. * @return { Number }
  406. */
  407. readFloatLE() {
  408. return this.readNumberValue(Buffer.prototype.readFloatLE, 4);
  409. }
  410. /**
  411. * Writes a FloatBE value to the current write position (or at optional offset).
  412. *
  413. * @param value { Number } The value to write.
  414. * @param offset { Number } The offset to write the value at.
  415. *
  416. * @return this
  417. */
  418. writeFloatBE(value, offset) {
  419. this.writeNumberValue(Buffer.prototype.writeFloatBE, 4, value, offset);
  420. return this;
  421. }
  422. /**
  423. * Writes a FloatLE value to the current write position (or at optional offset).
  424. *
  425. * @param value { Number } The value to write.
  426. * @param offset { Number } The offset to write the value at.
  427. *
  428. * @return this
  429. */
  430. writeFloatLE(value, offset) {
  431. this.writeNumberValue(Buffer.prototype.writeFloatLE, 4, value, offset);
  432. return this;
  433. }
  434. // Double Floating Point
  435. /**
  436. * Reads an DoublEBE value from the current read position.
  437. *
  438. * @return { Number }
  439. */
  440. readDoubleBE() {
  441. return this.readNumberValue(Buffer.prototype.readDoubleBE, 8);
  442. }
  443. /**
  444. * Reads an DoubleLE value from the current read position.
  445. *
  446. * @return { Number }
  447. */
  448. readDoubleLE() {
  449. return this.readNumberValue(Buffer.prototype.readDoubleLE, 8);
  450. }
  451. /**
  452. * Writes a DoubleBE value to the current write position (or at optional offset).
  453. *
  454. * @param value { Number } The value to write.
  455. * @param offset { Number } The offset to write the value at.
  456. *
  457. * @return this
  458. */
  459. writeDoubleBE(value, offset) {
  460. this.writeNumberValue(Buffer.prototype.writeDoubleBE, 8, value, offset);
  461. return this;
  462. }
  463. /**
  464. * Writes a DoubleLE value to the current write position (or at optional offset).
  465. *
  466. * @param value { Number } The value to write.
  467. * @param offset { Number } The offset to write the value at.
  468. *
  469. * @return this
  470. */
  471. writeDoubleLE(value, offset) {
  472. this.writeNumberValue(Buffer.prototype.writeDoubleLE, 8, value, offset);
  473. return this;
  474. }
  475. // Strings
  476. /**
  477. * Reads a String from the current read position.
  478. *
  479. * @param length { Number } The number of bytes to read as a String.
  480. * @param encoding { String } The BufferEncoding to use for the string (Defaults to instance level encoding).
  481. *
  482. * @return { String }
  483. */
  484. readString(length, encoding) {
  485. const lengthVal = Math.min(length, this.length - this.readOffset) || this.length - this.readOffset;
  486. const value = this.buff.slice(this.readOffset, this.readOffset + lengthVal).toString(encoding || this.encoding);
  487. this.readOffset += lengthVal;
  488. return value;
  489. }
  490. /**
  491. * Writes a String to the current write position.
  492. *
  493. * @param value { String } The String value to write.
  494. * @param arg2 { Number | String } The offset to write the string to, or the BufferEncoding to use.
  495. * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding).
  496. */
  497. writeString(value, arg2, encoding) {
  498. let offsetVal = this.writeOffset;
  499. let encodingVal = this.encoding;
  500. // Check for offset
  501. if (typeof arg2 === 'number') {
  502. offsetVal = arg2;
  503. }
  504. else if (typeof arg2 === 'string') {
  505. if (Buffer.isEncoding(arg2)) {
  506. encodingVal = arg2;
  507. }
  508. else {
  509. throw new Error('Invalid encoding provided. Please specify a valid encoding the internal Node.js Buffer supports.');
  510. }
  511. }
  512. // Check for encoding (third param)
  513. if (typeof encoding === 'string') {
  514. if (Buffer.isEncoding(encoding)) {
  515. encodingVal = encoding;
  516. }
  517. else {
  518. throw new Error('Invalid encoding provided. Please specify a valid encoding the internal Node.js Buffer supports.');
  519. }
  520. }
  521. // Calculate bytelength of string.
  522. const byteLength = Buffer.byteLength(value, encodingVal);
  523. // Ensure there is enough internal Buffer capacity.
  524. this.ensureWriteable(byteLength, offsetVal);
  525. // Write value
  526. this.buff.write(value, offsetVal, byteLength, encodingVal);
  527. // Increment internal Buffer write offset;
  528. this.writeOffset += byteLength;
  529. return this;
  530. }
  531. /**
  532. * Reads a null-terminated String from the current read position.
  533. *
  534. * @param encoding { String } The BufferEncoding to use for the string (Defaults to instance level encoding).
  535. *
  536. * @return { String }
  537. */
  538. readStringNT(encoding) {
  539. // Set null character position to the end SmartBuffer instance.
  540. let nullPos = this.length;
  541. // Find next null character (if one is not found, default from above is used)
  542. for (let i = this.readOffset; i < this.length; i++) {
  543. if (this.buff[i] === 0x00) {
  544. nullPos = i;
  545. break;
  546. }
  547. }
  548. // Read string value
  549. const value = this.buff.slice(this.readOffset, nullPos);
  550. // Increment internal Buffer read offset
  551. this.readOffset = nullPos + 1;
  552. return value.toString(encoding || this.encoding);
  553. }
  554. /**
  555. * Writes a null-terminated String to the current write position.
  556. *
  557. * @param value { String } The String value to write.
  558. * @param arg2 { Number | String } The offset to write the string to, or the BufferEncoding to use.
  559. * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding).
  560. */
  561. writeStringNT(value, offset, encoding) {
  562. // Write Values
  563. this.writeString(value, offset, encoding);
  564. this.writeUInt8(0x00, (typeof offset === 'number' ? offset + value.length : this.writeOffset));
  565. }
  566. // Buffers
  567. /**
  568. * Reads a Buffer from the internal read position.
  569. *
  570. * @param length { Number } The length of data to read as a Buffer.
  571. *
  572. * @return { Buffer }
  573. */
  574. readBuffer(length) {
  575. const lengthVal = typeof length === 'number' ? length : this.length;
  576. const endPoint = Math.min(this.length, this.readOffset + lengthVal);
  577. // Read buffer value
  578. const value = this.buff.slice(this.readOffset, endPoint);
  579. // Increment internal Buffer read offset
  580. this.readOffset = endPoint;
  581. return value;
  582. }
  583. /**
  584. * Writes a Buffer to the current write position.
  585. *
  586. * @param value { Buffer } The Buffer to write.
  587. * @param offset { Number } The offset to write the Buffer to.
  588. */
  589. writeBuffer(value, offset) {
  590. const offsetVal = typeof offset === 'number' ? offset : this.writeOffset;
  591. // Ensure there is enough internal Buffer capacity.
  592. this.ensureWriteable(value.length, offsetVal);
  593. // Write buffer value
  594. value.copy(this.buff, offsetVal);
  595. // Increment internal Buffer write offset
  596. this.writeOffset += value.length;
  597. return this;
  598. }
  599. /**
  600. * Reads a null-terminated Buffer from the current read poisiton.
  601. *
  602. * @return { Buffer }
  603. */
  604. readBufferNT() {
  605. // Set null character position to the end SmartBuffer instance.
  606. let nullPos = this.length;
  607. // Find next null character (if one is not found, default from above is used)
  608. for (let i = this.readOffset; i < this.length; i++) {
  609. if (this.buff[i] === 0x00) {
  610. nullPos = i;
  611. break;
  612. }
  613. }
  614. // Read value
  615. const value = this.buff.slice(this.readOffset, nullPos);
  616. // Increment internal Buffer read offset
  617. this.readOffset = nullPos + 1;
  618. return value;
  619. }
  620. /**
  621. * Writes a null-terminated Buffer to the current write position.
  622. *
  623. * @param value { Buffer } The Buffer to write.
  624. * @param offset { Number } The offset to write the Buffer to.
  625. */
  626. writeBufferNT(value, offset) {
  627. // Write Values
  628. this.writeBuffer(value, offset);
  629. this.writeUInt8(0, (typeof offset === 'number' ? offset + value.length : this.writeOffset));
  630. return this;
  631. }
  632. /**
  633. * Clears the SmartBuffer instance to its original empty state.
  634. */
  635. clear() {
  636. this.writeOffset = 0;
  637. this.readOffset = 0;
  638. this.length = 0;
  639. }
  640. /**
  641. * Gets the remaining data left to be read from the SmartBuffer instance.
  642. *
  643. * @return { Number }
  644. */
  645. remaining() {
  646. return this.length - this.readOffset;
  647. }
  648. /**
  649. * Moves the read offset forward.
  650. *
  651. * @param amount { Number } The amount to move the read offset forward by.
  652. */
  653. skip(amount) {
  654. if (this.readOffset + amount > this.length) {
  655. throw new Error('Target position is beyond the bounds of the SmartBuffer size.');
  656. }
  657. this.readOffset += amount;
  658. }
  659. /**
  660. * Moves the read offset backwards.
  661. *
  662. * @param amount { Number } The amount to move the read offset backwards by.
  663. */
  664. rewind(amount) {
  665. if (this.readOffset - amount < 0) {
  666. throw new Error('Target position is beyond the bounds of the SmartBuffer size.');
  667. }
  668. this.readOffset -= amount;
  669. }
  670. /**
  671. * Moves the read offset to a specific position.
  672. *
  673. * @param position { Number } The position to move the read offset to.
  674. */
  675. skipTo(position) {
  676. this.moveTo(position);
  677. }
  678. /**
  679. * Moves the read offset to a specific position.
  680. *
  681. * @param position { Number } The position to move the read offset to.
  682. */
  683. moveTo(position) {
  684. if (position > this.length) {
  685. throw new Error('Target position is beyond the bounds of the SmartBuffer size.');
  686. }
  687. this.readOffset = position;
  688. }
  689. /**
  690. * Gets the value of the internal managed Buffer
  691. *
  692. * @param { Buffer }
  693. */
  694. toBuffer() {
  695. return this.buff.slice(0, this.length);
  696. }
  697. /**
  698. * Gets the String value of the internal managed Buffer
  699. *
  700. * @param encoding { String } The BufferEncoding to display the Buffer as (defaults to instance level encoding).
  701. */
  702. toString(encoding) {
  703. const encodingVal = typeof encoding === 'string' ? encoding : this.encoding;
  704. if (Buffer.isEncoding(encodingVal)) {
  705. return this.buff.toString(encodingVal, 0, this.length);
  706. }
  707. else {
  708. throw new Error('Invalid encoding provided. Please specify a valid encoding the internal Node.js Buffer supports.');
  709. }
  710. }
  711. /**
  712. * Destroys the SmartBuffer instance.
  713. */
  714. destroy() {
  715. this.clear();
  716. }
  717. /**
  718. * Type checking function that determines if an object is a SmartBufferOptions object.
  719. */
  720. static isSmartBufferOptions(options) {
  721. const castOptions = options;
  722. return castOptions && (castOptions.encoding !== undefined || castOptions.size !== undefined || castOptions.buff !== undefined);
  723. }
  724. }
  725. module.exports = SmartBuffer;
  726. //# sourceMappingURL=smartbuffer.js.map