UNPKG

lz4

Version:

LZ4 streaming compression and decompression

1,974 lines (1,657 loc) 264 kB
require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({"./utils":[function(require,module,exports){ /** * Javascript emulated bindings */ var XXH = require('xxhashjs').h32 // XXX .h64 var CHECKSUM_SEED = 0 // Header checksum is second byte of xxhash using 0 as a seed exports.descriptorChecksum = function (d) { return (XXH(d, CHECKSUM_SEED).toNumber() >> 8) & 0xFF } exports.blockChecksum = function (d) { return XXH(d, CHECKSUM_SEED).toNumber() } exports.streamChecksum = function (d, c) { if (d === null) return c.digest().toNumber() if (c === null) c = XXH(CHECKSUM_SEED) return c.update(d) } // Provide simple readUInt32LE as the Buffer ones from node and browserify are incompatible exports.readUInt32LE = function (buffer, offset) { const val = (buffer[offset]) | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24) // bitwise operators operate on signed values, this trick returns the result unsigned return val >>> 0; } exports.bindings = require('./binding') },{"./binding":1,"xxhashjs":"xxhashjs"}],1:[function(require,module,exports){ /** Javascript version of the key LZ4 C functions */ var uint32 = require('cuint').UINT32 if (!Math.imul) Math.imul = function imul(a, b) { var ah = a >>> 16; var al = a & 0xffff; var bh = b >>> 16; var bl = b & 0xffff; return (al*bl + ((ah*bl + al*bh) << 16))|0; }; /** * Decode a block. Assumptions: input contains all sequences of a * chunk, output is large enough to receive the decoded data. * If the output buffer is too small, an error will be thrown. * If the returned value is negative, an error occured at the returned offset. * * @param input {Buffer} input data * @param output {Buffer} output data * @return {Number} number of decoded bytes * @private */ exports.uncompress = function (input, output, sIdx, eIdx) { sIdx = sIdx || 0 eIdx = eIdx || (input.length - sIdx) // Process each sequence in the incoming data for (var i = sIdx, n = eIdx, j = 0; i < n;) { var token = input[i++] // Literals var literals_length = (token >> 4) if (literals_length > 0) { // length of literals var l = literals_length + 240 while (l === 255) { l = input[i++] literals_length += l } // Copy the literals var end = i + literals_length while (i < end) output[j++] = input[i++] // End of buffer? if (i === n) return j } // Match copy // 2 bytes offset (little endian) var offset = input[i++] | (input[i++] << 8) // 0 is an invalid offset value if (offset === 0 || offset > j) return -(i-2) // length of match copy var match_length = (token & 0xf) var l = match_length + 240 while (l === 255) { l = input[i++] match_length += l } // Copy the match var pos = j - offset // position of the match copy in the current output var end = j + match_length + 4 // minmatch = 4 while (j < end) output[j++] = output[pos++] } return j } var maxInputSize = 0x7E000000 , minMatch = 4 // uint32() optimization , hashLog = 16 , hashShift = (minMatch * 8) - hashLog , hashSize = 1 << hashLog , copyLength = 8 , lastLiterals = 5 , mfLimit = copyLength + minMatch , skipStrength = 6 , mlBits = 4 , mlMask = (1 << mlBits) - 1 , runBits = 8 - mlBits , runMask = (1 << runBits) - 1 , hasher = 2654435761 // CompressBound returns the maximum length of a lz4 block, given it's uncompressed length exports.compressBound = function (isize) { return isize > maxInputSize ? 0 : (isize + (isize/255) + 16) | 0 } exports.compress = function (src, dst, sIdx, eIdx) { // V8 optimization: non sparse array with integers var hashTable = new Array(hashSize) for (var i = 0; i < hashSize; i++) { hashTable[i] = 0 } return compressBlock(src, dst, 0, hashTable, sIdx || 0, eIdx || dst.length) } exports.compressHC = exports.compress exports.compressDependent = compressBlock function compressBlock (src, dst, pos, hashTable, sIdx, eIdx) { var dpos = sIdx var dlen = eIdx - sIdx var anchor = 0 if (src.length >= maxInputSize) throw new Error("input too large") // Minimum of input bytes for compression (LZ4 specs) if (src.length > mfLimit) { var n = exports.compressBound(src.length) if ( dlen < n ) throw Error("output too small: " + dlen + " < " + n) var step = 1 , findMatchAttempts = (1 << skipStrength) + 3 // Keep last few bytes incompressible (LZ4 specs): // last 5 bytes must be literals , srcLength = src.length - mfLimit while (pos + minMatch < srcLength) { // Find a match // min match of 4 bytes aka sequence var sequenceLowBits = src[pos+1]<<8 | src[pos] var sequenceHighBits = src[pos+3]<<8 | src[pos+2] // compute hash for the current sequence var hash = Math.imul(sequenceLowBits | (sequenceHighBits << 16), hasher) >>> hashShift // get the position of the sequence matching the hash // NB. since 2 different sequences may have the same hash // it is double-checked below // do -1 to distinguish between initialized and uninitialized values var ref = hashTable[hash] - 1 // save position of current sequence in hash table hashTable[hash] = pos + 1 // first reference or within 64k limit or current sequence !== hashed one: no match if ( ref < 0 || ((pos - ref) >>> 16) > 0 || ( ((src[ref+3]<<8 | src[ref+2]) != sequenceHighBits) || ((src[ref+1]<<8 | src[ref]) != sequenceLowBits ) ) ) { // increase step if nothing found within limit step = findMatchAttempts++ >> skipStrength pos += step continue } findMatchAttempts = (1 << skipStrength) + 3 // got a match var literals_length = pos - anchor var offset = pos - ref // minMatch already verified pos += minMatch ref += minMatch // move to the end of the match (>=minMatch) var match_length = pos while (pos < srcLength && src[pos] == src[ref]) { pos++ ref++ } // match length match_length = pos - match_length // token var token = match_length < mlMask ? match_length : mlMask // encode literals length if (literals_length >= runMask) { // add match length to the token dst[dpos++] = (runMask << mlBits) + token for (var len = literals_length - runMask; len > 254; len -= 255) { dst[dpos++] = 255 } dst[dpos++] = len } else { // add match length to the token dst[dpos++] = (literals_length << mlBits) + token } // write literals for (var i = 0; i < literals_length; i++) { dst[dpos++] = src[anchor+i] } // encode offset dst[dpos++] = offset dst[dpos++] = (offset >> 8) // encode match length if (match_length >= mlMask) { match_length -= mlMask while (match_length >= 255) { match_length -= 255 dst[dpos++] = 255 } dst[dpos++] = match_length } anchor = pos } } // cannot compress input if (anchor == 0) return 0 // Write last literals // encode literals length literals_length = src.length - anchor if (literals_length >= runMask) { // add match length to the token dst[dpos++] = (runMask << mlBits) for (var ln = literals_length - runMask; ln > 254; ln -= 255) { dst[dpos++] = 255 } dst[dpos++] = ln } else { // add match length to the token dst[dpos++] = (literals_length << mlBits) } // write literals pos = anchor while (pos < src.length) { dst[dpos++] = src[pos++] } return dpos } },{"cuint":10}],2:[function(require,module,exports){ (function (Buffer){(function (){ var Decoder = require('./decoder_stream') /** Decode an LZ4 stream */ function LZ4_uncompress (input, options) { var output = [] var decoder = new Decoder(options) decoder.on('data', function (chunk) { output.push(chunk) }) decoder.end(input) return Buffer.concat(output) } exports.LZ4_uncompress = LZ4_uncompress }).call(this)}).call(this,require("buffer").Buffer) },{"./decoder_stream":3,"buffer":"buffer"}],3:[function(require,module,exports){ (function (Buffer){(function (){ var Transform = require('stream').Transform var inherits = require('util').inherits var lz4_static = require('./static') var utils = lz4_static.utils var lz4_binding = utils.bindings var lz4_jsbinding = require('./binding') var STATES = lz4_static.STATES var SIZES = lz4_static.SIZES function Decoder (options) { if ( !(this instanceof Decoder) ) return new Decoder(options) Transform.call(this, options) // Options this.options = options || {} this.binding = this.options.useJS ? lz4_jsbinding : lz4_binding // Encoded data being processed this.buffer = null // Current position within the data this.pos = 0 this.descriptor = null // Current state of the parsing this.state = STATES.MAGIC this.notEnoughData = false this.descriptorStart = 0 this.streamSize = null this.dictId = null this.currentStreamChecksum = null this.dataBlockSize = 0 this.skippableSize = 0 } inherits(Decoder, Transform) Decoder.prototype._transform = function (data, encoding, done) { // Handle skippable data if (this.skippableSize > 0) { this.skippableSize -= data.length if (this.skippableSize > 0) { // More to skip done() return } data = data.slice(-this.skippableSize) this.skippableSize = 0 this.state = STATES.MAGIC } // Buffer the incoming data this.buffer = this.buffer ? Buffer.concat( [ this.buffer, data ], this.buffer.length + data.length ) : data this._main(done) } Decoder.prototype.emit_Error = function (msg) { this.emit( 'error', new Error(msg + ' @' + this.pos) ) } Decoder.prototype.check_Size = function (n) { var delta = this.buffer.length - this.pos if (delta <= 0 || delta < n) { if (this.notEnoughData) this.emit_Error( 'Unexpected end of LZ4 stream' ) return true } this.pos += n return false } Decoder.prototype.read_MagicNumber = function () { var pos = this.pos if ( this.check_Size(SIZES.MAGIC) ) return true var magic = utils.readUInt32LE(this.buffer, pos) // Skippable chunk if ( (magic & 0xFFFFFFF0) === lz4_static.MAGICNUMBER_SKIPPABLE ) { this.state = STATES.SKIP_SIZE return } // LZ4 stream if ( magic !== lz4_static.MAGICNUMBER ) { this.pos = pos this.emit_Error( 'Invalid magic number: ' + magic.toString(16).toUpperCase() ) return true } this.state = STATES.DESCRIPTOR } Decoder.prototype.read_SkippableSize = function () { var pos = this.pos if ( this.check_Size(SIZES.SKIP_SIZE) ) return true this.state = STATES.SKIP_DATA this.skippableSize = utils.readUInt32LE(this.buffer, pos) } Decoder.prototype.read_Descriptor = function () { // Flags var pos = this.pos if ( this.check_Size(SIZES.DESCRIPTOR) ) return true this.descriptorStart = pos // version var descriptor_flg = this.buffer[pos] var version = descriptor_flg >> 6 if ( version !== lz4_static.VERSION ) { this.pos = pos this.emit_Error( 'Invalid version: ' + version + ' != ' + lz4_static.VERSION ) return true } // flags // reserved bit should not be set if ( (descriptor_flg >> 1) & 0x1 ) { this.pos = pos this.emit_Error('Reserved bit set') return true } var blockMaxSizeIndex = (this.buffer[pos+1] >> 4) & 0x7 var blockMaxSize = lz4_static.blockMaxSizes[ blockMaxSizeIndex ] if ( blockMaxSize === null ) { this.pos = pos this.emit_Error( 'Invalid block max size: ' + blockMaxSizeIndex ) return true } this.descriptor = { blockIndependence: Boolean( (descriptor_flg >> 5) & 0x1 ) , blockChecksum: Boolean( (descriptor_flg >> 4) & 0x1 ) , blockMaxSize: blockMaxSize , streamSize: Boolean( (descriptor_flg >> 3) & 0x1 ) , streamChecksum: Boolean( (descriptor_flg >> 2) & 0x1 ) , dict: Boolean( descriptor_flg & 0x1 ) , dictId: 0 } this.state = STATES.SIZE } Decoder.prototype.read_Size = function () { if (this.descriptor.streamSize) { var pos = this.pos if ( this.check_Size(SIZES.SIZE) ) return true //TODO max size is unsigned 64 bits this.streamSize = this.buffer.slice(pos, pos + 8) } this.state = STATES.DICTID } Decoder.prototype.read_DictId = function () { if (this.descriptor.dictId) { var pos = this.pos if ( this.check_Size(SIZES.DICTID) ) return true this.dictId = utils.readUInt32LE(this.buffer, pos) } this.state = STATES.DESCRIPTOR_CHECKSUM } Decoder.prototype.read_DescriptorChecksum = function () { var pos = this.pos if ( this.check_Size(SIZES.DESCRIPTOR_CHECKSUM) ) return true var checksum = this.buffer[pos] var currentChecksum = utils.descriptorChecksum( this.buffer.slice(this.descriptorStart, pos) ) if (currentChecksum !== checksum) { this.pos = pos this.emit_Error( 'Invalid stream descriptor checksum' ) return true } this.state = STATES.DATABLOCK_SIZE } Decoder.prototype.read_DataBlockSize = function () { var pos = this.pos if ( this.check_Size(SIZES.DATABLOCK_SIZE) ) return true var datablock_size = utils.readUInt32LE(this.buffer, pos) // Uncompressed if ( datablock_size === lz4_static.EOS ) { this.state = STATES.EOS return } // if (datablock_size > this.descriptor.blockMaxSize) { // this.emit_Error( 'ASSERTION: invalid datablock_size: ' + datablock_size.toString(16).toUpperCase() + ' > ' + this.descriptor.blockMaxSize.toString(16).toUpperCase() ) // } this.dataBlockSize = datablock_size this.state = STATES.DATABLOCK_DATA } Decoder.prototype.read_DataBlockData = function () { var pos = this.pos var datablock_size = this.dataBlockSize if ( datablock_size & 0x80000000 ) { // Uncompressed size datablock_size = datablock_size & 0x7FFFFFFF } if ( this.check_Size(datablock_size) ) return true this.dataBlock = this.buffer.slice(pos, pos + datablock_size) this.state = STATES.DATABLOCK_CHECKSUM } Decoder.prototype.read_DataBlockChecksum = function () { var pos = this.pos if (this.descriptor.blockChecksum) { if ( this.check_Size(SIZES.DATABLOCK_CHECKSUM) ) return true var checksum = utils.readUInt32LE(this.buffer, this.pos-4) var currentChecksum = utils.blockChecksum( this.dataBlock ) if (currentChecksum !== checksum) { this.pos = pos this.emit_Error( 'Invalid block checksum' ) return true } } this.state = STATES.DATABLOCK_UNCOMPRESS } Decoder.prototype.uncompress_DataBlock = function () { var uncompressed // uncompressed? if ( this.dataBlockSize & 0x80000000 ) { uncompressed = this.dataBlock } else { uncompressed = Buffer.alloc(this.descriptor.blockMaxSize) var decodedSize = this.binding.uncompress( this.dataBlock, uncompressed ) if (decodedSize < 0) { this.emit_Error( 'Invalid data block: ' + (-decodedSize) ) return true } if ( decodedSize < this.descriptor.blockMaxSize ) uncompressed = uncompressed.slice(0, decodedSize) } this.dataBlock = null this.push( uncompressed ) // Stream checksum if (this.descriptor.streamChecksum) { this.currentStreamChecksum = utils.streamChecksum(uncompressed, this.currentStreamChecksum) } this.state = STATES.DATABLOCK_SIZE } Decoder.prototype.read_EOS = function () { if (this.descriptor.streamChecksum) { var pos = this.pos if ( this.check_Size(SIZES.EOS) ) return true var checksum = utils.readUInt32LE(this.buffer, pos) if ( checksum !== utils.streamChecksum(null, this.currentStreamChecksum) ) { this.pos = pos this.emit_Error( 'Invalid stream checksum: ' + checksum.toString(16).toUpperCase() ) return true } } this.state = STATES.MAGIC } Decoder.prototype._flush = function (done) { // Error on missing data as no more will be coming this.notEnoughData = true this._main(done) } Decoder.prototype._main = function (done) { var pos = this.pos var notEnoughData while ( !notEnoughData && this.pos < this.buffer.length ) { if (this.state === STATES.MAGIC) notEnoughData = this.read_MagicNumber() if (this.state === STATES.SKIP_SIZE) notEnoughData = this.read_SkippableSize() if (this.state === STATES.DESCRIPTOR) notEnoughData = this.read_Descriptor() if (this.state === STATES.SIZE) notEnoughData = this.read_Size() if (this.state === STATES.DICTID) notEnoughData = this.read_DictId() if (this.state === STATES.DESCRIPTOR_CHECKSUM) notEnoughData = this.read_DescriptorChecksum() if (this.state === STATES.DATABLOCK_SIZE) notEnoughData = this.read_DataBlockSize() if (this.state === STATES.DATABLOCK_DATA) notEnoughData = this.read_DataBlockData() if (this.state === STATES.DATABLOCK_CHECKSUM) notEnoughData = this.read_DataBlockChecksum() if (this.state === STATES.DATABLOCK_UNCOMPRESS) notEnoughData = this.uncompress_DataBlock() if (this.state === STATES.EOS) notEnoughData = this.read_EOS() } if (this.pos > pos) { this.buffer = this.buffer.slice(this.pos) this.pos = 0 } done() } module.exports = Decoder }).call(this)}).call(this,require("buffer").Buffer) },{"./binding":1,"./static":6,"buffer":"buffer","stream":35,"util":40}],4:[function(require,module,exports){ (function (Buffer){(function (){ var Encoder = require('./encoder_stream') /** Encode an LZ4 stream */ function LZ4_compress (input, options) { var output = [] var encoder = new Encoder(options) encoder.on('data', function (chunk) { output.push(chunk) }) encoder.end(input) return Buffer.concat(output) } exports.LZ4_compress = LZ4_compress }).call(this)}).call(this,require("buffer").Buffer) },{"./encoder_stream":5,"buffer":"buffer"}],5:[function(require,module,exports){ (function (Buffer){(function (){ var Transform = require('stream').Transform var inherits = require('util').inherits var lz4_static = require('./static') var utils = lz4_static.utils var lz4_binding = utils.bindings var lz4_jsbinding = require('./binding') var STATES = lz4_static.STATES var SIZES = lz4_static.SIZES var defaultOptions = { blockIndependence: true , blockChecksum: false , blockMaxSize: 4<<20 , streamSize: false , streamChecksum: true , dict: false , dictId: 0 , highCompression: false } function Encoder (options) { if ( !(this instanceof Encoder) ) return new Encoder(options) Transform.call(this, options) // Set the options var o = options || defaultOptions if (o !== defaultOptions) Object.keys(defaultOptions).forEach(function (p) { if ( !o.hasOwnProperty(p) ) o[p] = defaultOptions[p] }) this.options = o this.binding = this.options.useJS ? lz4_jsbinding : lz4_binding this.compress = o.highCompression ? this.binding.compressHC : this.binding.compress // Build the stream descriptor from the options // flags var descriptor_flg = 0 descriptor_flg = descriptor_flg | (lz4_static.VERSION << 6) // Version descriptor_flg = descriptor_flg | ((o.blockIndependence & 1) << 5) // Block independence descriptor_flg = descriptor_flg | ((o.blockChecksum & 1) << 4) // Block checksum descriptor_flg = descriptor_flg | ((o.streamSize & 1) << 3) // Stream size descriptor_flg = descriptor_flg | ((o.streamChecksum & 1) << 2) // Stream checksum // Reserved bit descriptor_flg = descriptor_flg | (o.dict & 1) // Preset dictionary // block maximum size var descriptor_bd = lz4_static.blockMaxSizes.indexOf(o.blockMaxSize) if (descriptor_bd < 0) throw new Error('Invalid blockMaxSize: ' + o.blockMaxSize) this.descriptor = { flg: descriptor_flg, bd: (descriptor_bd & 0x7) << 4 } // Data being processed this.buffer = [] this.length = 0 this.first = true this.checksum = null } inherits(Encoder, Transform) // Header = magic number + stream descriptor Encoder.prototype.headerSize = function () { var streamSizeSize = this.options.streamSize ? SIZES.DESCRIPTOR : 0 var dictSize = this.options.dict ? SIZES.DICTID : 0 return SIZES.MAGIC + 1 + 1 + streamSizeSize + dictSize + 1 } Encoder.prototype.header = function () { var headerSize = this.headerSize() var output = Buffer.alloc(headerSize) this.state = STATES.MAGIC output.writeInt32LE(lz4_static.MAGICNUMBER, 0) this.state = STATES.DESCRIPTOR var descriptor = output.slice(SIZES.MAGIC, output.length - 1) // Update the stream descriptor descriptor.writeUInt8(this.descriptor.flg, 0) descriptor.writeUInt8(this.descriptor.bd, 1) var pos = 2 this.state = STATES.SIZE if (this.options.streamSize) { //TODO only 32bits size supported descriptor.writeInt32LE(0, pos) descriptor.writeInt32LE(this.size, pos + 4) pos += SIZES.SIZE } this.state = STATES.DICTID if (this.options.dict) { descriptor.writeInt32LE(this.dictId, pos) pos += SIZES.DICTID } this.state = STATES.DESCRIPTOR_CHECKSUM output.writeUInt8( utils.descriptorChecksum( descriptor ) , SIZES.MAGIC + pos ) return output } Encoder.prototype.update_Checksum = function (data) { // Calculate the stream checksum this.state = STATES.CHECKSUM_UPDATE if (this.options.streamChecksum) { this.checksum = utils.streamChecksum(data, this.checksum) } } Encoder.prototype.compress_DataBlock = function (data) { this.state = STATES.DATABLOCK_COMPRESS var dbChecksumSize = this.options.blockChecksum ? SIZES.DATABLOCK_CHECKSUM : 0 var maxBufSize = this.binding.compressBound(data.length) var buf = Buffer.alloc( SIZES.DATABLOCK_SIZE + maxBufSize + dbChecksumSize ) var compressed = buf.slice(SIZES.DATABLOCK_SIZE, SIZES.DATABLOCK_SIZE + maxBufSize) var compressedSize = this.compress(data, compressed) // Set the block size this.state = STATES.DATABLOCK_SIZE // Block size shall never be larger than blockMaxSize // console.log("blockMaxSize", this.options.blockMaxSize, "compressedSize", compressedSize) if (compressedSize > 0 && compressedSize <= this.options.blockMaxSize) { // highest bit is 0 (compressed data) buf.writeUInt32LE(compressedSize, 0) buf = buf.slice(0, SIZES.DATABLOCK_SIZE + compressedSize + dbChecksumSize) } else { // Cannot compress the data, leave it as is // highest bit is 1 (uncompressed data) buf.writeInt32LE( 0x80000000 | data.length, 0) buf = buf.slice(0, SIZES.DATABLOCK_SIZE + data.length + dbChecksumSize) data.copy(buf, SIZES.DATABLOCK_SIZE); } // Set the block checksum this.state = STATES.DATABLOCK_CHECKSUM if (this.options.blockChecksum) { // xxHash checksum on undecoded data with a seed of 0 var checksum = buf.slice(-dbChecksumSize) checksum.writeInt32LE( utils.blockChecksum(compressed), 0 ) } // Update the stream checksum this.update_Checksum(data) this.size += data.length return buf } Encoder.prototype._transform = function (data, encoding, done) { if (data) { // Buffer the incoming data this.buffer.push(data) this.length += data.length } // Stream header if (this.first) { this.push( this.header() ) this.first = false } var blockMaxSize = this.options.blockMaxSize // Not enough data for a block if ( this.length < blockMaxSize ) return done() // Build the data to be compressed var buf = Buffer.concat(this.buffer, this.length) for (var j = 0, i = buf.length; i >= blockMaxSize; i -= blockMaxSize, j += blockMaxSize) { // Compress the block this.push( this.compress_DataBlock( buf.slice(j, j + blockMaxSize) ) ) } // Set the remaining data if (i > 0) { this.buffer = [ buf.slice(j) ] this.length = this.buffer[0].length } else { this.buffer = [] this.length = 0 } done() } Encoder.prototype._flush = function (done) { if (this.first) { this.push( this.header() ) this.first = false } if (this.length > 0) { var buf = Buffer.concat(this.buffer, this.length) this.buffer = [] this.length = 0 var cc = this.compress_DataBlock(buf) this.push( cc ) } if (this.options.streamChecksum) { this.state = STATES.CHECKSUM var eos = Buffer.alloc(SIZES.EOS + SIZES.CHECKSUM) eos.writeUInt32LE( utils.streamChecksum(null, this.checksum), SIZES.EOS ) } else { var eos = Buffer.alloc(SIZES.EOS) } this.state = STATES.EOS eos.writeInt32LE(lz4_static.EOS, 0) this.push(eos) done() } module.exports = Encoder }).call(this)}).call(this,require("buffer").Buffer) },{"./binding":1,"./static":6,"buffer":"buffer","stream":35,"util":40}],6:[function(require,module,exports){ (function (Buffer){(function (){ /** * LZ4 based compression and decompression * Copyright (c) 2014 Pierre Curto * MIT Licensed */ // LZ4 stream constants exports.MAGICNUMBER = 0x184D2204 exports.MAGICNUMBER_BUFFER = Buffer.alloc(4) exports.MAGICNUMBER_BUFFER.writeUInt32LE(exports.MAGICNUMBER, 0) exports.EOS = 0 exports.EOS_BUFFER = Buffer.alloc(4) exports.EOS_BUFFER.writeUInt32LE(exports.EOS, 0) exports.VERSION = 1 exports.MAGICNUMBER_SKIPPABLE = 0x184D2A50 // n/a, n/a, n/a, n/a, 64KB, 256KB, 1MB, 4MB exports.blockMaxSizes = [ null, null, null, null, 64<<10, 256<<10, 1<<20, 4<<20 ] // Compressed file extension exports.extension = '.lz4' // Internal stream states exports.STATES = { // Compressed stream MAGIC: 0 , DESCRIPTOR: 1 , SIZE: 2 , DICTID: 3 , DESCRIPTOR_CHECKSUM: 4 , DATABLOCK_SIZE: 5 , DATABLOCK_DATA: 6 , DATABLOCK_CHECKSUM: 7 , DATABLOCK_UNCOMPRESS: 8 , DATABLOCK_COMPRESS: 9 , CHECKSUM: 10 , CHECKSUM_UPDATE: 11 , EOS: 90 // Skippable chunk , SKIP_SIZE: 101 , SKIP_DATA: 102 } exports.SIZES = { MAGIC: 4 , DESCRIPTOR: 2 , SIZE: 8 , DICTID: 4 , DESCRIPTOR_CHECKSUM: 1 , DATABLOCK_SIZE: 4 , DATABLOCK_CHECKSUM: 4 , CHECKSUM: 4 , EOS: 4 , SKIP_SIZE: 4 } exports.utils = require('./utils') }).call(this)}).call(this,require("buffer").Buffer) },{"./utils":"./utils","buffer":"buffer"}],7:[function(require,module,exports){ 'use strict' exports.byteLength = byteLength exports.toByteArray = toByteArray exports.fromByteArray = fromByteArray var lookup = [] var revLookup = [] var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' for (var i = 0, len = code.length; i < len; ++i) { lookup[i] = code[i] revLookup[code.charCodeAt(i)] = i } // Support decoding URL-safe base64 strings, as Node.js does. // See: https://en.wikipedia.org/wiki/Base64#URL_applications revLookup['-'.charCodeAt(0)] = 62 revLookup['_'.charCodeAt(0)] = 63 function getLens (b64) { var len = b64.length if (len % 4 > 0) { throw new Error('Invalid string. Length must be a multiple of 4') } // Trim off extra bytes after placeholder bytes are found // See: https://github.com/beatgammit/base64-js/issues/42 var validLen = b64.indexOf('=') if (validLen === -1) validLen = len var placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4) return [validLen, placeHoldersLen] } // base64 is 4/3 + up to two characters of the original data function byteLength (b64) { var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } function _byteLength (b64, validLen, placeHoldersLen) { return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } function toByteArray (b64) { var tmp var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) var curByte = 0 // if there are placeholders, only get up to the last complete 4 chars var len = placeHoldersLen > 0 ? validLen - 4 : validLen var i for (i = 0; i < len; i += 4) { tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] arr[curByte++] = (tmp >> 16) & 0xFF arr[curByte++] = (tmp >> 8) & 0xFF arr[curByte++] = tmp & 0xFF } if (placeHoldersLen === 2) { tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) arr[curByte++] = tmp & 0xFF } if (placeHoldersLen === 1) { tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) arr[curByte++] = (tmp >> 8) & 0xFF arr[curByte++] = tmp & 0xFF } return arr } function tripletToBase64 (num) { return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] } function encodeChunk (uint8, start, end) { var tmp var output = [] for (var i = start; i < end; i += 3) { tmp = ((uint8[i] << 16) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF) output.push(tripletToBase64(tmp)) } return output.join('') } function fromByteArray (uint8) { var tmp var len = uint8.length var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes var parts = [] var maxChunkLength = 16383 // must be multiple of 3 // go through the array every three bytes, we'll deal with trailing stuff later for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) } // pad the end with zeros, but make sure to not forget the extra bytes if (extraBytes === 1) { tmp = uint8[len - 1] parts.push( lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3F] + '==' ) } else if (extraBytes === 2) { tmp = (uint8[len - 2] << 8) + uint8[len - 1] parts.push( lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3F] + lookup[(tmp << 2) & 0x3F] + '=' ) } return parts.join('') } },{}],8:[function(require,module,exports){ },{}],9:[function(require,module,exports){ (function (Buffer){(function (){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // NOTE: These type checking functions intentionally don't use `instanceof` // because it is fragile and can be easily faked with `Object.create()`. function isArray(arg) { if (Array.isArray) { return Array.isArray(arg); } return objectToString(arg) === '[object Array]'; } exports.isArray = isArray; function isBoolean(arg) { return typeof arg === 'boolean'; } exports.isBoolean = isBoolean; function isNull(arg) { return arg === null; } exports.isNull = isNull; function isNullOrUndefined(arg) { return arg == null; } exports.isNullOrUndefined = isNullOrUndefined; function isNumber(arg) { return typeof arg === 'number'; } exports.isNumber = isNumber; function isString(arg) { return typeof arg === 'string'; } exports.isString = isString; function isSymbol(arg) { return typeof arg === 'symbol'; } exports.isSymbol = isSymbol; function isUndefined(arg) { return arg === void 0; } exports.isUndefined = isUndefined; function isRegExp(re) { return objectToString(re) === '[object RegExp]'; } exports.isRegExp = isRegExp; function isObject(arg) { return typeof arg === 'object' && arg !== null; } exports.isObject = isObject; function isDate(d) { return objectToString(d) === '[object Date]'; } exports.isDate = isDate; function isError(e) { return (objectToString(e) === '[object Error]' || e instanceof Error); } exports.isError = isError; function isFunction(arg) { return typeof arg === 'function'; } exports.isFunction = isFunction; function isPrimitive(arg) { return arg === null || typeof arg === 'boolean' || typeof arg === 'number' || typeof arg === 'string' || typeof arg === 'symbol' || // ES6 symbol typeof arg === 'undefined'; } exports.isPrimitive = isPrimitive; exports.isBuffer = Buffer.isBuffer; function objectToString(o) { return Object.prototype.toString.call(o); } }).call(this)}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) },{"../../is-buffer/index.js":16}],10:[function(require,module,exports){ exports.UINT32 = require('./lib/uint32') exports.UINT64 = require('./lib/uint64') },{"./lib/uint32":11,"./lib/uint64":12}],11:[function(require,module,exports){ /** C-like unsigned 32 bits integers in Javascript Copyright (C) 2013, Pierre Curto MIT license */ ;(function (root) { // Local cache for typical radices var radixPowerCache = { 36: UINT32( Math.pow(36, 5) ) , 16: UINT32( Math.pow(16, 7) ) , 10: UINT32( Math.pow(10, 9) ) , 2: UINT32( Math.pow(2, 30) ) } var radixCache = { 36: UINT32(36) , 16: UINT32(16) , 10: UINT32(10) , 2: UINT32(2) } /** * Represents an unsigned 32 bits integer * @constructor * @param {Number|String|Number} low bits | integer as a string | integer as a number * @param {Number|Number|Undefined} high bits | radix (optional, default=10) * @return */ function UINT32 (l, h) { if ( !(this instanceof UINT32) ) return new UINT32(l, h) this._low = 0 this._high = 0 this.remainder = null if (typeof h == 'undefined') return fromNumber.call(this, l) if (typeof l == 'string') return fromString.call(this, l, h) fromBits.call(this, l, h) } /** * Set the current _UINT32_ object with its low and high bits * @method fromBits * @param {Number} low bits * @param {Number} high bits * @return ThisExpression */ function fromBits (l, h) { this._low = l | 0 this._high = h | 0 return this } UINT32.prototype.fromBits = fromBits /** * Set the current _UINT32_ object from a number * @method fromNumber * @param {Number} number * @return ThisExpression */ function fromNumber (value) { this._low = value & 0xFFFF this._high = value >>> 16 return this } UINT32.prototype.fromNumber = fromNumber /** * Set the current _UINT32_ object from a string * @method fromString * @param {String} integer as a string * @param {Number} radix (optional, default=10) * @return ThisExpression */ function fromString (s, radix) { var value = parseInt(s, radix || 10) this._low = value & 0xFFFF this._high = value >>> 16 return this } UINT32.prototype.fromString = fromString /** * Convert this _UINT32_ to a number * @method toNumber * @return {Number} the converted UINT32 */ UINT32.prototype.toNumber = function () { return (this._high * 65536) + this._low } /** * Convert this _UINT32_ to a string * @method toString * @param {Number} radix (optional, default=10) * @return {String} the converted UINT32 */ UINT32.prototype.toString = function (radix) { return this.toNumber().toString(radix || 10) } /** * Add two _UINT32_. The current _UINT32_ stores the result * @method add * @param {Object} other UINT32 * @return ThisExpression */ UINT32.prototype.add = function (other) { var a00 = this._low + other._low var a16 = a00 >>> 16 a16 += this._high + other._high this._low = a00 & 0xFFFF this._high = a16 & 0xFFFF return this } /** * Subtract two _UINT32_. The current _UINT32_ stores the result * @method subtract * @param {Object} other UINT32 * @return ThisExpression */ UINT32.prototype.subtract = function (other) { //TODO inline return this.add( other.clone().negate() ) } /** * Multiply two _UINT32_. The current _UINT32_ stores the result * @method multiply * @param {Object} other UINT32 * @return ThisExpression */ UINT32.prototype.multiply = function (other) { /* a = a00 + a16 b = b00 + b16 a*b = (a00 + a16)(b00 + b16) = a00b00 + a00b16 + a16b00 + a16b16 a16b16 overflows the 32bits */ var a16 = this._high var a00 = this._low var b16 = other._high var b00 = other._low /* Removed to increase speed under normal circumstances (i.e. not multiplying by 0 or 1) // this == 0 or other == 1: nothing to do if ((a00 == 0 && a16 == 0) || (b00 == 1 && b16 == 0)) return this // other == 0 or this == 1: this = other if ((b00 == 0 && b16 == 0) || (a00 == 1 && a16 == 0)) { this._low = other._low this._high = other._high return this } */ var c16, c00 c00 = a00 * b00 c16 = c00 >>> 16 c16 += a16 * b00 c16 &= 0xFFFF // Not required but improves performance c16 += a00 * b16 this._low = c00 & 0xFFFF this._high = c16 & 0xFFFF return this } /** * Divide two _UINT32_. The current _UINT32_ stores the result. * The remainder is made available as the _remainder_ property on * the _UINT32_ object. It can be null, meaning there are no remainder. * @method div * @param {Object} other UINT32 * @return ThisExpression */ UINT32.prototype.div = function (other) { if ( (other._low == 0) && (other._high == 0) ) throw Error('division by zero') // other == 1 if (other._high == 0 && other._low == 1) { this.remainder = new UINT32(0) return this } // other > this: 0 if ( other.gt(this) ) { this.remainder = this.clone() this._low = 0 this._high = 0 return this } // other == this: 1 if ( this.eq(other) ) { this.remainder = new UINT32(0) this._low = 1 this._high = 0 return this } // Shift the divisor left until it is higher than the dividend var _other = other.clone() var i = -1 while ( !this.lt(_other) ) { // High bit can overflow the default 16bits // Its ok since we right shift after this loop // The overflown bit must be kept though _other.shiftLeft(1, true) i++ } // Set the remainder this.remainder = this.clone() // Initialize the current result to 0 this._low = 0 this._high = 0 for (; i >= 0; i--) { _other.shiftRight(1) // If shifted divisor is smaller than the dividend // then subtract it from the dividend if ( !this.remainder.lt(_other) ) { this.remainder.subtract(_other) // Update the current result if (i >= 16) { this._high |= 1 << (i - 16) } else { this._low |= 1 << i } } } return this } /** * Negate the current _UINT32_ * @method negate * @return ThisExpression */ UINT32.prototype.negate = function () { var v = ( ~this._low & 0xFFFF ) + 1 this._low = v & 0xFFFF this._high = (~this._high + (v >>> 16)) & 0xFFFF return this } /** * Equals * @method eq * @param {Object} other UINT32 * @return {Boolean} */ UINT32.prototype.equals = UINT32.prototype.eq = function (other) { return (this._low == other._low) && (this._high == other._high) } /** * Greater than (strict) * @method gt * @param {Object} other UINT32 * @return {Boolean} */ UINT32.prototype.greaterThan = UINT32.prototype.gt = function (other) { if (this._high > other._high) return true if (this._high < other._high) return false return this._low > other._low } /** * Less than (strict) * @method lt * @param {Object} other UINT32 * @return {Boolean} */ UINT32.prototype.lessThan = UINT32.prototype.lt = function (other) { if (this._high < other._high) return true if (this._high > other._high) return false return this._low < other._low } /** * Bitwise OR * @method or * @param {Object} other UINT32 * @return ThisExpression */ UINT32.prototype.or = function (other) { this._low |= other._low this._high |= other._high return this } /** * Bitwise AND * @method and * @param {Object} other UINT32 * @return ThisExpression */ UINT32.prototype.and = function (other) { this._low &= other._low this._high &= other._high return this } /** * Bitwise NOT * @method not * @return ThisExpression */ UINT32.prototype.not = function() { this._low = ~this._low & 0xFFFF this._high = ~this._high & 0xFFFF return this } /** * Bitwise XOR * @method xor * @param {Object} other UINT32 * @return ThisExpression */ UINT32.prototype.xor = function (other) { this._low ^= other._low this._high ^= other._high return this } /** * Bitwise shift right * @method shiftRight * @param {Number} number of bits to shift * @return ThisExpression */ UINT32.prototype.shiftRight = UINT32.prototype.shiftr = function (n) { if (n > 16) { this._low = this._high >> (n - 16) this._high = 0 } else if (n == 16) { this._low = this._high this._high = 0 } else { this._low = (this._low >> n) | ( (this._high << (16-n)) & 0xFFFF ) this._high >>= n } return this } /** * Bitwise shift left * @method shiftLeft * @param {Number} number of bits to shift * @param {Boolean} allow overflow * @return ThisExpression */ UINT32.prototype.shiftLeft = UINT32.prototype.shiftl = function (n, allowOverflow) { if (n > 16) { this._high = this._low << (n - 16) this._low = 0 if (!allowOverflow) { this._high &= 0xFFFF } } else if (n == 16) { this._high = this._low this._low = 0 } else { this._high = (this._high << n) | (this._low >> (16-n)) this._low = (this._low << n) & 0xFFFF if (!allowOverflow) { // Overflow only allowed on the high bits... this._high &= 0xFFFF } } return this } /** * Bitwise rotate left * @method rotl * @param {Number} number of bits to rotate * @return ThisExpression */ UINT32.prototype.rotateLeft = UINT32.prototype.rotl = function (n) { var v = (this._high << 16) | this._low v = (v << n) | (v >>> (32 - n)) this._low = v & 0xFFFF this._high = v >>> 16 return this } /** * Bitwise rotate right * @method rotr * @param {Number} number of bits to rotate * @return ThisExpression */ UINT32.prototype.rotateRight = UINT32.prototype.rotr = function (n) { var v = (this._high << 16) | this._low v = (v >>> n) | (v << (32 - n)) this._low = v & 0xFFFF this._high = v >>> 16 return this } /** * Clone the current _UINT32_ * @method clone * @return {Object} cloned UINT32 */ UINT32.prototype.clone = function () { return new UINT32(this._low, this._high) } if (typeof define != 'undefined' && define.amd) { // AMD / RequireJS define([], function () { return UINT32 }) } else if (typeof module != 'undefined' && module.exports) { // Node.js module.exports = UINT32 } else { // Browser root['UINT32'] = UINT32 } })(this) },{}],12:[function(require,module,exports){ /** C-like unsigned 64 bits integers in Javascript Copyright (C) 2013, Pierre Curto MIT license */ ;(function (root) { // Local cache for typical radices var radixPowerCache = { 16: UINT64( Math.pow(16, 5) ) , 10: UINT64( Math.pow(10, 5) ) , 2: UINT64( Math.pow(2, 5) ) } var radixCache = { 16: UINT64(16) , 10: UINT64(10) , 2: UINT64(2) } /** * Represents an unsigned 64 bits integer * @constructor * @param {Number} first low bits (8) * @param {Number} second low bits (8) * @param {Number} first high bits (8) * @param {Number} second high bits (8) * or * @param {Number} low bits (32) * @param {Number} high bits (32) * or * @param {String|Number} integer as a string | integer as a number * @param {Number|Undefined} radix (optional, default=10) * @return */ function UINT64 (a00, a16, a32, a48) { if ( !(this instanceof UINT64) ) return new UINT64(a00, a16, a32, a48) this.remainder = null if (typeof a00 == 'string') return fromString.call(this, a00, a16) if (typeof a16 == 'undefined') return fromNumber.call(this, a00) fromBits.apply(this, arguments) } /** * Set the current _UINT64_ object with its low and high bits * @method fromBits * @param {Number} first low bits (8) * @param {Number} second low bits (8) * @param {Number} first high bits (8) * @param {Number} second high bits (8) * or * @param {Number} low bits (32) * @param {Number} high bits (32) * @return ThisExpression */ function fromBits (a00, a16, a32, a48) { if (typeof a32 == 'undefined') { this._a00 = a00 & 0xFFFF this._a16 = a00 >>> 16 this._a32 = a16 & 0xFFFF this._a48 = a16 >>> 16 return this } this._a00 = a00 | 0 this._a16 = a16 | 0 this._a32 = a32 | 0 this._a48 = a48 | 0 return this } UINT64.prototype.fromBits = fromBits /** * Set the current _UINT64_ object from a number * @method fromNumber * @param {Number} number * @return ThisExpression */ function fromNumber (value) { this._a00 = value & 0xFFFF this._a16 = value >>> 16 this._a32 = 0 this._a48 = 0 return this } UINT64.prototype.fromNumber = fromNumber /** * Set the current _UINT64_ object from a string * @method fromString * @param {String} integer as a string * @param {Number} radix (optional, default=10) * @return ThisExpression */ function fromString (s, radix) { radix = radix || 10 this._a00 = 0 this._a16 = 0 this._a32 = 0 this._a48 = 0 /* In Javascript, bitwise operators only operate on the first 32 bits of a number, even though parseInt() encodes numbers with a 53 bits mantissa. Therefore UINT64(<Number>) can only work on 32 bits. The radix maximum value is 36 (as per ECMA specs) (26 letters + 10 digits) maximum input value is m = 32bits as 1 = 2^32 - 1 So the maximum substring length n is: 36^(n+1) - 1 = 2^32 - 1 36^(n+1) = 2^32 (n+1)ln(36) = 32ln(2) n = 32ln(2)/ln(36) - 1 n = 5.189644915687692 n = 5 */ var radixUint = radixPowerCache[radix] || new UINT64( Math.pow(radix, 5) ) for (var i = 0, len = s.length; i < len; i += 5) { var size = Math.min(5, len - i) var value = parseInt( s.slice(i, i + size), radix ) this.multiply( size < 5 ? new UINT64( Math.pow(radix, size) ) : radixUint ) .add( new UINT64(value) ) } return this } UINT64.prototype.fromString = fromString /** * Convert this _UINT64_ to a number (last 32 bits are dropped) * @method toNumber * @return {Number} the converted UINT64 */ UINT64.prototype.toNumber = function () { return (this._a16 * 65536) + this._a00 } /** * Convert this _UINT64_ to a string * @method toString * @param {Number} radix (optional, default=10) * @return {String} the converted UINT64 */ UINT64.prototype.toString = function (radix) { radix = radix || 10 var radixUint = radixCache[radix] || new UINT64(radix) if ( !this.gt(radixUint) ) return this.toNumber().toString(radix) var self = this.clone() var res = new Array(64) for (var i = 63; i >= 0; i--) { self.div(radixUint) res[i] = self.remainder.toNumber().toString(radix) if ( !self.gt(radixUint) ) break } res[i-1] = self.toNumber().toString(radix) return res.join('') } /** * Add two _UINT64_. The current _UINT64_ stores the result * @method add * @param {Object} other UINT64 * @return ThisExpression */ UINT64.prototype.add = function (other) { var a00 = this._a00 + other._a00 var a16 = a00 >>> 16 a16 += this._a16 + other._a16 var a32 = a16 >>> 16 a32 += this._a32 + other._a32 var a48 = a32 >>> 16 a48 += this._a48 + other._a48 this._a00 = a00 & 0xFFFF this._a16 = a16 & 0xFFFF this._a32 = a32 & 0xFFFF this._a48 = a48 & 0xFFFF return this } /** * Subtract two _UINT64_. The current _UINT64_ stores the result * @method subtract * @param {Object} other UINT64 * @return ThisExpression */ UINT64.prototype.subtract = function (other) { return this.add( other.clone().negate() ) } /** * Multiply two _UINT64_. The current _UINT64_ stores the result * @method multiply * @param {Object} other UINT64 * @return ThisExpression */ UINT64.prototype.multiply = function (other) { /* a = a00 + a16 + a32 + a48 b = b00 + b16 + b32 + b48 a*b = (a00 + a16 + a32 + a48)(b00 + b16 + b32 + b48) = a00b00 + a00b16 + a00b32 + a00b48 + a16b00 + a16b16 + a16b32 + a16b48 + a32b00 + a32b16 + a32b32 + a32b48 + a48b00 + a48b16 + a48b32 + a48b48 a16b48, a32b32, a48b16, a48b32 and a48b48 overflow the 64 bits so it comes down to: a*b = a00b00 + a00b16 + a00b32 + a00b48 + a16b00 + a16b16 + a16b32 + a32b00 + a32b16 + a48b00 = a00b00 + a00b16 + a16b00 + a00b32 + a16b16 + a32b00 + a00b48 + a16b32 + a32b16 + a48b00 */ var a00 = this._a00 var a16 = this._a16 var a32 = this._a32 var a48 = this._a48 var b00 = other._a00 var b16 = other._a16 var b32 = other._a32 var b48 = other._a48 var c00 = a00 * b00 var c16 = c00 >>> 16 c16 += a00 * b16 var c32 = c16 >>> 16 c16 &= 0xFFFF c16 += a16 * b00 c32 += c16 >>> 16 c32 += a00 * b32 var c48 = c32 >>> 16 c32 &= 0xFFFF c32 += a16 * b16 c48 += c32 >>> 16 c32 &= 0xFFFF c32 += a32 * b00 c48 += c32 >>> 16 c48 += a00 * b48 c48 &= 0xFFFF c48 += a16 * b32 c48 &= 0xFFFF c48 += a32 * b16 c48 &= 0xFFFF c48 += a48 * b00 this._a00 = c00 & 0xFFFF this._a16 = c16 & 0xFFFF this._a32 = c32 & 0xFFFF this._a48 = c48 & 0xFFFF return this } /** * Divide two _UINT64_. The current _UINT64_ stores the result. * The remainder is made available as the _remainder_ property on * the _UINT64_ object. It can be null, meaning there are no remainder. * @method div * @param {Object} other UINT64 * @return ThisExpression */ UINT64.prototype.div = function (other) { if ( (other._a16 ==