zlib: reduce number of static internal methods
There really isn’t any good reason for these to be static methods,
it just adds one layer of indirection (when reading the code,
not in a way that affects behaviour).
Addresses a `TODO` comment introduced in c072057049.
PR-URL: https://github.com/nodejs/node/pull/20674
Refs: c072057049
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
8c1186dfcc
commit
2b8cd93246
162
src/node_zlib.cc
162
src/node_zlib.cc
@ -202,7 +202,7 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
|
|||||||
// sync version
|
// sync version
|
||||||
env->PrintSyncTrace();
|
env->PrintSyncTrace();
|
||||||
ctx->DoThreadPoolWork();
|
ctx->DoThreadPoolWork();
|
||||||
if (CheckError(ctx)) {
|
if (ctx->CheckError()) {
|
||||||
ctx->write_result_[0] = ctx->strm_.avail_out;
|
ctx->write_result_[0] = ctx->strm_.avail_out;
|
||||||
ctx->write_result_[1] = ctx->strm_.avail_in;
|
ctx->write_result_[1] = ctx->strm_.avail_in;
|
||||||
ctx->write_in_progress_ = false;
|
ctx->write_in_progress_ = false;
|
||||||
@ -215,53 +215,43 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
|
|||||||
ctx->ScheduleWork();
|
ctx->ScheduleWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(addaleax): Make these methods non-static. It's a significant bunch
|
|
||||||
// of churn that's better left for a separate PR.
|
|
||||||
void DoThreadPoolWork() override {
|
|
||||||
Process(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AfterThreadPoolWork(int status) override {
|
|
||||||
After(this, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
// thread pool!
|
// thread pool!
|
||||||
// This function may be called multiple times on the uv_work pool
|
// This function may be called multiple times on the uv_work pool
|
||||||
// for a single write() call, until all of the input bytes have
|
// for a single write() call, until all of the input bytes have
|
||||||
// been consumed.
|
// been consumed.
|
||||||
static void Process(ZCtx* ctx) {
|
void DoThreadPoolWork() {
|
||||||
const Bytef* next_expected_header_byte = nullptr;
|
const Bytef* next_expected_header_byte = nullptr;
|
||||||
|
|
||||||
// If the avail_out is left at 0, then it means that it ran out
|
// If the avail_out is left at 0, then it means that it ran out
|
||||||
// of room. If there was avail_out left over, then it means
|
// of room. If there was avail_out left over, then it means
|
||||||
// that all of the input was consumed.
|
// that all of the input was consumed.
|
||||||
switch (ctx->mode_) {
|
switch (mode_) {
|
||||||
case DEFLATE:
|
case DEFLATE:
|
||||||
case GZIP:
|
case GZIP:
|
||||||
case DEFLATERAW:
|
case DEFLATERAW:
|
||||||
ctx->err_ = deflate(&ctx->strm_, ctx->flush_);
|
err_ = deflate(&strm_, flush_);
|
||||||
break;
|
break;
|
||||||
case UNZIP:
|
case UNZIP:
|
||||||
if (ctx->strm_.avail_in > 0) {
|
if (strm_.avail_in > 0) {
|
||||||
next_expected_header_byte = ctx->strm_.next_in;
|
next_expected_header_byte = strm_.next_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ctx->gzip_id_bytes_read_) {
|
switch (gzip_id_bytes_read_) {
|
||||||
case 0:
|
case 0:
|
||||||
if (next_expected_header_byte == nullptr) {
|
if (next_expected_header_byte == nullptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*next_expected_header_byte == GZIP_HEADER_ID1) {
|
if (*next_expected_header_byte == GZIP_HEADER_ID1) {
|
||||||
ctx->gzip_id_bytes_read_ = 1;
|
gzip_id_bytes_read_ = 1;
|
||||||
next_expected_header_byte++;
|
next_expected_header_byte++;
|
||||||
|
|
||||||
if (ctx->strm_.avail_in == 1) {
|
if (strm_.avail_in == 1) {
|
||||||
// The only available byte was already read.
|
// The only available byte was already read.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx->mode_ = INFLATE;
|
mode_ = INFLATE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,12 +262,12 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*next_expected_header_byte == GZIP_HEADER_ID2) {
|
if (*next_expected_header_byte == GZIP_HEADER_ID2) {
|
||||||
ctx->gzip_id_bytes_read_ = 2;
|
gzip_id_bytes_read_ = 2;
|
||||||
ctx->mode_ = GUNZIP;
|
mode_ = GUNZIP;
|
||||||
} else {
|
} else {
|
||||||
// There is no actual difference between INFLATE and INFLATERAW
|
// There is no actual difference between INFLATE and INFLATERAW
|
||||||
// (after initialization).
|
// (after initialization).
|
||||||
ctx->mode_ = INFLATE;
|
mode_ = INFLATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -289,39 +279,37 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
|
|||||||
case INFLATE:
|
case INFLATE:
|
||||||
case GUNZIP:
|
case GUNZIP:
|
||||||
case INFLATERAW:
|
case INFLATERAW:
|
||||||
ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
|
err_ = inflate(&strm_, flush_);
|
||||||
|
|
||||||
// If data was encoded with dictionary (INFLATERAW will have it set in
|
// If data was encoded with dictionary (INFLATERAW will have it set in
|
||||||
// SetDictionary, don't repeat that here)
|
// SetDictionary, don't repeat that here)
|
||||||
if (ctx->mode_ != INFLATERAW &&
|
if (mode_ != INFLATERAW &&
|
||||||
ctx->err_ == Z_NEED_DICT &&
|
err_ == Z_NEED_DICT &&
|
||||||
ctx->dictionary_ != nullptr) {
|
dictionary_ != nullptr) {
|
||||||
// Load it
|
// Load it
|
||||||
ctx->err_ = inflateSetDictionary(&ctx->strm_,
|
err_ = inflateSetDictionary(&strm_, dictionary_, dictionary_len_);
|
||||||
ctx->dictionary_,
|
if (err_ == Z_OK) {
|
||||||
ctx->dictionary_len_);
|
|
||||||
if (ctx->err_ == Z_OK) {
|
|
||||||
// And try to decode again
|
// And try to decode again
|
||||||
ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
|
err_ = inflate(&strm_, flush_);
|
||||||
} else if (ctx->err_ == Z_DATA_ERROR) {
|
} else if (err_ == Z_DATA_ERROR) {
|
||||||
// Both inflateSetDictionary() and inflate() return Z_DATA_ERROR.
|
// Both inflateSetDictionary() and inflate() return Z_DATA_ERROR.
|
||||||
// Make it possible for After() to tell a bad dictionary from bad
|
// Make it possible for After() to tell a bad dictionary from bad
|
||||||
// input.
|
// input.
|
||||||
ctx->err_ = Z_NEED_DICT;
|
err_ = Z_NEED_DICT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ctx->strm_.avail_in > 0 &&
|
while (strm_.avail_in > 0 &&
|
||||||
ctx->mode_ == GUNZIP &&
|
mode_ == GUNZIP &&
|
||||||
ctx->err_ == Z_STREAM_END &&
|
err_ == Z_STREAM_END &&
|
||||||
ctx->strm_.next_in[0] != 0x00) {
|
strm_.next_in[0] != 0x00) {
|
||||||
// Bytes remain in input buffer. Perhaps this is another compressed
|
// Bytes remain in input buffer. Perhaps this is another compressed
|
||||||
// member in the same archive, or just trailing garbage.
|
// member in the same archive, or just trailing garbage.
|
||||||
// Trailing zero bytes are okay, though, since they are frequently
|
// Trailing zero bytes are okay, though, since they are frequently
|
||||||
// used for padding.
|
// used for padding.
|
||||||
|
|
||||||
Reset(ctx);
|
Reset();
|
||||||
ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
|
err_ = inflate(&strm_, flush_);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -336,27 +324,27 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool CheckError(ZCtx* ctx) {
|
bool CheckError() {
|
||||||
// Acceptable error states depend on the type of zlib stream.
|
// Acceptable error states depend on the type of zlib stream.
|
||||||
switch (ctx->err_) {
|
switch (err_) {
|
||||||
case Z_OK:
|
case Z_OK:
|
||||||
case Z_BUF_ERROR:
|
case Z_BUF_ERROR:
|
||||||
if (ctx->strm_.avail_out != 0 && ctx->flush_ == Z_FINISH) {
|
if (strm_.avail_out != 0 && flush_ == Z_FINISH) {
|
||||||
ZCtx::Error(ctx, "unexpected end of file");
|
Error("unexpected end of file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case Z_STREAM_END:
|
case Z_STREAM_END:
|
||||||
// normal statuses, not fatal
|
// normal statuses, not fatal
|
||||||
break;
|
break;
|
||||||
case Z_NEED_DICT:
|
case Z_NEED_DICT:
|
||||||
if (ctx->dictionary_ == nullptr)
|
if (dictionary_ == nullptr)
|
||||||
ZCtx::Error(ctx, "Missing dictionary");
|
Error("Missing dictionary");
|
||||||
else
|
else
|
||||||
ZCtx::Error(ctx, "Bad dictionary");
|
Error("Bad dictionary");
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
// something else.
|
// something else.
|
||||||
ZCtx::Error(ctx, "Zlib error");
|
Error("Zlib error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,59 +353,57 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
|
|||||||
|
|
||||||
|
|
||||||
// v8 land!
|
// v8 land!
|
||||||
static void After(ZCtx* ctx, int status) {
|
void AfterThreadPoolWork(int status) {
|
||||||
Environment* env = ctx->env();
|
write_in_progress_ = false;
|
||||||
ctx->write_in_progress_ = false;
|
|
||||||
|
|
||||||
if (status == UV_ECANCELED) {
|
if (status == UV_ECANCELED) {
|
||||||
ctx->Close();
|
Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_EQ(status, 0);
|
CHECK_EQ(status, 0);
|
||||||
|
|
||||||
HandleScope handle_scope(env->isolate());
|
HandleScope handle_scope(env()->isolate());
|
||||||
Context::Scope context_scope(env->context());
|
Context::Scope context_scope(env()->context());
|
||||||
|
|
||||||
if (!CheckError(ctx))
|
if (!CheckError())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
// call the write() cb
|
// call the write() cb
|
||||||
Local<Function> cb = PersistentToLocal(env->isolate(),
|
Local<Function> cb = PersistentToLocal(env()->isolate(),
|
||||||
ctx->write_js_callback_);
|
write_js_callback_);
|
||||||
ctx->MakeCallback(cb, 0, nullptr);
|
MakeCallback(cb, 0, nullptr);
|
||||||
|
|
||||||
ctx->Unref();
|
Unref();
|
||||||
if (ctx->pending_close_)
|
if (pending_close_)
|
||||||
ctx->Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Error(ZCtx* ctx, const char* message) {
|
// TODO(addaleax): Switch to modern error system (node_errors.h).
|
||||||
Environment* env = ctx->env();
|
void Error(const char* message) {
|
||||||
|
|
||||||
// If you hit this assertion, you forgot to enter the v8::Context first.
|
// If you hit this assertion, you forgot to enter the v8::Context first.
|
||||||
CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
|
CHECK_EQ(env()->context(), env()->isolate()->GetCurrentContext());
|
||||||
|
|
||||||
if (ctx->strm_.msg != nullptr) {
|
if (strm_.msg != nullptr) {
|
||||||
message = ctx->strm_.msg;
|
message = strm_.msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleScope scope(env->isolate());
|
HandleScope scope(env()->isolate());
|
||||||
Local<Value> args[2] = {
|
Local<Value> args[2] = {
|
||||||
OneByteString(env->isolate(), message),
|
OneByteString(env()->isolate(), message),
|
||||||
Number::New(env->isolate(), ctx->err_)
|
Number::New(env()->isolate(), err_)
|
||||||
};
|
};
|
||||||
ctx->MakeCallback(env->onerror_string(), arraysize(args), args);
|
MakeCallback(env()->onerror_string(), arraysize(args), args);
|
||||||
|
|
||||||
// no hope of rescue.
|
// no hope of rescue.
|
||||||
if (ctx->write_in_progress_)
|
if (write_in_progress_)
|
||||||
ctx->Unref();
|
Unref();
|
||||||
ctx->write_in_progress_ = false;
|
write_in_progress_ = false;
|
||||||
if (ctx->pending_close_)
|
if (pending_close_)
|
||||||
ctx->Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void New(const FunctionCallbackInfo<Value>& args) {
|
static void New(const FunctionCallbackInfo<Value>& args) {
|
||||||
@ -510,7 +496,7 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
|
|||||||
static void Reset(const FunctionCallbackInfo<Value> &args) {
|
static void Reset(const FunctionCallbackInfo<Value> &args) {
|
||||||
ZCtx* ctx;
|
ZCtx* ctx;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
|
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
|
||||||
Reset(ctx);
|
ctx->Reset();
|
||||||
SetDictionary(ctx);
|
SetDictionary(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,7 +599,7 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->err_ != Z_OK) {
|
if (ctx->err_ != Z_OK) {
|
||||||
ZCtx::Error(ctx, "Failed to set dictionary");
|
ctx->Error("Failed to set dictionary");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,30 +616,30 @@ class ZCtx : public AsyncWrap, public ThreadPoolWork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->err_ != Z_OK && ctx->err_ != Z_BUF_ERROR) {
|
if (ctx->err_ != Z_OK && ctx->err_ != Z_BUF_ERROR) {
|
||||||
ZCtx::Error(ctx, "Failed to set parameters");
|
ctx->Error("Failed to set parameters");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Reset(ZCtx* ctx) {
|
void Reset() {
|
||||||
ctx->err_ = Z_OK;
|
err_ = Z_OK;
|
||||||
|
|
||||||
switch (ctx->mode_) {
|
switch (mode_) {
|
||||||
case DEFLATE:
|
case DEFLATE:
|
||||||
case DEFLATERAW:
|
case DEFLATERAW:
|
||||||
case GZIP:
|
case GZIP:
|
||||||
ctx->err_ = deflateReset(&ctx->strm_);
|
err_ = deflateReset(&strm_);
|
||||||
break;
|
break;
|
||||||
case INFLATE:
|
case INFLATE:
|
||||||
case INFLATERAW:
|
case INFLATERAW:
|
||||||
case GUNZIP:
|
case GUNZIP:
|
||||||
ctx->err_ = inflateReset(&ctx->strm_);
|
err_ = inflateReset(&strm_);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->err_ != Z_OK) {
|
if (err_ != Z_OK) {
|
||||||
ZCtx::Error(ctx, "Failed to reset stream");
|
Error("Failed to reset stream");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user