mirror of https://github.com/nodejs/node.git
zlib: allow changing of level and strategy
parent
086d4ccace
commit
9b09c9eedd
|
@ -151,6 +151,11 @@ class of the compressor/decompressor classes.
|
|||
Flush pending data. Don't call this frivolously, premature flushes negatively
|
||||
impact the effectiveness of the compression algorithm.
|
||||
|
||||
### zlib.params(level, strategy, callback)
|
||||
|
||||
Dynamically update the compression level and compression strategy.
|
||||
Only applicable to deflate algorithm.
|
||||
|
||||
### zlib.reset()
|
||||
|
||||
Reset the compressor/decompressor to factory defaults. Only applicable to
|
||||
|
|
32
lib/zlib.js
32
lib/zlib.js
|
@ -341,13 +341,43 @@ function Zlib(opts, mode) {
|
|||
this._buffer = new Buffer(this._chunkSize);
|
||||
this._offset = 0;
|
||||
this._closed = false;
|
||||
this._level = level;
|
||||
this._strategy = strategy;
|
||||
|
||||
this.once('end', this.close);
|
||||
}
|
||||
|
||||
util.inherits(Zlib, Transform);
|
||||
|
||||
Zlib.prototype.reset = function reset() {
|
||||
Zlib.prototype.params = function(level, strategy, callback) {
|
||||
if (level < exports.Z_MIN_LEVEL ||
|
||||
level > exports.Z_MAX_LEVEL) {
|
||||
throw new RangeError('Invalid compression level: ' + level);
|
||||
}
|
||||
if (strategy != exports.Z_FILTERED &&
|
||||
strategy != exports.Z_HUFFMAN_ONLY &&
|
||||
strategy != exports.Z_RLE &&
|
||||
strategy != exports.Z_FIXED &&
|
||||
strategy != exports.Z_DEFAULT_STRATEGY) {
|
||||
throw new TypeError('Invalid strategy: ' + strategy);
|
||||
}
|
||||
|
||||
if (this._level !== level || this._strategy !== strategy) {
|
||||
var self = this;
|
||||
this.flush(binding.Z_SYNC_FLUSH, function() {
|
||||
self._binding.params(level, strategy);
|
||||
if (!self._hadError) {
|
||||
self._level = level;
|
||||
self._strategy = strategy;
|
||||
if (callback) callback();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
process.nextTick(callback);
|
||||
}
|
||||
};
|
||||
|
||||
Zlib.prototype.reset = function() {
|
||||
return this._binding.reset();
|
||||
};
|
||||
|
||||
|
|
|
@ -360,6 +360,18 @@ class ZCtx : public ObjectWrap {
|
|||
return Undefined(node_isolate);
|
||||
}
|
||||
|
||||
static Handle<Value> Params(const Arguments& args) {
|
||||
HandleScope scope(node_isolate);
|
||||
|
||||
assert(args.Length() == 2 && "params(level, strategy)");
|
||||
|
||||
ZCtx* ctx = ObjectWrap::Unwrap<ZCtx>(args.This());
|
||||
|
||||
Params(ctx, args[0]->Int32Value(), args[1]->Int32Value());
|
||||
|
||||
return Undefined(node_isolate);
|
||||
}
|
||||
|
||||
static Handle<Value> Reset(const Arguments &args) {
|
||||
HandleScope scope(node_isolate);
|
||||
|
||||
|
@ -455,6 +467,23 @@ class ZCtx : public ObjectWrap {
|
|||
}
|
||||
}
|
||||
|
||||
static void Params(ZCtx* ctx, int level, int strategy) {
|
||||
ctx->err_ = Z_OK;
|
||||
|
||||
switch (ctx->mode_) {
|
||||
case DEFLATE:
|
||||
case DEFLATERAW:
|
||||
ctx->err_ = deflateParams(&ctx->strm_, level, strategy);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx->err_ != Z_OK && ctx->err_ != Z_BUF_ERROR) {
|
||||
ZCtx::Error(ctx, "Failed to set parameters");
|
||||
}
|
||||
}
|
||||
|
||||
static void Reset(ZCtx* ctx) {
|
||||
ctx->err_ = Z_OK;
|
||||
|
||||
|
@ -514,6 +543,7 @@ void InitZlib(Handle<Object> target) {
|
|||
NODE_SET_PROTOTYPE_METHOD(z, "write", ZCtx::Write);
|
||||
NODE_SET_PROTOTYPE_METHOD(z, "init", ZCtx::Init);
|
||||
NODE_SET_PROTOTYPE_METHOD(z, "close", ZCtx::Close);
|
||||
NODE_SET_PROTOTYPE_METHOD(z, "params", ZCtx::Params);
|
||||
NODE_SET_PROTOTYPE_METHOD(z, "reset", ZCtx::Reset);
|
||||
|
||||
z->SetClassName(String::NewSymbol("Zlib"));
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
var common = require('../common.js');
|
||||
var assert = require('assert');
|
||||
var zlib = require('zlib');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
var file = fs.readFileSync(path.resolve(common.fixturesDir, 'person.jpg')),
|
||||
chunkSize = 24 * 1024,
|
||||
opts = { level: 9, strategy: zlib.Z_DEFAULT_STRATEGY },
|
||||
deflater = zlib.createDeflate(opts);
|
||||
|
||||
var chunk1 = file.slice(0, chunkSize),
|
||||
chunk2 = file.slice(chunkSize),
|
||||
blkhdr = new Buffer([0x00, 0x48, 0x82, 0xb7, 0x7d]),
|
||||
expected = Buffer.concat([blkhdr, chunk2]),
|
||||
actual;
|
||||
|
||||
deflater.write(chunk1, function() {
|
||||
deflater.params(0, zlib.Z_DEFAULT_STRATEGY, function() {
|
||||
while (deflater.read());
|
||||
deflater.end(chunk2, function() {
|
||||
var bufs = [], buf;
|
||||
while (buf = deflater.read())
|
||||
bufs.push(buf);
|
||||
actual = Buffer.concat(bufs);
|
||||
});
|
||||
});
|
||||
while (deflater.read());
|
||||
});
|
||||
|
||||
process.once('exit', function() {
|
||||
assert.deepEqual(actual, expected);
|
||||
});
|
Loading…
Reference in New Issue