@@ -17,31 +17,29 @@ data. Binary-parser dynamically generates and compiles the parser and encoder co
17
17
on-the-fly, which runs as fast as a hand-written parser/encoder (which takes much more
18
18
time and effort to write). Supported data types are:
19
19
20
- - Integers (supports 8, 16, 32 bit signed- and unsigned integers)
21
- - Floating point numbers (supports 32 and 64 bit floating point values)
22
- - Bit fields (supports bit fields with length from 1 to 32 bits)
23
- - Strings (supports various encodings, fixed-length and variable-length, zero
24
- terminated string)
25
- - Arrays (supports user-defined element type, fixed-length and variable-length)
26
- - Choices
27
- - User defined types
28
-
29
- This library's features are inspired by [ BinData] ( https://github.com/dmendel/bindata )
30
- , its syntax by [ binary] ( https://github.com/substack/node-binary ) .
31
-
32
- ## Installation
33
- Binary-parser can be installed with [ npm] ( https://npmjs.org/ ) :
34
-
35
- ``` shell
36
- $ npm install binary-parser
37
- ```
20
+ - [ Integers] ( #uint8-16-32-64le-bename-options ) (8, 16, 32 and 64 bit signed
21
+ and unsigned integers)
22
+ - [ Floating point numbers] ( #float-doublele-bename-options ) (32 and 64 bit
23
+ floating point values)
24
+ - [ Bit fields] ( #bit1-32name-options ) (bit fields with length from 1 to 32
25
+ bits)
26
+ - [ Strings] ( #stringname-options ) (fixed-length, variable-length and zero
27
+ terminated strings with various encodings)
28
+ - [ Arrays] ( #arrayname-options ) (fixed-length and variable-length arrays of
29
+ builtin or user-defined element types)
30
+ - [ Choices] ( #choicename-options ) (supports integer keys)
31
+ - [ Pointers] ( #pointername-options )
32
+ - User defined types (arbitrary combination of builtin types)
33
+
34
+ Binary-parser was inspired by [ BinData] ( https://github.com/dmendel/bindata )
35
+ and [ binary] ( https://github.com/substack/node-binary ) .
38
36
39
37
## Quick Start
40
- 1 . Create an empty Parser object with ` new Parser() ` .
41
- 2 . Chain builder methods to build the desired parser and/or encoder. (See
42
- [ API] ( https://github.com/Keichi /binary-parser#api ) for detailed document of
43
- each methods )
44
- 3 . Call ` Parser.prototype.parse ` with an ` Buffer ` object passed as argument.
38
+ 1 . Create an empty Parser object with ` new Parser() ` or ` Parser.start() ` .
39
+ 2 . Chain methods to build your desired parser and/or encoder. (See
40
+ [ API] ( https://github.com/keichi /binary-parser#api ) for detailed document of
41
+ each method )
42
+ 3 . Call ` Parser.prototype.parse ` with an ` Buffer ` object passed as an argument.
45
43
4 . Parsed result will be returned as an object.
46
44
5 . Or call ` Parser.prototype.encode ` with an object passed as argument.
47
45
6 . Encoded result will be returned as a ` Buffer ` object.
@@ -106,8 +104,8 @@ parser.
106
104
107
105
### parse(buffer)
108
106
Parse a ` Buffer ` object ` buffer ` with this parser and return the resulting
109
- object. When ` parse(buffer) ` is called for the first time, parser code is
110
- compiled on-the-fly and internally cached.
107
+ object. When ` parse(buffer) ` is called for the first time, the associated
108
+ parser code is compiled on-the-fly and internally cached.
111
109
112
110
### encode(obj)
113
111
Encode an ` Object ` object ` obj ` with this parser and return the resulting
@@ -118,12 +116,17 @@ compiled on-the-fly and internally cached.
118
116
Set the constructor function that should be called to create the object
119
117
returned from the ` parse ` method.
120
118
121
- ### [ u] int{8, 16, 32}{le, be}(name[ , options] )
119
+ ### [ u] int{8, 16, 32, 64 }{le, be}(name[ , options] )
122
120
Parse bytes as an integer and store it in a variable named ` name ` . ` name `
123
121
should consist only of alphanumeric characters and start with an alphabet.
124
- Number of bits can be chosen from 8, 16 and 32 . Byte-ordering can be either
122
+ Number of bits can be chosen from 8, 16, 32 and 64 . Byte-ordering can be either
125
123
` l ` for little endian or ` b ` for big endian. With no prefix, it parses as a
126
- signed number, with ` u ` prefixed as an unsigned number.
124
+ signed number, with ` u ` prefixed as an unsigned number. The runtime type
125
+ returned by the 8, 16, 32 bit methods is ` number ` while the type
126
+ returned by the 64 bit is ` bigint ` .
127
+
128
+ ** Note:** [ u] int64{be,le} methods only work if your runtime is node v12.0.0 or
129
+ greater. Lower version will throw a runtime error.
127
130
128
131
``` javascript
129
132
var parser = new Parser ()
@@ -133,6 +136,8 @@ var parser = new Parser()
133
136
.uint8 (" b" )
134
137
// Signed 16-bit integer (big endian)
135
138
.int16be (" c" );
139
+ // signed 64-bit integer (big endian)
140
+ .int64be (" d" )
136
141
```
137
142
138
143
### bit\[ 1-32\] (name[ , options] )
@@ -141,9 +146,8 @@ methods from `bit1` to `bit32` each corresponding to 1-bit-length to
141
146
32-bits-length bit field.
142
147
143
148
### {float, double}{le, be}(name[ , options] )
144
- Parse bytes as an floating-point value and store it in a variable named
145
- ` name ` . ` name ` should consist only of alphanumeric characters and start with
146
- an alphabet.
149
+ Parse bytes as a floating-point value and stores it to a variable named
150
+ ` name ` .
147
151
148
152
``` javascript
149
153
var parser = new Parser ()
@@ -159,7 +163,7 @@ characters and start with an alphabet. `options` is an object which can have
159
163
the following keys:
160
164
161
165
- ` encoding ` - (Optional, defaults to ` utf8 ` ) Specify which encoding to use.
162
- ` "utf8" ` , ` "ascii" ` , ` "hex" ` and else are valid . See
166
+ Supported encodings include ` "utf8" ` , ` "ascii" ` and ` "hex" ` . See
163
167
[ ` Buffer.toString ` ] ( http://nodejs.org/api/buffer.html#buffer_buf_tostring_encoding_start_end )
164
168
for more info.
165
169
- ` length ` - (Optional) (Bytes)Length of the string. Can be a number, string or a
@@ -190,15 +194,17 @@ the following keys:
190
194
- ` clone ` - (Optional, defaults to ` false ` ) By default,
191
195
` buffer(name [,options]) ` returns a new buffer which references the same
192
196
memory as the parser input, but offset and cropped by a certain range. If
193
- this option is true, input buffer will be cloned and a new buffer referncing
194
- another memory is returned.
197
+ this option is true, input buffer will be cloned and a new buffer
198
+ referencing a new memory region is returned.
195
199
- ` length ` - (either ` length ` or ` readUntil ` is required) Length of the
196
200
buffer. Can be a number, string or a function. Use number for statically
197
201
sized buffers, string to reference another variable and function to do some
198
202
calculation.
199
203
- ` readUntil ` - (either ` length ` or ` readUntil ` is required) If ` "eof" ` , then
200
204
this parser will read till it reaches end of the ` Buffer ` object. (Note: has no
201
205
effect on encoding.)
206
+ If it is a function, this parser will read the buffer is read until the
207
+ function returns true.
202
208
203
209
### array(name, options)
204
210
Parse bytes as an array. ` options ` is an object which can have the following
@@ -242,7 +248,7 @@ var parser = new Parser()
242
248
type: " int32" ,
243
249
length : function () {
244
250
return this .dataLength - 1 ;
245
- } // other fields are available through this
251
+ } // other fields are available through ` this`
246
252
})
247
253
248
254
// Statically sized array
@@ -263,7 +269,7 @@ var parser = new Parser()
263
269
type: " int32" ,
264
270
lengthInBytes : function () {
265
271
return this .dataLengthInBytes - 4 ;
266
- } // other fields are available through this
272
+ } // other fields are available through ` this`
267
273
})
268
274
269
275
// Dynamically sized array (with stop-check on parsed item)
@@ -291,7 +297,7 @@ an object which can have the following keys:
291
297
` choices ` Can be a string pointing to another field or a function.
292
298
- ` choices ` - (Required) An object which key is an integer and value is the
293
299
parser which is executed when ` tag ` equals the key value.
294
- - ` defaultChoice ` - (Optional) In case of the tag value doesn't match any of
300
+ - ` defaultChoice ` - (Optional) In case if the tag value doesn't match any of
295
301
` choices ` , this parser is used.
296
302
297
303
``` javascript
@@ -302,15 +308,15 @@ var parser3 = ...;
302
308
var parser = new Parser ().uint8 (" tagValue" ).choice (" data" , {
303
309
tag: " tagValue" ,
304
310
choices: {
305
- 1 : parser1, // When tagValue == 1, execute parser1
306
- 4 : parser2, // When tagValue == 4, execute parser2
307
- 5 : parser3 // When tagValue == 5, execute parser3
311
+ 1 : parser1, // if tagValue == 1, execute parser1
312
+ 4 : parser2, // if tagValue == 4, execute parser2
313
+ 5 : parser3 // if tagValue == 5, execute parser3
308
314
}
309
315
});
310
316
```
311
317
312
318
Combining ` choice ` with ` array ` is an idiom to parse
313
- [ TLV] ( http://en.wikipedia.org/wiki/Type-length-value ) -based formats.
319
+ [ TLV] ( http://en.wikipedia.org/wiki/Type-length-value ) -based binary formats.
314
320
315
321
### nest([ name,] options)
316
322
Execute an inner parser and store its result to key ` name ` . If ` name ` is null
@@ -319,9 +325,46 @@ current object. `options` is an object which can have the following keys:
319
325
320
326
- ` type ` - (Required) A ` Parser ` object.
321
327
322
- ### skip(length)
323
- Skip parsing for ` length ` bytes. (Note: when encoding, the skipped bytes will be filled
324
- with zeros)
328
+ ### pointer(name [ ,options] )
329
+ Jump to ` offset ` , execute parser for ` type ` and rewind to previous offset.
330
+ Useful for parsing binary formats such as ELF where the offset of a field is
331
+ pointed by another field.
332
+
333
+ - ` type ` - (Required) Can be a string ` [u]int{8, 16, 32, 64}{le, be} `
334
+ or an user defined Parser object.
335
+ - ` offset ` - (Required) Indicates absolute offset from the beginning of the
336
+ input buffer. Can be a number, string or a function.
337
+
338
+ ### saveOffset(name [ ,options] )
339
+ Save the current buffer offset as key ` name ` . This function is only useful
340
+ when called after another function which would advance the internal buffer
341
+ offset.
342
+
343
+ ``` javascript
344
+ var parser = new Parser ()
345
+ // this call advances the buffer offset by
346
+ // a variable (i.e. unknown to us) number of bytes
347
+ .string (' name' , {
348
+ zeroTerminated: true
349
+ })
350
+ // this variable points to an absolute position
351
+ // in the buffer
352
+ .uint32 (' seekOffset' )
353
+ // now, save the "current" offset in the stream
354
+ // as the variable "currentOffset"
355
+ .saveOffset (' currentOffset' )
356
+ // finally, use the saved offset to figure out
357
+ // how many bytes we need to skip
358
+ .seek (function () {
359
+ return this .seekOffset - this .currentOffset ;
360
+ })
361
+ ... // the parser would continue here
362
+ ```
363
+
364
+ ### seek(relOffset)
365
+ Move the buffer offset for ` relOffset ` bytes from the current position. Use a
366
+ negative ` relOffset ` value to rewind the offset. Previously named ` skip(length) ` .
367
+ (Note: when encoding, the skipped bytes will be filled with zeros)
325
368
326
369
### endianess(endianess)
327
370
Define what endianess to use in this parser. ` endianess ` can be either
@@ -414,9 +457,10 @@ will contain two similar parts of the code included, while with the named
414
457
approach, it will include a function with a name, and will just call this
415
458
function for every case of usage.
416
459
417
- NB: This style could lead to circular references and infinite recursion, to
418
- avoid this, ensure that every possible path has its end. Also, this recursion
419
- is not tail-optimized, so could lead to memory leaks when it goes too deep.
460
+ ** Note** : This style could lead to circular references and infinite recursion,
461
+ to avoid this, ensure that every possible path has its end. Also, this
462
+ recursion is not tail-optimized, so could lead to memory leaks when it goes
463
+ too deep.
420
464
421
465
An example of referencing other patches:
422
466
@@ -453,10 +497,10 @@ executed for the first time.
453
497
454
498
### getCode() and getCodeEncode()
455
499
Dynamically generates the code for this parser/encoder and returns it as a string.
456
- Usually used for debugging.
500
+ Useful for debugging the generated code .
457
501
458
502
### Common options
459
- These are common options that can be specified in all parsers.
503
+ These options can be used in all parsers.
460
504
461
505
- ` formatter ` - Function that transforms the parsed value into a more desired
462
506
form. * formatter* (value, obj, buffer, offset) &rarr ; * new value* \
@@ -513,11 +557,10 @@ These are common options that can be specified in all parsers.
513
557
```
514
558
515
559
## Examples
516
- See ` example` for more complex examples.
560
+ See ` example/ ` for real - world examples.
517
561
518
562
## Support
519
563
Please report issues to the
520
- [issue tracker](https: // github.com/Keichi /binary-parser/issues) if you have
564
+ [issue tracker](https: // github.com/keichi /binary-parser/issues) if you have
521
565
any difficulties using this module , found a bug, or request a new feature.
522
-
523
- Pull requests with fixes and improvements are welcomed!
566
+ Pull requests are welcomed.
0 commit comments