mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-08 12:11:51 +09:00
85 lines
2.6 KiB
JavaScript
85 lines
2.6 KiB
JavaScript
var Bits = {
|
|
createNew: function (vec) {
|
|
var bits = {
|
|
vec: vec, // ArrayBuffer
|
|
bitPos: 0,
|
|
bytePos: 0
|
|
};
|
|
|
|
/**
|
|
* @return {number}
|
|
*/
|
|
bits.Bit = function () {
|
|
if (bits.vec.byteLength <= bits.bytePos) {
|
|
// TODO: Should this return error?
|
|
return 0;
|
|
}
|
|
var dv = new DataView(bits.vec, bits.bytePos);
|
|
var tmp = (dv.getUint8(0) >>> (7 - bits.bitPos)) >>> 0;
|
|
tmp &= 0x01;
|
|
bits.bytePos += ((bits.bitPos + 1) >>> 3) >>> 0;
|
|
bits.bitPos = (bits.bitPos + 1) & 0x07;
|
|
return tmp;
|
|
};
|
|
|
|
/**
|
|
* @return {number}
|
|
*/
|
|
bits.Bits = function (num) {
|
|
if (num === 0) {
|
|
return 0;
|
|
}
|
|
if (bits.vec.byteLength <= bits.bytePos) {
|
|
// TODO: Should this return error?
|
|
return 0;
|
|
}
|
|
var bb = new DataView(bits.vec, bits.bytePos);
|
|
// always end bit wise ops with >>> 0 so the result gets interpreted as unsigned.
|
|
// don't use >>. If the left-most bit is 1 it will try to preseve the sign and thus will introduce 1's to the left. Always use >>>.
|
|
// see https://stackoverflow.com/a/6798829
|
|
var tmp = (((getValue(bb, 0) << 24) >>> 0) | ((getValue(bb, 1) << 16) >>> 0) | ((getValue(bb, 2) << 8) >>> 0) | (getValue(bb, 3) >>> 0)) >>> 0;
|
|
tmp = (tmp << bits.bitPos) >>> 0;
|
|
tmp = (tmp >>> (32 - num)) >>> 0;
|
|
bits.bytePos += ((bits.bitPos + num) >>> 3) >>> 0;
|
|
bits.bitPos = (bits.bitPos + num) & 0x07;
|
|
return tmp;
|
|
};
|
|
|
|
bits.Tail = function (offset) {
|
|
var a = new Uint8Array(bits.vec);
|
|
return a.slice(bits.vec.byteLength - offset).buffer;
|
|
// return new Uint8Array(bits.vec, bits.vec.byteLength - offset).buffer;
|
|
};
|
|
|
|
bits.LenInBytes = function () {
|
|
return bits.vec.byteLength;
|
|
};
|
|
|
|
/**
|
|
* @return {number}
|
|
*/
|
|
bits.BitPos = function () {
|
|
return ((bits.bytePos << 3) >>> 0) + bits.bitPos;
|
|
};
|
|
|
|
bits.SetPos = function (pos) {
|
|
bits.bytePos = (pos >>> 3) >>> 0;
|
|
bits.bitPos = (pos & 0x7) >>> 0;
|
|
};
|
|
|
|
return bits;
|
|
},
|
|
append: function (bits, buf) {
|
|
return Bits.createNew(bits.vec.concat(buf));
|
|
},
|
|
};
|
|
|
|
var getValue = function (dv, index) {
|
|
if (index >= dv.byteLength) {
|
|
return 0;
|
|
}
|
|
return dv.getUint8(index);
|
|
};
|
|
|
|
exports = Bits;
|