You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

smartbuffer.js 43KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const utils_1 = require("./utils");
  4. // The default Buffer size if one is not provided.
  5. const DEFAULT_SMARTBUFFER_SIZE = 4096;
  6. // The default string encoding to use for reading/writing strings.
  7. const DEFAULT_SMARTBUFFER_ENCODING = 'utf8';
  8. class 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. }
  1232. exports.SmartBuffer = SmartBuffer;
  1233. //# sourceMappingURL=smartbuffer.js.map