2 // Refactored by Vjeux <vjeuxx@gmail.com>
3 // http://blog.vjeux.com/2010/javascript/javascript-binary-reader.html
6 //+ Jonas Raoni Soares Silva
7 //@ http://jsfromhell.com/classes/binary-parser [rev. #1]
9 BinaryReader = function (data
) {
14 BinaryReader
.prototype = {
18 readInt8: function (){ return this._decodeInt(8, true); },
19 readUInt8: function (){ return this._decodeInt(8, false); },
20 readInt16: function (){ return this._decodeInt(16, true); },
21 readUInt16: function (){ return this._decodeInt(16, false); },
22 readInt32: function (){ return this._decodeInt(32, true); },
23 readUInt32: function (){ return this._decodeInt(32, false); },
25 readFloat: function (){ return this._decodeFloat(23, 8); },
26 readDouble: function (){ return this._decodeFloat(52, 11); },
28 readChar: function () { return this.readString(1); },
29 readString: function (length
) {
30 this._checkSize(length
* 8);
31 var result
= this._buffer
.substr(this._pos
, length
);
36 seek: function (pos
) {
41 getPosition: function () {
45 getSize: function () {
46 return this._buffer
.length
;
52 _decodeFloat: function(precisionBits
, exponentBits
){
53 var length
= precisionBits
+ exponentBits
+ 1;
54 var size
= length
>> 3;
55 this._checkSize(length
);
57 var bias
= Math
.pow(2, exponentBits
- 1) - 1;
58 var signal
= this._readBits(precisionBits
+ exponentBits
, 1, size
);
59 var exponent
= this._readBits(precisionBits
, exponentBits
, size
);
62 // var curByte = length + (-precisionBits >> 3) - 1;
65 var byteValue
= this._readByte(++curByte
, size
);
66 var startBit
= precisionBits
% 8 || 8;
67 var mask
= 1 << startBit
;
69 if (byteValue
& mask
) {
70 significand
+= 1 / divisor
;
74 } while (precisionBits
-= startBit
);
78 return exponent
== (bias
<< 1) + 1 ? significand
? NaN
: signal
? -Infinity
: +Infinity
79 : (1 + signal
* -2) * (exponent
|| significand
? !exponent
? Math
.pow(2, -bias
+ 1) * significand
80 : Math
.pow(2, exponent
- bias
) * (1 + significand
) : 0);
83 _decodeInt: function(bits
, signed
){
84 var x
= this._readBits(0, bits
, bits
/ 8), max
= Math
.pow(2, bits
);
85 var result
= signed
&& x
>= max
/ 2 ? x
- max
: x
;
87 this._pos
+= bits
/ 8;
91 //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni)
92 _shl: function (a
, b
){
93 for (++b
; --b
; a
= ((a
%= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a
* 2 : (a
- 0x40000000) * 2 + 0x7fffffff + 1);
97 _readByte: function (i
, size
) {
98 return this._buffer
.charCodeAt(this._pos
+ size
- i
- 1) & 0xff;
101 _readBits: function (start
, length
, size
) {
102 var offsetLeft
= (start
+ length
) % 8;
103 var offsetRight
= start
% 8;
104 var curByte
= size
- (start
>> 3) - 1;
105 var lastByte
= size
+ (-(start
+ length
) >> 3);
106 var diff
= curByte
- lastByte
;
108 var sum
= (this._readByte(curByte
, size
) >> offsetRight
) & ((1 << (diff
? 8 - offsetRight
: length
)) - 1);
110 if (diff
&& offsetLeft
) {
111 sum
+= (this._readByte(lastByte
++, size
) & ((1 << offsetLeft
) - 1)) << (diff
-- << 3) - offsetRight
;
115 sum
+= this._shl(this._readByte(lastByte
++, size
), (diff
-- << 3) - offsetRight
);
121 _checkSize: function (neededBits
) {
122 if (!(this._pos
+ Math
.ceil(neededBits
/ 8) < this._buffer
.length
)) {
123 throw new Error("Index out of bound");