#include "stream_encode.h" #include "stream_encode_worker.h" using namespace v8; StreamEncode::StreamEncode(bool isAsync, Local<Object> params): isAsync(isAsync) { state = BrotliEncoderCreateInstance(Allocator::Alloc, Allocator::Free, &alloc); Local<String> key; Local<Value> localVal; uint32_t val; key = Nan::New<String>("mode").ToLocalChecked(); if (Nan::Has(params, key).FromJust()) { localVal = Nan::Get(params, key).ToLocalChecked(); val = Nan::To<uint32_t>(localVal).FromJust(); BrotliEncoderSetParameter(state, BROTLI_PARAM_MODE, val); } key = Nan::New<String>("quality").ToLocalChecked(); if (Nan::Has(params, key).FromJust()) { localVal = Nan::Get(params, key).ToLocalChecked(); val = Nan::To<uint32_t>(localVal).FromJust(); BrotliEncoderSetParameter(state, BROTLI_PARAM_QUALITY, val); } key = Nan::New<String>("lgwin").ToLocalChecked(); if (Nan::Has(params, key).FromJust()) { localVal = Nan::Get(params, key).ToLocalChecked(); val = Nan::To<uint32_t>(localVal).FromJust(); BrotliEncoderSetParameter(state, BROTLI_PARAM_LGWIN, val); } key = Nan::New<String>("lgblock").ToLocalChecked(); if (Nan::Has(params, key).FromJust()) { localVal = Nan::Get(params, key).ToLocalChecked(); val = Nan::To<uint32_t>(localVal).FromJust(); BrotliEncoderSetParameter(state, BROTLI_PARAM_LGBLOCK, val); } key = Nan::New<String>("disable_literal_context_modeling").ToLocalChecked(); if (Nan::Has(params, key).FromJust()) { localVal = Nan::Get(params, key).ToLocalChecked(); val = Nan::To<uint32_t>(localVal).FromJust(); BrotliEncoderSetParameter(state, BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING, val); } key = Nan::New<String>("size_hint").ToLocalChecked(); if (Nan::Has(params, key).FromJust()) { localVal = Nan::Get(params, key).ToLocalChecked(); val = Nan::To<uint32_t>(localVal).FromJust(); BrotliEncoderSetParameter(state, BROTLI_PARAM_SIZE_HINT, val); } key = Nan::New<String>("large_window").ToLocalChecked(); if (Nan::Has(params, key).FromJust()) { localVal = Nan::Get(params, key).ToLocalChecked(); val = Nan::To<uint32_t>(localVal).FromJust(); BrotliEncoderSetParameter(state, BROTLI_PARAM_LARGE_WINDOW, val); } key = Nan::New<String>("npostfix").ToLocalChecked(); if (Nan::Has(params, key).FromJust()) { localVal = Nan::Get(params, key).ToLocalChecked(); val = Nan::To<uint32_t>(localVal).FromJust(); BrotliEncoderSetParameter(state, BROTLI_PARAM_NPOSTFIX, val); } key = Nan::New<String>("ndirect").ToLocalChecked(); if (Nan::Has(params, key).FromJust()) { localVal = Nan::Get(params, key).ToLocalChecked(); val = Nan::To<uint32_t>(localVal).FromJust(); BrotliEncoderSetParameter(state, BROTLI_PARAM_NDIRECT, val); } } StreamEncode::~StreamEncode() { BrotliEncoderDestroyInstance(state); } void StreamEncode::Init(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) { Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New); tpl->SetClassName(Nan::New("StreamEncode").ToLocalChecked()); tpl->InstanceTemplate()->SetInternalFieldCount(1); Nan::SetPrototypeMethod(tpl, "transform", Transform); Nan::SetPrototypeMethod(tpl, "flush", Flush); constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked()); Nan::Set(target, Nan::New("StreamEncode").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked()); } NAN_METHOD(StreamEncode::New) { StreamEncode* obj = new StreamEncode( Nan::To<bool>(info[0]).FromJust(), Nan::To<Object>(info[1]).ToLocalChecked() ); obj->Wrap(info.This()); info.GetReturnValue().Set(info.This()); } NAN_METHOD(StreamEncode::Transform) { StreamEncode* obj = ObjectWrap::Unwrap<StreamEncode>(info.Holder()); Local<Object> buffer = Nan::To<Object>(info[0]).ToLocalChecked(); obj->next_in = (const uint8_t*) node::Buffer::Data(buffer); obj->available_in = node::Buffer::Length(buffer); Nan::Callback *callback = new Nan::Callback(info[1].As<Function>()); StreamEncodeWorker *worker = new StreamEncodeWorker(callback, obj, BROTLI_OPERATION_PROCESS); if (obj->isAsync) { Nan::AsyncQueueWorker(worker); } else { worker->Execute(); worker->WorkComplete(); worker->Destroy(); } } NAN_METHOD(StreamEncode::Flush) { StreamEncode* obj = ObjectWrap::Unwrap<StreamEncode>(info.Holder()); Nan::Callback *callback = new Nan::Callback(info[1].As<Function>()); BrotliEncoderOperation op = Nan::To<bool>(info[0]).FromJust() ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_FLUSH; obj->next_in = nullptr; obj->available_in = 0; StreamEncodeWorker *worker = new StreamEncodeWorker(callback, obj, op); if (obj->isAsync) { Nan::AsyncQueueWorker(worker); } else { worker->Execute(); worker->WorkComplete(); worker->Destroy(); } } Nan::Persistent<Function> StreamEncode::constructor;