lz4
Version:
LZ4 streaming compression and decompression
1,974 lines (1,657 loc) • 264 kB
JavaScript
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 ==