zlib: reset() method for deflate/inflate streams
* ammended test-zlib-dictionary to cover reusing streams
This commit is contained in:
parent
89556f5a2f
commit
71ae175319
@ -309,6 +309,10 @@ Zlib.prototype.write = function write(chunk, cb) {
|
||||
return empty;
|
||||
};
|
||||
|
||||
Zlib.prototype.reset = function reset() {
|
||||
return this._binding.reset();
|
||||
};
|
||||
|
||||
Zlib.prototype.flush = function flush(cb) {
|
||||
this._flush = binding.Z_SYNC_FLUSH;
|
||||
return this.write(cb);
|
||||
|
@ -249,6 +249,17 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap {
|
||||
|
||||
Init(ctx, level, windowBits, memLevel, strategy,
|
||||
dictionary, dictionary_len);
|
||||
SetDictionary(ctx);
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
static Handle<Value> Reset(const Arguments &args) {
|
||||
HandleScope scope;
|
||||
|
||||
ZCtx<mode> *ctx = ObjectWrap::Unwrap< ZCtx<mode> >(args.This());
|
||||
|
||||
Reset(ctx);
|
||||
SetDictionary(ctx);
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
@ -304,25 +315,48 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap {
|
||||
ctx->dictionary_ = reinterpret_cast<Bytef *>(dictionary);
|
||||
ctx->dictionary_len_ = dictionary_len;
|
||||
|
||||
if (dictionary != NULL) {
|
||||
switch (mode) {
|
||||
case DEFLATE:
|
||||
case DEFLATERAW:
|
||||
err = deflateSetDictionary(&ctx->strm_,
|
||||
ctx->dictionary_,
|
||||
dictionary_len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
assert(err == Z_OK && "Failed to set dictionary");
|
||||
}
|
||||
|
||||
ctx->write_in_progress_ = false;
|
||||
ctx->init_done_ = true;
|
||||
}
|
||||
|
||||
static void SetDictionary(ZCtx* ctx) {
|
||||
if (ctx->dictionary_ == NULL) return;
|
||||
|
||||
int err;
|
||||
|
||||
switch (mode) {
|
||||
case DEFLATE:
|
||||
case DEFLATERAW:
|
||||
err = deflateSetDictionary(&ctx->strm_,
|
||||
ctx->dictionary_,
|
||||
ctx->dictionary_len_);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
assert(err == Z_OK && "Failed to set dictionary");
|
||||
}
|
||||
|
||||
static void Reset(ZCtx* ctx) {
|
||||
int err;
|
||||
|
||||
switch (mode) {
|
||||
case DEFLATE:
|
||||
case DEFLATERAW:
|
||||
err = deflateReset(&ctx->strm_);
|
||||
break;
|
||||
case INFLATE:
|
||||
case INFLATERAW:
|
||||
err = inflateReset(&ctx->strm_);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
assert(err == Z_OK && "Failed to reset stream");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool init_done_;
|
||||
@ -352,6 +386,7 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap {
|
||||
z->InstanceTemplate()->SetInternalFieldCount(1); \
|
||||
NODE_SET_PROTOTYPE_METHOD(z, "write", ZCtx<mode>::Write); \
|
||||
NODE_SET_PROTOTYPE_METHOD(z, "init", ZCtx<mode>::Init); \
|
||||
NODE_SET_PROTOTYPE_METHOD(z, "reset", ZCtx<mode>::Reset); \
|
||||
z->SetClassName(String::NewSymbol(name)); \
|
||||
target->Set(String::NewSymbol(name), z->GetFunction()); \
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ var spdyDict = new Buffer([
|
||||
].join(''));
|
||||
|
||||
var deflate = zlib.createDeflate({ dictionary: spdyDict });
|
||||
var inflate = zlib.createInflate({ dictionary: spdyDict });
|
||||
|
||||
var input = [
|
||||
'HTTP/1.1 200 Ok',
|
||||
@ -52,22 +51,45 @@ var input = [
|
||||
''
|
||||
].join('\r\n');
|
||||
|
||||
// Put data into deflate stream
|
||||
deflate.on('data', function(chunk) {
|
||||
inflate.write(chunk);
|
||||
});
|
||||
deflate.on('end', function() {
|
||||
inflate.end();
|
||||
});
|
||||
var called = 0;
|
||||
|
||||
// Get data from inflate stream
|
||||
var output = [];
|
||||
inflate.on('data', function(chunk) {
|
||||
output.push(chunk);
|
||||
});
|
||||
inflate.on('end', function() {
|
||||
assert.equal(output.join(''), input);
|
||||
});
|
||||
//
|
||||
// We'll use clean-new inflate stream each time
|
||||
// and .reset() old dirty deflate one
|
||||
//
|
||||
function run(num) {
|
||||
var inflate = zlib.createInflate({ dictionary: spdyDict });
|
||||
|
||||
deflate.write(input);
|
||||
deflate.end();
|
||||
if (num === 2) {
|
||||
deflate.reset();
|
||||
deflate.removeAllListeners('data');
|
||||
}
|
||||
|
||||
// Put data into deflate stream
|
||||
deflate.on('data', function(chunk) {
|
||||
inflate.write(chunk);
|
||||
});
|
||||
|
||||
// Get data from inflate stream
|
||||
var output = [];
|
||||
inflate.on('data', function(chunk) {
|
||||
output.push(chunk);
|
||||
});
|
||||
inflate.on('end', function() {
|
||||
called++;
|
||||
|
||||
assert.equal(output.join(''), input);
|
||||
|
||||
if (num < 2) run(num + 1);
|
||||
});
|
||||
|
||||
deflate.write(input);
|
||||
deflate.flush(function() {
|
||||
inflate.end();
|
||||
});
|
||||
}
|
||||
run(1);
|
||||
|
||||
process.on('exit', function() {
|
||||
assert.equal(called, 2);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user