From bc024e3d3db856b75a637837136064d3b3558518 Mon Sep 17 00:00:00 2001 From: Alan Sikora Date: Thu, 27 Sep 2018 12:34:23 -0300 Subject: [PATCH] Added the possibility of reading little endian bits --- lib/binary_parser.js | 75 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/lib/binary_parser.js b/lib/binary_parser.js index 12ece7ee..1fdccc56 100644 --- a/lib/binary_parser.js +++ b/lib/binary_parser.js @@ -29,7 +29,8 @@ var SPECIAL_TYPES = { Skip: null, Choice: null, Nest: null, - Bit: null + Bit: null, + Bitle: null, }; var aliasRegistry = {}; @@ -100,6 +101,14 @@ BIT_RANGE.forEach(function(i) { options.length = i; return this.setNextParser("bit", varName, options); }; + + Parser.prototype["bitle" + i.toString()] = function(varName, options) { + if (!options) { + options = {}; + } + options.length = i; + return this.setNextParser("bitle", varName, options); + }; }); Parser.prototype.namely = function(alias) { @@ -487,17 +496,17 @@ Parser.prototype.generateBit = function(ctx) { ctx.pushCode("var {0} = buffer.readUInt8(offset);", val); sum = 8; } else if (sum <= 16) { - ctx.pushCode("var {0} = buffer.readUInt16BE(offset);", val); + ctx.pushCode(`var {0} = buffer.readUInt16BE(offset);`, val); sum = 16; } else if (sum <= 24) { var val1 = ctx.generateTmpVariable(); var val2 = ctx.generateTmpVariable(); - ctx.pushCode("var {0} = buffer.readUInt16BE(offset);", val1); + ctx.pushCode(`var {0} = buffer.readUInt16BE(offset);`, val1); ctx.pushCode("var {0} = buffer.readUInt8(offset + 2);", val2); ctx.pushCode("var {2} = ({0} << 8) | {1};", val1, val2, val); sum = 24; } else if (sum <= 32) { - ctx.pushCode("var {0} = buffer.readUInt32BE(offset);", val); + ctx.pushCode(`var {0} = buffer.readUInt32BE(offset);`, val); sum = 32; } else { throw new Error( @@ -523,6 +532,62 @@ Parser.prototype.generateBit = function(ctx) { } }; +Parser.prototype.generateBitle = function(ctx) { + // TODO find better method to handle nested bit fields + var parser = JSON.parse(JSON.stringify(this)); + parser.varName = ctx.generateVariable(parser.varName); + ctx.bitFields.push(parser); + + if ( + !this.next || + (this.next && ["Bitle", "Nest"].indexOf(this.next.type) < 0) + ) { + var sum = 0; + ctx.bitFields.forEach(function(parser) { + sum += parser.options.length; + }); + + var val = ctx.generateTmpVariable(); + + if (sum <= 8) { + ctx.pushCode("var {0} = buffer.readUInt8(offset);", val); + sum = 8; + } else if (sum <= 16) { + ctx.pushCode(`var {0} = buffer.readUInt16LE(offset);`, val); + sum = 16; + } else if (sum <= 24) { + var val1 = ctx.generateTmpVariable(); + var val2 = ctx.generateTmpVariable(); + ctx.pushCode(`var {0} = buffer.readUInt16LE(offset);`, val1); + ctx.pushCode("var {0} = buffer.readUInt8(offset + 2);", val2); + ctx.pushCode("var {2} = ({0} << 8) | {1};", val1, val2, val); + sum = 24; + } else if (sum <= 32) { + ctx.pushCode(`var {0} = buffer.readUInt32LE(offset);`, val); + sum = 32; + } else { + throw new Error( + "Currently, bit field sequence longer than 4-bytes is not supported." + ); + } + ctx.pushCode("offset += {0};", sum / 8); + + var bitOffset = 0; + ctx.bitFields.forEach(function(parser) { + ctx.pushCode( + "{0} = {1} >> {2} & {3};", + parser.varName, + val, + bitOffset, + (1 << parser.options.length) - 1 + ); + bitOffset += parser.options.length; + }); + + ctx.bitFields = []; + } +}; + Parser.prototype.generateSkip = function(ctx) { var length = ctx.generateOption(this.options.length); ctx.pushCode("offset += {0};", length); @@ -739,7 +804,7 @@ Parser.prototype.generateFormatter = function(ctx, varName, formatter) { }; Parser.prototype.isInteger = function() { - return !!this.type.match(/U?Int[8|16|32][BE|LE]?|Bit\d+/); + return !!this.type.match(/U?Int[8|16|32][BE|LE]?|Bit\d+|Bitle\d+/); }; //========================================================================================