From 239d8bd0c21e9ef5045956fc58ef4f9b3a3381c1 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 22 Nov 2011 04:36:48 +0100 Subject: [PATCH] fixed binaryParsers for small negativ values WARNING: bigint support is not correctly working for really big values. If the value of a integer gets big the number gets fuzzy in javascript. This is not a limitation of this library. If you want to handle bigint with the exact value, get it as string and do not calculate things with it! --- lib/binaryParsers.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/binaryParsers.js b/lib/binaryParsers.js index dcec67dc..9333a972 100644 --- a/lib/binaryParsers.js +++ b/lib/binaryParsers.js @@ -1,8 +1,17 @@ -var parseBits = function(data, bits, offset, callback) { +var parseBits = function(data, bits, offset, invert, callback) { offset = offset || 0; + invert = invert || false; callback = callback || function(lastValue, newValue, bits) { return (lastValue * Math.pow(2, bits)) + newValue; }; var offsetBytes = offset >> 3; + var inv = function(value) { + if (invert) { + return ~value & 0xff; + } + + return value; + }; + // read first (maybe partial) byte var mask = 0xff; var firstBits = 8 - (offset % 8); @@ -17,19 +26,19 @@ var parseBits = function(data, bits, offset, callback) { var result = 0; if ((offset % 8) + bits >= 8) { - result = callback(0, data[offsetBytes] & mask, firstBits); + result = callback(0, inv(data[offsetBytes]) & mask, firstBits); } // read bytes var bytes = (bits + offset) >> 3; for (var i = offsetBytes + 1; i < bytes; i++) { - result = callback(result, data[i], 8); + result = callback(result, inv(data[i]), 8); } // bits to read, that are not a complete byte var lastBits = (bits + offset) % 8; if (lastBits > 0) { - result = callback(result, data[bytes] >> (8 - lastBits), lastBits); + result = callback(result, inv(data[bytes]) >> (8 - lastBits), lastBits); } return result; @@ -60,7 +69,7 @@ var parseFloatFromBits = function(data, precisionBits, exponentBits) { return lastValue; }; - var mantissa = parseBits(data, precisionBits, exponentBits + 1, parsePrecisionBits); + var mantissa = parseBits(data, precisionBits, exponentBits + 1, false, parsePrecisionBits); // special cases if (exponent == (Math.pow(2, exponentBits + 1) - 1)) { @@ -81,7 +90,7 @@ var parseBool = function(value) { var parseInt16 = function(value) { if (parseBits(value, 1) == 1) { - return -1 * (Math.pow(2, 15) - parseBits(value, 15, 1)); + return -1 * (parseBits(value, 15, 1, true) + 1); } return parseBits(value, 15, 1); @@ -89,7 +98,7 @@ var parseInt16 = function(value) { var parseInt32 = function(value) { if (parseBits(value, 1) == 1) { - return -1 * (Math.pow(2, 31) - parseBits(value, 31, 1)); + return -1 * (parseBits(value, 31, 1, true) + 1); } return parseBits(value, 31, 1); @@ -97,7 +106,7 @@ var parseInt32 = function(value) { var parseInt64 = function(value) { if (parseBits(value, 1) == 1) { - return -1 * (Math.pow(2, 63) - parseBits(value, 63, 1)); + return -1 * (parseBits(value, 63, 1, true) + 1); } return parseBits(value, 63, 1);