Closed wpyoga closed 1 year ago
Sorry for the unclarity, you need to call useContextVars()
on the top-level parser. If you change
const parser = new Parser().array('data', {
to
const parser = new Parser().useContextVars().array('data', {
This works:
const Parser = require('binary-parser').Parser;
const buf = Buffer.from('a1012aa2027ab8a30460713d44ff03414243a401ff', 'hex');
const parser = new Parser().useContextVars().array('data', {
readUntil: 'eof',
type: new Parser()
.uint8('type')
.uint8('length')
.choice('value', {
tag: 'type',
choices: {
0xa1: new Parser().uint8('_a1'),
0xa2: new Parser().uint16be('_a2'),
0xa3: new Parser().buffer('_a3', { length: '$parent.length' }),
0xa4: new Parser().uint8('_a4'),
},
defaultChoice: new Parser().buffer('other', { length: '$parent.length' }),
}),
});
console.dir(parser.parse(buf), { depth: null });
Output:
{
data: [
{ type: 161, length: 1, value: { _a1: 42 } },
{ type: 162, length: 2, value: { _a2: 31416 } },
{
type: 163,
length: 4,
value: { _a3: Buffer(4) [Uint8Array] [ 96, 113, 61, 68 ] }
},
{
type: 255,
length: 3,
value: { other: Buffer(3) [Uint8Array] [ 65, 66, 67 ] }
},
{ type: 164, length: 1, value: { _a4: 255 } }
]
}
I see... your solution works. I'm curious though, does this mean useContextVars() have to declared at the very top level parser, and at that level only?
Yes, you have to declare it at the top level. If you call it at the lower levels it's simply ignored. This is required because the top-level parser has to know if the context vars is enabled as it sets$root
.
Closing since your initial problem seems resolved. Feel free to reopen if needed.
I see, thank you for the explanation.
When parsing a TLV with variable-length data (
choice
insidearray
), these methods don't work:length: "$parent.length"
length: "length"
length: function(vars) {return vars.length;}
If we try to access
"$parent.length"
(supposed to be introduced by #166), thents-node
will throw an error:If we use
"length"
, then parsing is abruptly stopped, although no error seems to be thrown.If we use
function(vars)
as mentioned in #126, it also doesn't work, and we get the same result as if we are using"length"
.If we specify a literal
length
likelength: 3
, which is known in advance (see0xff
type below) then it works. It just doesn't work if the length is read from the data itself.Using
.useContextVars()
doesn't help at all.Example, with multiple commented lines that can be uncommented in order to see the issue in action:
Am I doing something wrong here...?