Skip to content

Implements encoding from Parser #73

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 68 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

[![Circle CI](https://circleci.com/gh/keichi/binary-parser.svg?style=svg)](https://circleci.com/gh/keichi/binary-parser)

Binary-parser is a binary parser builder for [node](http://nodejs.org) that
enables you to write efficient parsers in a simple and declarative manner.
Binary-parser is a binary parser/encoder builder for [node](http://nodejs.org) that
enables you to write efficient parsers/encoders in a simple and declarative manner.

It supports all common data types required to analyze a structured binary
data. Binary-parser dynamically generates and compiles the parser code
on-the-fly, which runs as fast as a hand-written parser (which takes much more
data. Binary-parser dynamically generates and compiles the parser and encoder code
on-the-fly, which runs as fast as a hand-written parser/encoder (which takes much more
time and effort to write). Supported data types are:

- Integers (supports 8, 16, 32 bit signed- and unsigned integers)
Expand All @@ -31,11 +31,13 @@ $ npm install binary-parser

## Quick Start
1. Create an empty Parser object with `new Parser()`.
2. Chain builder methods to build the desired parser. (See
2. Chain builder methods to build the desired parser and/or encoder. (See
[API](https://github.com/Keichi/binary-parser#api) for detailed document of
each methods)
3. Call `Parser.prototype.parse` with an `Buffer` object passed as argument.
4. Parsed result will be returned as an object.
5. Or call `Parser.prototype.encode` with an object passed as argument.
6. Encoded result will be returned as a `Buffer` object.

```javascript
// Module import
Expand Down Expand Up @@ -68,19 +70,43 @@ var buf = Buffer.from("450002c5939900002c06ef98adc24f6c850186d1", "hex");

// Parse buffer and show result
console.log(ipHeader.parse(buf));

var anIpHeader = {
version: 4,
headerLength: 5,
tos: 0,
packetLength: 709,
id: 37785,
offset: 0,
fragOffset: 0,
ttl: 44,
protocol: 6,
checksum: 61336,
src: [ 173, 194, 79, 108 ],
dst: [ 133, 1, 134, 209 ] };

// Encode an IP header object and show result as hex string
console.log(ipHeader.encode(anIpHeader).toString("hex"));
```

## API

### new Parser()
### new Parser([options])
Constructs a Parser object. Returned object represents a parser which parses
nothing.
nothing. `options` is an optional object to pass options to this declarative
parser.
- `smartBufferSize` The chunk size of the encoding (smart)buffer (when encoding is used) (default is 256 bytes).

### parse(buffer)
Parse a `Buffer` object `buffer` with this parser and return the resulting
object. When `parse(buffer)` is called for the first time, parser code is
compiled on-the-fly and internally cached.

### encode(obj)
Encode an `Object` object `obj` with this parser and return the resulting
`Buffer`. When `encode(obj)` is called for the first time, encoder code is
compiled on-the-fly and internally cached.

### create(constructorFunction)
Set the constructor function that should be called to create the object
returned from the `parse` method.
Expand Down Expand Up @@ -129,15 +155,18 @@ the following keys:
`"utf8"`, `"ascii"`, `"hex"` and else are valid. See
[`Buffer.toString`](http://nodejs.org/api/buffer.html#buffer_buf_tostring_encoding_start_end)
for more info.
- `length ` - (Optional) Length of the string. Can be a number, string or a
- `length ` - (Optional) (Bytes)Length of the string. Can be a number, string or a
function. Use number for statically sized arrays, string to reference
another variable and function to do some calculation.
Note: when encoding the string is padded with spaces (0x20) at end to fit the length requirement.
- `zeroTerminated` - (Optional, defaults to `false`) If true, then this parser
reads until it reaches zero.
- `greedy` - (Optional, defaults to `false`) If true, then this parser reads
until it reaches the end of the buffer. Will consume zero-bytes.
until it reaches the end of the buffer. Will consume zero-bytes. (Note: has
no effect on encoding function)
- `stripNull` - (Optional, must be used with `length`) If true, then strip
null characters from end of the string
null characters from end of the string. (Note: has no effect on encoding, but
when used, then the parse() and encode() functions are not the exact opposite)

### buffer(name[, options])
Parse bytes as a buffer. `name` should consist only of alpha numeric
Expand All @@ -154,7 +183,8 @@ the following keys:
sized buffers, string to reference another variable and function to do some
calculation.
- `readUntil` - (either `length` or `readUntil` is required) If `"eof"`, then
this parser will read till it reaches end of the `Buffer` object.
this parser will read till it reaches end of the `Buffer` object. (Note: has no
effect on encoding.)

### array(name, options)
Parse bytes as an array. `options` is an object which can have the following
Expand Down Expand Up @@ -271,7 +301,8 @@ current object. `options` is an object which can have the following keys:
- `type` - (Required) A `Parser` object.

### skip(length)
Skip parsing for `length` bytes.
Skip parsing for `length` bytes. (Note: when encoding, the skipped bytes will be filled
with zeros)

### endianess(endianess)
Define what endianess to use in this parser. `endianess` can be either
Expand Down Expand Up @@ -381,26 +412,44 @@ var buffer = Buffer.from([2, /* left */ 1, 1, 0, /* right */ 0]);
parser.parse(buffer);
```

### compile()
Compile this parser on-the-fly and cache its result. Usually, there is no need
to call this method directly, since it's called when `parse(buffer)` is
### compile() and compileEncode()
Compile this parser/encoder on-the-fly and cache its result. Usually, there is no need
to call this method directly, since it's called when `parse(buffer)` or `encode(obj)` is
executed for the first time.

### getCode()
Dynamically generates the code for this parser and returns it as a string.
### getCode() and getCodeEncode()
Dynamically generates the code for this parser/encoder and returns it as a string.
Usually used for debugging.

### Common options
These are common options that can be specified in all parsers.

- `formatter` - Function that transforms the parsed value into a more desired
form.
form. *formatter*(value, obj, buffer, offset) → *new value* \
where `value` is the value to be formatted, `obj` is the current object being generated, `buffer` is the buffer currently beeing parsed and `offset` is the current offset in that buffer.
```javascript
var parser = new Parser().array("ipv4", {
type: uint8,
length: "4",
formatter: function(arr, obj, buffer, offset) {
return arr.join(".");
}
});
```

- `encoder` - Function that transforms an object property into a more desired
form for encoding. This is the opposite of the above `formatter` function. \
*encoder*(value) → *new value* \
where `value` is the value to be encoded (de-formatted) and `obj` is the object currently being encoded.
```javascript
var parser = new Parser().array("ipv4", {
type: uint8,
length: "4",
formatter: function(arr) {
formatter: function(arr, obj, buffer, offset) {
return arr.join(".");
},
encoder: function(str, obj) {
return str.split(".");
}
});
```
Expand Down
Loading