Skip to content

Commit c6b22b7

Browse files
authored
Merge pull request keichi#55 from keichi/amorri40-master
Allow Parent parser attributes in choice
2 parents aacfc14 + 7ad7d7a commit c6b22b7

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

lib/binary_parser.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -607,14 +607,16 @@ Parser.prototype.generateChoiceCase = function(ctx, varName, type) {
607607
} else if (type instanceof Parser) {
608608
ctx.pushPath(varName);
609609
type.generate(ctx);
610-
ctx.popPath();
610+
ctx.popPath(varName);
611611
}
612612
};
613613

614614
Parser.prototype.generateChoice = function(ctx) {
615615
var tag = ctx.generateOption(this.options.tag);
616-
617-
ctx.pushCode('{0} = {};', ctx.generateVariable(this.varName));
616+
if (this.varName)
617+
{
618+
ctx.pushCode('{0} = {};', ctx.generateVariable(this.varName));
619+
}
618620
ctx.pushCode('switch({0}) {', tag);
619621
Object.keys(this.options.choices).forEach(function(tag) {
620622
var type = this.options.choices[tag];
@@ -638,7 +640,7 @@ Parser.prototype.generateNest = function(ctx) {
638640
ctx.pushCode('{0} = {};', nestVar);
639641
ctx.pushPath(this.varName);
640642
this.options.type.generate(ctx);
641-
ctx.popPath();
643+
ctx.popPath(this.varName);
642644
} else if (aliasRegistry[this.options.type]) {
643645
var tempVar = ctx.generateTmpVariable();
644646
ctx.pushCode('var {0} = {1}(offset);', tempVar, FUNCTION_PREFIX + this.options.type);

lib/context.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Context.prototype.generateOption = function(val) {
3737
case 'string':
3838
return this.generateVariable(val);
3939
case 'function':
40-
return '(' + val + ').call(' + this.generateVariable() + ')';
40+
return '(' + val + ').call(' + this.generateVariable() + ', vars)';
4141
}
4242
};
4343

@@ -63,11 +63,17 @@ Context.prototype.pushCode = function() {
6363
};
6464

6565
Context.prototype.pushPath = function(name) {
66-
this.scopes[this.scopes.length - 1].push(name);
66+
if (name)
67+
{
68+
this.scopes[this.scopes.length - 1].push(name);
69+
}
6770
};
6871

69-
Context.prototype.popPath = function() {
70-
this.scopes[this.scopes.length - 1].pop();
72+
Context.prototype.popPath = function(name) {
73+
if (name)
74+
{
75+
this.scopes[this.scopes.length - 1].pop();
76+
}
7177
};
7278

7379
Context.prototype.pushScope = function(name) {

test/composite_parser.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,33 @@ describe('Composite parser', function(){
321321
} ]
322322
});
323323
});
324+
325+
it('should allow parent parser attributes as choice key', function() {
326+
var ChildParser = Parser.start()
327+
.choice('data', {
328+
tag: function(vars) {
329+
return vars.version;
330+
},
331+
choices: {
332+
1: Parser.start().uint8('v1'),
333+
2: Parser.start().uint16('v2'),
334+
}
335+
});
336+
337+
var ParentParser = Parser.start()
338+
.uint8('version')
339+
.nest('child', { type: ChildParser });
340+
341+
var buffer = new Buffer([0x1, 0x2]);
342+
assert.deepEqual(ParentParser.parse(buffer), {
343+
version: 1, child: { data: { v1: 2 } }
344+
});
345+
346+
buffer = new Buffer([0x2, 0x3, 0x4]);
347+
assert.deepEqual(ParentParser.parse(buffer), {
348+
version: 2, child: { data: { v2: 0x0304 } }
349+
});
350+
});
324351
});
325352

326353
describe('Choice parser', function() {

0 commit comments

Comments
 (0)