bit_iterator.js 1.11 KB
var BITMASK = [0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF];

// returns a function that reads bits.
// takes a buffer iterator as input
module.exports = function bitIterator(nextBuffer) {
    var bit = 0, byte = 0;
    var bytes = nextBuffer();
    var f = function(n) {
        if (n === null && bit != 0) {  // align to byte boundary
            bit = 0
            byte++;
            return;
        }
        var result = 0;
        while(n > 0) {
            if (byte >= bytes.length) {
                byte = 0;
                bytes = nextBuffer();
            }
            var left = 8 - bit;
            if (bit === 0 && n > 0)
                f.bytesRead++;
            if (n >= left) {
                result <<= left;
                result |= (BITMASK[left] & bytes[byte++]);
                bit = 0;
                n -= left;
            } else {
                result <<= n;
                result |= ((bytes[byte] & (BITMASK[n] << (8 - n - bit))) >> (8 - n - bit));
                bit += n;
                n = 0;
            }
        }
        return result;
    };
    f.bytesRead = 0;
    return f;
};