forked from ably/xdelta-async-nodejs-addon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathXdelta3Addon.cc
135 lines (107 loc) · 4.2 KB
/
Xdelta3Addon.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <napi.h>
#include "./XdeltaEncodeAsyncWorker.h"
#include "./XdeltaDecodeAsyncWorker.h"
using namespace std;
using namespace Napi;
Object CreateErrorObject(Env env, int code, std::string message)
{
Object object = Object::New(env);
object.Set("code", code);
object.Set("message", message);
return object;
}
Value EncodeBuffer(const CallbackInfo& info) {
Env env = info.Env();
if (info.Length() != 5 || !info[4].IsFunction()) {
return env.Undefined();
}
Function callback = info[4].As<Function>();
if (!info[0].IsBuffer()) {
callback.Call({CreateErrorObject(env, 1, "Expected buffer as first argument.")});
return env.Undefined();
}
Buffer<uint8_t> dictionary = info[0].As<Buffer<uint8_t>>();
if (!info[1].IsBuffer()) {
callback.Call({CreateErrorObject(env, 1, "Expected buffer as second argument.")});
return env.Undefined();
}
Buffer<uint8_t> target = info[1].As<Buffer<uint8_t>>();
if (!info[2].IsBuffer()) {
callback.Call({CreateErrorObject(env, 1, "Expected buffer as third argument.")});
return env.Undefined();
}
Buffer<uint8_t> result = info[2].As<Buffer<uint8_t>>();
if (!info[3].IsNumber()) {
callback.Call({CreateErrorObject(env, 1, "Expected number as fourth argument.")});
return env.Undefined();
}
int32_t stringMatcherType = info[3].As<Number>().Int32Value();
if(stringMatcherType < XD3_SMATCH_DEFAULT ||
stringMatcherType > XD3_SMATCH_SOFT)
{
callback.Call({CreateErrorObject(env, 1, "Illegal fourth argument value. Only values defined in xd3SmatchConfig allowed.")});
return env.Undefined();
}
XdeltaEncodeAsyncWorker *encoder = NULL;
string error = XdeltaEncodeAsyncWorker::New(dictionary, target, result, stringMatcherType, callback, &encoder);
if (!error.empty()) {
callback.Call({CreateErrorObject(env, 2, error)});
return env.Undefined();
}
encoder->Queue();
return Number::New(env, encoder->id);
}
void DecodeBuffer(const CallbackInfo& info) {
Env env = info.Env();
if (!info[3].IsFunction()) {
return;
}
Function callback = info[3].As<Function>();
if (!info[0].IsBuffer()) {
callback.Call({CreateErrorObject(env, 1, "Expected buffer as first argument.")});
return;
}
Buffer<uint8_t> dictionary = info[0].As<Buffer<uint8_t>>();
if (!info[1].IsBuffer()) {
callback.Call({CreateErrorObject(env, 1, "Expected buffer as second argument.")});
return;
}
Buffer<uint8_t> delta = info[1].As<Buffer<uint8_t>>();
if (!info[2].IsBuffer()) {
callback.Call({CreateErrorObject(env, 1, "Expected buffer as third argument.")});
return;
}
Buffer<uint8_t> result = info[2].As<Buffer<uint8_t>>();
XdeltaDecodeAsyncWorker *decoder = new XdeltaDecodeAsyncWorker(dictionary, delta, result, callback);
decoder->Queue();
}
Value CancelEncode(const CallbackInfo& info) {
Env env = info.Env();
if (!info[0].IsNumber()) {
return CreateErrorObject(env, 1, "Expected number as first argument.");
}
int32_t encoderId = info[0].As<Number>().Int32Value();
string error = XdeltaEncodeAsyncWorker::RequestCancellation(encoderId);
if (!error.empty()) {
return CreateErrorObject(env, 2, error);
}
return env.Undefined();
}
Object Init(Env env, Object exports) {
Object xd3SmatchConfig = Object::New(env);
xd3SmatchConfig.Set("default", (int)XD3_SMATCH_DEFAULT);
xd3SmatchConfig.Set("slow", (int)XD3_SMATCH_SLOW);
xd3SmatchConfig.Set("fast", (int)XD3_SMATCH_FAST);
xd3SmatchConfig.Set("faster", (int)XD3_SMATCH_FASTER);
xd3SmatchConfig.Set("fastest", (int)XD3_SMATCH_FASTEST);
xd3SmatchConfig.Set("soft", (int)XD3_SMATCH_SOFT);
exports.Set("xd3SmatchConfig", xd3SmatchConfig);
exports.Set(String::New(env, "EncodeBuffer"),
Function::New(env, EncodeBuffer));
exports.Set(String::New(env, "DecodeBuffer"),
Function::New(env, DecodeBuffer));
exports.Set(String::New(env, "CancelEncode"),
Function::New(env, CancelEncode));
return exports;
}
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)