From e4c1f88a41d64a19a13897e6a4d1ba270a187987 Mon Sep 17 00:00:00 2001 From: Autarc Date: Sat, 11 Jul 2015 16:52:45 +0200 Subject: [PATCH 1/3] Enable Strings as choice keys --- lib/binary_parser.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/binary_parser.js b/lib/binary_parser.js index 978e9484..23b3694a 100644 --- a/lib/binary_parser.js +++ b/lib/binary_parser.js @@ -148,9 +148,6 @@ Parser.prototype.choice = function(varName, options) { throw new Error('Choices option of array is not defined.'); } Object.keys(options.choices).forEach(function(key) { - if (isNaN(parseInt(key, 10))) { - throw new Error('Key of choices must be a number.'); - } if (!options.choices[key]) { throw new Error('Choice Case ' + key + ' of ' + varName + ' is not valid.'); } @@ -524,7 +521,7 @@ Parser.prototype.generateChoice = function(ctx) { Object.keys(this.options.choices).forEach(function(tag) { var type = this.options.choices[tag]; - ctx.pushCode('case {0}:', tag); + ctx.pushCode('case ' + (isNaN(tag) ? '"{0}"' : '{0}') + ':', tag); this.generateChoiceCase(ctx, this.varName, type); ctx.pushCode('break;'); }, this); From 5dd275278dd57c81a4c8d18661f2ff9915f221a9 Mon Sep 17 00:00:00 2001 From: Autarc Date: Sat, 11 Jul 2015 20:40:51 +0200 Subject: [PATCH 2/3] Add $parent property for passing scoped references --- README.md | 8 ++++++-- lib/binary_parser.js | 24 ++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c11e6c4a..0bac94dc 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,8 @@ Parse bytes as an array. `options` is an object; following options are available Use number for statically sized arrays. - `readUntil` - (either `length` or `readUntil` is required) If `'eof'`, then this parser reads until the end of `Buffer` object. If function it reads until the function returns true. +- `$parent` - (Optional) An array with selected properties from the parental scope. References can be + accessed inside functions using `this.$parent[...]`. ```javascript var parser = new Parser() @@ -193,9 +195,11 @@ Combining `choice` with `array` is useful for parsing a typical - `tag` - (Required) The value used to determine which parser to use from the `choices` Can be a string pointing to another field or a function. -- `choices` - (Required) An object which key is an integer and value is the parser which is executed +- `choices` - (Required) An object which key is an integer/string and value is the parser which is executed when `tag` equals the key value. - `defaultChoice` - (Optional) In case of the tag value doesn't match any of `choices` use this parser. +- `$parent` - (Optional) An array with selected properties from the parental scope. References can be +accessed inside functions using `this.$parent[...]`. ```javascript var parser1 = ...; @@ -254,7 +258,7 @@ These are common options that can be specified in all parsers. ```javascript var parser = new Parser() .array('ipv4', { - type: uint8, + type: 'uint8', length: '4', formatter: function(arr) { return arr.join('.'); } }); diff --git a/lib/binary_parser.js b/lib/binary_parser.js index 23b3694a..faacc8be 100644 --- a/lib/binary_parser.js +++ b/lib/binary_parser.js @@ -482,7 +482,17 @@ Parser.prototype.generateArray = function(ctx) { ctx.pushCode('var {0} = buffer.read{1}(offset);', item, NAME_MAP[type]); ctx.pushCode('offset += {0};', PRIMITIVE_TYPES[NAME_MAP[type]]); } else if (type instanceof Parser) { - ctx.pushCode('var {0} = {};', item); + if (!this.options.$parent) { + ctx.pushCode('var {0} = {};', item); + } else { + ctx.pushCode('var {0} = { "$parent": {1} };', item, + '[' + this.options.$parent.map(function(prop){ return '"' + prop + '"'; }).toString() + + '].reduce(function($parent, key){\ + $parent[key] = ' + ctx.generateVariable() + '[key];\ + return $parent;\ + }, {})' + ); + } ctx.pushScope(item); type.generate(ctx); @@ -516,7 +526,17 @@ Parser.prototype.generateChoiceCase = function(ctx, varName, type) { Parser.prototype.generateChoice = function(ctx) { var tag = ctx.generateOption(this.options.tag); - ctx.pushCode('{0} = {};', ctx.generateVariable(this.varName)); + if (!this.options.$parent) { + ctx.pushCode('{0} = {};', ctx.generateVariable(this.varName)); + } else { + ctx.pushCode('{0} = { "$parent": {1} };', ctx.generateVariable(this.varName), + '[' + this.options.$parent.map(function(prop){ return '"' + prop + '"'; }).toString() + + '].reduce(function($parent, key){\ + $parent[key] = ' + ctx.generateVariable() + '[key];\ + return $parent;\ + }, {})' + ); + } ctx.pushCode('switch({0}) {', tag); Object.keys(this.options.choices).forEach(function(tag) { var type = this.options.choices[tag]; From 165c61a35c1b43991121f3fdf34315cbf611fd58 Mon Sep 17 00:00:00 2001 From: Autarc Date: Wed, 15 Jul 2015 10:34:42 +0200 Subject: [PATCH 3/3] improve skip parameter description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0bac94dc..2d492492 100644 --- a/README.md +++ b/README.md @@ -225,7 +225,7 @@ Nest a parser in this position. Parse result of the nested parser is stored in t - `type` - (Required) A `Parser` object. ### skip(length) -Skip parsing for `length` bytes. +Skip parsing of bytes. `length` can be either a number, a string or a function. ### endianess(endianess) Define what endianess to use in this parser. `endianess` can be either `'little'` or `'big'`.