binary-parser
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -53,2 +53,3 @@ //======================================================================================== | ||
this.compiled = null; | ||
this.isAsync = false; | ||
}; | ||
@@ -152,8 +153,18 @@ | ||
var ctx = new Context(); | ||
if (this.isAsync) { | ||
ctx.isAsync = true; | ||
} | ||
ctx.pushCode('var vars = {};'); | ||
ctx.pushCode('var iterator = 0;'); | ||
ctx.pushCode('if (!Buffer.isBuffer(buffer)) {'); | ||
ctx.generateError('"argument buffer is not a Buffer object"'); | ||
ctx.pushCode('}'); | ||
this.generate(ctx); | ||
ctx.pushCode('return vars;'); | ||
if (!this.isAsync) { | ||
ctx.pushCode('return vars;'); | ||
} | ||
return ctx.code; | ||
@@ -163,3 +174,3 @@ }; | ||
Parser.prototype.compile = function() { | ||
this.compiled = new Function('buffer', this.getCode()); | ||
this.compiled = new Function('buffer', 'callback', this.getCode()); | ||
}; | ||
@@ -203,7 +214,3 @@ | ||
// Follow the parser chain till the root and start parsing from there | ||
Parser.prototype.parse = function(buffer) { | ||
if (!Buffer.isBuffer(buffer)) { | ||
throw new Error('argument "buffer" is not a Buffer object'); | ||
} | ||
Parser.prototype.parse = function(buffer, callback) { | ||
if (!this.compiled) { | ||
@@ -213,3 +220,3 @@ this.compile(); | ||
return this.compiled(buffer); | ||
return this.compiled(buffer, callback); | ||
}; | ||
@@ -235,2 +242,6 @@ | ||
if (parser.options.async) { | ||
this.isAsync = true; | ||
} | ||
return this; | ||
@@ -242,4 +253,15 @@ }; | ||
if (this.type) { | ||
if (this.options.async) { | ||
ctx.pushCode('process.nextTick(function() {'); | ||
} | ||
this['generate' + this.type](ctx); | ||
this.generateAssert(ctx); | ||
if (this.options.async) { | ||
if (!this.next) { | ||
ctx.pushCode('process.nextTick(function() { callback(null, vars); });'); | ||
} | ||
ctx.pushCode('});'); | ||
} | ||
} | ||
@@ -258,3 +280,3 @@ | ||
ctx.pushCode('if (!({0})({1})) {', this.options.assert, varName); | ||
ctx.pushCode('throw new Error("Assert error: {0} is " + {0});', varName); | ||
ctx.generateError('"Assert error: {0} is " + {0}', varName); | ||
ctx.pushCode('}'); | ||
@@ -375,3 +397,3 @@ }; | ||
} else { | ||
ctx.pushCode('throw new Error("Met undefined tag value " + {0} + " at choice");', tag); | ||
ctx.generateError('"Met undefined tag value " + {0} + " at choice"', tag); | ||
} | ||
@@ -382,3 +404,3 @@ ctx.pushCode('}'); | ||
//======================================================================================== | ||
// Utilities | ||
// class Context | ||
//======================================================================================== | ||
@@ -393,2 +415,3 @@ | ||
this.scopes = []; | ||
this.isAsync = false; | ||
}; | ||
@@ -420,5 +443,26 @@ | ||
Context.prototype.pushCode = function(code) { | ||
Context.prototype.generateError = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var err = Context.interpolate.apply(this, args); | ||
if (this.isAsync) { | ||
this.pushCode('return process.nextTick(function() { callback(new Error(' + err + '), vars); });'); | ||
} else { | ||
this.pushCode('throw new Error(' + err + ');'); | ||
} | ||
}; | ||
Context.prototype.pushCode = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
this.code += Context.interpolate.apply(this, args) + '\n'; | ||
}; | ||
//---------------------------------------------------------------------------------------- | ||
// private methods | ||
//---------------------------------------------------------------------------------------- | ||
Context.interpolate = function(s) { | ||
var re = /{\d+}/g; | ||
var matches = code.match(re); | ||
var matches = s.match(re); | ||
var params = Array.prototype.slice.call(arguments, 1); | ||
@@ -429,7 +473,7 @@ | ||
var index = parseInt(match.substr(1, match.length - 2), 10); | ||
code = code.replace(match, params[index].toString()); | ||
s = s.replace(match, params[index].toString()); | ||
}); | ||
} | ||
this.code += code + '\n'; | ||
return s; | ||
}; | ||
@@ -436,0 +480,0 @@ |
{ | ||
"name": "binary-parser", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Blazing-fast binary parser builder", | ||
@@ -20,3 +20,7 @@ "main": "lib/binary_parser.js", | ||
], | ||
"author": "Keichi Takahashi", | ||
"author": { | ||
"name" : "Keichi Takahashi", | ||
"email" : "keichi.t@me.com", | ||
"url" : "http://blog.keichi.net/" | ||
}, | ||
"license": "MIT", | ||
@@ -23,0 +27,0 @@ "repository" : { |
@@ -49,3 +49,3 @@ # Binary-parser | ||
### parse(buffer) | ||
### parse(buffer[, callback]) | ||
Parse a `Buffer` object `buffer` with this parser and return the resulting object. | ||
@@ -55,2 +55,6 @@ When `parse(buffer)` is called for the first time, parser code is compiled on-the-fly | ||
If parser's `async` option is `true`, then a callback function has to be passed as an | ||
argument. This callback should take two arguements like other node.js callbacks: | ||
`function(err, result)`. | ||
### [u]int{8, 16, 32}{le, be}(name [,options]) | ||
@@ -82,3 +86,3 @@ Parse bytes as an integer and store it in a variable named `name`. `name` should consist | ||
- `encoding` - (Optional) Specify which encoding to use. `'utf8'`, `'ascii'`, `'hex'` and else | ||
- `encoding` - (Optional, defaults to `utf8`) Specify which encoding to use. `'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. | ||
@@ -88,3 +92,3 @@ - `length ` - (Required) Length of the string. Can be a number, string or a function. | ||
function to do some calculation. | ||
- `zeroTerminated` - (Optional) If true, then this parser reads until it reaches zero. | ||
- `zeroTerminated` - (Optional, defaults to `false`) If true, then this parser reads until it reaches zero. | ||
@@ -197,5 +201,6 @@ ### buffer(name [,options]) | ||
### Assertion | ||
You can do assertions during the parsing (useful for checking magic numbers and so on). | ||
In the `options` hash, define `assert` with an assertion function. | ||
### Common options | ||
These are common options that can be specified in all parsers. | ||
- `assert` - A predicate function. You can do assertions during the parsing (useful for checking magic numbers and so on). | ||
This assertion function should take one argument, which is the parsed result, and return | ||
@@ -205,12 +210,21 @@ `true` if assertion successes or `false` when assertion fails. | ||
```javascript | ||
var ClassFile = | ||
Parser.start() | ||
.endianess('big') | ||
.uint32('magic', {assert: function(x) {return x === 0xcafebabe; }}) | ||
``` | ||
```javascript | ||
var ClassFile = | ||
Parser.start() | ||
.endianess('big') | ||
.uint32('magic', {assert: function(x) {return x === 0xcafebabe; }}) | ||
``` | ||
- `async` - If `true`, then this parser will be executed asynchronously. You also have | ||
to pass a callback function to `Parser.parse(buffer, callback)`. | ||
## Examples | ||
See `test/` for more complex examples. | ||
## Support | ||
Please report issues to the [issue tracker](https://github.com/Keichi/binary-parser/issues) if you | ||
have any difficulties using this module, found a bug, or request a new feature. | ||
Pull requests with fixes and improvements are welcomed! | ||
## License | ||
@@ -217,0 +231,0 @@ The MIT License (MIT) |
@@ -329,3 +329,38 @@ var assert = require('assert'); | ||
}); | ||
it('should parse asynchronously', function() { | ||
var parser = new Parser() | ||
.uint8('len') | ||
.string('text', {length: 'len', async: true}); | ||
var buf = new Buffer('0c68656c6c6f2c20776f726c64', 'hex'); | ||
parser.parse(buf, function(err, result) { | ||
assert.deepEqual(result, {len: 12, text: 'hello, world'}); | ||
}); | ||
}); | ||
it('should emit error asynchronously', function() { | ||
var parser = new Parser() | ||
.uint8('len') | ||
.string('text', {length: 'len', async: true}); | ||
var buf = null; | ||
parser.parse(buf, function(err, result) { | ||
assert(err); | ||
}); | ||
parser = new Parser().uint32be('val', { | ||
assert: function(x) { | ||
return x === 0xdeadbeef; | ||
}, | ||
async: true | ||
}); | ||
buf = new Buffer('cafebabe', 'hex'); | ||
parser.parse(buf, function(err, result) { | ||
assert(err); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
274586
987
246