}
function onEnd() {
- callback(null, Buffer.concat(buffers, nread));
+ var buf = Buffer.concat(buffers, nread);
+ buffers = [];
+ callback(null, buf);
+ engine._clear();
}
engine.on('error', onError);
return ret;
};
+Zlib.prototype._clear = function() {
+ return this._binding.clear();
+};
+
Zlib.prototype._process = function() {
if (this._hadError) return;
static Persistent<String> onerror_sym;
enum node_zlib_mode {
- DEFLATE = 1,
+ NONE,
+ DEFLATE,
INFLATE,
GZIP,
GUNZIP,
ZCtx(node_zlib_mode mode) : ObjectWrap(), dictionary_(NULL), mode_(mode) {}
+
~ZCtx() {
+ Clear();
+ }
+
+
+ void Clear() {
+ assert(!write_in_progress_ && "write in progress");
+ assert(init_done_ && "clear before init");
+ assert(mode_ <= UNZIP);
+
if (mode_ == DEFLATE || mode_ == GZIP || mode_ == DEFLATERAW) {
(void)deflateEnd(&strm_);
} else if (mode_ == INFLATE || mode_ == GUNZIP || mode_ == INFLATERAW ||
mode_ == UNZIP) {
(void)inflateEnd(&strm_);
}
+ mode_ = NONE;
+
+ if (dictionary_ != NULL) {
+ delete[] dictionary_;
+ dictionary_ = NULL;
+ }
+ }
+
- if (dictionary_ != NULL) delete[] dictionary_;
+ static Handle<Value> Clear(const Arguments& args) {
+ HandleScope scope;
+ ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This());
+ ctx->Clear();
+ return scope.Close(Undefined());
}
+
// write(flush, in, in_off, in_len, out, out_off, out_len)
static Handle<Value> Write(const Arguments& args) {
HandleScope scope;
ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This());
assert(ctx->init_done_ && "write before init");
+ assert(ctx->mode_ != NONE && "already finalized");
assert(!ctx->write_in_progress_ && "write already in progress");
ctx->write_in_progress_ = true;
NODE_SET_PROTOTYPE_METHOD(z, "write", ZCtx::Write);
NODE_SET_PROTOTYPE_METHOD(z, "init", ZCtx::Init);
+ NODE_SET_PROTOTYPE_METHOD(z, "clear", ZCtx::Clear);
NODE_SET_PROTOTYPE_METHOD(z, "reset", ZCtx::Reset);
z->SetClassName(String::NewSymbol("Zlib"));