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.

README_v3.md 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. smart-buffer [![Build Status](https://travis-ci.org/JoshGlazebrook/smart-buffer.svg?branch=master)](https://travis-ci.org/JoshGlazebrook/smart-buffer) [![Coverage Status](https://coveralls.io/repos/github/JoshGlazebrook/smart-buffer/badge.svg?branch=master)](https://coveralls.io/github/JoshGlazebrook/smart-buffer?branch=master)
  2. =============
  3. smart-buffer is a light Buffer wrapper that takes away the need to keep track of what position to read and write data to and from the underlying Buffer. It also adds null terminating string operations and **grows** as you add more data.
  4. ![stats](https://nodei.co/npm/smart-buffer.png?downloads=true&downloadRank=true&stars=true "stats")
  5. ### What it's useful for:
  6. I created smart-buffer because I wanted to simplify the process of using Buffer for building and reading network packets to send over a socket. Rather than having to keep track of which position I need to write a UInt16 to after adding a string of variable length, I simply don't have to.
  7. Key Features:
  8. * Proxies all of the Buffer write and read functions.
  9. * Keeps track of read and write positions for you.
  10. * Grows the internal Buffer as you add data to it.
  11. * Useful string operations. (Null terminating strings)
  12. * Allows for inserting values at specific points in the internal Buffer.
  13. * Built in TypeScript
  14. * Type Definitions Provided
  15. Requirements:
  16. * Node v4.0+ is supported at this time. (Versions prior to 2.0 will work on node 0.10)
  17. #### Note:
  18. smart-buffer can be used for writing to an underlying buffer as well as reading from it. It however does not function correctly if you're mixing both read and write operations with each other.
  19. ## Breaking Changes with 2.0
  20. The latest version (2.0+) is written in TypeScript, and are compiled to ES6 Javascript. This means the earliest Node.js it supports will be 4.x (in strict mode.) If you're using version 6 and above it will work without any issues. From an API standpoint, 2.0 is backwards compatible. The only difference is SmartBuffer is not exported directly as the root module.
  21. ## Breaking Changes with 3.0
  22. Starting with 3.0, if any of the readIntXXXX() methods are called and the requested data is larger than the bounds of the internally managed valid buffer data, an exception will now be thrown.
  23. ## Installing:
  24. `npm install smart-buffer`
  25. or
  26. `yarn add smart-buffer`
  27. Note: The published NPM package includes the built javascript library.
  28. If you cloned this repo and wish to build the library manually use:
  29. `tsc -p ./`
  30. ## Using smart-buffer
  31. ### Example
  32. Say you were building a packet that had to conform to the following protocol:
  33. `[PacketType:2][PacketLength:2][Data:XX]`
  34. To build this packet using the vanilla Buffer class, you would have to count up the length of the data payload beforehand. You would also need to keep track of the current "cursor" position in your Buffer so you write everything in the right places. With smart-buffer you don't have to do either of those things.
  35. ```javascript
  36. // 1.x (javascript)
  37. var SmartBuffer = require('smart-buffer');
  38. // 1.x (typescript)
  39. import SmartBuffer = require('smart-buffer');
  40. // 2.x+ (javascript)
  41. const SmartBuffer = require('smart-buffer').SmartBuffer;
  42. // 2.x+ (typescript)
  43. import { SmartBuffer, SmartBufferOptions} from 'smart-buffer';
  44. function createLoginPacket(username, password, age, country) {
  45. let packet = new SmartBuffer();
  46. packet.writeUInt16LE(0x0060); // Login Packet Type/ID
  47. packet.writeStringNT(username);
  48. packet.writeStringNT(password);
  49. packet.writeUInt8(age);
  50. packet.writeStringNT(country);
  51. packet.writeUInt16LE(packet.length - 2, 2);
  52. return packet.toBuffer();
  53. }
  54. ```
  55. With the above function, you now can do this:
  56. ```javascript
  57. let login = createLoginPacket("Josh", "secret123", 22, "United States");
  58. // <Buffer 60 00 1e 00 4a 6f 73 68 00 73 65 63 72 65 74 31 32 33 00 16 55 6e 69 74 65 64 20 53 74 61 74 65 73 00>
  59. ```
  60. Notice that the `[PacketLength:2]` part of the packet was inserted after we had added everything else, and as shown in the Buffer dump above, is in the correct location along with everything else.
  61. Reading back the packet we created above is just as easy:
  62. ```javascript
  63. let reader = SmartBuffer.fromBuffer(login);
  64. let logininfo = {
  65. packetType: reader.readUInt16LE(),
  66. packetLength: reader.readUInt16LE(),
  67. username: reader.readStringNT(),
  68. password: reader.readStringNT(),
  69. age: reader.readUInt8(),
  70. country: reader.readStringNT()
  71. };
  72. /*
  73. {
  74. packetType: 96, (0x0060)
  75. packetLength: 30,
  76. username: 'Josh',
  77. password: 'secret123',
  78. age: 22,
  79. country: 'United States'
  80. };
  81. */
  82. ```
  83. # Api Reference:
  84. ### Constructing a smart-buffer
  85. smart-buffer has a few different ways to construct an instance. Starting with version 2.0, the following factory methods are preffered.
  86. ```javascript
  87. let SmartBuffer = require('smart-buffer');
  88. // Creating SmartBuffer from existing Buffer
  89. let buff = SmartBuffer.fromBuffer(buffer); // Creates instance from buffer. (Uses default utf8 encoding)
  90. let buff = SmartBuffer.fromBuffer(buffer, 'ascii'); // Creates instance from buffer with ascii encoding for Strings.
  91. // Creating SmartBuffer with specified internal Buffer size.
  92. let buff = SmartBuffer.fromSize(1024); // Creates instance with internal Buffer size of 1024.
  93. let buff = SmartBuffer.fromSize(1024, 'utf8'); // Creates instance with intenral Buffer size of 1024, and utf8 encoding.
  94. // Creating SmartBuffer with options object. This one specifies size and encoding.
  95. let buff = SmartBuffer.fromOptions({
  96. size: 1024,
  97. encoding: 'ascii'
  98. });
  99. // Creating SmartBuffer with options object. This one specified an existing Buffer.
  100. let buff = SmartBuffer.fromOptions({
  101. buff: buffer
  102. });
  103. // Just want a regular SmartBuffer with all default options?
  104. let buff = new SmartBuffer();
  105. ```
  106. ## Backwards Compatibility:
  107. All constructors used prior to 2.0 still are supported. However it's not recommended to use these.
  108. ```javascript
  109. let writer = new SmartBuffer(); // Defaults to utf8, 4096 length internal Buffer.
  110. let writer = new SmartBuffer(1024); // Defaults to utf8, 1024 length internal Buffer.
  111. let writer = new SmartBuffer('ascii'); // Sets to ascii encoding, 4096 length internal buffer.
  112. let writer = new SmartBuffer(1024, 'ascii'); // Sets to ascii encoding, 1024 length internal buffer.
  113. ```
  114. ## Reading Data
  115. smart-buffer supports all of the common read functions you will find in the vanilla Buffer class. The only difference is, you do not need to specify which location to start reading from. This is possible because as you read data out of a smart-buffer, it automatically progresses an internal read offset/position to know where to pick up from on the next read.
  116. ## Reading Numeric Values
  117. When numeric values, you simply need to call the function you want, and the data is returned.
  118. Supported Operations:
  119. * readInt8
  120. * readInt16BE
  121. * readInt16LE
  122. * readInt32BE
  123. * readInt32LE
  124. * readBigInt64LE
  125. * readBigInt64BE
  126. * readUInt8
  127. * readUInt16BE
  128. * readUInt16LE
  129. * readUInt32BE
  130. * readUInt32LE
  131. * readBigUInt64LE
  132. * readBigUInt64BE
  133. * readFloatBE
  134. * readFloatLE
  135. * readDoubleBE
  136. * readDoubleLE
  137. ```javascript
  138. let reader = new SmartBuffer(somebuffer);
  139. let num = reader.readInt8();
  140. ```
  141. ## Reading String Values
  142. When reading String values, you can either choose to read a null terminated string, or a string of a specified length.
  143. ### SmartBuffer.readStringNT( [encoding] )
  144. > `String` **String encoding to use** - Defaults to the encoding set in the constructor.
  145. returns `String`
  146. > Note: When readStringNT is called and there is no null character found, smart-buffer will read to the end of the internal Buffer.
  147. ### SmartBuffer.readString( [length] )
  148. ### SmartBuffer.readString( [encoding] )
  149. ### SmartBuffer.readString( [length], [encoding] )
  150. > `Number` **Length of the string to read**
  151. > `String` **String encoding to use** - Defaults to the encoding set in the constructor, or utf8.
  152. returns `String`
  153. > Note: When readString is called without a specified length, smart-buffer will read to the end of the internal Buffer.
  154. ## Reading Buffer Values
  155. ### SmartBuffer.readBuffer( length )
  156. > `Number` **Length of data to read into a Buffer**
  157. returns `Buffer`
  158. > Note: This function uses `slice` to retrieve the Buffer.
  159. ### SmartBuffer.readBufferNT()
  160. returns `Buffer`
  161. > Note: This reads the next sequence of bytes in the buffer until a null (0x00) value is found. (Null terminated buffer)
  162. > Note: This function uses `slice` to retrieve the Buffer.
  163. ## Writing Data
  164. smart-buffer supports all of the common write functions you will find in the vanilla Buffer class. The only difference is, you do not need to specify which location to write to in your Buffer by default. You do however have the option of **inserting** a piece of data into your smart-buffer at a given location.
  165. ## Writing Numeric Values
  166. For numeric values, you simply need to call the function you want, and the data is written at the end of the internal Buffer's current write position. You can specify a offset/position to **insert** the given value at, but keep in mind this does not override data at the given position. This feature also does not work properly when inserting a value beyond the current internal length of the smart-buffer (length being the .length property of the smart-buffer instance you're writing to)
  167. Supported Operations:
  168. * writeInt8
  169. * writeInt16BE
  170. * writeInt16LE
  171. * writeInt32BE
  172. * writeInt32LE
  173. * writeBigInt64BE
  174. * writeBigInt64LE
  175. * writeUInt8
  176. * writeUInt16BE
  177. * writeUInt16LE
  178. * writeUInt32BE
  179. * writeUInt32LE
  180. * writeBigUInt64BE
  181. * writeBigUInt64LE
  182. * writeFloatBE
  183. * writeFloatLE
  184. * writeDoubleBE
  185. * writeDoubleLE
  186. The following signature is the same for all the above functions:
  187. ### SmartBuffer.writeInt8( value, [offset] )
  188. > `Number` **A valid Int8 number**
  189. > `Number` **The position to insert this value at**
  190. returns this
  191. > Note: All write operations return `this` to allow for chaining.
  192. ## Writing String Values
  193. When reading String values, you can either choose to write a null terminated string, or a non null terminated string.
  194. ### SmartBuffer.writeStringNT( value, [offset], [encoding] )
  195. ### SmartBuffer.writeStringNT( value, [offset] )
  196. ### SmartBuffer.writeStringNT( value, [encoding] )
  197. > `String` **String value to write**
  198. > `Number` **The position to insert this String at**
  199. > `String` **The String encoding to use.** - Defaults to the encoding set in the constructor, or utf8.
  200. returns this
  201. ### SmartBuffer.writeString( value, [offset], [encoding] )
  202. ### SmartBuffer.writeString( value, [offset] )
  203. ### SmartBuffer.writeString( value, [encoding] )
  204. > `String` **String value to write**
  205. > `Number` **The position to insert this String at**
  206. > `String` **The String encoding to use** - Defaults to the encoding set in the constructor, or utf8.
  207. returns this
  208. ## Writing Buffer Values
  209. ### SmartBuffer.writeBuffer( value, [offset] )
  210. > `Buffer` **Buffer value to write**
  211. > `Number` **The position to insert this Buffer's content at**
  212. returns this
  213. ### SmartBuffer.writeBufferNT( value, [offset] )
  214. > `Buffer` **Buffer value to write**
  215. > `Number` **The position to insert this Buffer's content at**
  216. returns this
  217. ## Utility Functions
  218. ### SmartBuffer.clear()
  219. Resets the SmartBuffer to its default state where it can be reused for reading or writing.
  220. ### SmartBuffer.remaining()
  221. returns `Number` The amount of data left to read based on the current read Position.
  222. ### SmartBuffer.skip( value )
  223. > `Number` **The amount of bytes to skip ahead**
  224. Skips the read position ahead by the given value.
  225. returns this
  226. ### SmartBuffer.rewind( value )
  227. > `Number` **The amount of bytes to reward backwards**
  228. Rewinds the read position backwards by the given value.
  229. returns this
  230. ### SmartBuffer.moveTo( position )
  231. > `Number` **The point to skip the read position to**
  232. Moves the read position to the given point.
  233. returns this
  234. ### SmartBuffer.toBuffer()
  235. returns `Buffer` A Buffer containing the contents of the internal Buffer.
  236. > Note: This uses the slice function.
  237. ### SmartBuffer.toString( [encoding] )
  238. > `String` **The String encoding to use** - Defaults to the encoding set in the constructor, or utf8.
  239. returns `String` The internal Buffer in String representation.
  240. ## Properties
  241. ### SmartBuffer.length
  242. returns `Number` **The length of the data that is being tracked in the internal Buffer** - Does NOT return the absolute length of the internal Buffer being written to.
  243. ## License
  244. This work is licensed under the [MIT license](http://en.wikipedia.org/wiki/MIT_License).