Browse Source

zlib: reset() method for deflate/inflate streams

* ammended test-zlib-dictionary to cover reusing streams
v0.7.4-release
Fedor Indutny 13 years ago
parent
commit
71ae175319
  1. 4
      lib/zlib.js
  2. 63
      src/node_zlib.cc
  3. 58
      test/simple/test-zlib-dictionary.js

4
lib/zlib.js

@ -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);

63
src/node_zlib.cc

@ -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,23 +315,46 @@ 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) { ctx->write_in_progress_ = false;
switch (mode) { ctx->init_done_ = true;
case DEFLATE: }
case DEFLATERAW:
err = deflateSetDictionary(&ctx->strm_, static void SetDictionary(ZCtx* ctx) {
ctx->dictionary_, if (ctx->dictionary_ == NULL) return;
dictionary_len);
break;
default:
break;
}
assert(err == Z_OK && "Failed to set dictionary"); int err;
switch (mode) {
case DEFLATE:
case DEFLATERAW:
err = deflateSetDictionary(&ctx->strm_,
ctx->dictionary_,
ctx->dictionary_len_);
break;
default:
break;
} }
ctx->write_in_progress_ = false; assert(err == Z_OK && "Failed to set dictionary");
ctx->init_done_ = true; }
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:
@ -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()); \
} }

58
test/simple/test-zlib-dictionary.js

@ -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);
}); if (num === 2) {
deflate.reset();
deflate.removeAllListeners('data');
}
deflate.write(input); // Put data into deflate stream
deflate.end(); 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…
Cancel
Save