src: clean up zlib write code

Split the existing `Write()` method into one that takes care
of translating the arguments from JS to C++, and a non-static
method for the actual write operations, as well as some minor
stylistic drive-by fixes.

PR-URL: https://github.com/nodejs/node/pull/23183
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
This commit is contained in:
Anna Henningsen 2018-09-30 13:41:57 -04:00 committed by Daniel Bevenius
parent f01adb5454
commit 1fd99b4ac7

View File

@ -138,24 +138,15 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
// write(flush, in, in_off, in_len, out, out_off, out_len) // write(flush, in, in_off, in_len, out, out_off, out_len)
template <bool async> template <bool async>
static void Write(const FunctionCallbackInfo<Value>& args) { static void Write(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
Local<Context> context = env->context();
CHECK_EQ(args.Length(), 7); CHECK_EQ(args.Length(), 7);
ZCtx* ctx; uint32_t in_off, in_len, out_off, out_len, flush;
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder()); char* in;
CHECK(ctx->init_done_ && "write before init"); char* out;
CHECK(ctx->mode_ != NONE && "already finalized");
CHECK_EQ(false, ctx->write_in_progress_ && "write already in progress");
CHECK_EQ(false, ctx->pending_close_ && "close is pending");
ctx->write_in_progress_ = true;
ctx->Ref();
CHECK_EQ(false, args[0]->IsUndefined() && "must provide flush value"); CHECK_EQ(false, args[0]->IsUndefined() && "must provide flush value");
Environment* env = ctx->env();
Local<Context> context = env->context();
unsigned int flush;
if (!args[0]->Uint32Value(context).To(&flush)) return; if (!args[0]->Uint32Value(context).To(&flush)) return;
if (flush != Z_NO_FLUSH && if (flush != Z_NO_FLUSH &&
@ -167,12 +158,6 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
CHECK(0 && "Invalid flush value"); CHECK(0 && "Invalid flush value");
} }
AllocScope alloc_scope(ctx);
Bytef* in;
Bytef* out;
uint32_t in_off, in_len, out_off, out_len;
if (args[1]->IsNull()) { if (args[1]->IsNull()) {
// just a flush // just a flush
in = nullptr; in = nullptr;
@ -180,43 +165,62 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
in_off = 0; in_off = 0;
} else { } else {
CHECK(Buffer::HasInstance(args[1])); CHECK(Buffer::HasInstance(args[1]));
Local<Object> in_buf; Local<Object> in_buf = args[1].As<Object>();
in_buf = args[1]->ToObject(context).ToLocalChecked();
if (!args[2]->Uint32Value(context).To(&in_off)) return; if (!args[2]->Uint32Value(context).To(&in_off)) return;
if (!args[3]->Uint32Value(context).To(&in_len)) return; if (!args[3]->Uint32Value(context).To(&in_len)) return;
CHECK(Buffer::IsWithinBounds(in_off, in_len, Buffer::Length(in_buf))); CHECK(Buffer::IsWithinBounds(in_off, in_len, Buffer::Length(in_buf)));
in = reinterpret_cast<Bytef *>(Buffer::Data(in_buf) + in_off); in = Buffer::Data(in_buf) + in_off;
} }
CHECK(Buffer::HasInstance(args[4])); CHECK(Buffer::HasInstance(args[4]));
Local<Object> out_buf = args[4]->ToObject(context).ToLocalChecked(); Local<Object> out_buf = args[4].As<Object>();
if (!args[5]->Uint32Value(context).To(&out_off)) return; if (!args[5]->Uint32Value(context).To(&out_off)) return;
if (!args[6]->Uint32Value(context).To(&out_len)) return; if (!args[6]->Uint32Value(context).To(&out_len)) return;
CHECK(Buffer::IsWithinBounds(out_off, out_len, Buffer::Length(out_buf))); CHECK(Buffer::IsWithinBounds(out_off, out_len, Buffer::Length(out_buf)));
out = reinterpret_cast<Bytef *>(Buffer::Data(out_buf) + out_off); out = Buffer::Data(out_buf) + out_off;
ctx->strm_.avail_in = in_len; ZCtx* ctx;
ctx->strm_.next_in = in; ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
ctx->strm_.avail_out = out_len;
ctx->strm_.next_out = out; ctx->Write<async>(flush, in, in_len, out, out_len);
ctx->flush_ = flush; }
template <bool async>
void Write(uint32_t flush,
char* in, uint32_t in_len,
char* out, uint32_t out_len) {
AllocScope alloc_scope(this);
CHECK(init_done_ && "write before init");
CHECK(mode_ != NONE && "already finalized");
CHECK_EQ(false, write_in_progress_);
CHECK_EQ(false, pending_close_);
write_in_progress_ = true;
Ref();
strm_.avail_in = in_len;
strm_.next_in = reinterpret_cast<Bytef*>(in);
strm_.avail_out = out_len;
strm_.next_out = reinterpret_cast<Bytef*>(out);
flush_ = flush;
if (!async) { if (!async) {
// sync version // sync version
env->PrintSyncTrace(); env()->PrintSyncTrace();
ctx->DoThreadPoolWork(); DoThreadPoolWork();
if (ctx->CheckError()) { if (CheckError()) {
ctx->write_result_[0] = ctx->strm_.avail_out; write_result_[0] = strm_.avail_out;
ctx->write_result_[1] = ctx->strm_.avail_in; write_result_[1] = strm_.avail_in;
ctx->write_in_progress_ = false; write_in_progress_ = false;
} }
ctx->Unref(); Unref();
return; return;
} }
// async version // async version
ctx->ScheduleWork(); ScheduleWork();
} }
// thread pool! // thread pool!