From 7b2e5da8a9ddb0b18722d76e7f544a82ffe2f844 Mon Sep 17 00:00:00 2001 From: Vitaly Puzrin Date: Thu, 13 Mar 2014 10:45:14 +0400 Subject: [PATCH] Rewritten utils unterfaces & internals --- .../deflate-pako-untyped/index.js | 4 +- .../inflate-pako-untyped/index.js | 4 +- lib/deflate.js | 14 +- lib/inflate.js | 13 +- lib/zlib/deflate.js | 20 +-- lib/zlib/inflate.js | 18 +-- lib/zlib/inftrees.js | 4 +- lib/zlib/utils.js | 132 +++++++----------- test/helpers.js | 8 +- 9 files changed, 89 insertions(+), 128 deletions(-) diff --git a/benchmark/implementations/deflate-pako-untyped/index.js b/benchmark/implementations/deflate-pako-untyped/index.js index 8471b04..4fd5455 100644 --- a/benchmark/implementations/deflate-pako-untyped/index.js +++ b/benchmark/implementations/deflate-pako-untyped/index.js @@ -4,9 +4,9 @@ var pako = require('../../../'); var utils = require('../../../lib/zlib/utils'); exports.run = function(data, level) { - utils.forceUntyped = true; + utils.setTyped(false); pako.deflate(data.typed, { level: level }); - utils.forceUntyped = false; + utils.setTyped(true); } diff --git a/benchmark/implementations/inflate-pako-untyped/index.js b/benchmark/implementations/inflate-pako-untyped/index.js index 6d5eb5f..bd1b157 100644 --- a/benchmark/implementations/inflate-pako-untyped/index.js +++ b/benchmark/implementations/inflate-pako-untyped/index.js @@ -4,8 +4,8 @@ var pako = require('../../../'); var utils = require('../../../lib/zlib/utils'); exports.run = function(data, level) { - utils.forceUntyped = true; + utils.setTyped(false); pako.inflate(data.deflateTyped, { }); - utils.forceUntyped = false; + utils.setTyped(true); } diff --git a/lib/deflate.js b/lib/deflate.js index 7485539..bf5060c 100644 --- a/lib/deflate.js +++ b/lib/deflate.js @@ -25,14 +25,6 @@ var Z_DEFLATED = 8; /* ===========================================================================*/ -// return sliced buffer, trying to avoid new objects creation and mem copy -function sliceBuf(buf, size) { - if (buf.length === size) { return buf; } - if (utils.typedOk()) { return buf.subarray(0, size); } - buf.length = size; - return buf; -} - /** * class Deflate * @@ -190,7 +182,7 @@ Deflate.prototype.push = function(data, mode) { strm.next_in = data; strm.next_in_index = 0; strm.avail_in = strm.next_in.length; - strm.next_out = utils.arrayCreate(chunkSize); + strm.next_out = new utils.Buf8(chunkSize); do { strm.avail_out = this.options.chunkSize; @@ -203,10 +195,10 @@ Deflate.prototype.push = function(data, mode) { return false; } if(strm.next_out_index) { - this.onData(sliceBuf(strm.next_out, strm.next_out_index)); + this.onData(utils.shrinkBuf(strm.next_out, strm.next_out_index)); // Allocate buffer for next chunk, if not last if (strm.avail_in > 0 || strm.avail_out === 0) { - strm.next_out = utils.arrayCreate(this.options.chunkSize); + strm.next_out = new utils.Buf8(this.options.chunkSize); } } } while (strm.avail_in > 0 || strm.avail_out === 0); diff --git a/lib/inflate.js b/lib/inflate.js index 521aad8..662ad7b 100644 --- a/lib/inflate.js +++ b/lib/inflate.js @@ -7,13 +7,6 @@ var c = require('./zlib/constants'); var msg = require('./zlib/messages'); var zstream = require('./zlib/zstream'); -// return sliced buffer, trying to avoid new objects creation and mem copy -function sliceBuf(buf, size) { - if (buf.length === size) { return buf; } - if (utils.typedOk()) { return buf.subarray(0, size); } - buf.length = size; - return buf; -} /** * class Inflate @@ -162,7 +155,7 @@ Inflate.prototype.push = function(data, mode) { strm.next_in = data; strm.next_in_index = 0; strm.avail_in = strm.next_in.length; - strm.next_out = utils.arrayCreate(chunkSize); + strm.next_out = new utils.Buf8(chunkSize); do { strm.avail_out = this.options.chunkSize; @@ -175,10 +168,10 @@ Inflate.prototype.push = function(data, mode) { return false; } if(strm.next_out_index) { - this.onData(sliceBuf(strm.next_out, strm.next_out_index)); + this.onData(utils.shrinkBuf(strm.next_out, strm.next_out_index)); // Allocate buffer for next chunk, if not last if (strm.avail_in > 0 || strm.avail_out === 0) { - strm.next_out = utils.arrayCreate(this.options.chunkSize); + strm.next_out = new utils.Buf8(this.options.chunkSize); } } } while (strm.avail_in > 0 || strm.avail_out === 0); diff --git a/lib/zlib/deflate.js b/lib/zlib/deflate.js index 97a2f39..8df5613 100644 --- a/lib/zlib/deflate.js +++ b/lib/zlib/deflate.js @@ -1167,9 +1167,9 @@ function DeflateState() { // Use flat array of DOUBLE size, with interleaved fata, // because JS does not support effective - this.dyn_ltree = utils.array16Create(HEAP_SIZE * 2); - this.dyn_dtree = utils.array16Create((2*D_CODES+1) * 2); - this.bl_tree = utils.array16Create((2*BL_CODES+1) * 2); + this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); + this.dyn_dtree = new utils.Buf16((2*D_CODES+1) * 2); + this.bl_tree = new utils.Buf16((2*BL_CODES+1) * 2); zero(this.dyn_ltree); zero(this.dyn_dtree); zero(this.bl_tree); @@ -1186,11 +1186,11 @@ function DeflateState() { this.bl_desc = null; /* desc. for bit length tree */ //ush bl_count[MAX_BITS+1]; - this.bl_count = utils.array16Create(MAX_BITS+1); + this.bl_count = new utils.Buf16(MAX_BITS+1); /* number of codes at each bit length for an optimal tree */ //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - this.heap = utils.array16Create(2*L_CODES+1); /* heap used to build the Huffman trees */ + this.heap = new utils.Buf16(2*L_CODES+1); /* heap used to build the Huffman trees */ zero(this.heap); this.heap_len = 0; /* number of elements in the heap */ @@ -1199,7 +1199,7 @@ function DeflateState() { * The same heap array is used to build all trees. */ - this.depth = utils.array16Create(2*L_CODES+1); //uch depth[2*L_CODES+1]; + this.depth = new utils.Buf16(2*L_CODES+1); //uch depth[2*L_CODES+1]; zero(this.depth); /* Depth of each subtree used as tie breaker for trees of equal frequency */ @@ -1342,16 +1342,16 @@ function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { s.hash_mask = s.hash_size - 1; s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); - s.window = utils.arrayCreate(s.w_size * 2); - s.head = utils.array16Create(s.hash_size); - s.prev = utils.array16Create(s.w_size); + s.window = new utils.Buf8(s.w_size * 2); + s.head = new utils.Buf16(s.hash_size); + s.prev = new utils.Buf16(s.w_size); s.high_water = 0; /* nothing written to s->window yet */ s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ s.pending_buf_size = s.lit_bufsize * 4; - s.pending_buf = utils.arrayCreate(s.pending_buf_size); + s.pending_buf = new utils.Buf8(s.pending_buf_size); s.d_buf = s.lit_bufsize >> 1; s.l_buf = (1 + 2) * s.lit_bufsize; diff --git a/lib/zlib/inflate.js b/lib/zlib/inflate.js index 0df6927..28ac423 100644 --- a/lib/zlib/inflate.js +++ b/lib/zlib/inflate.js @@ -146,11 +146,11 @@ function InflateState() { //unsigned short array //todo: test later with Uint16Array - this.lens = utils.array16Create(320); /* temporary storage for code lengths */ - this.work = utils.array16Create(280); /* work area for code table building */ + this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ + this.work = new utils.Buf16(280); /* work area for code table building */ // TODO: 8 or 16 bits? - this.codes = utils.array32Create(ENOUGH); /* space for code tables */ + this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ this.sane = 0; /* if false, allow invalid distance too far */ this.back = 0; /* bits back of last unprocessed length/lit */ this.was = 0; /* initial length of match */ @@ -188,8 +188,8 @@ function inflateResetKeep(strm) { //state.lencode = state.distcode = state.next = state.codes; //utils.arraySet(state.lencode,state.codes,0,state.codes.length,0); //utils.arraySet(state.distcode,state.codes,0,state.codes.length,0); - state.lencode = utils.array32Create(ENOUGH); - state.distcode = utils.array32Create(ENOUGH); + state.lencode = new utils.Buf32(ENOUGH); + state.distcode = new utils.Buf32(ENOUGH); state.sane = 1; state.back = -1; @@ -305,8 +305,8 @@ function fixedtables(state) { if (virgin) { var sym, bits; - lenfix = utils.array32Create(512); - distfix = utils.array32Create(32); + lenfix = new utils.Buf32(512); + distfix = new utils.Buf32(32); /* literal/length table */ sym = 0; @@ -360,7 +360,7 @@ function updatewindow(strm, src, end, copy) { state.wnext = 0; state.whave = 0; - state.window = utils.arrayCreate(state.wsize); + state.window = new utils.Buf8(state.wsize); } /* copy state->wsize or less output bytes into the circular window */ @@ -410,7 +410,7 @@ function inflate(strm, flush) { var last_bits, last_op, last_val; // paked "last" denormalized var len; /* length to copy for repeats, bits to drop */ var ret; /* return code */ - var hbuf = utils.arrayCreate(4); /* buffer for gzip header crc calculation */ + var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ var opts; var n; // temporary var for NEED_BITS diff --git a/lib/zlib/inftrees.js b/lib/zlib/inftrees.js index fc97867..f46bc21 100644 --- a/lib/zlib/inftrees.js +++ b/lib/zlib/inftrees.js @@ -62,8 +62,8 @@ module.exports = function inflate_table(opts) var base_index = 0; // var shoextra; /* extra bits table to use */ var end; /* use base and extra for symbol > end */ - var count = utils.array16Create(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */ - var offs = utils.array16Create(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */ + var count = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */ var extra = null; var extra_index = 0; diff --git a/lib/zlib/utils.js b/lib/zlib/utils.js index 0e62165..6aab672 100644 --- a/lib/zlib/utils.js +++ b/lib/zlib/utils.js @@ -3,18 +3,7 @@ var TYPED_OK = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && - (typeof Uint32Array !== 'undefined'); - -var isArray = Array.isArray || function (obj) { return Object.prototype.toString.call(obj) === '[object Array]'; }; - -// For debug/testing. Set true to force use untyped arrays -exports.forceUntyped = false; - -function typedOk() { - return TYPED_OK && !exports.forceUntyped; -} - -exports.typedOk = typedOk; + (typeof Int32Array !== 'undefined'); exports.assign = function (obj /*from1, from2, from3, ...*/) { @@ -38,73 +27,32 @@ exports.assign = function (obj /*from1, from2, from3, ...*/) { }; -exports.arraySet = function (dest, src, src_offs, len, dest_offs) { - - // Suppose, that with typed array support destination is - // always typed - don't check it - if (typedOk() && (!isArray(src))) { - - // optimize full copy - //if ((src_offs === 0) && (src.length === len)) { - // dest.set(src, dest_offs); - // return; - //} - - dest.set(src.subarray(src_offs, src_offs+len), dest_offs); - return; - } - - // Fallback to ordinary array - for(var i=0; i