Skip to content

Commit 334ce37

Browse files
authored
Merge pull request #109 from Toxicable/offset-save
add saveoffset method
2 parents c4e29ee + 844fee4 commit 334ce37

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,30 @@ pointed by another field.
286286
- `offset` - (Required) Indicates absolute offset from the beginning of the
287287
input buffer. Can be a number, string or a function.
288288

289+
### saveOffset(name [,options])
290+
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.
291+
292+
```javascript
293+
var parser = new Parser()
294+
// this call advances the buffer offset by
295+
// a variable (i.e. unknown to us) number of bytes
296+
.string('name', {
297+
zeroTerminated: true
298+
})
299+
// this variable points to an absolute position
300+
// in the buffer
301+
.uint32('seekOffset')
302+
// now, save the "current" offset in the stream
303+
// as the variable "currentOffset"
304+
.saveOffset('currentOffset')
305+
// finally, use the saved offset to figure out
306+
// how many bytes we need to skip
307+
.skip(function() {
308+
return this.seekOffset - this.currentOffset;
309+
})
310+
... // the parser would continue here
311+
```
312+
289313
### skip(length)
290314
Skip `length` bytes.
291315

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
}
@@ -1123,4 +1132,9 @@ export class Parser {
11231132
// Restore offset
11241133
ctx.pushCode(`offset = ${tempVar};`);
11251134
}
1135+
1136+
private generateSaveOffset(ctx: Context) {
1137+
const varName = ctx.generateVariable(this.varName);
1138+
ctx.pushCode(`${varName} = offset`);
1139+
}
11261140
}

test/composite_parser.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,48 @@ describe('Composite parser', function() {
979979
});
980980
});
981981

982+
describe('SaveOffset', () => {
983+
it('should save the offset', () => {
984+
const buff = Buffer.from([0x01, 0x00, 0x02]);
985+
const parser = Parser.start()
986+
.int8('a')
987+
.int16('b')
988+
.saveoffset('bytesRead');
989+
990+
assert.deepEqual(parser.parse(buff), {
991+
a: 1,
992+
b: 2,
993+
bytesRead: 3,
994+
});
995+
});
996+
997+
it('should save the offset if not at end', () => {
998+
const buff = Buffer.from([0x01, 0x00, 0x02]);
999+
const parser = Parser.start()
1000+
.int8('a')
1001+
.saveoffset('bytesRead')
1002+
.int16('b');
1003+
1004+
assert.deepEqual(parser.parse(buff), {
1005+
a: 1,
1006+
b: 2,
1007+
bytesRead: 1,
1008+
});
1009+
});
1010+
1011+
it('should save the offset with a dynamic parser', () => {
1012+
const buff = Buffer.from([0x74, 0x65, 0x73, 0x74, 0x00]);
1013+
const parser = Parser.start()
1014+
.string('name', { zeroTerminated: true })
1015+
.saveoffset('bytesRead');
1016+
1017+
assert.deepEqual(parser.parse(buff), {
1018+
name: 'test',
1019+
bytesRead: 5,
1020+
});
1021+
});
1022+
});
1023+
9821024
describe('Utilities', function() {
9831025
it('should count size for fixed size structs', function() {
9841026
var parser = Parser.start()

0 commit comments

Comments
 (0)