|
| 1 | +/** |
| 2 | + * Created by housisong on 2021.04.07. |
| 3 | + */ |
| 4 | +#include <nan.h> |
| 5 | +#include <node.h> |
| 6 | +#include <node_buffer.h> |
| 7 | +#include <cstdlib> |
| 8 | +#include "hdiff.h" |
| 9 | + |
| 10 | +using namespace std; |
| 11 | + |
| 12 | +namespace hdiffpatchNode |
| 13 | +{ |
| 14 | + using v8::FunctionCallbackInfo; |
| 15 | + using v8::HandleScope; |
| 16 | + using v8::Isolate; |
| 17 | + using v8::Local; |
| 18 | + using v8::Object; |
| 19 | + using v8::String; |
| 20 | + using v8::Value; |
| 21 | + using v8::Function; |
| 22 | + using v8::MaybeLocal; |
| 23 | + using v8::Null; |
| 24 | + using v8::Boolean; |
| 25 | + using v8::Exception; |
| 26 | + |
| 27 | + struct DiffStreamOpaque { |
| 28 | + Isolate* isolate; |
| 29 | + Local<Function> cb; |
| 30 | + }; |
| 31 | + |
| 32 | + static int callback_write(DiffStreamOpaque* opaque, const void* buffer, size_t size) |
| 33 | + { |
| 34 | + |
| 35 | + Local<Object> returnObj = node::Buffer::Copy(opaque->isolate, (const char*)buffer, size).ToLocalChecked(); |
| 36 | + |
| 37 | + Local<Value> argv[1] = { returnObj }; |
| 38 | + // opaque->cb->Call(Nan::GetCurrentContext()->Global(), Null(opaque->isolate), 1, argv); |
| 39 | + |
| 40 | + Nan::MakeCallback(Nan::GetCurrentContext()->Global(), opaque->cb, 1, argv); |
| 41 | + |
| 42 | + return 0; |
| 43 | + } |
| 44 | + |
| 45 | + void diff(const FunctionCallbackInfo<Value>& args) { |
| 46 | + Isolate* isolate = args.GetIsolate(); |
| 47 | + HandleScope scope(isolate); |
| 48 | + |
| 49 | + if (!node::Buffer::HasInstance(args[0]) || !node::Buffer::HasInstance(args[1]) || !args[2]->IsFunction()) { |
| 50 | + Nan::ThrowError("Invalid arguments."); |
| 51 | + } |
| 52 | + |
| 53 | + char* oldData = node::Buffer::Data(args[0]); |
| 54 | + size_t oldLength = node::Buffer::Length(args[0]); |
| 55 | + char* newData = node::Buffer::Data(args[1]); |
| 56 | + size_t newLength = node::Buffer::Length(args[1]); |
| 57 | + |
| 58 | + DiffStreamOpaque streamOpaque; |
| 59 | + streamOpaque.isolate = isolate; |
| 60 | + streamOpaque.cb = Local<Function>::Cast(args[2]); |
| 61 | + |
| 62 | + std::vector<uint8_t> codeBuf; |
| 63 | + try{ |
| 64 | + hdiff((const uint8_t*)oldData,oldLength,(const uint8_t*)newData,newLength,codeBuf); |
| 65 | + }catch(const std::exception& e){ |
| 66 | + Nan::ThrowError("Create hdiff failed."); |
| 67 | + } |
| 68 | + if (0!=callback_write(&streamOpaque,codeBuf.data(),codeBuf.size())) |
| 69 | + Nan::ThrowError("Write DiffStreamOpaque failed."); |
| 70 | + |
| 71 | +// args.GetReturnValue().Set(returnObj); |
| 72 | +// args.GetReturnValue().Set(String::NewFromUtf8(isolate, bufferData, String::kNormalString, bufferLength)); |
| 73 | + } |
| 74 | + |
| 75 | + void init(Local<Object> exports) |
| 76 | + { |
| 77 | + Isolate* isolate = exports->GetIsolate(); |
| 78 | + HandleScope scope(isolate); |
| 79 | + |
| 80 | + NODE_SET_METHOD(exports, "diff", diff); |
| 81 | + } |
| 82 | + |
| 83 | + NODE_MODULE(hdiffpatch, init) |
| 84 | + |
| 85 | +} // namespace hdiffpatch |
0 commit comments