/**
* Deflate/Inflate
*/
-class ZCtx : public ObjectWrap {
+class ZCtx : public AsyncWrap {
public:
- ZCtx(node_zlib_mode mode)
- : ObjectWrap()
- , init_done_(false)
- , level_(0)
- , windowBits_(0)
- , memLevel_(0)
- , strategy_(0)
- , err_(0)
- , dictionary_(NULL)
- , dictionary_len_(0)
- , flush_(0)
- , chunk_size_(0)
- , write_in_progress_(false)
- , pending_close_(false)
- , mode_(mode)
- {
+ ZCtx(Environment* env, Local<Object> wrap, node_zlib_mode mode)
+ : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_ZLIB),
+ chunk_size_(0),
+ dictionary_(NULL),
+ dictionary_len_(0),
+ err_(0),
+ flush_(0),
+ init_done_(false),
+ level_(0),
+ memLevel_(0),
+ mode_(mode),
+ strategy_(0),
+ windowBits_(0),
+ write_in_progress_(false),
++ pending_close_(false),
+ refs_(0) {
+ MakeWeak<ZCtx>(this);
}
Close();
}
-
void Close() {
- assert(!write_in_progress_ && "write in progress");
+ if (write_in_progress_) {
+ pending_close_ = true;
+ return;
+ }
+
+ pending_close_ = false;
assert(init_done_ && "close before init");
assert(mode_ <= UNZIP);
ctx->write_in_progress_ = false;
// call the write() cb
- assert(ctx->handle_->Get(callback_sym)->IsFunction() &&
- "Invalid callback");
Local<Value> args[2] = { avail_in, avail_out };
- MakeCallback(ctx->handle_, callback_sym, ARRAY_SIZE(args), args);
+ ctx->MakeCallback(env->callback_string(), ARRAY_SIZE(args), args);
ctx->Unref();
+ if (ctx->pending_close_)
+ ctx->Close();
}
- static void Error(ZCtx *ctx, const char *msg_) {
- const char *msg;
+ static void Error(ZCtx* ctx, const char* message) {
+ Environment* env = ctx->env();
+
+ // If you hit this assertion, you forgot to enter the v8::Context first.
+ assert(env->context() == env->isolate()->GetCurrentContext());
+
if (ctx->strm_.msg != NULL) {
- msg = ctx->strm_.msg;
- } else {
- msg = msg_;
+ message = ctx->strm_.msg;
}
- assert(ctx->handle_->Get(onerror_sym)->IsFunction() &&
- "Invalid error handler");
- HandleScope scope;
- Local<Value> args[2] = { String::New(msg),
- Local<Value>::New(Number::New(ctx->err_)) };
- MakeCallback(ctx->handle_, onerror_sym, ARRAY_SIZE(args), args);
+ HandleScope scope(node_isolate);
+ Local<Value> args[2] = {
+ OneByteString(node_isolate, message),
+ Number::New(ctx->err_)
+ };
+ ctx->MakeCallback(env->onerror_string(), ARRAY_SIZE(args), args);
// no hope of rescue.
ctx->write_in_progress_ = false;
ctx->Unref();
+ if (ctx->pending_close_)
+ ctx->Close();
}
- static Handle<Value> New(const Arguments& args) {
- HandleScope scope;
+ static void New(const FunctionCallbackInfo<Value>& args) {
+ HandleScope handle_scope(args.GetIsolate());
+ Environment* env = Environment::GetCurrent(args.GetIsolate());
+
if (args.Length() < 1 || !args[0]->IsInt32()) {
- return ThrowException(Exception::TypeError(String::New("Bad argument")));
+ return ThrowTypeError("Bad argument");
}
- node_zlib_mode mode = (node_zlib_mode) args[0]->Int32Value();
+ node_zlib_mode mode = static_cast<node_zlib_mode>(args[0]->Int32Value());
if (mode < DEFLATE || mode > UNZIP) {
- return ThrowException(Exception::TypeError(String::New("Bad argument")));
+ return ThrowTypeError("Bad argument");
}
- ZCtx *ctx = new ZCtx(mode);
- ctx->Wrap(args.This());
- return args.This();
+ new ZCtx(env, args.This(), mode);
}
// just pull the ints out of the args and call the other Init
}
private:
- static const int kDeflateContextSize = 16384; // approximate
- static const int kInflateContextSize = 10240; // approximate
-
- bool init_done_;
+ void Ref() {
+ if (++refs_ == 1) {
+ ClearWeak();
+ }
+ }
- z_stream strm_;
- int level_;
- int windowBits_;
- int memLevel_;
- int strategy_;
+ void Unref() {
+ assert(refs_ > 0);
+ if (--refs_ == 0) {
+ MakeWeak<ZCtx>(this);
+ }
+ }
- int err_;
+ static const int kDeflateContextSize = 16384; // approximate
+ static const int kInflateContextSize = 10240; // approximate
+ int chunk_size_;
Bytef* dictionary_;
size_t dictionary_len_;
-
+ int err_;
int flush_;
-
- int chunk_size_;
-
+ bool init_done_;
+ int level_;
+ int memLevel_;
+ node_zlib_mode mode_;
+ int strategy_;
+ z_stream strm_;
+ int windowBits_;
+ uv_work_t work_req_;
bool write_in_progress_;
-
- uv_work_t work_req_;
- node_zlib_mode mode_;
+ bool pending_close_;
+ unsigned int refs_;
};