diff --git a/lib/constructor.js b/lib/constructor.js index 07acd3b..64d7d19 100644 --- a/lib/constructor.js +++ b/lib/constructor.js @@ -64,7 +64,10 @@ function size_of(segments, bindings) { function writeInteger(segment, buf, offset, bindings) { var value = (segment.name) ? bindings[segment.name] : segment.value; - var size = segment.size * segment.unit; + var size = segment.size * segment.unit, mod = segment.mod; + if(mod){ + value = value * Math.pow(10, mod); + } switch (size) { case 8: buf.writeUInt8(value, offset); diff --git a/lib/grammar.pegjs b/lib/grammar.pegjs index e96023b..96b7647 100644 --- a/lib/grammar.pegjs +++ b/lib/grammar.pegjs @@ -59,9 +59,12 @@ specifierTail specifier = 'little' / 'big' / 'signed' / 'unsigned' / 'integer' / 'binary' / 'float' - / unit + / unit / mod unit = 'unit:' num:number { return 'unit:' + num; } +mod + = 'mod:' num:number { return 'mod:' + num; } + ws = [ \t\n]* diff --git a/lib/interp.js b/lib/interp.js index 352500c..e875a1d 100644 --- a/lib/interp.js +++ b/lib/interp.js @@ -112,7 +112,7 @@ function match(pattern, binary, boundvars) { function get_integer(segment) { debug("get_integer"); debug(segment); // let's do only multiples of eight bits for now - var unit = segment.unit, size = size_of(segment, vars); + var unit = segment.unit, size = size_of(segment, vars), mod = segment.mod; var bitsize = size * unit; var byteoffset = offset / 8; // NB assumes aligned offset += bitsize; @@ -120,8 +120,13 @@ function match(pattern, binary, boundvars) { return false; } else { - return parse_int(binary, byteoffset, bitsize, + num = parse_int(binary, byteoffset, bitsize, segment.bigendian, segment.signed); + if(mod){ + return (num * Math.pow(0.1, mod)).toFixed(mod); + } else { + return num; + } } } diff --git a/lib/pattern.js b/lib/pattern.js index 4985d83..f78336d 100644 --- a/lib/pattern.js +++ b/lib/pattern.js @@ -58,6 +58,7 @@ function specs(segment, type, specifiers) { switch (type) { case 'integer': segment.signed = signed_in(specifiers); + segment.mod = mod_in(specifiers); // fall through case 'float': segment.bigendian = endian_in(specifiers); @@ -89,13 +90,22 @@ function unit_in(specifiers, type) { // OK defaults then switch (type) { case 'binary': - return 8; case 'integer': case 'float': - return 1; + return 8; } } +function mod_in(specifiers) { + for (var s in specifiers) { + if (s.substr(0, 4) == 'mod:') { + var mod = parseInt(s.substr(4)); + return mod; + } + } + return 0; +} + function size_of(segment, type, size, unit) { if (size !== undefined && size !== '') { return size; @@ -103,9 +113,9 @@ function size_of(segment, type, size, unit) { else { switch (type) { case 'integer': - return 8; + return 1; case 'float': - return 64; + return 8; case 'binary': return true; }