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;
|
return empty;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Zlib.prototype.reset = function reset() {
|
||||||
|
return this._binding.reset();
|
||||||
|
};
|
||||||
|
|
||||||
Zlib.prototype.flush = function flush(cb) {
|
Zlib.prototype.flush = function flush(cb) {
|
||||||
this._flush = binding.Z_SYNC_FLUSH;
|
this._flush = binding.Z_SYNC_FLUSH;
|
||||||
return this.write(cb);
|
return this.write(cb);
|
||||||
|
@ -249,6 +249,17 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap {
|
|||||||
|
|
||||||
Init(ctx, level, windowBits, memLevel, strategy,
|
Init(ctx, level, windowBits, memLevel, strategy,
|
||||||
dictionary, dictionary_len);
|
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();
|
return Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,25 +315,48 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap {
|
|||||||
ctx->dictionary_ = reinterpret_cast<Bytef *>(dictionary);
|
ctx->dictionary_ = reinterpret_cast<Bytef *>(dictionary);
|
||||||
ctx->dictionary_len_ = dictionary_len;
|
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->write_in_progress_ = false;
|
||||||
ctx->init_done_ = true;
|
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:
|
private:
|
||||||
|
|
||||||
bool init_done_;
|
bool init_done_;
|
||||||
@ -352,6 +386,7 @@ template <node_zlib_mode mode> class ZCtx : public ObjectWrap {
|
|||||||
z->InstanceTemplate()->SetInternalFieldCount(1); \
|
z->InstanceTemplate()->SetInternalFieldCount(1); \
|
||||||
NODE_SET_PROTOTYPE_METHOD(z, "write", ZCtx<mode>::Write); \
|
NODE_SET_PROTOTYPE_METHOD(z, "write", ZCtx<mode>::Write); \
|
||||||
NODE_SET_PROTOTYPE_METHOD(z, "init", ZCtx<mode>::Init); \
|
NODE_SET_PROTOTYPE_METHOD(z, "init", ZCtx<mode>::Init); \
|
||||||
|
NODE_SET_PROTOTYPE_METHOD(z, "reset", ZCtx<mode>::Reset); \
|
||||||
z->SetClassName(String::NewSymbol(name)); \
|
z->SetClassName(String::NewSymbol(name)); \
|
||||||
target->Set(String::NewSymbol(name), z->GetFunction()); \
|
target->Set(String::NewSymbol(name), z->GetFunction()); \
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ var spdyDict = new Buffer([
|
|||||||
].join(''));
|
].join(''));
|
||||||
|
|
||||||
var deflate = zlib.createDeflate({ dictionary: spdyDict });
|
var deflate = zlib.createDeflate({ dictionary: spdyDict });
|
||||||
var inflate = zlib.createInflate({ dictionary: spdyDict });
|
|
||||||
|
|
||||||
var input = [
|
var input = [
|
||||||
'HTTP/1.1 200 Ok',
|
'HTTP/1.1 200 Ok',
|
||||||
@ -52,22 +51,45 @@ var input = [
|
|||||||
''
|
''
|
||||||
].join('\r\n');
|
].join('\r\n');
|
||||||
|
|
||||||
// Put data into deflate stream
|
var called = 0;
|
||||||
deflate.on('data', function(chunk) {
|
|
||||||
inflate.write(chunk);
|
|
||||||
});
|
|
||||||
deflate.on('end', function() {
|
|
||||||
inflate.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get data from inflate stream
|
//
|
||||||
var output = [];
|
// We'll use clean-new inflate stream each time
|
||||||
inflate.on('data', function(chunk) {
|
// and .reset() old dirty deflate one
|
||||||
output.push(chunk);
|
//
|
||||||
});
|
function run(num) {
|
||||||
inflate.on('end', function() {
|
var inflate = zlib.createInflate({ dictionary: spdyDict });
|
||||||
assert.equal(output.join(''), input);
|
|
||||||
});
|
|
||||||
|
|
||||||
deflate.write(input);
|
if (num === 2) {
|
||||||
deflate.end();
|
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