Skip to content

Commit 1b75344

Browse files
author
Fabian Wiles
committed
add saveoffset method
1 parent 810c290 commit 1b75344

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,30 @@ Jump to `offset`, execute parser for `type` and rewind to previous offset.
289289
start of the input buffer. Can be a string `[u]int{8, 16, 32, 64}{le, be}`
290290
or an user defined Parser object.
291291

292+
### saveOffset(name [,options])
293+
Save the current buffer offset as key `name`. This function is only useful when called after another function which would advance the internal buffer offset.
294+
295+
```javascript
296+
var parser = new Parser()
297+
// this call advances the buffer offset by
298+
// a variable (i.e. unknown to us) number of bytes
299+
.string('name', {
300+
zeroTerminated: true
301+
})
302+
// this variable points to an absolute position
303+
// in the buffer
304+
.uint32('seekOffset')
305+
// now, save the "current" offset in the stream
306+
// as the variable "currentOffset"
307+
.saveOffset('currentOffset')
308+
// finally, use the saved offset to figure out
309+
// how many bytes we need to skip
310+
.skip(function() {
311+
return this.seekOffset - this.currentOffset;
312+
})
313+
... // the parser would continue here
314+
```
315+
292316
### skip(length)
293317
Skip parsing for `length` bytes.
294318

lib/binary_parser.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type ComplexTypes =
3535
| 'nest'
3636
| 'skip'
3737
| 'pointer'
38+
| 'saveoffset'
3839
| '';
3940

4041
type Endianess = 'be' | 'le';
@@ -151,6 +152,7 @@ const CAPITILIZED_TYPE_NAMES: { [key in Types]: string } = {
151152
nest: 'Nest',
152153
skip: 'Skip',
153154
pointer: 'Pointer',
155+
saveoffset: 'SaveOffset',
154156
'': '',
155157
};
156158

@@ -539,6 +541,10 @@ export class Parser {
539541
return this.setNextParser('pointer', varName, options);
540542
}
541543

544+
saveoffset(varName: string, options?: ParserOptions) {
545+
return this.setNextParser('saveoffset', varName, options);
546+
}
547+
542548
endianess(endianess: 'little' | 'big') {
543549
switch (endianess.toLowerCase()) {
544550
case 'little':
@@ -762,6 +768,9 @@ export class Parser {
762768
case 'pointer':
763769
this.generatePointer(ctx);
764770
break;
771+
case 'saveoffset':
772+
this.generateSaveOffset(ctx);
773+
break;
765774
}
766775
this.generateAssert(ctx);
767776
}
@@ -1108,4 +1117,9 @@ export class Parser {
11081117
// Restore offset
11091118
ctx.pushCode(`offset = ${tempVar};`);
11101119
}
1120+
1121+
private generateSaveOffset(ctx: Context) {
1122+
const varName = ctx.generateVariable(this.varName);
1123+
ctx.pushCode(`${varName} = offset`);
1124+
}
11111125
}

test/composite_parser.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,40 @@ describe('Composite parser', function() {
995995
});
996996
});
997997

998+
describe('SaveOffset', () => {
999+
it('should save the offset', () => {
1000+
const buff = Buffer.from([0x01, 0x00, 0x02]);
1001+
const parser = Parser.start().int8('a').int16('b').saveoffset('bytesRead');
1002+
1003+
assert.deepEqual(parser.parse(buff), {
1004+
a: 1,
1005+
b: 2,
1006+
bytesRead: 3,
1007+
})
1008+
})
1009+
1010+
it('should save the offset if not at end', () => {
1011+
const buff = Buffer.from([0x01, 0x00, 0x02]);
1012+
const parser = Parser.start().int8('a').saveoffset('bytesRead').int16('b');
1013+
1014+
assert.deepEqual(parser.parse(buff), {
1015+
a: 1,
1016+
b: 2,
1017+
bytesRead: 1,
1018+
})
1019+
})
1020+
1021+
it('should save the offset with a dynamic parser', () => {
1022+
const buff = Buffer.from([0x74, 0x65, 0x73, 0x74, 0x00]);
1023+
const parser = Parser.start().string('name', {zeroTerminated: true}).saveoffset('bytesRead');
1024+
1025+
assert.deepEqual(parser.parse(buff), {
1026+
name: 'test',
1027+
bytesRead: 5,
1028+
})
1029+
})
1030+
})
1031+
9981032
describe('Utilities', function() {
9991033
it('should count size for fixed size structs', function() {
10001034
var parser = Parser.start()

0 commit comments

Comments
 (0)