Browse Source

zlib: allow changing of level and strategy

v0.11.4-release
Brian White 12 years ago
committed by Ben Noordhuis
parent
commit
9b09c9eedd
  1. 5
      doc/api/zlib.markdown
  2. 32
      lib/zlib.js
  3. 30
      src/node_zlib.cc
  4. 33
      test/simple/test-zlib-params.js

5
doc/api/zlib.markdown

@ -151,6 +151,11 @@ class of the compressor/decompressor classes.
Flush pending data. Don't call this frivolously, premature flushes negatively Flush pending data. Don't call this frivolously, premature flushes negatively
impact the effectiveness of the compression algorithm. 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() ### zlib.reset()
Reset the compressor/decompressor to factory defaults. Only applicable to Reset the compressor/decompressor to factory defaults. Only applicable to

32
lib/zlib.js

@ -341,13 +341,43 @@ function Zlib(opts, mode) {
this._buffer = new Buffer(this._chunkSize); this._buffer = new Buffer(this._chunkSize);
this._offset = 0; this._offset = 0;
this._closed = false; this._closed = false;
this._level = level;
this._strategy = strategy;
this.once('end', this.close); this.once('end', this.close);
} }
util.inherits(Zlib, Transform); 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(); return this._binding.reset();
}; };

30
src/node_zlib.cc

@ -360,6 +360,18 @@ class ZCtx : public ObjectWrap {
return Undefined(node_isolate); 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) { static Handle<Value> Reset(const Arguments &args) {
HandleScope scope(node_isolate); 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) { static void Reset(ZCtx* ctx) {
ctx->err_ = Z_OK; 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, "write", ZCtx::Write);
NODE_SET_PROTOTYPE_METHOD(z, "init", ZCtx::Init); NODE_SET_PROTOTYPE_METHOD(z, "init", ZCtx::Init);
NODE_SET_PROTOTYPE_METHOD(z, "close", ZCtx::Close); NODE_SET_PROTOTYPE_METHOD(z, "close", ZCtx::Close);
NODE_SET_PROTOTYPE_METHOD(z, "params", ZCtx::Params);
NODE_SET_PROTOTYPE_METHOD(z, "reset", ZCtx::Reset); NODE_SET_PROTOTYPE_METHOD(z, "reset", ZCtx::Reset);
z->SetClassName(String::NewSymbol("Zlib")); z->SetClassName(String::NewSymbol("Zlib"));

33
test/simple/test-zlib-params.js

@ -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…
Cancel
Save