|
| 1 | +#include <node.h> |
| 2 | +#include <node_buffer.h> |
| 3 | +#include <assert.h> |
| 4 | +#include <zlib.h> |
| 5 | + |
| 6 | +namespace { |
| 7 | + |
| 8 | +inline void CompressBytes(const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 9 | + assert(info[0]->IsArrayBufferView()); |
| 10 | + auto view = info[0].As<v8::ArrayBufferView>(); |
| 11 | + auto byte_offset = view->ByteOffset(); |
| 12 | + auto byte_length = view->ByteLength(); |
| 13 | + assert(view->HasBuffer()); |
| 14 | + auto buffer = view->Buffer(); |
| 15 | + auto contents = buffer->GetContents(); |
| 16 | + auto data = static_cast<unsigned char*>(contents.Data()) + byte_offset; |
| 17 | + |
| 18 | + Bytef buf[1024]; |
| 19 | + |
| 20 | + z_stream stream; |
| 21 | + stream.zalloc = nullptr; |
| 22 | + stream.zfree = nullptr; |
| 23 | + |
| 24 | + int err = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, |
| 25 | + -15, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); |
| 26 | + assert(err == Z_OK); |
| 27 | + |
| 28 | + stream.avail_in = byte_length; |
| 29 | + stream.next_in = data; |
| 30 | + stream.avail_out = sizeof(buf); |
| 31 | + stream.next_out = buf; |
| 32 | + err = deflate(&stream, Z_FINISH); |
| 33 | + assert(err == Z_STREAM_END); |
| 34 | + |
| 35 | + auto result = node::Buffer::Copy(info.GetIsolate(), |
| 36 | + reinterpret_cast<const char*>(buf), |
| 37 | + sizeof(buf) - stream.avail_out); |
| 38 | + |
| 39 | + deflateEnd(&stream); |
| 40 | + |
| 41 | + info.GetReturnValue().Set(result.ToLocalChecked()); |
| 42 | +} |
| 43 | + |
| 44 | +inline void Initialize(v8::Local<v8::Object> exports, |
| 45 | + v8::Local<v8::Value> module, |
| 46 | + v8::Local<v8::Context> context) { |
| 47 | + auto isolate = context->GetIsolate(); |
| 48 | + auto key = v8::String::NewFromUtf8(isolate, "compressBytes"); |
| 49 | + auto value = v8::FunctionTemplate::New(isolate, CompressBytes)->GetFunction(); |
| 50 | + assert(exports->Set(context, key, value).IsJust()); |
| 51 | +} |
| 52 | + |
| 53 | +} // anonymous namespace |
| 54 | + |
| 55 | +NODE_MODULE_CONTEXT_AWARE(binding, Initialize) |
0 commit comments