k2hash 1.1.34 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/k2h_shm.cc CHANGED
@@ -23,7 +23,6 @@
23
23
  #include "k2h_queue.h"
24
24
  #include "k2h_keyqueue.h"
25
25
 
26
- using namespace v8;
27
26
  using namespace std;
28
27
 
29
28
  //---------------------------------------------------------
@@ -80,38 +79,81 @@ const char* stc_k2h_emitters[] = {
80
79
  };
81
80
 
82
81
  //---------------------------------------------------------
83
- // Utility macros
82
+ // Utility (using StackEmitCB Class)
84
83
  //---------------------------------------------------------
85
- #define SetK2hEmitterCallback(info, pos, pemitter) \
86
- { \
87
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This()); \
88
- if(info.Length() <= pos){ \
89
- Nan::ThrowSyntaxError("No callback is specified."); \
90
- return; \
91
- } \
92
- Nan::Callback* cb = new Nan::Callback(); \
93
- cb->SetFunction(info[pos].As<v8::Function>()); \
94
- bool result = obj->_cbs.Set(pemitter, cb); \
95
- info.GetReturnValue().Set(Nan::New(result)); \
96
- }
97
-
98
- #define UnsetK2hEmitterCallback(info, pemitter) \
99
- { \
100
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This()); \
101
- bool result = obj->_cbs.Unset(pemitter); \
102
- info.GetReturnValue().Set(Nan::New(result)); \
103
- }
84
+ static Napi::Value SetK2hEmitterCallback(const Napi::CallbackInfo& info, size_t pos, const char* pemitter)
85
+ {
86
+ Napi::Env env = info.Env();
87
+
88
+ // Unwrap
89
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
90
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
91
+ return env.Undefined();
92
+ }
93
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
94
+
95
+ // check parameter
96
+ if(info.Length() <= pos){
97
+ Napi::TypeError::New(env, "No callback is specified.").ThrowAsJavaScriptException();
98
+ return env.Undefined();
99
+ }
100
+ if(!info[pos].IsFunction()){
101
+ Napi::TypeError::New(env, "The parameter is not callback function.").ThrowAsJavaScriptException();
102
+ return env.Undefined();
103
+ }
104
+ Napi::Function cb = info[pos].As<Napi::Function>();
105
+
106
+ // set
107
+ bool result = obj->_cbs.Set(std::string(pemitter), cb);
108
+ return Napi::Boolean::New(env, result);
109
+ }
110
+
111
+ static Napi::Value UnsetK2hEmitterCallback(const Napi::CallbackInfo& info, const char* pemitter)
112
+ {
113
+ Napi::Env env = info.Env();
114
+
115
+ // Unwrap
116
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
117
+ Napi::TypeError::New(env, "Invalid this object").ThrowAsJavaScriptException();
118
+ return env.Undefined();
119
+ }
120
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
121
+
122
+ // unset
123
+ bool result = obj->_cbs.Unset(std::string(pemitter));
124
+ return Napi::Boolean::New(env, result);
125
+ }
104
126
 
105
127
  //---------------------------------------------------------
106
128
  // K2hNode Class
107
129
  //---------------------------------------------------------
108
- Nan::Persistent<Function> K2hNode::constructor;
130
+ Napi::FunctionReference K2hNode::constructor;
109
131
 
110
132
  //---------------------------------------------------------
111
133
  // K2hNode Methods
112
134
  //---------------------------------------------------------
113
- K2hNode::K2hNode() : _k2hshm(), _cbs()
135
+ K2hNode::K2hNode(const Napi::CallbackInfo& info) : Napi::ObjectWrap<K2hNode>(info), _cbs(), _k2hshm()
114
136
  {
137
+ // [NOTE]
138
+ // Perhaps due to an initialization order issue, these
139
+ // k2hash debug environment variable settings don't work.
140
+ // So, load the environment variables and set the debug
141
+ // mode/file settings here.
142
+ //
143
+ const char* k2hdbgmode = std::getenv("K2HDBGMODE");
144
+ const char* k2hdbgfile = std::getenv("K2HDBGFILE");
145
+ if(k2hdbgmode && k2hdbgfile){
146
+ if(0 == strcasecmp(k2hdbgmode, "SLT") || 0 == strcasecmp(k2hdbgmode, "SILENT")){
147
+ k2h_set_debug_level_silent();
148
+ }else if(0 == strcasecmp(k2hdbgmode, "ERR") || 0 == strcasecmp(k2hdbgmode, "ERROR")){
149
+ k2h_set_debug_level_error();
150
+ }else if(0 == strcasecmp(k2hdbgmode, "WARNING") || 0 == strcasecmp(k2hdbgmode, "WARN") || 0 == strcasecmp(k2hdbgmode, "WAN")){
151
+ k2h_set_debug_level_warning();
152
+ }else if(0 == strcasecmp(k2hdbgmode, "INFO") || 0 == strcasecmp(k2hdbgmode, "INF") || 0 == strcasecmp(k2hdbgmode, "MSG")){
153
+ k2h_set_debug_level_message();
154
+ }
155
+ k2h_set_debug_file(k2hdbgfile); // Ignore any errors that occur.
156
+ }
115
157
  }
116
158
 
117
159
  K2hNode::~K2hNode()
@@ -119,140 +161,153 @@ K2hNode::~K2hNode()
119
161
  _k2hshm.Detach();
120
162
  }
121
163
 
122
- void K2hNode::Init(void)
123
- {
124
- // Prepare constructor template
125
- Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
126
- tpl->SetClassName(Nan::New("K2hNode").ToLocalChecked());
127
- tpl->InstanceTemplate()->SetInternalFieldCount(1);
128
-
129
- // Prototype for event emitter
130
- Nan::SetPrototypeMethod(tpl, "on", On);
131
- Nan::SetPrototypeMethod(tpl, "onCreate", OnCreate);
132
- Nan::SetPrototypeMethod(tpl, "onOpen", OnOpen);
133
- Nan::SetPrototypeMethod(tpl, "onOpenRW", OnOpenRW);
134
- Nan::SetPrototypeMethod(tpl, "onOpenRO", OnOpenRO);
135
- Nan::SetPrototypeMethod(tpl, "onOpenTempfile", OnOpenTempfile);
136
- Nan::SetPrototypeMethod(tpl, "onOpenMem", OnOpenMem);
137
- Nan::SetPrototypeMethod(tpl, "onClose", OnClose);
138
- Nan::SetPrototypeMethod(tpl, "onGet", OnGet);
139
- Nan::SetPrototypeMethod(tpl, "onGetSubkeys", OnGetSubkeys);
140
- Nan::SetPrototypeMethod(tpl, "onGetAttrs", OnGetAttrs);
141
- Nan::SetPrototypeMethod(tpl, "onGetAttrValue", OnGetAttrValue);
142
- Nan::SetPrototypeMethod(tpl, "onSet", OnSet);
143
- Nan::SetPrototypeMethod(tpl, "onAddSubkey", OnAddSubkey);
144
- Nan::SetPrototypeMethod(tpl, "onAddSubkeys", OnAddSubkeys);
145
- Nan::SetPrototypeMethod(tpl, "onAddAttr", OnAddAttr);
146
- Nan::SetPrototypeMethod(tpl, "onRemove", OnRemove);
147
- Nan::SetPrototypeMethod(tpl, "onRemoveAll", OnRemoveAll);
148
- Nan::SetPrototypeMethod(tpl, "onLoad", OnLoad);
149
- Nan::SetPrototypeMethod(tpl, "onLoadArchive", OnLoad);
150
- Nan::SetPrototypeMethod(tpl, "onPut", OnPut);
151
- Nan::SetPrototypeMethod(tpl, "onPutArchive", OnPut);
152
- Nan::SetPrototypeMethod(tpl, "off", Off);
153
- Nan::SetPrototypeMethod(tpl, "offCreate", OffCreate);
154
- Nan::SetPrototypeMethod(tpl, "offOpen", OffOpen);
155
- Nan::SetPrototypeMethod(tpl, "offOpenRW", OffOpenRW);
156
- Nan::SetPrototypeMethod(tpl, "offOpenRO", OffOpenRO);
157
- Nan::SetPrototypeMethod(tpl, "offOpenTempfile", OffOpenTempfile);
158
- Nan::SetPrototypeMethod(tpl, "offOpenMem", OffOpenMem);
159
- Nan::SetPrototypeMethod(tpl, "offClose", OffClose);
160
- Nan::SetPrototypeMethod(tpl, "offGet", OffGet);
161
- Nan::SetPrototypeMethod(tpl, "offGetSubkeys", OffGetSubkeys);
162
- Nan::SetPrototypeMethod(tpl, "offGetAttrs", OffGetAttrs);
163
- Nan::SetPrototypeMethod(tpl, "offGetAttrValue", OffGetAttrValue);
164
- Nan::SetPrototypeMethod(tpl, "offSet", OffSet);
165
- Nan::SetPrototypeMethod(tpl, "offAddSubkey", OffAddSubkey);
166
- Nan::SetPrototypeMethod(tpl, "offAddSubkeys", OffAddSubkeys);
167
- Nan::SetPrototypeMethod(tpl, "offAddAttr", OffAddAttr);
168
- Nan::SetPrototypeMethod(tpl, "offRemove", OffRemove);
169
- Nan::SetPrototypeMethod(tpl, "offRemoveAll", OffRemoveAll);
170
- Nan::SetPrototypeMethod(tpl, "offLoad", OffLoad);
171
- Nan::SetPrototypeMethod(tpl, "offLoadArchive", OffLoad);
172
- Nan::SetPrototypeMethod(tpl, "offPut", OffPut);
173
- Nan::SetPrototypeMethod(tpl, "offPutArchive", OffPut);
174
-
175
- // Prototype
176
- Nan::SetPrototypeMethod(tpl, "create", Create);
177
- Nan::SetPrototypeMethod(tpl, "open", Open);
178
- Nan::SetPrototypeMethod(tpl, "openRW", OpenRW);
179
- Nan::SetPrototypeMethod(tpl, "openRO", OpenRO);
180
- Nan::SetPrototypeMethod(tpl, "openTempfile", OpenTempfile);
181
- Nan::SetPrototypeMethod(tpl, "openMem", OpenMem);
182
- Nan::SetPrototypeMethod(tpl, "close", Close);
183
-
184
- Nan::SetPrototypeMethod(tpl, "getValue", GetValue);
185
- Nan::SetPrototypeMethod(tpl, "getSubkeys", GetSubkeys);
186
-
187
- Nan::SetPrototypeMethod(tpl, "setValue", SetValue);
188
- Nan::SetPrototypeMethod(tpl, "addSubkey", AddSubkey);
189
- Nan::SetPrototypeMethod(tpl, "addSubkeys", AddSubkeys);
190
-
191
- Nan::SetPrototypeMethod(tpl, "remove", Remove);
192
- Nan::SetPrototypeMethod(tpl, "removeAll", RemoveAll);
193
-
194
- Nan::SetPrototypeMethod(tpl, "printState", PrintState);
195
- Nan::SetPrototypeMethod(tpl, "printVersion", PrintVersion);
196
-
197
- Nan::SetPrototypeMethod(tpl, "dumpHead", DumpHead);
198
- Nan::SetPrototypeMethod(tpl, "dumpKeytable", DumpKeytable);
199
- Nan::SetPrototypeMethod(tpl, "dumpFullKeytable", DumpFullKeytable);
200
- Nan::SetPrototypeMethod(tpl, "dumpElementtable", DumpElementtable);
201
- Nan::SetPrototypeMethod(tpl, "dumpFull", DumpFull);
202
-
203
- Nan::SetPrototypeMethod(tpl, "transaction", Transaction);
204
- Nan::SetPrototypeMethod(tpl, "enableTransaction", EnableTransaction);
205
- Nan::SetPrototypeMethod(tpl, "disableTransaction", DisableTransaction);
206
-
207
- Nan::SetPrototypeMethod(tpl, "getTransactionThreadPool", GetTransactionThreadPool);
208
- Nan::SetPrototypeMethod(tpl, "setTransactionThreadPool", SetTransactionThreadPool);
209
- Nan::SetPrototypeMethod(tpl, "unsetTransactionThreadPool", UnsetTransactionThreadPool);
210
-
211
- Nan::SetPrototypeMethod(tpl, "putArchive", PutArchive);
212
- Nan::SetPrototypeMethod(tpl, "loadArchive", LoadArchive);
213
-
214
- Nan::SetPrototypeMethod(tpl, "getQueue", getQueue);
215
- Nan::SetPrototypeMethod(tpl, "getKeyQueue", getKeyQueue);
216
-
217
- Nan::SetPrototypeMethod(tpl, "setCommonAttribute", SetCommonAttribute);
218
- Nan::SetPrototypeMethod(tpl, "cleanCommonAttribute", CleanCommonAttribute);
219
-
220
- Nan::SetPrototypeMethod(tpl, "addAttrPluginLib", AddAttrPluginLib);
221
- Nan::SetPrototypeMethod(tpl, "addAttrCryptPass", AddAttrCryptPass);
222
-
223
- Nan::SetPrototypeMethod(tpl, "getAttrVersionInfos", GetAttrVersionInfos);
224
- Nan::SetPrototypeMethod(tpl, "getAttrInfos", GetAttrInfos);
225
- Nan::SetPrototypeMethod(tpl, "getAttrs", GetAttrs);
226
- Nan::SetPrototypeMethod(tpl, "getAttrValue", GetAttrValue);
227
-
228
- Nan::SetPrototypeMethod(tpl, "addAttr", AddAttr);
229
-
230
- // Reset
231
- constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
232
- }
233
-
234
- NAN_METHOD(K2hNode::New)
235
- {
236
- if(info.IsConstructCall()){
164
+ void K2hNode::Init(Napi::Env env, Napi::Object exports)
165
+ {
166
+ Napi::Function funcs = DefineClass(env, "K2hNode", {
167
+ // DefineClass normally handles the constructor internally. Therefore, there is no need
168
+ // to include a static wrapper New() in the class prototype, which works the same way as
169
+ // when using NAN.
170
+ // For reference, the following example shows how to declare New as a static method.
171
+ // (Registration is not normally required.)
172
+ //
173
+ // K2hNode::InstanceMethod("new", &K2hNode::New),
174
+
175
+ // Prototype for event emitter
176
+ K2hNode::InstanceMethod("on", &K2hNode::On),
177
+ K2hNode::InstanceMethod("onCreate", &K2hNode::OnCreate),
178
+ K2hNode::InstanceMethod("onOpen", &K2hNode::OnOpen),
179
+ K2hNode::InstanceMethod("onOpenRW", &K2hNode::OnOpenRW),
180
+ K2hNode::InstanceMethod("onOpenRO", &K2hNode::OnOpenRO),
181
+ K2hNode::InstanceMethod("onOpenTempfile", &K2hNode::OnOpenTempfile),
182
+ K2hNode::InstanceMethod("onOpenMem", &K2hNode::OnOpenMem),
183
+ K2hNode::InstanceMethod("onClose", &K2hNode::OnClose),
184
+ K2hNode::InstanceMethod("onGet", &K2hNode::OnGet),
185
+ K2hNode::InstanceMethod("onGetSubkeys", &K2hNode::OnGetSubkeys),
186
+ K2hNode::InstanceMethod("onGetAttrs", &K2hNode::OnGetAttrs),
187
+ K2hNode::InstanceMethod("onGetAttrValue", &K2hNode::OnGetAttrValue),
188
+ K2hNode::InstanceMethod("onSet", &K2hNode::OnSet),
189
+ K2hNode::InstanceMethod("onAddSubkey", &K2hNode::OnAddSubkey),
190
+ K2hNode::InstanceMethod("onAddSubkeys", &K2hNode::OnAddSubkeys),
191
+ K2hNode::InstanceMethod("onAddAttr", &K2hNode::OnAddAttr),
192
+ K2hNode::InstanceMethod("onRemove", &K2hNode::OnRemove),
193
+ K2hNode::InstanceMethod("onRemoveAll", &K2hNode::OnRemoveAll),
194
+ K2hNode::InstanceMethod("onLoad", &K2hNode::OnLoad),
195
+ K2hNode::InstanceMethod("onLoadArchive", &K2hNode::OnLoad),
196
+ K2hNode::InstanceMethod("onPut", &K2hNode::OnPut),
197
+ K2hNode::InstanceMethod("onPutArchive", &K2hNode::OnPut),
198
+ K2hNode::InstanceMethod("off", &K2hNode::Off),
199
+ K2hNode::InstanceMethod("offCreate", &K2hNode::OffCreate),
200
+ K2hNode::InstanceMethod("offOpen", &K2hNode::OffOpen),
201
+ K2hNode::InstanceMethod("offOpenRW", &K2hNode::OffOpenRW),
202
+ K2hNode::InstanceMethod("offOpenRO", &K2hNode::OffOpenRO),
203
+ K2hNode::InstanceMethod("offOpenTempfile", &K2hNode::OffOpenTempfile),
204
+ K2hNode::InstanceMethod("offOpenMem", &K2hNode::OffOpenMem),
205
+ K2hNode::InstanceMethod("offClose", &K2hNode::OffClose),
206
+ K2hNode::InstanceMethod("offGet", &K2hNode::OffGet),
207
+ K2hNode::InstanceMethod("offGetSubkeys", &K2hNode::OffGetSubkeys),
208
+ K2hNode::InstanceMethod("offGetAttrs", &K2hNode::OffGetAttrs),
209
+ K2hNode::InstanceMethod("offGetAttrValue", &K2hNode::OffGetAttrValue),
210
+ K2hNode::InstanceMethod("offSet", &K2hNode::OffSet),
211
+ K2hNode::InstanceMethod("offAddSubkey", &K2hNode::OffAddSubkey),
212
+ K2hNode::InstanceMethod("offAddSubkeys", &K2hNode::OffAddSubkeys),
213
+ K2hNode::InstanceMethod("offAddAttr", &K2hNode::OffAddAttr),
214
+ K2hNode::InstanceMethod("offRemove", &K2hNode::OffRemove),
215
+ K2hNode::InstanceMethod("offRemoveAll", &K2hNode::OffRemoveAll),
216
+ K2hNode::InstanceMethod("offLoad", &K2hNode::OffLoad),
217
+ K2hNode::InstanceMethod("offLoadArchive", &K2hNode::OffLoad),
218
+ K2hNode::InstanceMethod("offPut", &K2hNode::OffPut),
219
+ K2hNode::InstanceMethod("offPutArchive", &K2hNode::OffPut),
220
+
221
+ // Prototype
222
+ K2hNode::InstanceMethod("create", &K2hNode::Create),
223
+ K2hNode::InstanceMethod("open", &K2hNode::Open),
224
+ K2hNode::InstanceMethod("openRW", &K2hNode::OpenRW),
225
+ K2hNode::InstanceMethod("openRO", &K2hNode::OpenRO),
226
+ K2hNode::InstanceMethod("openTempfile", &K2hNode::OpenTempfile),
227
+ K2hNode::InstanceMethod("openMem", &K2hNode::OpenMem),
228
+ K2hNode::InstanceMethod("close", &K2hNode::Close),
229
+
230
+ K2hNode::InstanceMethod("getValue", &K2hNode::GetValue),
231
+ K2hNode::InstanceMethod("getSubkeys", &K2hNode::GetSubkeys),
232
+
233
+ K2hNode::InstanceMethod("setValue", &K2hNode::SetValue),
234
+ K2hNode::InstanceMethod("addSubkey", &K2hNode::AddSubkey),
235
+ K2hNode::InstanceMethod("addSubkeys", &K2hNode::AddSubkeys),
236
+
237
+ K2hNode::InstanceMethod("remove", &K2hNode::Remove),
238
+ K2hNode::InstanceMethod("removeAll", &K2hNode::RemoveAll),
239
+
240
+ K2hNode::InstanceMethod("printState", &K2hNode::PrintState),
241
+ K2hNode::InstanceMethod("printVersion", &K2hNode::PrintVersion),
242
+
243
+ K2hNode::InstanceMethod("dumpHead", &K2hNode::DumpHead),
244
+ K2hNode::InstanceMethod("dumpKeytable", &K2hNode::DumpKeytable),
245
+ K2hNode::InstanceMethod("dumpFullKeytable", &K2hNode::DumpFullKeytable),
246
+ K2hNode::InstanceMethod("dumpElementtable", &K2hNode::DumpElementtable),
247
+ K2hNode::InstanceMethod("dumpFull", &K2hNode::DumpFull),
248
+
249
+ K2hNode::InstanceMethod("transaction", &K2hNode::Transaction),
250
+ K2hNode::InstanceMethod("enableTransaction", &K2hNode::EnableTransaction),
251
+ K2hNode::InstanceMethod("disableTransaction", &K2hNode::DisableTransaction),
252
+
253
+ K2hNode::InstanceMethod("getTransactionThreadPool", &K2hNode::GetTransactionThreadPool),
254
+ K2hNode::InstanceMethod("setTransactionThreadPool", &K2hNode::SetTransactionThreadPool),
255
+ K2hNode::InstanceMethod("unsetTransactionThreadPool", &K2hNode::UnsetTransactionThreadPool),
256
+
257
+ K2hNode::InstanceMethod("putArchive", &K2hNode::PutArchive),
258
+ K2hNode::InstanceMethod("loadArchive", &K2hNode::LoadArchive),
259
+
260
+ K2hNode::InstanceMethod("getQueue", &K2hNode::getQueue),
261
+ K2hNode::InstanceMethod("getKeyQueue", &K2hNode::getKeyQueue),
262
+
263
+ K2hNode::InstanceMethod("setCommonAttribute", &K2hNode::SetCommonAttribute),
264
+ K2hNode::InstanceMethod("cleanCommonAttribute", &K2hNode::CleanCommonAttribute),
265
+
266
+ K2hNode::InstanceMethod("addAttrPluginLib", &K2hNode::AddAttrPluginLib),
267
+ K2hNode::InstanceMethod("addAttrCryptPass", &K2hNode::AddAttrCryptPass),
268
+
269
+ K2hNode::InstanceMethod("getAttrVersionInfos", &K2hNode::GetAttrVersionInfos),
270
+ K2hNode::InstanceMethod("getAttrInfos", &K2hNode::GetAttrInfos),
271
+ K2hNode::InstanceMethod("getAttrs", &K2hNode::GetAttrs),
272
+ K2hNode::InstanceMethod("getAttrValue", &K2hNode::GetAttrValue),
273
+
274
+ K2hNode::InstanceMethod("addAttr", &K2hNode::AddAttr)
275
+ });
276
+
277
+ constructor = Napi::Persistent(funcs);
278
+ constructor.SuppressDestruct();
279
+
280
+ // Initialize K2hQueue and K2hKeyQueue classes
281
+ K2hQueue::Init(env, exports);
282
+ K2hKeyQueue::Init(env, exports);
283
+
284
+ // [NOTE]
285
+ // do NOT do exports.Set("K2hNode", func) here if InitAll will return createFn.
286
+ //
287
+ }
288
+
289
+ Napi::Value K2hNode::New(const Napi::CallbackInfo& info)
290
+ {
291
+ if(info.IsConstructCall()){
237
292
  // Invoked as constructor: new K2hNode()
238
- K2hNode* obj = new K2hNode();
239
- obj->Wrap(info.This());
240
- info.GetReturnValue().Set(info.This());
241
- }else{
242
- // Invoked as plain function K2hNode(), turn into construct call.
243
- const int argc = 1;
244
- Local<Value> argv[argc] = {info[0]};
245
- Local<Function> cons = Nan::New<Function>(constructor);
246
- info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
293
+ return info.This();
294
+ }else{
295
+ // Invoked as plain function K2hNode(), turn into construct call.
296
+ return constructor.New({}); // always no arguments
247
297
  }
248
298
  }
249
299
 
250
- NAN_METHOD(K2hNode::NewInstance)
300
+ // [NOTE]
301
+ // The logic for receiving arguments when switching to N-API has been removed.
302
+ // This is because the arguments were not used in the first place and did not
303
+ // need to be defined.
304
+ //
305
+ // NewInstance( always no argments )
306
+ Napi::Object K2hNode::NewInstance(Napi::Env env)
251
307
  {
252
- const unsigned argc = 1;
253
- Local<Value> argv[argc] = {info[0]};
254
- Local<Function> cons = Nan::New<Function>(constructor);
255
- info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
308
+ Napi::EscapableHandleScope scope(env);
309
+ Napi::Object obj = constructor.New({}).As<Napi::Object>();
310
+ return scope.Escape(napi_value(obj)).ToObject();
256
311
  }
257
312
 
258
313
  /**
@@ -277,28 +332,32 @@ NAN_METHOD(K2hNode::NewInstance)
277
332
  * @return return true for success, false for failure
278
333
  */
279
334
 
280
- NAN_METHOD(K2hNode::On)
335
+ Napi::Value K2hNode::On(const Napi::CallbackInfo& info)
281
336
  {
337
+ Napi::Env env = info.Env();
338
+
339
+ // check
282
340
  if(info.Length() < 1){
283
- Nan::ThrowSyntaxError("No handle emitter name is specified.");
284
- return;
341
+ Napi::TypeError::New(env, "No handle emitter name is specified.").ThrowAsJavaScriptException();
342
+ return env.Undefined();
285
343
  }else if(info.Length() < 2){
286
- Nan::ThrowSyntaxError("No callback is specified.");
287
- return;
344
+ Napi::TypeError::New(env, "No callback is specified.").ThrowAsJavaScriptException();
345
+ return env.Undefined();
288
346
  }
289
347
 
290
348
  // check emitter name
291
- Nan::Utf8String emitter(info[0]);
292
- const char* pemitter;
293
- if(NULL == (pemitter = GetNormalizationEmitter(*emitter, stc_k2h_emitters))){
294
- string msg = "Unknown ";
295
- msg += *emitter;
296
- msg += " emitter";
297
- Nan::ThrowSyntaxError(msg.c_str());
298
- return;
349
+ std::string emitter = info[0].ToString().Utf8Value();
350
+ const char* pemitter = GetNormalizationEmitter(emitter.c_str(), stc_k2h_emitters);
351
+ if(!pemitter){
352
+ std::string msg = "Unknown ";
353
+ msg += emitter;
354
+ msg += " emitter";
355
+ Napi::TypeError::New(env, msg).ThrowAsJavaScriptException();
356
+ return env.Undefined();
299
357
  }
358
+
300
359
  // add callback
301
- SetK2hEmitterCallback(info, 1, pemitter);
360
+ return SetK2hEmitterCallback(info, 1, pemitter);
302
361
  }
303
362
 
304
363
  /**
@@ -314,9 +373,9 @@ NAN_METHOD(K2hNode::On)
314
373
  * @return return true for success, false for failure
315
374
  */
316
375
 
317
- NAN_METHOD(K2hNode::OnCreate)
376
+ Napi::Value K2hNode::OnCreate(const Napi::CallbackInfo& info)
318
377
  {
319
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_CREATE]);
378
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_CREATE]);
320
379
  }
321
380
 
322
381
  /**
@@ -332,9 +391,9 @@ NAN_METHOD(K2hNode::OnCreate)
332
391
  * @return return true for success, false for failure
333
392
  */
334
393
 
335
- NAN_METHOD(K2hNode::OnOpen)
394
+ Napi::Value K2hNode::OnOpen(const Napi::CallbackInfo& info)
336
395
  {
337
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPEN]);
396
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPEN]);
338
397
  }
339
398
 
340
399
  /**
@@ -350,9 +409,9 @@ NAN_METHOD(K2hNode::OnOpen)
350
409
  * @return return true for success, false for failure
351
410
  */
352
411
 
353
- NAN_METHOD(K2hNode::OnOpenRW)
412
+ Napi::Value K2hNode::OnOpenRW(const Napi::CallbackInfo& info)
354
413
  {
355
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPENRW]);
414
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPENRW]);
356
415
  }
357
416
 
358
417
  /**
@@ -368,9 +427,9 @@ NAN_METHOD(K2hNode::OnOpenRW)
368
427
  * @return return true for success, false for failure
369
428
  */
370
429
 
371
- NAN_METHOD(K2hNode::OnOpenRO)
430
+ Napi::Value K2hNode::OnOpenRO(const Napi::CallbackInfo& info)
372
431
  {
373
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPENRO]);
432
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPENRO]);
374
433
  }
375
434
 
376
435
  /**
@@ -386,9 +445,9 @@ NAN_METHOD(K2hNode::OnOpenRO)
386
445
  * @return return true for success, false for failure
387
446
  */
388
447
 
389
- NAN_METHOD(K2hNode::OnOpenTempfile)
448
+ Napi::Value K2hNode::OnOpenTempfile(const Napi::CallbackInfo& info)
390
449
  {
391
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPENTEMP]);
450
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPENTEMP]);
392
451
  }
393
452
 
394
453
  /**
@@ -404,9 +463,9 @@ NAN_METHOD(K2hNode::OnOpenTempfile)
404
463
  * @return return true for success, false for failure
405
464
  */
406
465
 
407
- NAN_METHOD(K2hNode::OnOpenMem)
466
+ Napi::Value K2hNode::OnOpenMem(const Napi::CallbackInfo& info)
408
467
  {
409
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPENMEM]);
468
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_OPENMEM]);
410
469
  }
411
470
 
412
471
  /**
@@ -422,9 +481,9 @@ NAN_METHOD(K2hNode::OnOpenMem)
422
481
  * @return return true for success, false for failure
423
482
  */
424
483
 
425
- NAN_METHOD(K2hNode::OnClose)
484
+ Napi::Value K2hNode::OnClose(const Napi::CallbackInfo& info)
426
485
  {
427
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_CLOSE]);
486
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_CLOSE]);
428
487
  }
429
488
 
430
489
  /**
@@ -440,9 +499,9 @@ NAN_METHOD(K2hNode::OnClose)
440
499
  * @return return true for success, false for failure
441
500
  */
442
501
 
443
- NAN_METHOD(K2hNode::OnGet)
502
+ Napi::Value K2hNode::OnGet(const Napi::CallbackInfo& info)
444
503
  {
445
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_GET]);
504
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_GET]);
446
505
  }
447
506
 
448
507
  /**
@@ -458,9 +517,9 @@ NAN_METHOD(K2hNode::OnGet)
458
517
  * @return return true for success, false for failure
459
518
  */
460
519
 
461
- NAN_METHOD(K2hNode::OnGetSubkeys)
520
+ Napi::Value K2hNode::OnGetSubkeys(const Napi::CallbackInfo& info)
462
521
  {
463
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_GETSUBKEYS]);
522
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_GETSUBKEYS]);
464
523
  }
465
524
 
466
525
  /**
@@ -476,9 +535,9 @@ NAN_METHOD(K2hNode::OnGetSubkeys)
476
535
  * @return return true for success, false for failure
477
536
  */
478
537
 
479
- NAN_METHOD(K2hNode::OnGetAttrs)
538
+ Napi::Value K2hNode::OnGetAttrs(const Napi::CallbackInfo& info)
480
539
  {
481
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_GETATTRS]);
540
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_GETATTRS]);
482
541
  }
483
542
 
484
543
  /**
@@ -494,9 +553,9 @@ NAN_METHOD(K2hNode::OnGetAttrs)
494
553
  * @return return true for success, false for failure
495
554
  */
496
555
 
497
- NAN_METHOD(K2hNode::OnGetAttrValue)
556
+ Napi::Value K2hNode::OnGetAttrValue(const Napi::CallbackInfo& info)
498
557
  {
499
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_GETATTRVAL]);
558
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_GETATTRVAL]);
500
559
  }
501
560
 
502
561
  /**
@@ -512,9 +571,9 @@ NAN_METHOD(K2hNode::OnGetAttrValue)
512
571
  * @return return true for success, false for failure
513
572
  */
514
573
 
515
- NAN_METHOD(K2hNode::OnSet)
574
+ Napi::Value K2hNode::OnSet(const Napi::CallbackInfo& info)
516
575
  {
517
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_SET]);
576
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_SET]);
518
577
  }
519
578
 
520
579
  /**
@@ -530,9 +589,9 @@ NAN_METHOD(K2hNode::OnSet)
530
589
  * @return return true for success, false for failure
531
590
  */
532
591
 
533
- NAN_METHOD(K2hNode::OnAddSubkey)
592
+ Napi::Value K2hNode::OnAddSubkey(const Napi::CallbackInfo& info)
534
593
  {
535
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEY]);
594
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEY]);
536
595
  }
537
596
 
538
597
  /**
@@ -548,9 +607,9 @@ NAN_METHOD(K2hNode::OnAddSubkey)
548
607
  * @return return true for success, false for failure
549
608
  */
550
609
 
551
- NAN_METHOD(K2hNode::OnAddSubkeys)
610
+ Napi::Value K2hNode::OnAddSubkeys(const Napi::CallbackInfo& info)
552
611
  {
553
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEYS]);
612
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEYS]);
554
613
  }
555
614
 
556
615
  /**
@@ -566,9 +625,9 @@ NAN_METHOD(K2hNode::OnAddSubkeys)
566
625
  * @return return true for success, false for failure
567
626
  */
568
627
 
569
- NAN_METHOD(K2hNode::OnAddAttr)
628
+ Napi::Value K2hNode::OnAddAttr(const Napi::CallbackInfo& info)
570
629
  {
571
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_ADDATTR]);
630
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_ADDATTR]);
572
631
  }
573
632
 
574
633
  /**
@@ -584,9 +643,9 @@ NAN_METHOD(K2hNode::OnAddAttr)
584
643
  * @return return true for success, false for failure
585
644
  */
586
645
 
587
- NAN_METHOD(K2hNode::OnRemove)
646
+ Napi::Value K2hNode::OnRemove(const Napi::CallbackInfo& info)
588
647
  {
589
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_REMOVE]);
648
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_REMOVE]);
590
649
  }
591
650
 
592
651
  /**
@@ -602,9 +661,9 @@ NAN_METHOD(K2hNode::OnRemove)
602
661
  * @return return true for success, false for failure
603
662
  */
604
663
 
605
- NAN_METHOD(K2hNode::OnRemoveAll)
664
+ Napi::Value K2hNode::OnRemoveAll(const Napi::CallbackInfo& info)
606
665
  {
607
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_REMOVEALL]);
666
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_REMOVEALL]);
608
667
  }
609
668
 
610
669
  /**
@@ -620,9 +679,9 @@ NAN_METHOD(K2hNode::OnRemoveAll)
620
679
  * @return return true for success, false for failure
621
680
  */
622
681
 
623
- NAN_METHOD(K2hNode::OnLoad)
682
+ Napi::Value K2hNode::OnLoad(const Napi::CallbackInfo& info)
624
683
  {
625
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_LOAD]);
684
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_LOAD]);
626
685
  }
627
686
 
628
687
  /**
@@ -638,9 +697,9 @@ NAN_METHOD(K2hNode::OnLoad)
638
697
  * @return return true for success, false for failure
639
698
  */
640
699
 
641
- NAN_METHOD(K2hNode::OnPut)
700
+ Napi::Value K2hNode::OnPut(const Napi::CallbackInfo& info)
642
701
  {
643
- SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_PUT]);
702
+ return SetK2hEmitterCallback(info, 0, stc_k2h_emitters[K2H_EMITTER_POS_PUT]);
644
703
  }
645
704
 
646
705
  /**
@@ -656,25 +715,27 @@ NAN_METHOD(K2hNode::OnPut)
656
715
  * @return return true for success, false for failure
657
716
  */
658
717
 
659
- NAN_METHOD(K2hNode::Off)
718
+ Napi::Value K2hNode::Off(const Napi::CallbackInfo& info)
660
719
  {
720
+ Napi::Env env = info.Env();
721
+
661
722
  if(info.Length() < 1){
662
- Nan::ThrowSyntaxError("No handle emitter name is specified.");
663
- return;
723
+ Napi::TypeError::New(env, "No handle emitter name is specified.").ThrowAsJavaScriptException();
724
+ return env.Undefined();
664
725
  }
665
726
 
666
727
  // check emitter name
667
- Nan::Utf8String emitter(info[0]);
668
- const char* pemitter;
669
- if(NULL == (pemitter = GetNormalizationEmitter(*emitter, stc_k2h_emitters))){
670
- string msg = "Unknown ";
671
- msg += *emitter;
672
- msg += " emitter";
673
- Nan::ThrowSyntaxError(msg.c_str());
674
- return;
728
+ std::string emitter = info[0].ToString().Utf8Value();
729
+ const char* pemitter = GetNormalizationEmitter(emitter.c_str(), stc_k2h_emitters);
730
+ if (nullptr == pemitter) {
731
+ std::string msg = "Unknown ";
732
+ msg += emitter;
733
+ msg += " emitter";
734
+ Napi::TypeError::New(env, msg).ThrowAsJavaScriptException();
735
+ return env.Undefined();
675
736
  }
676
737
  // unset callback
677
- UnsetK2hEmitterCallback(info, pemitter);
738
+ return UnsetK2hEmitterCallback(info, pemitter);
678
739
  }
679
740
 
680
741
  /**
@@ -687,9 +748,9 @@ NAN_METHOD(K2hNode::Off)
687
748
  * @return return true for success, false for failure
688
749
  */
689
750
 
690
- NAN_METHOD(K2hNode::OffCreate)
751
+ Napi::Value K2hNode::OffCreate(const Napi::CallbackInfo& info)
691
752
  {
692
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_CREATE]);
753
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_CREATE]);
693
754
  }
694
755
 
695
756
  /**
@@ -702,9 +763,9 @@ NAN_METHOD(K2hNode::OffCreate)
702
763
  * @return return true for success, false for failure
703
764
  */
704
765
 
705
- NAN_METHOD(K2hNode::OffOpen)
766
+ Napi::Value K2hNode::OffOpen(const Napi::CallbackInfo& info)
706
767
  {
707
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPEN]);
768
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPEN]);
708
769
  }
709
770
 
710
771
  /**
@@ -717,9 +778,9 @@ NAN_METHOD(K2hNode::OffOpen)
717
778
  * @return return true for success, false for failure
718
779
  */
719
780
 
720
- NAN_METHOD(K2hNode::OffOpenRW)
781
+ Napi::Value K2hNode::OffOpenRW(const Napi::CallbackInfo& info)
721
782
  {
722
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPENRW]);
783
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPENRW]);
723
784
  }
724
785
 
725
786
  /**
@@ -732,9 +793,9 @@ NAN_METHOD(K2hNode::OffOpenRW)
732
793
  * @return return true for success, false for failure
733
794
  */
734
795
 
735
- NAN_METHOD(K2hNode::OffOpenRO)
796
+ Napi::Value K2hNode::OffOpenRO(const Napi::CallbackInfo& info)
736
797
  {
737
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPENRO]);
798
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPENRO]);
738
799
  }
739
800
 
740
801
  /**
@@ -747,9 +808,9 @@ NAN_METHOD(K2hNode::OffOpenRO)
747
808
  * @return return true for success, false for failure
748
809
  */
749
810
 
750
- NAN_METHOD(K2hNode::OffOpenTempfile)
811
+ Napi::Value K2hNode::OffOpenTempfile(const Napi::CallbackInfo& info)
751
812
  {
752
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPENTEMP]);
813
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPENTEMP]);
753
814
  }
754
815
 
755
816
  /**
@@ -762,9 +823,9 @@ NAN_METHOD(K2hNode::OffOpenTempfile)
762
823
  * @return return true for success, false for failure
763
824
  */
764
825
 
765
- NAN_METHOD(K2hNode::OffOpenMem)
826
+ Napi::Value K2hNode::OffOpenMem(const Napi::CallbackInfo& info)
766
827
  {
767
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPENMEM]);
828
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_OPENMEM]);
768
829
  }
769
830
 
770
831
  /**
@@ -777,9 +838,9 @@ NAN_METHOD(K2hNode::OffOpenMem)
777
838
  * @return return true for success, false for failure
778
839
  */
779
840
 
780
- NAN_METHOD(K2hNode::OffClose)
841
+ Napi::Value K2hNode::OffClose(const Napi::CallbackInfo& info)
781
842
  {
782
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_CLOSE]);
843
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_CLOSE]);
783
844
  }
784
845
 
785
846
  /**
@@ -792,9 +853,9 @@ NAN_METHOD(K2hNode::OffClose)
792
853
  * @return return true for success, false for failure
793
854
  */
794
855
 
795
- NAN_METHOD(K2hNode::OffGet)
856
+ Napi::Value K2hNode::OffGet(const Napi::CallbackInfo& info)
796
857
  {
797
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_GET]);
858
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_GET]);
798
859
  }
799
860
 
800
861
  /**
@@ -807,9 +868,9 @@ NAN_METHOD(K2hNode::OffGet)
807
868
  * @return return true for success, false for failure
808
869
  */
809
870
 
810
- NAN_METHOD(K2hNode::OffGetSubkeys)
871
+ Napi::Value K2hNode::OffGetSubkeys(const Napi::CallbackInfo& info)
811
872
  {
812
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_GETSUBKEYS]);
873
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_GETSUBKEYS]);
813
874
  }
814
875
 
815
876
  /**
@@ -822,9 +883,9 @@ NAN_METHOD(K2hNode::OffGetSubkeys)
822
883
  * @return return true for success, false for failure
823
884
  */
824
885
 
825
- NAN_METHOD(K2hNode::OffGetAttrs)
886
+ Napi::Value K2hNode::OffGetAttrs(const Napi::CallbackInfo& info)
826
887
  {
827
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_GETATTRS]);
888
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_GETATTRS]);
828
889
  }
829
890
 
830
891
  /**
@@ -837,9 +898,9 @@ NAN_METHOD(K2hNode::OffGetAttrs)
837
898
  * @return return true for success, false for failure
838
899
  */
839
900
 
840
- NAN_METHOD(K2hNode::OffGetAttrValue)
901
+ Napi::Value K2hNode::OffGetAttrValue(const Napi::CallbackInfo& info)
841
902
  {
842
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_GETATTRVAL]);
903
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_GETATTRVAL]);
843
904
  }
844
905
 
845
906
  /**
@@ -852,9 +913,9 @@ NAN_METHOD(K2hNode::OffGetAttrValue)
852
913
  * @return return true for success, false for failure
853
914
  */
854
915
 
855
- NAN_METHOD(K2hNode::OffSet)
916
+ Napi::Value K2hNode::OffSet(const Napi::CallbackInfo& info)
856
917
  {
857
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_SET]);
918
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_SET]);
858
919
  }
859
920
 
860
921
  /**
@@ -867,9 +928,9 @@ NAN_METHOD(K2hNode::OffSet)
867
928
  * @return return true for success, false for failure
868
929
  */
869
930
 
870
- NAN_METHOD(K2hNode::OffAddSubkey)
931
+ Napi::Value K2hNode::OffAddSubkey(const Napi::CallbackInfo& info)
871
932
  {
872
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEY]);
933
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEY]);
873
934
  }
874
935
 
875
936
  /**
@@ -882,9 +943,9 @@ NAN_METHOD(K2hNode::OffAddSubkey)
882
943
  * @return return true for success, false for failure
883
944
  */
884
945
 
885
- NAN_METHOD(K2hNode::OffAddSubkeys)
946
+ Napi::Value K2hNode::OffAddSubkeys(const Napi::CallbackInfo& info)
886
947
  {
887
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEYS]);
948
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEYS]);
888
949
  }
889
950
 
890
951
  /**
@@ -897,9 +958,9 @@ NAN_METHOD(K2hNode::OffAddSubkeys)
897
958
  * @return return true for success, false for failure
898
959
  */
899
960
 
900
- NAN_METHOD(K2hNode::OffAddAttr)
961
+ Napi::Value K2hNode::OffAddAttr(const Napi::CallbackInfo& info)
901
962
  {
902
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_ADDATTR]);
963
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_ADDATTR]);
903
964
  }
904
965
 
905
966
  /**
@@ -912,9 +973,9 @@ NAN_METHOD(K2hNode::OffAddAttr)
912
973
  * @return return true for success, false for failure
913
974
  */
914
975
 
915
- NAN_METHOD(K2hNode::OffRemove)
976
+ Napi::Value K2hNode::OffRemove(const Napi::CallbackInfo& info)
916
977
  {
917
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_REMOVE]);
978
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_REMOVE]);
918
979
  }
919
980
 
920
981
  /**
@@ -927,9 +988,9 @@ NAN_METHOD(K2hNode::OffRemove)
927
988
  * @return return true for success, false for failure
928
989
  */
929
990
 
930
- NAN_METHOD(K2hNode::OffRemoveAll)
991
+ Napi::Value K2hNode::OffRemoveAll(const Napi::CallbackInfo& info)
931
992
  {
932
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_REMOVEALL]);
993
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_REMOVEALL]);
933
994
  }
934
995
 
935
996
  /**
@@ -942,9 +1003,9 @@ NAN_METHOD(K2hNode::OffRemoveAll)
942
1003
  * @return return true for success, false for failure
943
1004
  */
944
1005
 
945
- NAN_METHOD(K2hNode::OffLoad)
1006
+ Napi::Value K2hNode::OffLoad(const Napi::CallbackInfo& info)
946
1007
  {
947
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_LOAD]);
1008
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_LOAD]);
948
1009
  }
949
1010
 
950
1011
  /**
@@ -957,9 +1018,9 @@ NAN_METHOD(K2hNode::OffLoad)
957
1018
  * @return return true for success, false for failure
958
1019
  */
959
1020
 
960
- NAN_METHOD(K2hNode::OffPut)
1021
+ Napi::Value K2hNode::OffPut(const Napi::CallbackInfo& info)
961
1022
  {
962
- UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_PUT]);
1023
+ return UnsetK2hEmitterCallback(info, stc_k2h_emitters[K2H_EMITTER_POS_PUT]);
963
1024
  }
964
1025
 
965
1026
  /**
@@ -999,97 +1060,158 @@ NAN_METHOD(K2hNode::OffPut)
999
1060
  * var k2hash = require('bindings')('k2hash') ;
1000
1061
  * var k2h = k2hash() ;
1001
1062
  * k2h.Create('/tmp/zz.k2h') ;
1002
- * k2h.SetValue('key','val') ;
1063
+ * k2h.SetValue('key', 'val') ;
1003
1064
  * console_log( k2h.GetValue('key') ) ;
1004
1065
  * k2h.Close() ;
1005
1066
  * @endcode
1006
1067
  *
1007
1068
  */
1008
1069
 
1009
- NAN_METHOD(K2hNode::Create)
1070
+ Napi::Value K2hNode::Create(const Napi::CallbackInfo& info)
1010
1071
  {
1072
+ Napi::Env env = info.Env();
1073
+
1074
+ // check
1011
1075
  if(info.Length() < 1){
1012
- Nan::ThrowSyntaxError("No file name is specified.");
1076
+ Napi::TypeError::New(env, "No file name is specified.").ThrowAsJavaScriptException();
1077
+ return env.Undefined();
1078
+ }
1079
+
1080
+ // Unwrap
1081
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
1082
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
1083
+ return env.Undefined();
1013
1084
  }
1085
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
1014
1086
 
1015
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
1016
- Nan::Utf8String filename(info[0]);
1017
- bool isfullmapping = true;
1018
- int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1019
- int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1020
- int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1021
- size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1022
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_CREATE]);
1087
+ // Variables with default value for optional parameters
1088
+ bool isfullmapping = true;
1089
+ int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1090
+ int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1091
+ int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1092
+ size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1023
1093
 
1094
+ // initial callback comes from emitter map if set
1095
+ Napi::Function maybeCallback;
1096
+ bool hasCallback = false;
1097
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_CREATE]);
1098
+ if(emitterCbRef){
1099
+ maybeCallback = emitterCbRef->Value();
1100
+ hasCallback = true;
1101
+ }
1102
+
1103
+ // info[0] : Required
1104
+ if(info[0].IsNull() || info[0].IsUndefined()){
1105
+ Napi::TypeError::New(env, "file name is empty.").ThrowAsJavaScriptException();
1106
+ return env.Undefined();
1107
+ }
1108
+ std::string filename = info[0].ToString().Utf8Value();
1109
+
1110
+ // info[1]
1024
1111
  if(1 < info.Length()){
1025
- if(info[1]->IsFunction()){
1112
+ if(info[1].IsFunction()){
1026
1113
  if(2 < info.Length()){
1027
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1028
- return;
1114
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1115
+ return env.Undefined();
1029
1116
  }
1030
- callback = new Nan::Callback(info[1].As<v8::Function>());
1117
+ maybeCallback = info[1].As<Napi::Function>();
1118
+ hasCallback = true;
1031
1119
  }else{
1032
- isfullmapping = Nan::To<bool>(info[1]).ToChecked();
1120
+ isfullmapping = info[1].ToBoolean();
1033
1121
  }
1034
1122
  }
1123
+
1124
+ // info[2]
1035
1125
  if(2 < info.Length()){
1036
- if(info[2]->IsFunction()){
1126
+ if(info[2].IsFunction()){
1037
1127
  if(3 < info.Length()){
1038
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1039
- return;
1128
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1129
+ return env.Undefined();
1040
1130
  }
1041
- callback = new Nan::Callback(info[2].As<v8::Function>());
1131
+ maybeCallback = info[2].As<Napi::Function>();
1132
+ hasCallback = true;
1042
1133
  }else{
1043
- mask_bitcnt = Nan::To<int>(info[2]).ToChecked();
1134
+ if(!info[2].IsNumber()){
1135
+ Napi::TypeError::New(env, "Third parameter must be int.").ThrowAsJavaScriptException();
1136
+ return env.Undefined();
1137
+ }
1138
+ mask_bitcnt = info[2].As<Napi::Number>().Int32Value();
1044
1139
  }
1045
1140
  }
1141
+
1142
+ // info[3]
1046
1143
  if(3 < info.Length()){
1047
- if(info[3]->IsFunction()){
1144
+ if(info[3].IsFunction()){
1048
1145
  if(4 < info.Length()){
1049
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1050
- return;
1146
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1147
+ return env.Undefined();
1051
1148
  }
1052
- callback = new Nan::Callback(info[3].As<v8::Function>());
1149
+ maybeCallback = info[3].As<Napi::Function>();
1150
+ hasCallback = true;
1053
1151
  }else{
1054
- cmask_bitcnt = Nan::To<int>(info[3]).ToChecked();
1152
+ if(!info[3].IsNumber()){
1153
+ Napi::TypeError::New(env, "Fourth parameter must be int.").ThrowAsJavaScriptException();
1154
+ return env.Undefined();
1155
+ }
1156
+ cmask_bitcnt = info[3].As<Napi::Number>().Int32Value();
1055
1157
  }
1056
1158
  }
1159
+
1160
+ // info[4]
1057
1161
  if(4 < info.Length()){
1058
- if(info[4]->IsFunction()){
1162
+ if(info[4].IsFunction()){
1059
1163
  if(5 < info.Length()){
1060
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1061
- return;
1164
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1165
+ return env.Undefined();
1062
1166
  }
1063
- callback = new Nan::Callback(info[4].As<v8::Function>());
1167
+ maybeCallback = info[4].As<Napi::Function>();
1168
+ hasCallback = true;
1064
1169
  }else{
1065
- max_element_cnt = Nan::To<int>(info[4]).ToChecked();
1170
+ if(!info[4].IsNumber()){
1171
+ Napi::TypeError::New(env, "Fifth parameter must be int.").ThrowAsJavaScriptException();
1172
+ return env.Undefined();
1173
+ }
1174
+ max_element_cnt = info[4].As<Napi::Number>().Int32Value();
1066
1175
  }
1067
1176
  }
1177
+
1178
+ // info[5]
1068
1179
  if(5 < info.Length()){
1069
- if(info[5]->IsFunction()){
1180
+ if(info[5].IsFunction()){
1070
1181
  if(6 < info.Length()){
1071
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1072
- return;
1182
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1183
+ return env.Undefined();
1073
1184
  }
1074
- callback = new Nan::Callback(info[5].As<v8::Function>());
1185
+ maybeCallback = info[5].As<Napi::Function>();
1186
+ hasCallback = true;
1075
1187
  }else{
1076
- pagesize = Nan::To<int>(info[5]).ToChecked();
1188
+ if(!info[5].IsNumber()){
1189
+ Napi::TypeError::New(env, "Sixth parameter must be int.").ThrowAsJavaScriptException();
1190
+ return env.Undefined();
1191
+ }
1192
+ pagesize = static_cast<size_t>(info[5].As<Napi::Number>().Int64Value());
1077
1193
  }
1078
1194
  }
1195
+
1196
+ // info[6]
1079
1197
  if(6 < info.Length()){
1080
- if(7 < info.Length() || !info[6]->IsFunction()){
1081
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1082
- return;
1198
+ if(7 < info.Length() || !info[6].IsFunction()){
1199
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1200
+ return env.Undefined();
1083
1201
  }
1084
- callback = new Nan::Callback(info[6].As<v8::Function>());
1202
+ maybeCallback = info[6].As<Napi::Function>();
1203
+ hasCallback = true;
1085
1204
  }
1086
1205
 
1087
- // work
1088
- if(callback){
1089
- Nan::AsyncQueueWorker(new CreateWorker(callback, &(obj->_k2hshm), *filename, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize));
1090
- info.GetReturnValue().Set(Nan::True());
1206
+ // Execute
1207
+ if(hasCallback){
1208
+ // Create worker and Queue it
1209
+ CreateAsyncWorker* worker = new CreateAsyncWorker(maybeCallback, &(obj->_k2hshm), filename, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1210
+ worker->Queue();
1211
+ return Napi::Boolean::New(env, true);
1091
1212
  }else{
1092
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Create(*filename, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize)));
1213
+ bool result = obj->_k2hshm.Create(filename.c_str(), isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1214
+ return Napi::Boolean::New(env, result);
1093
1215
  }
1094
1216
  }
1095
1217
 
@@ -1135,114 +1257,149 @@ NAN_METHOD(K2hNode::Create)
1135
1257
  *
1136
1258
  */
1137
1259
 
1138
- NAN_METHOD(K2hNode::Open)
1260
+ Napi::Value K2hNode::Open(const Napi::CallbackInfo& info)
1139
1261
  {
1262
+ Napi::Env env = info.Env();
1263
+
1140
1264
  if(info.Length() < 1){
1141
- Nan::ThrowSyntaxError("No file name is specified.");
1265
+ Napi::TypeError::New(env, "No file name is specified.").ThrowAsJavaScriptException();
1266
+ return env.Undefined();
1142
1267
  }
1143
1268
 
1144
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
1145
- Nan::Utf8String filename(info[0]);
1146
- bool isreadonly = false;
1147
- bool istempfile = false;
1148
- bool isfullmapping = true;
1149
- int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1150
- int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1151
- int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1152
- size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1153
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPEN]);
1269
+ // Unwrap
1270
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
1271
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
1272
+ return env.Undefined();
1273
+ }
1274
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
1154
1275
 
1276
+ std::string filename = info[0].ToString().Utf8Value();
1277
+ bool isreadonly = false;
1278
+ bool istempfile = false;
1279
+ bool isfullmapping = true;
1280
+ int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1281
+ int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1282
+ int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1283
+ size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1284
+
1285
+ // initial callback comes from emitter map if set
1286
+ Napi::Function maybeCallback;
1287
+ bool hasCallback = false;
1288
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPEN]);
1289
+ if(emitterCbRef){
1290
+ maybeCallback = emitterCbRef->Value();
1291
+ hasCallback = true;
1292
+ }
1293
+
1294
+ // parse positional optional args
1155
1295
  if(1 < info.Length()){
1156
- if(info[1]->IsFunction()){
1296
+ if(info[1].IsFunction()){
1157
1297
  if(2 < info.Length()){
1158
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1159
- return;
1298
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1299
+ return env.Undefined();
1160
1300
  }
1161
- callback = new Nan::Callback(info[1].As<v8::Function>());
1301
+ maybeCallback = info[1].As<Napi::Function>();
1302
+ hasCallback = true;
1162
1303
  }else{
1163
- isreadonly = Nan::To<bool>(info[1]).ToChecked();
1304
+ isreadonly = info[1].ToBoolean().Value();
1164
1305
  }
1165
1306
  }
1307
+
1166
1308
  if(2 < info.Length()){
1167
- if(info[2]->IsFunction()){
1309
+ if(info[2].IsFunction()){
1168
1310
  if(3 < info.Length()){
1169
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1170
- return;
1311
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1312
+ return env.Undefined();
1171
1313
  }
1172
- callback = new Nan::Callback(info[2].As<v8::Function>());
1173
- }else{
1174
- istempfile = Nan::To<bool>(info[2]).ToChecked();
1314
+ maybeCallback = info[2].As<Napi::Function>();
1315
+ hasCallback = true;
1316
+ } else {
1317
+ istempfile = info[2].ToBoolean().Value();
1175
1318
  }
1176
1319
  }
1320
+
1177
1321
  if(3 < info.Length()){
1178
- if(info[3]->IsFunction()){
1322
+ if(info[3].IsFunction()){
1179
1323
  if(4 < info.Length()){
1180
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1181
- return;
1324
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1325
+ return env.Undefined();
1182
1326
  }
1183
- callback = new Nan::Callback(info[3].As<v8::Function>());
1184
- }else{
1185
- isfullmapping = Nan::To<bool>(info[3]).ToChecked();
1327
+ maybeCallback = info[3].As<Napi::Function>();
1328
+ hasCallback = true;
1329
+ } else {
1330
+ isfullmapping = info[3].ToBoolean().Value();
1186
1331
  }
1187
1332
  }
1333
+
1188
1334
  if(4 < info.Length()){
1189
- if(info[4]->IsFunction()){
1335
+ if(info[4].IsFunction()){
1190
1336
  if(5 < info.Length()){
1191
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1192
- return;
1337
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1338
+ return env.Undefined();
1193
1339
  }
1194
- callback = new Nan::Callback(info[4].As<v8::Function>());
1340
+ maybeCallback = info[4].As<Napi::Function>();
1341
+ hasCallback = true;
1195
1342
  }else{
1196
- mask_bitcnt = Nan::To<int>(info[4]).ToChecked();
1343
+ mask_bitcnt = info[4].ToNumber().Int32Value();
1197
1344
  }
1198
1345
  }
1346
+
1199
1347
  if(5 < info.Length()){
1200
- if(info[5]->IsFunction()){
1348
+ if(info[5].IsFunction()){
1201
1349
  if(6 < info.Length()){
1202
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1203
- return;
1350
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1351
+ return env.Undefined();
1204
1352
  }
1205
- callback = new Nan::Callback(info[5].As<v8::Function>());
1353
+ maybeCallback = info[5].As<Napi::Function>();
1354
+ hasCallback = true;
1206
1355
  }else{
1207
- cmask_bitcnt = Nan::To<int>(info[5]).ToChecked();
1356
+ cmask_bitcnt = info[5].ToNumber().Int32Value();
1208
1357
  }
1209
1358
  }
1359
+
1210
1360
  if(6 < info.Length()){
1211
- if(info[6]->IsFunction()){
1361
+ if(info[6].IsFunction()){
1212
1362
  if(7 < info.Length()){
1213
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1214
- return;
1363
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1364
+ return env.Undefined();
1215
1365
  }
1216
- callback = new Nan::Callback(info[6].As<v8::Function>());
1366
+ maybeCallback = info[6].As<Napi::Function>();
1367
+ hasCallback = true;
1217
1368
  }else{
1218
- max_element_cnt = Nan::To<int>(info[6]).ToChecked();
1369
+ max_element_cnt = info[6].ToNumber().Int32Value();
1219
1370
  }
1220
1371
  }
1372
+
1221
1373
  if(7 < info.Length()){
1222
- if(info[7]->IsFunction()){
1374
+ if(info[7].IsFunction()){
1223
1375
  if(8 < info.Length()){
1224
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1225
- return;
1376
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1377
+ return env.Undefined();
1226
1378
  }
1227
- callback = new Nan::Callback(info[7].As<v8::Function>());
1379
+ maybeCallback = info[7].As<Napi::Function>();
1380
+ hasCallback = true;
1228
1381
  }else{
1229
- pagesize = Nan::To<int>(info[7]).ToChecked();
1382
+ pagesize = static_cast<size_t>(info[7].ToNumber().Int64Value());
1230
1383
  }
1231
1384
  }
1385
+
1232
1386
  if(8 < info.Length()){
1233
- if(9 < info.Length() || !info[8]->IsFunction()){
1234
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1235
- return;
1387
+ if(9 < info.Length() || !info[8].IsFunction()) {
1388
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1389
+ return env.Undefined();
1236
1390
  }
1237
- callback = new Nan::Callback(info[8].As<v8::Function>());
1391
+ maybeCallback = info[8].As<Napi::Function>();
1392
+ hasCallback = true;
1238
1393
  }
1239
1394
 
1240
- // work
1241
- if(callback){
1242
- Nan::AsyncQueueWorker(new OpenWorker(callback, &(obj->_k2hshm), *filename, isreadonly, false, istempfile, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize));
1243
- info.GetReturnValue().Set(Nan::True());
1395
+ // Execute
1396
+ if(hasCallback){
1397
+ OpenAsyncWorker* worker = new OpenAsyncWorker(maybeCallback, &(obj->_k2hshm), filename, isreadonly, false, istempfile, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1398
+ worker->Queue();
1399
+ return Napi::Boolean::New(env, true);
1244
1400
  }else{
1245
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Attach(*filename, isreadonly, false, istempfile, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize)));
1401
+ bool result = obj->_k2hshm.Attach(filename.c_str(), isreadonly, false, istempfile, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1402
+ return Napi::Boolean::New(env, result);
1246
1403
  }
1247
1404
  }
1248
1405
 
@@ -1283,90 +1440,121 @@ NAN_METHOD(K2hNode::Open)
1283
1440
  *
1284
1441
  */
1285
1442
 
1286
- NAN_METHOD(K2hNode::OpenRW)
1443
+ Napi::Value K2hNode::OpenRW(const Napi::CallbackInfo& info)
1287
1444
  {
1445
+ Napi::Env env = info.Env();
1446
+
1288
1447
  if(info.Length() < 1){
1289
- Nan::ThrowSyntaxError("No file name is specified.");
1448
+ Napi::TypeError::New(env, "No file name is specified.").ThrowAsJavaScriptException();
1449
+ return env.Undefined();
1290
1450
  }
1291
1451
 
1292
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
1293
- Nan::Utf8String filename(info[0]);
1294
- bool isfullmapping = true;
1295
- int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1296
- int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1297
- int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1298
- size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1299
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPENRW]);
1452
+ // Unwrap
1453
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
1454
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
1455
+ return env.Undefined();
1456
+ }
1457
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
1300
1458
 
1459
+ std::string filename = info[0].ToString().Utf8Value();
1460
+ bool isfullmapping = true;
1461
+ int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1462
+ int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1463
+ int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1464
+ size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1465
+
1466
+ // initial callback comes from emitter map if set
1467
+ Napi::Function maybeCallback;
1468
+ bool hasCallback = false;
1469
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPENRW]);
1470
+ if(emitterCbRef){
1471
+ maybeCallback = emitterCbRef->Value();
1472
+ hasCallback = true;
1473
+ }
1474
+
1475
+ // parse positional optional args
1301
1476
  if(1 < info.Length()){
1302
- if(info[1]->IsFunction()){
1477
+ if(info[1].IsFunction()){
1303
1478
  if(2 < info.Length()){
1304
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1305
- return;
1479
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1480
+ return env.Undefined();
1306
1481
  }
1307
- callback = new Nan::Callback(info[1].As<v8::Function>());
1482
+ maybeCallback = info[1].As<Napi::Function>();
1483
+ hasCallback = true;
1308
1484
  }else{
1309
- isfullmapping = Nan::To<bool>(info[1]).ToChecked();
1485
+ isfullmapping = info[1].ToBoolean().Value();
1310
1486
  }
1311
1487
  }
1488
+
1312
1489
  if(2 < info.Length()){
1313
- if(info[2]->IsFunction()){
1490
+ if(info[2].IsFunction()){
1314
1491
  if(3 < info.Length()){
1315
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1316
- return;
1492
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1493
+ return env.Undefined();
1317
1494
  }
1318
- callback = new Nan::Callback(info[2].As<v8::Function>());
1495
+ maybeCallback = info[2].As<Napi::Function>();
1496
+ hasCallback = true;
1319
1497
  }else{
1320
- mask_bitcnt = Nan::To<int>(info[2]).ToChecked();
1498
+ mask_bitcnt = info[2].ToNumber().Int32Value();
1321
1499
  }
1322
1500
  }
1501
+
1323
1502
  if(3 < info.Length()){
1324
- if(info[3]->IsFunction()){
1503
+ if(info[3].IsFunction()){
1325
1504
  if(4 < info.Length()){
1326
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1327
- return;
1505
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1506
+ return env.Undefined();
1328
1507
  }
1329
- callback = new Nan::Callback(info[3].As<v8::Function>());
1508
+ maybeCallback = info[3].As<Napi::Function>();
1509
+ hasCallback = true;
1330
1510
  }else{
1331
- cmask_bitcnt = Nan::To<int>(info[3]).ToChecked();
1511
+ cmask_bitcnt = info[3].ToNumber().Int32Value();
1332
1512
  }
1333
1513
  }
1514
+
1334
1515
  if(4 < info.Length()){
1335
- if(info[4]->IsFunction()){
1516
+ if(info[4].IsFunction()){
1336
1517
  if(5 < info.Length()){
1337
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1338
- return;
1518
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1519
+ return env.Undefined();
1339
1520
  }
1340
- callback = new Nan::Callback(info[4].As<v8::Function>());
1521
+ maybeCallback = info[4].As<Napi::Function>();
1522
+ hasCallback = true;
1341
1523
  }else{
1342
- max_element_cnt = Nan::To<int>(info[4]).ToChecked();
1524
+ max_element_cnt = info[4].ToNumber().Int32Value();
1343
1525
  }
1344
1526
  }
1527
+
1345
1528
  if(5 < info.Length()){
1346
- if(info[5]->IsFunction()){
1529
+ if(info[5].IsFunction()){
1347
1530
  if(6 < info.Length()){
1348
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1349
- return;
1531
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1532
+ return env.Undefined();
1350
1533
  }
1351
- callback = new Nan::Callback(info[5].As<v8::Function>());
1534
+ maybeCallback = info[5].As<Napi::Function>();
1535
+ hasCallback = true;
1352
1536
  }else{
1353
- pagesize = Nan::To<int>(info[5]).ToChecked();
1537
+ pagesize = static_cast<size_t>(info[5].ToNumber().Int64Value());
1354
1538
  }
1355
1539
  }
1540
+
1356
1541
  if(6 < info.Length()){
1357
- if(7 < info.Length() || !info[6]->IsFunction()){
1358
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1359
- return;
1542
+ if(7 < info.Length() || !info[6].IsFunction()){
1543
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1544
+ return env.Undefined();
1360
1545
  }
1361
- callback = new Nan::Callback(info[6].As<v8::Function>());
1546
+ maybeCallback = info[6].As<Napi::Function>();
1547
+ hasCallback = true;
1362
1548
  }
1363
1549
 
1364
- // work
1365
- if(callback){
1366
- Nan::AsyncQueueWorker(new OpenWorker(callback, &(obj->_k2hshm), *filename, false, false, false, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize));
1367
- info.GetReturnValue().Set(Nan::True());
1550
+ // Execute
1551
+ if(hasCallback){
1552
+ OpenAsyncWorker* worker = new OpenAsyncWorker(maybeCallback, &(obj->_k2hshm), filename, false, false, false, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1553
+ worker->Queue();
1554
+ return Napi::Boolean::New(env, true);
1368
1555
  }else{
1369
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Attach(*filename, false, false, false, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize)));
1556
+ bool result = obj->_k2hshm.Attach(filename.c_str(), false, false, false, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1557
+ return Napi::Boolean::New(env, result);
1370
1558
  }
1371
1559
  }
1372
1560
 
@@ -1407,90 +1595,121 @@ NAN_METHOD(K2hNode::OpenRW)
1407
1595
  *
1408
1596
  */
1409
1597
 
1410
- NAN_METHOD(K2hNode::OpenRO)
1598
+ Napi::Value K2hNode::OpenRO(const Napi::CallbackInfo& info)
1411
1599
  {
1600
+ Napi::Env env = info.Env();
1601
+
1412
1602
  if(info.Length() < 1){
1413
- Nan::ThrowSyntaxError("No file name is specified.");
1603
+ Napi::TypeError::New(env, "No file name is specified.").ThrowAsJavaScriptException();
1604
+ return env.Undefined();
1414
1605
  }
1415
1606
 
1416
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
1417
- Nan::Utf8String filename(info[0]);
1418
- bool isfullmapping = true;
1419
- int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1420
- int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1421
- int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1422
- size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1423
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPENRO]);
1607
+ // Unwrap
1608
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
1609
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
1610
+ return env.Undefined();
1611
+ }
1612
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
1613
+
1614
+ std::string filename = info[0].ToString().Utf8Value();
1615
+ bool isfullmapping = true;
1616
+ int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1617
+ int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1618
+ int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1619
+ size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1424
1620
 
1621
+ // initial callback comes from emitter map if set
1622
+ Napi::Function maybeCallback;
1623
+ bool hasCallback = false;
1624
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPENRO]);
1625
+ if(emitterCbRef){
1626
+ maybeCallback = emitterCbRef->Value();
1627
+ hasCallback = true;
1628
+ }
1629
+
1630
+ // parse positional optional args
1425
1631
  if(1 < info.Length()){
1426
- if(info[1]->IsFunction()){
1632
+ if(info[1].IsFunction()){
1427
1633
  if(2 < info.Length()){
1428
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1429
- return;
1634
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1635
+ return env.Undefined();
1430
1636
  }
1431
- callback = new Nan::Callback(info[1].As<v8::Function>());
1637
+ maybeCallback = info[1].As<Napi::Function>();
1638
+ hasCallback = true;
1432
1639
  }else{
1433
- isfullmapping = Nan::To<bool>(info[1]).ToChecked();
1640
+ isfullmapping = info[1].ToBoolean().Value();
1434
1641
  }
1435
1642
  }
1643
+
1436
1644
  if(2 < info.Length()){
1437
- if(info[2]->IsFunction()){
1645
+ if(info[2].IsFunction()){
1438
1646
  if(3 < info.Length()){
1439
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1440
- return;
1647
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1648
+ return env.Undefined();
1441
1649
  }
1442
- callback = new Nan::Callback(info[2].As<v8::Function>());
1650
+ maybeCallback = info[2].As<Napi::Function>();
1651
+ hasCallback = true;
1443
1652
  }else{
1444
- mask_bitcnt = Nan::To<int>(info[2]).ToChecked();
1653
+ mask_bitcnt = info[2].ToNumber().Int32Value();
1445
1654
  }
1446
1655
  }
1656
+
1447
1657
  if(3 < info.Length()){
1448
- if(info[3]->IsFunction()){
1658
+ if(info[3].IsFunction()){
1449
1659
  if(4 < info.Length()){
1450
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1451
- return;
1660
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1661
+ return env.Undefined();
1452
1662
  }
1453
- callback = new Nan::Callback(info[3].As<v8::Function>());
1663
+ maybeCallback = info[3].As<Napi::Function>();
1664
+ hasCallback = true;
1454
1665
  }else{
1455
- cmask_bitcnt = Nan::To<int>(info[3]).ToChecked();
1666
+ cmask_bitcnt = info[3].ToNumber().Int32Value();
1456
1667
  }
1457
1668
  }
1669
+
1458
1670
  if(4 < info.Length()){
1459
- if(info[4]->IsFunction()){
1671
+ if(info[4].IsFunction()){
1460
1672
  if(5 < info.Length()){
1461
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1462
- return;
1673
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1674
+ return env.Undefined();
1463
1675
  }
1464
- callback = new Nan::Callback(info[4].As<v8::Function>());
1676
+ maybeCallback = info[4].As<Napi::Function>();
1677
+ hasCallback = true;
1465
1678
  }else{
1466
- max_element_cnt = Nan::To<int>(info[4]).ToChecked();
1679
+ max_element_cnt = info[4].ToNumber().Int32Value();
1467
1680
  }
1468
1681
  }
1682
+
1469
1683
  if(5 < info.Length()){
1470
- if(info[5]->IsFunction()){
1684
+ if(info[5].IsFunction()){
1471
1685
  if(6 < info.Length()){
1472
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1473
- return;
1686
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1687
+ return env.Undefined();
1474
1688
  }
1475
- callback = new Nan::Callback(info[5].As<v8::Function>());
1689
+ maybeCallback = info[5].As<Napi::Function>();
1690
+ hasCallback = true;
1476
1691
  }else{
1477
- pagesize = Nan::To<int>(info[5]).ToChecked();
1692
+ pagesize = static_cast<size_t>(info[5].ToNumber().Int64Value());
1478
1693
  }
1479
1694
  }
1695
+
1480
1696
  if(6 < info.Length()){
1481
- if(7 < info.Length() || !info[6]->IsFunction()){
1482
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1483
- return;
1697
+ if(7 < info.Length() || !info[6].IsFunction()){
1698
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1699
+ return env.Undefined();
1484
1700
  }
1485
- callback = new Nan::Callback(info[6].As<v8::Function>());
1701
+ maybeCallback = info[6].As<Napi::Function>();
1702
+ hasCallback = true;
1486
1703
  }
1487
1704
 
1488
- // work
1489
- if(callback){
1490
- Nan::AsyncQueueWorker(new OpenWorker(callback, &(obj->_k2hshm), *filename, true, false, false, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize));
1491
- info.GetReturnValue().Set(Nan::True());
1705
+ // Execute
1706
+ if(hasCallback){
1707
+ OpenAsyncWorker* worker = new OpenAsyncWorker(maybeCallback, &(obj->_k2hshm), filename, true, false, false, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1708
+ worker->Queue();
1709
+ return Napi::Boolean::New(env, true);
1492
1710
  }else{
1493
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Attach(*filename, true, false, false, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize)));
1711
+ bool result = obj->_k2hshm.Attach(filename.c_str(), true, false, false, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1712
+ return Napi::Boolean::New(env, result);
1494
1713
  }
1495
1714
  }
1496
1715
 
@@ -1532,90 +1751,121 @@ NAN_METHOD(K2hNode::OpenRO)
1532
1751
  *
1533
1752
  */
1534
1753
 
1535
- NAN_METHOD(K2hNode::OpenTempfile)
1754
+ Napi::Value K2hNode::OpenTempfile(const Napi::CallbackInfo& info)
1536
1755
  {
1756
+ Napi::Env env = info.Env();
1757
+
1537
1758
  if(info.Length() < 1){
1538
- Nan::ThrowSyntaxError("No file name is specified.");
1759
+ Napi::TypeError::New(env, "No file name is specified.").ThrowAsJavaScriptException();
1760
+ return env.Undefined();
1761
+ }
1762
+
1763
+ // Unwrap
1764
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
1765
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
1766
+ return env.Undefined();
1539
1767
  }
1768
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
1540
1769
 
1541
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
1542
- Nan::Utf8String filename(info[0]);
1543
- bool isfullmapping = true;
1544
- int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1545
- int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1546
- int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1547
- size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1548
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPENTEMP]);
1770
+ std::string filename = info[0].ToString().Utf8Value();
1771
+ bool isfullmapping = true;
1772
+ int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1773
+ int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1774
+ int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1775
+ size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1549
1776
 
1777
+ // initial callback comes from emitter map if set
1778
+ Napi::Function maybeCallback;
1779
+ bool hasCallback = false;
1780
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPENTEMP]);
1781
+ if(emitterCbRef){
1782
+ maybeCallback = emitterCbRef->Value();
1783
+ hasCallback = true;
1784
+ }
1785
+
1786
+ // parse positional optional args
1550
1787
  if(1 < info.Length()){
1551
- if(info[1]->IsFunction()){
1788
+ if(info[1].IsFunction()){
1552
1789
  if(2 < info.Length()){
1553
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1554
- return;
1790
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1791
+ return env.Undefined();
1555
1792
  }
1556
- callback = new Nan::Callback(info[1].As<v8::Function>());
1793
+ maybeCallback = info[1].As<Napi::Function>();
1794
+ hasCallback = true;
1557
1795
  }else{
1558
- isfullmapping = Nan::To<bool>(info[1]).ToChecked();
1796
+ isfullmapping = info[1].ToBoolean().Value();
1559
1797
  }
1560
1798
  }
1799
+
1561
1800
  if(2 < info.Length()){
1562
- if(info[2]->IsFunction()){
1801
+ if(info[2].IsFunction()){
1563
1802
  if(3 < info.Length()){
1564
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1565
- return;
1803
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1804
+ return env.Undefined();
1566
1805
  }
1567
- callback = new Nan::Callback(info[2].As<v8::Function>());
1806
+ maybeCallback = info[2].As<Napi::Function>();
1807
+ hasCallback = true;
1568
1808
  }else{
1569
- mask_bitcnt = Nan::To<int>(info[2]).ToChecked();
1809
+ mask_bitcnt = info[2].ToNumber().Int32Value();
1570
1810
  }
1571
1811
  }
1812
+
1572
1813
  if(3 < info.Length()){
1573
- if(info[3]->IsFunction()){
1814
+ if(info[3].IsFunction()){
1574
1815
  if(4 < info.Length()){
1575
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1576
- return;
1816
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1817
+ return env.Undefined();
1577
1818
  }
1578
- callback = new Nan::Callback(info[3].As<v8::Function>());
1819
+ maybeCallback = info[3].As<Napi::Function>();
1820
+ hasCallback = true;
1579
1821
  }else{
1580
- cmask_bitcnt = Nan::To<int>(info[3]).ToChecked();
1822
+ cmask_bitcnt = info[3].ToNumber().Int32Value();
1581
1823
  }
1582
1824
  }
1825
+
1583
1826
  if(4 < info.Length()){
1584
- if(info[4]->IsFunction()){
1827
+ if(info[4].IsFunction()){
1585
1828
  if(5 < info.Length()){
1586
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1587
- return;
1829
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1830
+ return env.Undefined();
1588
1831
  }
1589
- callback = new Nan::Callback(info[4].As<v8::Function>());
1832
+ maybeCallback = info[4].As<Napi::Function>();
1833
+ hasCallback = true;
1590
1834
  }else{
1591
- max_element_cnt = Nan::To<int>(info[4]).ToChecked();
1835
+ max_element_cnt = info[4].ToNumber().Int32Value();
1592
1836
  }
1593
1837
  }
1838
+
1594
1839
  if(5 < info.Length()){
1595
- if(info[5]->IsFunction()){
1840
+ if(info[5].IsFunction()){
1596
1841
  if(6 < info.Length()){
1597
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1598
- return;
1842
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1843
+ return env.Undefined();
1599
1844
  }
1600
- callback = new Nan::Callback(info[5].As<v8::Function>());
1845
+ maybeCallback = info[5].As<Napi::Function>();
1846
+ hasCallback = true;
1601
1847
  }else{
1602
- pagesize = Nan::To<int>(info[5]).ToChecked();
1848
+ pagesize = static_cast<size_t>(info[5].ToNumber().Int64Value());
1603
1849
  }
1604
1850
  }
1851
+
1605
1852
  if(6 < info.Length()){
1606
- if(7 < info.Length() || !info[6]->IsFunction()){
1607
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1608
- return;
1853
+ if(7 < info.Length() || !info[6].IsFunction()){
1854
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1855
+ return env.Undefined();
1609
1856
  }
1610
- callback = new Nan::Callback(info[6].As<v8::Function>());
1857
+ maybeCallback = info[6].As<Napi::Function>();
1858
+ hasCallback = true;
1611
1859
  }
1612
1860
 
1613
- // work
1614
- if(callback){
1615
- Nan::AsyncQueueWorker(new OpenWorker(callback, &(obj->_k2hshm), *filename, false, false, true, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize));
1616
- info.GetReturnValue().Set(Nan::True());
1861
+ // Execute
1862
+ if(hasCallback){
1863
+ OpenAsyncWorker* worker = new OpenAsyncWorker(maybeCallback, &(obj->_k2hshm), filename, false, false, true, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1864
+ worker->Queue();
1865
+ return Napi::Boolean::New(env, true);
1617
1866
  }else{
1618
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Attach(*filename, false, false, true, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize)));
1867
+ bool result = obj->_k2hshm.Attach(filename.c_str(), false, false, true, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1868
+ return Napi::Boolean::New(env, result);
1619
1869
  }
1620
1870
  }
1621
1871
 
@@ -1650,73 +1900,101 @@ NAN_METHOD(K2hNode::OpenTempfile)
1650
1900
  *
1651
1901
  */
1652
1902
 
1653
- NAN_METHOD(K2hNode::OpenMem)
1903
+ Napi::Value K2hNode::OpenMem(const Napi::CallbackInfo& info)
1654
1904
  {
1655
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
1656
- int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1657
- int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1658
- int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1659
- size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1660
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPENMEM]);
1905
+ Napi::Env env = info.Env();
1906
+
1907
+ // Unwrap
1908
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
1909
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
1910
+ return env.Undefined();
1911
+ }
1912
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
1913
+
1914
+ int mask_bitcnt = K2HShm::MIN_MASK_BITCOUNT;
1915
+ int cmask_bitcnt = K2HShm::DEFAULT_COLLISION_MASK_BITCOUNT;
1916
+ int max_element_cnt = K2HShm::DEFAULT_MAX_ELEMENT_CNT;
1917
+ size_t pagesize = K2HShm::MIN_PAGE_SIZE;
1918
+
1919
+ // initial callback comes from emitter map if set
1920
+ Napi::Function maybeCallback;
1921
+ bool hasCallback = false;
1922
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_OPENMEM]);
1923
+ if(emitterCbRef){
1924
+ maybeCallback = emitterCbRef->Value();
1925
+ hasCallback = true;
1926
+ }
1927
+
1928
+ // parse positional optional args
1929
+ if(0 < info.Length()){
1930
+ if(info[0].IsFunction()){
1931
+ if(1 < info.Length()){
1932
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1933
+ return env.Undefined();
1934
+ }
1935
+ maybeCallback = info[0].As<Napi::Function>();
1936
+ hasCallback = true;
1937
+ }else{
1938
+ mask_bitcnt = info[0].ToNumber().Int32Value();
1939
+ }
1940
+ }
1661
1941
 
1662
1942
  if(1 < info.Length()){
1663
- if(info[1]->IsFunction()){
1943
+ if(info[1].IsFunction()){
1664
1944
  if(2 < info.Length()){
1665
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1666
- return;
1945
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1946
+ return env.Undefined();
1667
1947
  }
1668
- callback = new Nan::Callback(info[1].As<v8::Function>());
1948
+ maybeCallback = info[1].As<Napi::Function>();
1949
+ hasCallback = true;
1669
1950
  }else{
1670
- mask_bitcnt = Nan::To<int>(info[1]).ToChecked();
1951
+ cmask_bitcnt = info[1].ToNumber().Int32Value();
1671
1952
  }
1672
1953
  }
1954
+
1673
1955
  if(2 < info.Length()){
1674
- if(info[2]->IsFunction()){
1956
+ if(info[2].IsFunction()){
1675
1957
  if(3 < info.Length()){
1676
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1677
- return;
1958
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1959
+ return env.Undefined();
1678
1960
  }
1679
- callback = new Nan::Callback(info[2].As<v8::Function>());
1961
+ maybeCallback = info[2].As<Napi::Function>();
1962
+ hasCallback = true;
1680
1963
  }else{
1681
- cmask_bitcnt = Nan::To<int>(info[2]).ToChecked();
1964
+ max_element_cnt = info[2].ToNumber().Int32Value();
1682
1965
  }
1683
1966
  }
1967
+
1684
1968
  if(3 < info.Length()){
1685
- if(info[3]->IsFunction()){
1969
+ if(info[3].IsFunction()){
1686
1970
  if(4 < info.Length()){
1687
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1688
- return;
1971
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1972
+ return env.Undefined();
1689
1973
  }
1690
- callback = new Nan::Callback(info[3].As<v8::Function>());
1974
+ maybeCallback = info[3].As<Napi::Function>();
1975
+ hasCallback = true;
1691
1976
  }else{
1692
- max_element_cnt = Nan::To<int>(info[3]).ToChecked();
1977
+ pagesize = static_cast<size_t>(info[3].ToNumber().Int64Value());
1693
1978
  }
1694
1979
  }
1980
+
1695
1981
  if(4 < info.Length()){
1696
- if(info[4]->IsFunction()){
1697
- if(5 < info.Length()){
1698
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1699
- return;
1700
- }
1701
- callback = new Nan::Callback(info[4].As<v8::Function>());
1702
- }else{
1703
- pagesize = Nan::To<int>(info[4]).ToChecked();
1704
- }
1705
- }
1706
- if(5 < info.Length()){
1707
- if(6 < info.Length() || !info[5]->IsFunction()){
1708
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1709
- return;
1982
+ if(5 < info.Length() || !info[4].IsFunction()){
1983
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
1984
+ return env.Undefined();
1710
1985
  }
1711
- callback = new Nan::Callback(info[5].As<v8::Function>());
1986
+ maybeCallback = info[4].As<Napi::Function>();
1987
+ hasCallback = true;
1712
1988
  }
1713
1989
 
1714
- // work
1715
- if(callback){
1716
- Nan::AsyncQueueWorker(new OpenWorker(callback, &(obj->_k2hshm), NULL, false, true, false, true, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize));
1717
- info.GetReturnValue().Set(Nan::True());
1990
+ // Execute
1991
+ if(hasCallback){
1992
+ OpenAsyncWorker* worker = new OpenAsyncWorker(maybeCallback, &(obj->_k2hshm), std::string(""), false, true, false, true, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1993
+ worker->Queue();
1994
+ return Napi::Boolean::New(env, true);
1718
1995
  }else{
1719
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Attach(NULL, false, true, false, true, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize)));
1996
+ bool result = obj->_k2hshm.Attach(nullptr, false, true, false, true, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize);
1997
+ return Napi::Boolean::New(env, result);
1720
1998
  }
1721
1999
  }
1722
2000
 
@@ -1739,31 +2017,50 @@ NAN_METHOD(K2hNode::OpenMem)
1739
2017
  * var k2hash = require('bindings')('k2hash') ;
1740
2018
  * var k2h = k2hash() ;
1741
2019
  * k2h.OpenMem() ;
1742
- * k2h.SetValue('key','val') ;
2020
+ * k2h.SetValue('key', 'val') ;
1743
2021
  * console_log( k2h.GetValue('key') ) ;
1744
2022
  * k2h.Close() ;
1745
2023
  * @endcode
1746
2024
  */
1747
2025
 
1748
- NAN_METHOD(K2hNode::Close)
2026
+ Napi::Value K2hNode::Close(const Napi::CallbackInfo& info)
1749
2027
  {
1750
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
1751
- Nan::Callback* callback= obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_CLOSE]);
2028
+ Napi::Env env = info.Env();
2029
+
2030
+ // Unwrap
2031
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2032
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2033
+ return env.Undefined();
2034
+ }
2035
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2036
+
2037
+ // initial callback comes from emitter map if set
2038
+ Napi::Function maybeCallback;
2039
+ bool hasCallback = false;
2040
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_CLOSE]);
2041
+ if(emitterCbRef){
2042
+ maybeCallback = emitterCbRef->Value();
2043
+ hasCallback = true;
2044
+ }
1752
2045
 
2046
+ // parse positional optional args
1753
2047
  if(0 < info.Length()){
1754
- if(1 < info.Length() || !info[0]->IsFunction()){
1755
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1756
- return;
2048
+ if(1 < info.Length() || !info[0].IsFunction()){
2049
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2050
+ return env.Undefined();
1757
2051
  }
1758
- callback = new Nan::Callback(info[0].As<v8::Function>());
2052
+ maybeCallback = info[0].As<Napi::Function>();
2053
+ hasCallback = true;
1759
2054
  }
1760
2055
 
1761
- // work
1762
- if(callback){
1763
- Nan::AsyncQueueWorker(new CloseWorker(callback, &(obj->_k2hshm)));
1764
- info.GetReturnValue().Set(Nan::True());
2056
+ // Execute
2057
+ if(hasCallback){
2058
+ CloseAsyncWorker* worker = new CloseAsyncWorker(maybeCallback, &(obj->_k2hshm));
2059
+ worker->Queue();
2060
+ return Napi::Boolean::New(env, true);
1765
2061
  }else{
1766
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Detach()));
2062
+ bool result = obj->_k2hshm.Detach();
2063
+ return Napi::Boolean::New(env, result);
1767
2064
  }
1768
2065
  }
1769
2066
 
@@ -1796,87 +2093,110 @@ NAN_METHOD(K2hNode::Close)
1796
2093
  * var k2hash = require('bindings')('k2hash') ;
1797
2094
  * var k2h = k2hash() ;
1798
2095
  * k2h.OpenMem() ;
1799
- * k2h.SetValue('key','val') ;
2096
+ * k2h.SetValue('key', 'val') ;
1800
2097
  * console_log( k2h.GetValue('key') ) ;
1801
2098
  * k2h.Close() ;
1802
2099
  * @endcode
1803
2100
  */
1804
2101
 
1805
- NAN_METHOD(K2hNode::GetValue)
2102
+ Napi::Value K2hNode::GetValue(const Napi::CallbackInfo& info)
1806
2103
  {
2104
+ Napi::Env env = info.Env();
2105
+
1807
2106
  if(info.Length() < 1){
1808
- Nan::ThrowSyntaxError("No key name is specified.");
1809
- return;
1810
- }
1811
-
1812
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
1813
- string strkey;
1814
- bool is_subkey_set = false;
1815
- string strsubkey;
1816
- bool attrchk = true;
1817
- bool is_pass_set = false;
1818
- string strpass;
1819
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_GET]);
1820
-
1821
- if(info[0]->IsNull()){
1822
- Nan::ThrowSyntaxError("key is empty.");
1823
- return;
2107
+ Napi::TypeError::New(env, "No key name is specified.").ThrowAsJavaScriptException();
2108
+ return env.Undefined();
2109
+ }
2110
+
2111
+ // Unwrap
2112
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2113
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2114
+ return env.Undefined();
2115
+ }
2116
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2117
+
2118
+ std::string strkey;
2119
+ bool is_subkey_set = false;
2120
+ std::string strsubkey;
2121
+ bool attrchk = true;
2122
+ bool is_pass_set = false;
2123
+ std::string strpass;
2124
+
2125
+ // initial callback comes from emitter map if set
2126
+ Napi::Function maybeCallback;
2127
+ bool hasCallback = false;
2128
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_GET]);
2129
+ if(emitterCbRef){
2130
+ maybeCallback = emitterCbRef->Value();
2131
+ hasCallback = true;
2132
+ }
2133
+
2134
+ // parse positional optional args
2135
+ if(info[0].IsNull()){
2136
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
2137
+ return env.Undefined();
1824
2138
  }else{
1825
- Nan::Utf8String buf(info[0]);
1826
- strkey = std::string(*buf);
2139
+ strkey = info[0].ToString().Utf8Value();
1827
2140
  }
2141
+
1828
2142
  if(1 < info.Length()){
1829
- if(info[1]->IsFunction()){
2143
+ if(info[1].IsFunction()){
1830
2144
  if(2 < info.Length()){
1831
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1832
- return;
2145
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2146
+ return env.Undefined();
1833
2147
  }
1834
- callback = new Nan::Callback(info[1].As<v8::Function>());
1835
- }else if(!info[1]->IsNull()){
1836
- Nan::Utf8String buf(info[1]);
1837
- strsubkey = std::string(*buf);
2148
+ maybeCallback = info[1].As<Napi::Function>();
2149
+ hasCallback = true;
2150
+ }else if(!info[1].IsNull()){
2151
+ strsubkey = info[1].ToString().Utf8Value();
1838
2152
  is_subkey_set = true;
1839
2153
  }
1840
2154
  }
2155
+
1841
2156
  if(2 < info.Length()){
1842
- if(info[2]->IsFunction()){
2157
+ if(info[2].IsFunction()){
1843
2158
  if(3 < info.Length()){
1844
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1845
- return;
2159
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2160
+ return env.Undefined();
1846
2161
  }
1847
- callback = new Nan::Callback(info[2].As<v8::Function>());
1848
- }else if(info[2]->IsBoolean()){
1849
- attrchk = Nan::To<bool>(info[2]).ToChecked();
2162
+ maybeCallback = info[2].As<Napi::Function>();
2163
+ hasCallback = true;
2164
+ }else if(info[2].IsBoolean()){
2165
+ attrchk = info[2].ToBoolean().Value();
1850
2166
  }else{
1851
- Nan::ThrowSyntaxError("Third parameter must be boolean.");
1852
- return;
2167
+ Napi::TypeError::New(env, "Third parameter must be boolean.").ThrowAsJavaScriptException();
2168
+ return env.Undefined();
1853
2169
  }
1854
2170
  }
2171
+
1855
2172
  if(3 < info.Length()){
1856
- if(info[3]->IsFunction()){
2173
+ if(info[3].IsFunction()){
1857
2174
  if(4 < info.Length()){
1858
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1859
- return;
2175
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2176
+ return env.Undefined();
1860
2177
  }
1861
- callback = new Nan::Callback(info[3].As<v8::Function>());
1862
- }else if(!info[3]->IsNull()){
1863
- Nan::Utf8String buf(info[3]);
1864
- strpass = std::string(*buf);
2178
+ maybeCallback = info[3].As<Napi::Function>();
2179
+ hasCallback = true;
2180
+ }else if(!info[3].IsNull()){
2181
+ strpass = info[3].ToString().Utf8Value();
1865
2182
  is_pass_set = true;
1866
2183
  }
1867
2184
  }
2185
+
1868
2186
  if(4 < info.Length()){
1869
- if(5 < info.Length() || !info[4]->IsFunction()){
1870
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1871
- return;
2187
+ if(5 < info.Length() || !info[4].IsFunction()){
2188
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2189
+ return env.Undefined();
1872
2190
  }
1873
- callback = new Nan::Callback(info[4].As<v8::Function>());
2191
+ maybeCallback = info[4].As<Napi::Function>();
2192
+ hasCallback = true;
1874
2193
  }
1875
2194
 
1876
- // work
1877
- if(callback){
1878
- Nan::AsyncQueueWorker(new GetValueWorker(callback, &(obj->_k2hshm), strkey.c_str(), (is_subkey_set ? strsubkey.c_str() : NULL), attrchk, (is_pass_set ? strpass.c_str() : NULL)));
1879
- info.GetReturnValue().Set(Nan::True());
2195
+ // Execute
2196
+ if(hasCallback){
2197
+ GetValueAsyncWorker* worker = new GetValueAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str(), (is_subkey_set ? strsubkey.c_str() : NULL), attrchk, (is_pass_set ? strpass.c_str() : NULL));
2198
+ worker->Queue();
2199
+ return Napi::Boolean::New(env, true);
1880
2200
  }else{
1881
2201
  if(is_subkey_set){
1882
2202
  // subkey is specified, thus need to check the key has it.
@@ -1894,18 +2214,18 @@ NAN_METHOD(K2hNode::GetValue)
1894
2214
  delete sk;
1895
2215
  }
1896
2216
  if(!found){
1897
- info.GetReturnValue().Set(Nan::Undefined());
1898
- return;
2217
+ return env.Undefined();
1899
2218
  }
1900
2219
  strkey = strsubkey;
1901
2220
  }
1902
2221
 
1903
2222
  char* presult = obj->_k2hshm.Get(strkey.c_str(), attrchk, (is_pass_set ? strpass.c_str() : NULL));
1904
2223
  if(presult){
1905
- info.GetReturnValue().Set(Nan::New<String>(presult).ToLocalChecked());
2224
+ Napi::String result = Napi::String::New(env, presult, static_cast<size_t>(strlen(presult)));
1906
2225
  K2H_Free(presult);
2226
+ return result;
1907
2227
  }else{
1908
- info.GetReturnValue().Set(Nan::Null());
2228
+ return env.Null();
1909
2229
  }
1910
2230
  }
1911
2231
  }
@@ -1930,53 +2250,71 @@ NAN_METHOD(K2hNode::GetValue)
1930
2250
  *
1931
2251
  */
1932
2252
 
1933
- NAN_METHOD(K2hNode::GetSubkeys)
2253
+ Napi::Value K2hNode::GetSubkeys(const Napi::CallbackInfo& info)
1934
2254
  {
2255
+ Napi::Env env = info.Env();
2256
+
1935
2257
  if(info.Length() < 1){
1936
- Nan::ThrowSyntaxError("No key name is specified.");
1937
- return;
2258
+ Napi::TypeError::New(env, "No key name is specified.").ThrowAsJavaScriptException();
2259
+ return env.Undefined();
1938
2260
  }
1939
2261
 
1940
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
1941
- string strkey;
1942
- Nan::Callback* callback= obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_GETSUBKEYS]);
2262
+ // Unwrap
2263
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2264
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2265
+ return env.Undefined();
2266
+ }
2267
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2268
+
2269
+ std::string strkey;
1943
2270
 
1944
- if(info[0]->IsNull()){
1945
- Nan::ThrowSyntaxError("key is empty.");
1946
- return;
2271
+ // initial callback comes from emitter map if set
2272
+ Napi::Function maybeCallback;
2273
+ bool hasCallback = false;
2274
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_GETSUBKEYS]);
2275
+ if(emitterCbRef){
2276
+ maybeCallback = emitterCbRef->Value();
2277
+ hasCallback = true;
2278
+ }
2279
+
2280
+ // parse positional optional args
2281
+ if(info[0].IsNull()){
2282
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
2283
+ return env.Undefined();
1947
2284
  }else{
1948
- Nan::Utf8String buf(info[0]);
1949
- strkey = std::string(*buf);
2285
+ strkey = info[0].ToString().Utf8Value();
1950
2286
  }
2287
+
1951
2288
  if(1 < info.Length()){
1952
- if(2 < info.Length() || !info[1]->IsFunction()){
1953
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
1954
- return;
2289
+ if(2 < info.Length() || !info[1].IsFunction()){
2290
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2291
+ return env.Undefined();
1955
2292
  }
1956
- callback = new Nan::Callback(info[1].As<v8::Function>());
2293
+ maybeCallback = info[1].As<Napi::Function>();
2294
+ hasCallback = true;
1957
2295
  }
1958
2296
 
1959
- // work
1960
- if(callback){
1961
- Nan::AsyncQueueWorker(new GetSubkeysWorker(callback, &(obj->_k2hshm), strkey.c_str()));
1962
- info.GetReturnValue().Set(Nan::True());
2297
+ // Execute
2298
+ if(hasCallback){
2299
+ GetSubkeysAsyncWorker* worker = new GetSubkeysAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str());
2300
+ worker->Queue();
2301
+ return Napi::Boolean::New(env, true);
1963
2302
  }else{
1964
2303
  K2HSubKeys* sk = obj->_k2hshm.GetSubKeys(strkey.c_str());
1965
2304
  if(!sk){
1966
- info.GetReturnValue().Set(Nan::Null());
1967
- return;
2305
+ return env.Null();
1968
2306
  }
1969
2307
  strarr_t strarr;
1970
2308
  sk->StringArray(strarr);
1971
2309
 
1972
- Local<Array> retarr = Nan::New<Array>();
1973
- int pos = 0 ;
2310
+ Napi::Array retarr = Napi::Array::New(env, static_cast<size_t>(strarr.size()));
2311
+ uint32_t pos = 0;
1974
2312
  for(strarr_t::const_iterator iter = strarr.begin(); iter != strarr.end(); ++iter, ++pos){
1975
- Nan::Set(retarr, pos, Nan::New<String>(iter->c_str()).ToLocalChecked());
2313
+ retarr.Set(pos, Napi::String::New(env, iter->c_str(), static_cast<size_t>(strlen(iter->c_str()))));
1976
2314
  }
1977
2315
  delete sk;
1978
2316
 
1979
- info.GetReturnValue().Set(retarr);
2317
+ return retarr;
1980
2318
  }
1981
2319
  }
1982
2320
 
@@ -2014,103 +2352,128 @@ NAN_METHOD(K2hNode::GetSubkeys)
2014
2352
  * var k2hash = require('bindings')('k2hash') ;
2015
2353
  * var k2h = k2hash() ;
2016
2354
  * k2h.OpenMem() ;
2017
- * k2h.SetValue('key','val') ;
2355
+ * k2h.SetValue('key', 'val') ;
2018
2356
  * console_log( k2h.GetValue('key') ) ;
2019
2357
  * k2h.Close() ;
2020
2358
  * @endcode
2021
2359
  */
2022
2360
 
2023
- NAN_METHOD(K2hNode::SetValue)
2361
+ Napi::Value K2hNode::SetValue(const Napi::CallbackInfo& info)
2024
2362
  {
2363
+ Napi::Env env = info.Env();
2364
+
2025
2365
  if(info.Length() < 2){
2026
- Nan::ThrowSyntaxError("No key name or no value are specified.");
2027
- return;
2028
- }
2029
-
2030
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
2031
- string strkey;
2032
- bool is_val_set = false;
2033
- string strval;
2034
- bool is_skey_set = false;
2035
- string strsubkey;
2036
- bool is_pass_set = false;
2037
- string strpass;
2038
- time_t expire = 0;
2039
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_SET]);
2040
-
2041
- if(info[0]->IsNull()){
2042
- Nan::ThrowSyntaxError("key is empty.");
2043
- return;
2366
+ Napi::TypeError::New(env, "No key name or no value are specified.").ThrowAsJavaScriptException();
2367
+ return env.Undefined();
2368
+ }
2369
+
2370
+ // Unwrap
2371
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2372
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2373
+ return env.Undefined();
2374
+ }
2375
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2376
+
2377
+ std::string strkey;
2378
+ bool is_val_set = false;
2379
+ std::string strval;
2380
+ bool is_skey_set = false;
2381
+ std::string strsubkey;
2382
+ bool is_pass_set = false;
2383
+ std::string strpass;
2384
+ time_t expire = 0;
2385
+
2386
+ // initial callback comes from emitter map if set
2387
+ Napi::Function maybeCallback;
2388
+ bool hasCallback = false;
2389
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_SET]);
2390
+ if(emitterCbRef){
2391
+ maybeCallback = emitterCbRef->Value();
2392
+ hasCallback = true;
2393
+ }
2394
+
2395
+ // parse positional optional args
2396
+ if(info[0].IsNull()){
2397
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
2398
+ return env.Undefined();
2044
2399
  }else{
2045
- Nan::Utf8String buf(info[0]);
2046
- strkey = std::string(*buf);
2400
+ strkey = info[0].ToString().Utf8Value();
2047
2401
  }
2048
- if(!info[1]->IsNull()){
2049
- Nan::Utf8String buf(info[1]);
2050
- strval = std::string(*buf);
2051
- is_val_set = true;
2402
+
2403
+ if(!info[1].IsNull()){
2404
+ strval = info[1].ToString().Utf8Value();
2405
+ is_val_set = true;
2052
2406
  }
2407
+
2053
2408
  if(2 < info.Length()){
2054
- if(info[2]->IsFunction()){
2409
+ if(info[2].IsFunction()){
2055
2410
  if(3 < info.Length()){
2056
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2057
- return;
2411
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2412
+ return env.Undefined();
2058
2413
  }
2059
- callback = new Nan::Callback(info[2].As<v8::Function>());
2060
- }else if(!info[2]->IsNull()){
2061
- Nan::Utf8String buf(info[2]);
2062
- strsubkey = std::string(*buf);
2063
- is_skey_set = true;
2414
+ maybeCallback = info[2].As<Napi::Function>();
2415
+ hasCallback = true;
2416
+ }else if(!info[2].IsNull()){
2417
+ strsubkey = info[2].ToString().Utf8Value();
2418
+ is_skey_set = true;
2064
2419
  }
2065
2420
  }
2421
+
2066
2422
  if(3 < info.Length()){
2067
- if(info[3]->IsFunction()){
2423
+ if(info[3].IsFunction()){
2068
2424
  if(4 < info.Length()){
2069
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2070
- return;
2425
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2426
+ return env.Undefined();
2071
2427
  }
2072
- callback = new Nan::Callback(info[3].As<v8::Function>());
2073
- }else if(!info[3]->IsNull()){
2074
- Nan::Utf8String buf(info[3]);
2075
- strpass = std::string(*buf);
2076
- is_pass_set = true;
2428
+ maybeCallback = info[3].As<Napi::Function>();
2429
+ hasCallback = true;
2430
+ }else if(!info[3].IsNull()){
2431
+ strpass = info[3].ToString().Utf8Value();
2432
+ is_pass_set = true;
2077
2433
  }
2078
2434
  }
2435
+
2079
2436
  if(4 < info.Length()){
2080
- if(info[4]->IsFunction()){
2437
+ if(info[4].IsFunction()){
2081
2438
  if(5 < info.Length()){
2082
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2083
- return;
2439
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2440
+ return env.Undefined();
2084
2441
  }
2085
- callback = new Nan::Callback(info[4].As<v8::Function>());
2086
- }else if(info[4]->IsInt32()){
2087
- int nexpire = Nan::To<int32_t>(info[4]).ToChecked();
2088
- expire = static_cast<time_t>(nexpire);
2442
+ maybeCallback = info[4].As<Napi::Function>();
2443
+ hasCallback = true;
2444
+ }else if(info[4].IsNumber()){
2445
+ int32_t nexpire = info[4].ToNumber().Int32Value();
2446
+ expire = static_cast<time_t>(nexpire);
2089
2447
  }else{
2090
- Nan::ThrowSyntaxError("Expire parameter must be int32 value.");
2091
- return;
2448
+ Napi::TypeError::New(env, "Expire parameter must be int32 value.").ThrowAsJavaScriptException();
2449
+ return env.Undefined();
2092
2450
  }
2093
2451
  }
2452
+
2094
2453
  if(5 < info.Length()){
2095
- if(6 < info.Length() || !info[5]->IsFunction()){
2096
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2097
- return;
2454
+ if(6 < info.Length() || !info[5].IsFunction()){
2455
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2456
+ return env.Undefined();
2098
2457
  }
2099
- callback = new Nan::Callback(info[5].As<v8::Function>());
2458
+ maybeCallback = info[5].As<Napi::Function>();
2459
+ hasCallback = true;
2100
2460
  }
2101
2461
 
2102
- // work
2103
- if(callback){
2104
- Nan::AsyncQueueWorker(new SetValueWorker(callback, &(obj->_k2hshm), strkey.c_str(), (is_skey_set ? strsubkey.c_str() : NULL), (is_val_set ? strval.c_str() : NULL), (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL)));
2105
- info.GetReturnValue().Set(Nan::True());
2462
+ // Execute
2463
+ if(hasCallback){
2464
+ SetValueAsyncWorker* worker = new SetValueAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str(), (is_skey_set ? strsubkey.c_str() : NULL), (is_val_set ? strval.c_str() : NULL), (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL));
2465
+ worker->Queue();
2466
+ return Napi::Boolean::New(env, true);
2106
2467
  }else{
2468
+ bool result;
2107
2469
  if(is_skey_set){
2108
2470
  // subkey is specified
2109
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.AddSubkey(strkey.c_str(), strsubkey.c_str(), (is_val_set ? strval.c_str() : NULL), (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL))));
2471
+ result = obj->_k2hshm.AddSubkey(strkey.c_str(), strsubkey.c_str(), (is_val_set ? strval.c_str() : NULL), (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL));
2110
2472
  }else{
2111
2473
  // subkey is not specified
2112
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Set(strkey.c_str(), (is_val_set ? strval.c_str() : NULL), (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL))));
2474
+ result = obj->_k2hshm.Set(strkey.c_str(), (is_val_set ? strval.c_str() : NULL), (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL));
2113
2475
  }
2476
+ return Napi::Boolean::New(env, result);
2114
2477
  }
2115
2478
  }
2116
2479
 
@@ -2138,61 +2501,82 @@ NAN_METHOD(K2hNode::SetValue)
2138
2501
  *
2139
2502
  */
2140
2503
 
2141
- NAN_METHOD(K2hNode::AddSubkey)
2504
+ Napi::Value K2hNode::AddSubkey(const Napi::CallbackInfo& info)
2142
2505
  {
2506
+ Napi::Env env = info.Env();
2507
+
2143
2508
  if(info.Length() < 2){
2144
- Nan::ThrowSyntaxError("No key name or no subkey name are specified.");
2145
- return;
2509
+ Napi::TypeError::New(env, "No key name or no subkey name are specified.").ThrowAsJavaScriptException();
2510
+ return env.Undefined();
2511
+ }
2512
+
2513
+ // Unwrap
2514
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2515
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2516
+ return env.Undefined();
2146
2517
  }
2518
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2519
+
2520
+ std::string strkey;
2521
+ std::string strsubkey;
2522
+ bool is_value_set = false;
2523
+ std::string strvalue;
2147
2524
 
2148
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
2149
- string strkey;
2150
- string strsubkey;
2151
- bool is_value_set= false;
2152
- string strvalue;
2153
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEY]);
2525
+ // initial callback comes from emitter map if set
2526
+ Napi::Function maybeCallback;
2527
+ bool hasCallback = false;
2528
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEY]);
2529
+ if(emitterCbRef){
2530
+ maybeCallback = emitterCbRef->Value();
2531
+ hasCallback = true;
2532
+ }
2154
2533
 
2155
- if(info[0]->IsNull()){
2156
- Nan::ThrowSyntaxError("key is empty.");
2157
- return;
2534
+ // parse positional optional args
2535
+ if(info[0].IsNull()){
2536
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
2537
+ return env.Undefined();
2158
2538
  }else{
2159
- Nan::Utf8String buf(info[0]);
2160
- strkey = std::string(*buf);
2539
+ strkey = info[0].ToString().Utf8Value();
2161
2540
  }
2162
- if(info[1]->IsNull()){
2163
- Nan::ThrowSyntaxError("subkey is empty.");
2164
- return;
2541
+
2542
+ if(info[1].IsNull()){
2543
+ Napi::TypeError::New(env, "subkey is empty.").ThrowAsJavaScriptException();
2544
+ return env.Undefined();
2165
2545
  }else{
2166
- Nan::Utf8String buf(info[1]);
2167
- strsubkey = std::string(*buf);
2546
+ strsubkey = info[1].ToString().Utf8Value();
2168
2547
  }
2548
+
2169
2549
  if(2 < info.Length()){
2170
- if(info[2]->IsFunction()){
2550
+ if(info[2].IsFunction()){
2171
2551
  if(3 < info.Length()){
2172
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2173
- return;
2552
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2553
+ return env.Undefined();
2174
2554
  }
2175
- callback = new Nan::Callback(info[2].As<v8::Function>());
2176
- }else if(!info[2]->IsNull()){
2177
- Nan::Utf8String buf(info[2]);
2178
- strvalue = std::string(*buf);
2555
+ maybeCallback = info[2].As<Napi::Function>();
2556
+ hasCallback = true;
2557
+ }else if(!info[2].IsNull()){
2558
+ strvalue = info[2].ToString().Utf8Value();
2179
2559
  is_value_set = true;
2180
2560
  }
2181
2561
  }
2562
+
2182
2563
  if(3 < info.Length()){
2183
- if(4 < info.Length() || !info[3]->IsFunction()){
2184
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2185
- return;
2564
+ if(4 < info.Length() || !info[3].IsFunction()){
2565
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2566
+ return env.Undefined();
2186
2567
  }
2187
- callback = new Nan::Callback(info[3].As<v8::Function>());
2568
+ maybeCallback = info[3].As<Napi::Function>();
2569
+ hasCallback = true;
2188
2570
  }
2189
2571
 
2190
2572
  // work
2191
- if(callback){
2192
- Nan::AsyncQueueWorker(new AddSubkeyWorker(callback, &(obj->_k2hshm), strkey.c_str(), strsubkey.c_str(), (is_value_set ? strvalue.c_str() : NULL)));
2193
- info.GetReturnValue().Set(Nan::True());
2573
+ if(hasCallback){
2574
+ AddSubkeyAsyncWorker* worker = new AddSubkeyAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str(), strsubkey.c_str(), (is_value_set ? strvalue.c_str() : NULL));
2575
+ worker->Queue();
2576
+ return Napi::Boolean::New(env, true);
2194
2577
  }else{
2195
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.AddSubkey(strkey.c_str(), strsubkey.c_str(), (is_value_set ? strvalue.c_str() : NULL))));
2578
+ bool result = obj->_k2hshm.AddSubkey(strkey.c_str(), strsubkey.c_str(), (is_value_set ? strvalue.c_str() : NULL));
2579
+ return Napi::Boolean::New(env, result);
2196
2580
  }
2197
2581
  }
2198
2582
 
@@ -2220,71 +2604,91 @@ NAN_METHOD(K2hNode::AddSubkey)
2220
2604
  *
2221
2605
  */
2222
2606
 
2223
- NAN_METHOD(K2hNode::AddSubkeys)
2607
+ Napi::Value K2hNode::AddSubkeys(const Napi::CallbackInfo& info)
2224
2608
  {
2609
+ Napi::Env env = info.Env();
2610
+
2225
2611
  if(info.Length() < 2){
2226
- Nan::ThrowSyntaxError("No key name or no subkeys array are specified.");
2227
- return;
2612
+ Napi::TypeError::New(env, "No key name or no subkeys array are specified.").ThrowAsJavaScriptException();
2613
+ return env.Undefined();
2228
2614
  }
2229
2615
 
2230
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
2231
- string strkey;
2616
+ // Unwrap
2617
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2618
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2619
+ return env.Undefined();
2620
+ }
2621
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2622
+
2623
+ std::string strkey;
2232
2624
  unsigned char* bySubkeys = NULL;
2233
2625
  size_t skeylen = 0UL;
2234
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEYS]);
2235
2626
 
2236
- if(info[0]->IsNull()){
2237
- Nan::ThrowSyntaxError("key is empty.");
2238
- return;
2627
+ // initial callback comes from emitter map if set
2628
+ Napi::Function maybeCallback;
2629
+ bool hasCallback = false;
2630
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_ADDSUBKEYS]);
2631
+ if(emitterCbRef){
2632
+ maybeCallback = emitterCbRef->Value();
2633
+ hasCallback = true;
2634
+ }
2635
+
2636
+ // initial callback comes from emitter map if set
2637
+ if(info[0].IsNull()){
2638
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
2639
+ return env.Undefined();
2239
2640
  }else{
2240
- Nan::Utf8String buf(info[0]);
2241
- strkey = std::string(*buf);
2641
+ strkey = info[0].ToString().Utf8Value();
2242
2642
  }
2243
- if(!info[1]->IsArray()){
2244
- Nan::ThrowSyntaxError("Specified subkeys is not array.");
2245
- return;
2643
+
2644
+ if(!info[1].IsArray()){
2645
+ Napi::TypeError::New(env, "Specified subkeys is not array.").ThrowAsJavaScriptException();
2646
+ return env.Undefined();
2246
2647
  }else{
2247
- Local<Array> inSubkeys= Local<Array>::Cast(info[1]);
2248
- K2HSubKeys Subkeys;
2249
- for(int pos = 0; pos < static_cast<int>(inSubkeys->Length()); ++pos){
2250
- string tmpkey;
2251
- {
2252
- Nan::Utf8String buf(Nan::Get(inSubkeys, pos).ToLocalChecked());
2253
- tmpkey = std::string(*buf);
2254
- }
2648
+ Napi::Array inSubkeys = info[1].As<Napi::Array>();
2649
+ K2HSubKeys Subkeys;
2650
+ uint32_t len = inSubkeys.Length();
2651
+ for(uint32_t pos = 0; pos < len; ++pos){
2652
+ std::string tmpkey = inSubkeys.Get(pos).ToString().Utf8Value();
2255
2653
  if(Subkeys.end() == Subkeys.insert(tmpkey.c_str())){
2256
2654
  // failed to set subkey
2257
- info.GetReturnValue().Set(Nan::False());
2258
- return;
2655
+ K2H_Free(bySubkeys);
2656
+ return Napi::Boolean::New(env, false);
2259
2657
  }
2260
2658
  }
2261
2659
  if(0UL >= Subkeys.size()){
2262
2660
  // there is no subkey
2263
- info.GetReturnValue().Set(Nan::False());
2264
- return;
2661
+ K2H_Free(bySubkeys);
2662
+ return Napi::Boolean::New(env, false);
2265
2663
  }
2266
2664
  // serialize
2267
2665
  if(!Subkeys.Serialize(&bySubkeys, skeylen)){
2268
- info.GetReturnValue().Set(Nan::False());
2269
- return;
2666
+ K2H_Free(bySubkeys);
2667
+ return Napi::Boolean::New(env, false);
2270
2668
  }
2271
2669
  }
2670
+
2272
2671
  if(2 < info.Length()){
2273
- if(3 < info.Length() || !info[2]->IsFunction()){
2274
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2275
- return;
2672
+ if(3 < info.Length() || !info[2].IsFunction()){
2673
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2674
+ K2H_Free(bySubkeys);
2675
+ return env.Undefined();
2276
2676
  }
2277
- callback = new Nan::Callback(info[2].As<v8::Function>());
2677
+ maybeCallback = info[2].As<Napi::Function>();
2678
+ hasCallback = true;
2278
2679
  }
2279
2680
 
2280
- // work
2281
- if(callback){
2282
- Nan::AsyncQueueWorker(new AddSubkeysWorker(callback, &(obj->_k2hshm), strkey.c_str(), bySubkeys, skeylen));
2283
- info.GetReturnValue().Set(Nan::True());
2681
+ // Execute
2682
+ if(hasCallback){
2683
+ AddSubkeysAsyncWorker* worker = new AddSubkeysAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str(), bySubkeys, skeylen);
2684
+ worker->Queue();
2685
+ K2H_Free(bySubkeys);
2686
+ return Napi::Boolean::New(env, true);
2284
2687
  }else{
2285
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.ReplaceSubkeys(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, bySubkeys, skeylen)));
2688
+ bool result = obj->_k2hshm.ReplaceSubkeys(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, bySubkeys, skeylen);
2689
+ K2H_Free(bySubkeys);
2690
+ return Napi::Boolean::New(env, result);
2286
2691
  }
2287
- K2H_Free(bySubkeys);
2288
2692
  }
2289
2693
 
2290
2694
  /**
@@ -2310,57 +2714,79 @@ NAN_METHOD(K2hNode::AddSubkeys)
2310
2714
  *
2311
2715
  */
2312
2716
 
2313
- NAN_METHOD(K2hNode::Remove)
2717
+ Napi::Value K2hNode::Remove(const Napi::CallbackInfo& info)
2314
2718
  {
2719
+ Napi::Env env = info.Env();
2720
+
2315
2721
  if(info.Length() < 1){
2316
- Nan::ThrowSyntaxError("No key name is specified.");
2317
- return;
2722
+ Napi::TypeError::New(env, "No key name is specified.").ThrowAsJavaScriptException();
2723
+ return env.Undefined();
2724
+ }
2725
+
2726
+ // Unwrap
2727
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2728
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2729
+ return env.Undefined();
2318
2730
  }
2731
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2319
2732
 
2320
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
2321
- string strkey;
2322
- bool is_subkey_set = false;
2323
- string strsubkey;
2324
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_REMOVE]);
2733
+ std::string strkey;
2734
+ bool is_subkey_set = false;
2735
+ std::string strsubkey;
2325
2736
 
2326
- if(info[0]->IsNull()){
2327
- Nan::ThrowSyntaxError("key is empty.");
2328
- return;
2737
+ // initial callback comes from emitter map if set
2738
+ Napi::Function maybeCallback;
2739
+ bool hasCallback = false;
2740
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_REMOVE]);
2741
+ if(emitterCbRef){
2742
+ maybeCallback = emitterCbRef->Value();
2743
+ hasCallback = true;
2744
+ }
2745
+
2746
+ // parse positional optional args
2747
+ if(info[0].IsNull()){
2748
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
2749
+ return env.Undefined();
2329
2750
  }else{
2330
- Nan::Utf8String buf(info[0]);
2331
- strkey = std::string(*buf);
2751
+ strkey = info[0].ToString().Utf8Value();
2332
2752
  }
2753
+
2333
2754
  if(1 < info.Length()){
2334
- if(info[1]->IsFunction()){
2755
+ if(info[1].IsFunction()){
2335
2756
  if(2 < info.Length()){
2336
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2337
- return;
2757
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2758
+ return env.Undefined();
2338
2759
  }
2339
- callback = new Nan::Callback(info[1].As<v8::Function>());
2340
- }else if(!info[1]->IsNull()){
2341
- Nan::Utf8String buf(info[1]);
2342
- strsubkey = std::string(*buf);
2343
- is_subkey_set = true;
2760
+ maybeCallback = info[1].As<Napi::Function>();
2761
+ hasCallback = true;
2762
+ }else if(!info[1].IsNull()){
2763
+ strsubkey = info[1].ToString().Utf8Value();
2764
+ is_subkey_set = true;
2344
2765
  }
2345
2766
  }
2767
+
2346
2768
  if(2 < info.Length()){
2347
- if(3 < info.Length() || !info[2]->IsFunction()){
2348
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2349
- return;
2769
+ if(3 < info.Length() || !info[2].IsFunction()){
2770
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2771
+ return env.Undefined();
2350
2772
  }
2351
- callback = new Nan::Callback(info[2].As<v8::Function>());
2773
+ maybeCallback = info[2].As<Napi::Function>();
2774
+ hasCallback = true;
2352
2775
  }
2353
2776
 
2354
- // work
2355
- if(callback){
2356
- Nan::AsyncQueueWorker(new RemoveWorker(callback, &(obj->_k2hshm), strkey.c_str(), (is_subkey_set ? strsubkey.c_str() : NULL), false));
2357
- info.GetReturnValue().Set(Nan::True());
2777
+ // Execute
2778
+ if(hasCallback){
2779
+ RemoveAsyncWorker* worker = new RemoveAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str(), (is_subkey_set ? strsubkey.c_str() : NULL), false);
2780
+ worker->Queue();
2781
+ return Napi::Boolean::New(env, true);
2358
2782
  }else{
2783
+ bool result;
2359
2784
  if(is_subkey_set){
2360
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Remove(strkey.c_str(), strsubkey.c_str())));
2785
+ result = obj->_k2hshm.Remove(strkey.c_str(), strsubkey.c_str());
2361
2786
  }else{
2362
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Remove(strkey.c_str(), false)));
2787
+ result = obj->_k2hshm.Remove(strkey.c_str(), false);
2363
2788
  }
2789
+ return Napi::Boolean::New(env, result);
2364
2790
  }
2365
2791
  }
2366
2792
 
@@ -2383,38 +2809,58 @@ NAN_METHOD(K2hNode::Remove)
2383
2809
  *
2384
2810
  */
2385
2811
 
2386
- NAN_METHOD(K2hNode::RemoveAll)
2812
+ Napi::Value K2hNode::RemoveAll(const Napi::CallbackInfo& info)
2387
2813
  {
2814
+ Napi::Env env = info.Env();
2815
+
2388
2816
  if(info.Length() < 1){
2389
- Nan::ThrowSyntaxError("No key name is specified.");
2390
- return;
2817
+ Napi::TypeError::New(env, "No key name is specified.").ThrowAsJavaScriptException();
2818
+ return env.Undefined();
2391
2819
  }
2392
2820
 
2393
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
2394
- string strkey;
2395
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_REMOVEALL]);
2821
+ // Unwrap
2822
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2823
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2824
+ return env.Undefined();
2825
+ }
2826
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2396
2827
 
2397
- if(info[0]->IsNull()){
2398
- Nan::ThrowSyntaxError("key is empty.");
2399
- return;
2828
+ std::string strkey;
2829
+
2830
+ // initial callback comes from emitter map if set
2831
+ Napi::Function maybeCallback;
2832
+ bool hasCallback = false;
2833
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_REMOVEALL]);
2834
+ if(emitterCbRef){
2835
+ maybeCallback = emitterCbRef->Value();
2836
+ hasCallback = true;
2837
+ }
2838
+
2839
+ // parse positional optional args
2840
+ if(info[0].IsNull()){
2841
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
2842
+ return env.Undefined();
2400
2843
  }else{
2401
- Nan::Utf8String buf(info[0]);
2402
- strkey = std::string(*buf);
2844
+ strkey = info[0].ToString().Utf8Value();
2403
2845
  }
2846
+
2404
2847
  if(1 < info.Length()){
2405
- if(2 < info.Length() || !info[1]->IsFunction()){
2406
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2407
- return;
2848
+ if(2 < info.Length() || !info[1].IsFunction()){
2849
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
2850
+ return env.Undefined();
2408
2851
  }
2409
- callback = new Nan::Callback(info[1].As<v8::Function>());
2852
+ maybeCallback = info[1].As<Napi::Function>();
2853
+ hasCallback = true;
2410
2854
  }
2411
2855
 
2412
- // work
2413
- if(callback){
2414
- Nan::AsyncQueueWorker(new RemoveWorker(callback, &(obj->_k2hshm), strkey.c_str(), NULL, true));
2415
- info.GetReturnValue().Set(Nan::True());
2856
+ // Execute
2857
+ if(hasCallback){
2858
+ RemoveAsyncWorker* worker = new RemoveAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str(), NULL, true);
2859
+ worker->Queue();
2860
+ return Napi::Boolean::New(env, true);
2416
2861
  }else{
2417
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.Remove(strkey.c_str(), true)));
2862
+ bool result = obj->_k2hshm.Remove(strkey.c_str(), true);
2863
+ return Napi::Boolean::New(env, result);
2418
2864
  }
2419
2865
  }
2420
2866
 
@@ -2430,29 +2876,36 @@ NAN_METHOD(K2hNode::RemoveAll)
2430
2876
  * @return return true for success, false for failure
2431
2877
  */
2432
2878
 
2433
- NAN_METHOD(K2hNode::PrintState)
2879
+ Napi::Value K2hNode::PrintState(const Napi::CallbackInfo& info)
2434
2880
  {
2435
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
2881
+ Napi::Env env = info.Env();
2436
2882
 
2437
- if(0 >= info.Length()){
2438
- info.GetReturnValue().Set(Nan::New(
2439
- obj->_k2hshm.PrintState()
2440
- ));
2883
+ // Unwrap
2884
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2885
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2886
+ return env.Undefined();
2887
+ }
2888
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2889
+
2890
+ // Execute
2891
+ if(info.Length() <= 0){
2892
+ bool result = obj->_k2hshm.PrintState();
2893
+ return Napi::Boolean::New(env, result);
2441
2894
  }else{
2442
- int fd = info[0]->IsInt32() ? Nan::To<int32_t>(info[0]).ToChecked() : -1;
2895
+ int fd = info[0].IsNumber() ? info[0].ToNumber().Int32Value() : -1;
2443
2896
  FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
2444
2897
  if(!fp){
2445
- Nan::ThrowError("could not open output stream.");
2446
- return;
2898
+ Napi::Error::New(env, "could not open output stream.").ThrowAsJavaScriptException();
2899
+ return env.Undefined();
2447
2900
  }
2448
2901
  bool result = obj->_k2hshm.PrintState(fp);
2449
2902
 
2450
2903
  // [NOTE]
2451
2904
  // Must flush at here, because nodejs's file descriptor is used for fd.
2452
- // Otherwise, calling flash on nodejs(javascript) is not effected.
2905
+ // Otherwise, calling flush on nodejs(javascript) is not effected.
2453
2906
  fflush(fp);
2454
2907
 
2455
- info.GetReturnValue().Set(result);
2908
+ return Napi::Boolean::New(env, result);
2456
2909
  }
2457
2910
  }
2458
2911
 
@@ -2468,22 +2921,25 @@ NAN_METHOD(K2hNode::PrintState)
2468
2921
  * @return return true for success, false for failure
2469
2922
  */
2470
2923
 
2471
- NAN_METHOD(K2hNode::PrintVersion)
2924
+ Napi::Value K2hNode::PrintVersion(const Napi::CallbackInfo& info)
2472
2925
  {
2473
- int fd = (0 < info.Length() && info[0]->IsInt32()) ? Nan::To<int32_t>(info[0]).ToChecked() : -1;
2474
- FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
2926
+ Napi::Env env = info.Env();
2927
+
2928
+ // Execute
2929
+ int fd = (0 < info.Length() && info[0].IsNumber()) ? info[0].ToNumber().Int32Value() : -1;
2930
+ FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
2475
2931
  if(!fp){
2476
- Nan::ThrowError("could not open output stream.");
2477
- return;
2932
+ Napi::Error::New(env, "could not open output stream.").ThrowAsJavaScriptException();
2933
+ return env.Undefined();
2478
2934
  }
2479
2935
  k2h_print_version(fp);
2480
2936
 
2481
2937
  // [NOTE]
2482
2938
  // Must flush at here, because nodejs's file descriptor is used for fd.
2483
- // Otherwise, calling flash on nodejs(javascript) is not effected.
2939
+ // Otherwise, calling flush on nodejs(javascript) is not effected.
2484
2940
  fflush(fp);
2485
2941
 
2486
- info.GetReturnValue().Set(Nan::True());
2942
+ return Napi::Boolean::New(env, true);
2487
2943
  }
2488
2944
 
2489
2945
  /**
@@ -2498,29 +2954,33 @@ NAN_METHOD(K2hNode::PrintVersion)
2498
2954
  * @return return true for success, false for failure
2499
2955
  */
2500
2956
 
2501
- NAN_METHOD(K2hNode::DumpHead)
2957
+ Napi::Value K2hNode::DumpHead(const Napi::CallbackInfo& info)
2502
2958
  {
2503
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
2959
+ Napi::Env env = info.Env();
2960
+
2961
+ // Unwrap
2962
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
2963
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
2964
+ return env.Undefined();
2965
+ }
2966
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2504
2967
 
2505
- int fd = (0 < info.Length() && info[0]->IsInt32()) ? Nan::To<int32_t>(info[0]).ToChecked() : -1;
2506
- FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
2968
+ // Execute
2969
+ int fd = (0 < info.Length() && info[0].IsNumber()) ? info[0].ToNumber().Int32Value() : -1;
2970
+ FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
2507
2971
  if(!fp){
2508
- Nan::ThrowError("could not open output stream.");
2509
- return;
2972
+ Napi::Error::New(env, "could not open output stream.").ThrowAsJavaScriptException();
2973
+ return env.Undefined();
2510
2974
  }
2511
2975
 
2512
2976
  //SetK2hDbgMode(K2HDBG_MSG);
2513
-
2514
- info.GetReturnValue().Set(Nan::New(
2515
- obj->_k2hshm.Dump(fp, K2HShm::DUMP_HEAD)
2516
- ));
2517
-
2977
+ obj->_k2hshm.Dump(fp, K2HShm::DUMP_HEAD);
2518
2978
  //SetK2hDbgMode(K2HDBG_SILENT);
2519
2979
 
2520
2980
  // Need to flush stream here!
2521
- fflush(fp) ;
2981
+ fflush(fp);
2522
2982
 
2523
- info.GetReturnValue().Set(Nan::True());
2983
+ return Napi::Boolean::New(env, true);
2524
2984
  }
2525
2985
 
2526
2986
  /**
@@ -2535,29 +2995,33 @@ NAN_METHOD(K2hNode::DumpHead)
2535
2995
  * @return return true for success, false for failure
2536
2996
  */
2537
2997
 
2538
- NAN_METHOD(K2hNode::DumpKeytable)
2998
+ Napi::Value K2hNode::DumpKeytable(const Napi::CallbackInfo& info)
2539
2999
  {
2540
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3000
+ Napi::Env env = info.Env();
3001
+
3002
+ // Unwrap
3003
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3004
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3005
+ return env.Undefined();
3006
+ }
3007
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2541
3008
 
2542
- int fd = (0 < info.Length() && info[0]->IsInt32()) ? Nan::To<int32_t>(info[0]).ToChecked() : -1;
2543
- FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
3009
+ // Execute
3010
+ int fd = (0 < info.Length() && info[0].IsNumber()) ? info[0].ToNumber().Int32Value() : -1;
3011
+ FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
2544
3012
  if(!fp){
2545
- Nan::ThrowError("could not open output stream.");
2546
- return;
3013
+ Napi::Error::New(env, "could not open output stream.").ThrowAsJavaScriptException();
3014
+ return env.Undefined();
2547
3015
  }
2548
3016
 
2549
3017
  //SetK2hDbgMode(K2HDBG_MSG);
2550
-
2551
- info.GetReturnValue().Set(Nan::New(
2552
- obj->_k2hshm.Dump(fp, K2HShm::DUMP_KINDEX_ARRAY)
2553
- ));
2554
-
3018
+ obj->_k2hshm.Dump(fp, K2HShm::DUMP_KINDEX_ARRAY);
2555
3019
  //SetK2hDbgMode(K2HDBG_SILENT);
2556
3020
 
2557
3021
  // Need to flush stream here!
2558
- fflush(fp) ;
3022
+ fflush(fp);
2559
3023
 
2560
- info.GetReturnValue().Set(Nan::True());
3024
+ return Napi::Boolean::New(env, true);
2561
3025
  }
2562
3026
 
2563
3027
  /**
@@ -2572,29 +3036,33 @@ NAN_METHOD(K2hNode::DumpKeytable)
2572
3036
  * @return return true for success, false for failure
2573
3037
  */
2574
3038
 
2575
- NAN_METHOD(K2hNode::DumpFullKeytable)
3039
+ Napi::Value K2hNode::DumpFullKeytable(const Napi::CallbackInfo& info)
2576
3040
  {
2577
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3041
+ Napi::Env env = info.Env();
3042
+
3043
+ // Unwrap
3044
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3045
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3046
+ return env.Undefined();
3047
+ }
3048
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2578
3049
 
2579
- int fd = (0 < info.Length() && info[0]->IsInt32()) ? Nan::To<int32_t>(info[0]).ToChecked() : -1;
2580
- FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
3050
+ // Execute
3051
+ int fd = (0 < info.Length() && info[0].IsNumber()) ? info[0].ToNumber().Int32Value() : -1;
3052
+ FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
2581
3053
  if(!fp){
2582
- Nan::ThrowError("could not open output stream.");
2583
- return;
3054
+ Napi::Error::New(env, "could not open output stream.").ThrowAsJavaScriptException();
3055
+ return env.Undefined();
2584
3056
  }
2585
3057
 
2586
3058
  //SetK2hDbgMode(K2HDBG_MSG);
2587
-
2588
- info.GetReturnValue().Set(Nan::New(
2589
- obj->_k2hshm.Dump(fp, K2HShm::DUMP_CKINDEX_ARRAY)
2590
- ));
2591
-
3059
+ obj->_k2hshm.Dump(fp, K2HShm::DUMP_CKINDEX_ARRAY);
2592
3060
  //SetK2hDbgMode(K2HDBG_SILENT);
2593
3061
 
2594
3062
  // Need to flush stream here!
2595
- fflush(fp) ;
3063
+ fflush(fp);
2596
3064
 
2597
- info.GetReturnValue().Set(Nan::True());
3065
+ return Napi::Boolean::New(env, true);
2598
3066
  }
2599
3067
 
2600
3068
  /**
@@ -2609,29 +3077,33 @@ NAN_METHOD(K2hNode::DumpFullKeytable)
2609
3077
  * @return return true for success, false for failure
2610
3078
  */
2611
3079
 
2612
- NAN_METHOD(K2hNode::DumpElementtable)
3080
+ Napi::Value K2hNode::DumpElementtable(const Napi::CallbackInfo& info)
2613
3081
  {
2614
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3082
+ Napi::Env env = info.Env();
3083
+
3084
+ // Unwrap
3085
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3086
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3087
+ return env.Undefined();
3088
+ }
3089
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2615
3090
 
2616
- int fd = (0 < info.Length() && info[0]->IsInt32()) ? Nan::To<int32_t>(info[0]).ToChecked() : -1;
2617
- FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
3091
+ // Execute
3092
+ int fd = (0 < info.Length() && info[0].IsNumber()) ? info[0].ToNumber().Int32Value() : -1;
3093
+ FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
2618
3094
  if(!fp){
2619
- Nan::ThrowError("could not open output stream.");
2620
- return;
3095
+ Napi::Error::New(env, "could not open output stream.").ThrowAsJavaScriptException();
3096
+ return env.Undefined();
2621
3097
  }
2622
3098
 
2623
3099
  //SetK2hDbgMode(K2HDBG_MSG);
2624
-
2625
- info.GetReturnValue().Set(Nan::New(
2626
- obj->_k2hshm.Dump(fp, K2HShm::DUMP_ELEMENT_LIST)
2627
- ));
2628
-
3100
+ obj->_k2hshm.Dump(fp, K2HShm::DUMP_ELEMENT_LIST);
2629
3101
  //SetK2hDbgMode(K2HDBG_SILENT);
2630
3102
 
2631
3103
  // Need to flush stream here!
2632
- fflush(fp) ;
3104
+ fflush(fp);
2633
3105
 
2634
- info.GetReturnValue().Set(Nan::True());
3106
+ return Napi::Boolean::New(env, true);
2635
3107
  }
2636
3108
 
2637
3109
  /**
@@ -2646,29 +3118,33 @@ NAN_METHOD(K2hNode::DumpElementtable)
2646
3118
  * @return return true for success, false for failure
2647
3119
  */
2648
3120
 
2649
- NAN_METHOD(K2hNode::DumpFull)
3121
+ Napi::Value K2hNode::DumpFull(const Napi::CallbackInfo& info)
2650
3122
  {
2651
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3123
+ Napi::Env env = info.Env();
3124
+
3125
+ // Unwrap
3126
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3127
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3128
+ return env.Undefined();
3129
+ }
3130
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2652
3131
 
2653
- int fd = (0 < info.Length() && info[0]->IsInt32()) ? Nan::To<int32_t>(info[0]).ToChecked() : -1;
2654
- FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
3132
+ // Execute
3133
+ int fd = (0 < info.Length() && info[0].IsNumber()) ? info[0].ToNumber().Int32Value() : -1;
3134
+ FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
2655
3135
  if(!fp){
2656
- Nan::ThrowError("could not open output stream.");
2657
- return;
3136
+ Napi::Error::New(env, "could not open output stream.").ThrowAsJavaScriptException();
3137
+ return env.Undefined();
2658
3138
  }
2659
3139
 
2660
3140
  //SetK2hDbgMode(K2HDBG_MSG);
2661
-
2662
- info.GetReturnValue().Set(Nan::New(
2663
- obj->_k2hshm.Dump(fp, K2HShm::DUMP_PAGE_LIST)
2664
- ));
2665
-
3141
+ obj->_k2hshm.Dump(fp, K2HShm::DUMP_PAGE_LIST);
2666
3142
  //SetK2hDbgMode(K2HDBG_SILENT);
2667
3143
 
2668
3144
  // Need to flush stream here!
2669
- fflush(fp) ;
3145
+ fflush(fp);
2670
3146
 
2671
- info.GetReturnValue().Set(Nan::True());
3147
+ return Napi::Boolean::New(env, true);
2672
3148
  }
2673
3149
 
2674
3150
  /**
@@ -2700,49 +3176,63 @@ NAN_METHOD(K2hNode::DumpFull)
2700
3176
  * @return return true for success, false for failure
2701
3177
  */
2702
3178
 
2703
- NAN_METHOD(K2hNode::Transaction)
3179
+ Napi::Value K2hNode::Transaction(const Napi::CallbackInfo& info)
2704
3180
  {
2705
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3181
+ Napi::Env env = info.Env();
2706
3182
 
2707
3183
  if(info.Length() < 1){
2708
- Nan::ThrowSyntaxError("Need to specify first parameter for dis/enable.");
2709
- return;
3184
+ Napi::TypeError::New(env, "Need to specify first parameter for dis/enable.").ThrowAsJavaScriptException();
3185
+ return env.Undefined();
3186
+ }
3187
+
3188
+ // Unwrap
3189
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3190
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3191
+ return env.Undefined();
2710
3192
  }
3193
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2711
3194
 
2712
- bool enable = Nan::To<bool>(info[0]).ToChecked();
3195
+ // parse positional optional args
3196
+ bool enable = info[0].ToBoolean().Value();
3197
+
3198
+ // Execute
2713
3199
  if(enable){
2714
3200
  std::string transfile;
2715
3201
  std::string prefix;
2716
3202
  std::string param;
2717
- int expire = (info.Length() < 5 || !info[4]->IsInt32()) ? 0 : Nan::To<int32_t>(info[4]).ToChecked();
2718
-
2719
- if(2 <= info.Length()){
2720
- Nan::Utf8String buf(info[1]);
2721
- transfile = std::string(*buf);
2722
- }
2723
- if(3 <= info.Length()){
2724
- Nan::Utf8String buf(info[2]);
2725
- prefix = std::string(*buf);
2726
- }
2727
- if(4 <= info.Length()){
2728
- Nan::Utf8String buf(info[3]);
2729
- param = std::string(*buf);
2730
- }
2731
-
2732
- info.GetReturnValue().Set(Nan::New(
2733
- obj->_k2hshm.EnableTransaction(
2734
- (transfile.empty() ? NULL : transfile.c_str()),
2735
- (prefix.empty() ? NULL : reinterpret_cast<const unsigned char*>(prefix.c_str())),
2736
- (prefix.empty() ? 0 : prefix.length()),
2737
- (param.empty() ? NULL : reinterpret_cast<const unsigned char*>(param.c_str())),
2738
- (param.empty() ? 0 : param.length()),
2739
- (0 >= expire ? NULL : reinterpret_cast<const time_t*>(&expire))
2740
- )
2741
- ));
3203
+ int expire = (info.Length() < 5 || !info[4].IsNumber()) ? 0 : info[4].ToNumber().Int32Value();
3204
+
3205
+ if(1 < info.Length()){
3206
+ transfile = info[1].ToString().Utf8Value();
3207
+ }
3208
+ if(2 < info.Length()){
3209
+ prefix = info[2].ToString().Utf8Value();
3210
+ }
3211
+ if(3 < info.Length()){
3212
+ param = info[3].ToString().Utf8Value();
3213
+ }
3214
+
3215
+ // cppcheck-suppress unmatchedSuppression
3216
+ // cppcheck-suppress unreadVariable
3217
+ time_t expire_tt = 0;
3218
+ const time_t* pexpire = NULL;
3219
+ if(0 < expire){
3220
+ expire_tt = static_cast<time_t>(expire);
3221
+ pexpire = &expire_tt;
3222
+ }
3223
+
3224
+ bool res = obj->_k2hshm.EnableTransaction(
3225
+ (transfile.empty() ? NULL : transfile.c_str()),
3226
+ (prefix.empty() ? NULL : reinterpret_cast<const unsigned char*>(prefix.c_str())),
3227
+ (prefix.empty() ? 0 : prefix.length()),
3228
+ (param.empty() ? NULL : reinterpret_cast<const unsigned char*>(param.c_str())),
3229
+ (param.empty() ? 0 : param.length()),
3230
+ (pexpire)
3231
+ );
3232
+ return Napi::Boolean::New(env, res);
2742
3233
  }else{
2743
- info.GetReturnValue().Set(Nan::New(
2744
- obj->_k2hshm.DisableTransaction()
2745
- ));
3234
+ bool res = obj->_k2hshm.DisableTransaction();
3235
+ return Napi::Boolean::New(env, res);
2746
3236
  }
2747
3237
  }
2748
3238
 
@@ -2766,38 +3256,54 @@ NAN_METHOD(K2hNode::Transaction)
2766
3256
  * @return return true for success, false for failure
2767
3257
  */
2768
3258
 
2769
- NAN_METHOD(K2hNode::EnableTransaction)
3259
+ Napi::Value K2hNode::EnableTransaction(const Napi::CallbackInfo& info)
2770
3260
  {
2771
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3261
+ Napi::Env env = info.Env();
2772
3262
 
2773
- std::string transfile;
2774
- std::string prefix;
2775
- std::string param;
2776
- int expire = (info.Length() < 4 || !info[4]->IsInt32()) ? 0 : Nan::To<int32_t>(info[3]).ToChecked();
3263
+ // Unwrap
3264
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3265
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3266
+ return env.Undefined();
3267
+ }
3268
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2777
3269
 
2778
- if(1 <= info.Length()){
2779
- Nan::Utf8String buf(info[0]);
2780
- transfile = std::string(*buf);
3270
+ std::string transfile;
3271
+ std::string prefix;
3272
+ std::string param;
3273
+
3274
+ // cppcheck-suppress unmatchedSuppression
3275
+ // cppcheck-suppress unreadVariable
3276
+ time_t expire_tt = 0;
3277
+ const time_t* pexpire = NULL;
3278
+
3279
+ // parse positional optional args
3280
+ if(0 < info.Length()){
3281
+ transfile = info[0].ToString().Utf8Value();
2781
3282
  }
2782
- if(2 <= info.Length()){
2783
- Nan::Utf8String buf(info[1]);
2784
- prefix = std::string(*buf);
3283
+ if(1 < info.Length()){
3284
+ prefix = info[1].ToString().Utf8Value();
2785
3285
  }
2786
- if(3 <= info.Length()){
2787
- Nan::Utf8String buf(info[2]);
2788
- param = std::string(*buf);
3286
+ if(2 < info.Length()){
3287
+ param = info[2].ToString().Utf8Value();
3288
+ }
3289
+ if(3 < info.Length()&&info[3].IsNumber()){
3290
+ int nexpire = info[3].ToNumber().Int32Value();
3291
+ if(0 < nexpire){
3292
+ expire_tt = static_cast<time_t>(nexpire);
3293
+ pexpire = &expire_tt;
3294
+ }
2789
3295
  }
2790
3296
 
2791
- info.GetReturnValue().Set(Nan::New(
2792
- obj->_k2hshm.EnableTransaction(
2793
- (transfile.empty() ? NULL : transfile.c_str()),
2794
- (prefix.empty() ? NULL : reinterpret_cast<const unsigned char*>(prefix.c_str())),
2795
- (prefix.empty() ? 0 : (prefix.length() + 1)),
2796
- (param.empty() ? NULL : reinterpret_cast<const unsigned char*>(param.c_str())),
2797
- (param.empty() ? 0 : (param.length() + 1)),
2798
- (0 >= expire ? NULL : reinterpret_cast<const time_t*>(&expire))
2799
- )
2800
- ));
3297
+ // Execute
3298
+ bool res = obj->_k2hshm.EnableTransaction(
3299
+ (transfile.empty() ? NULL : transfile.c_str()),
3300
+ (prefix.empty() ? NULL : reinterpret_cast<const unsigned char*>(prefix.c_str())),
3301
+ (prefix.empty() ? 0 : (prefix.length() + 1)),
3302
+ (param.empty() ? NULL : reinterpret_cast<const unsigned char*>(param.c_str())),
3303
+ (param.empty() ? 0 : (param.length() + 1)),
3304
+ pexpire
3305
+ );
3306
+ return Napi::Boolean::New(env, res);
2801
3307
  }
2802
3308
 
2803
3309
  /**
@@ -2808,13 +3314,20 @@ NAN_METHOD(K2hNode::EnableTransaction)
2808
3314
  * @return return true for success, false for failure
2809
3315
  */
2810
3316
 
2811
- NAN_METHOD(K2hNode::DisableTransaction)
3317
+ Napi::Value K2hNode::DisableTransaction(const Napi::CallbackInfo& info)
2812
3318
  {
2813
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3319
+ Napi::Env env = info.Env();
3320
+
3321
+ // Unwrap
3322
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3323
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3324
+ return env.Undefined();
3325
+ }
3326
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2814
3327
 
2815
- info.GetReturnValue().Set(Nan::New(
2816
- obj->_k2hshm.DisableTransaction()
2817
- ));
3328
+ // Execute
3329
+ bool res = obj->_k2hshm.DisableTransaction();
3330
+ return Napi::Boolean::New(env, res);
2818
3331
  }
2819
3332
 
2820
3333
  /**
@@ -2825,13 +3338,20 @@ NAN_METHOD(K2hNode::DisableTransaction)
2825
3338
  * @return return true for success, false for failure
2826
3339
  */
2827
3340
 
2828
- NAN_METHOD(K2hNode::UnsetTransactionThreadPool)
3341
+ Napi::Value K2hNode::UnsetTransactionThreadPool(const Napi::CallbackInfo& info)
2829
3342
  {
2830
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3343
+ Napi::Env env = info.Env();
3344
+
3345
+ // Unwrap
3346
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3347
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3348
+ return env.Undefined();
3349
+ }
3350
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2831
3351
 
2832
- info.GetReturnValue().Set(Nan::New(
2833
- obj->_k2hshm.UnsetTransThreadPool()
2834
- ));
3352
+ // Execute
3353
+ bool res = obj->_k2hshm.UnsetTransThreadPool();
3354
+ return Napi::Boolean::New(env, res);
2835
3355
  }
2836
3356
 
2837
3357
  /**
@@ -2842,13 +3362,20 @@ NAN_METHOD(K2hNode::UnsetTransactionThreadPool)
2842
3362
  * @return Return count of transaction thread pool
2843
3363
  */
2844
3364
 
2845
- NAN_METHOD(K2hNode::GetTransactionThreadPool)
3365
+ Napi::Value K2hNode::GetTransactionThreadPool(const Napi::CallbackInfo& info)
2846
3366
  {
2847
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3367
+ Napi::Env env = info.Env();
3368
+
3369
+ // Unwrap
3370
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3371
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3372
+ return env.Undefined();
3373
+ }
3374
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
2848
3375
 
2849
- info.GetReturnValue().Set(Nan::New(
2850
- obj->_k2hshm.GetTransThreadPool()
2851
- ));
3376
+ // Execute
3377
+ int res = obj->_k2hshm.GetTransThreadPool();
3378
+ return Napi::Number::New(env, res);
2852
3379
  }
2853
3380
 
2854
3381
  /**
@@ -2861,18 +3388,28 @@ NAN_METHOD(K2hNode::GetTransactionThreadPool)
2861
3388
  * @return return true for success, false for failure
2862
3389
  */
2863
3390
 
2864
- NAN_METHOD(K2hNode::SetTransactionThreadPool)
3391
+ Napi::Value K2hNode::SetTransactionThreadPool(const Napi::CallbackInfo& info)
2865
3392
  {
2866
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3393
+ Napi::Env env = info.Env();
2867
3394
 
2868
3395
  if(info.Length() < 1){
2869
- Nan::ThrowSyntaxError("Need to specify first parameter for count of pool.");
2870
- return;
3396
+ Napi::TypeError::New(env, "Need to specify first parameter for count of pool.").ThrowAsJavaScriptException();
3397
+ return env.Undefined();
2871
3398
  }
2872
3399
 
2873
- info.GetReturnValue().Set(Nan::New(
2874
- obj->_k2hshm.SetTransThreadPool(Nan::To<int>(info[0]).ToChecked())
2875
- ));
3400
+ // Unwrap
3401
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3402
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3403
+ return env.Undefined();
3404
+ }
3405
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3406
+
3407
+ // parse positional optional args
3408
+ int count = info[0].ToNumber().Int32Value();
3409
+
3410
+ // Execute
3411
+ bool res = obj->_k2hshm.SetTransThreadPool(count);
3412
+ return Napi::Boolean::New(env, res);
2876
3413
  }
2877
3414
 
2878
3415
  /**
@@ -2898,53 +3435,75 @@ NAN_METHOD(K2hNode::SetTransactionThreadPool)
2898
3435
  *
2899
3436
  */
2900
3437
 
2901
- NAN_METHOD(K2hNode::LoadArchive)
3438
+ Napi::Value K2hNode::LoadArchive(const Napi::CallbackInfo& info)
2902
3439
  {
3440
+ Napi::Env env = info.Env();
3441
+
2903
3442
  if(info.Length() < 1){
2904
- Nan::ThrowSyntaxError("No file name is specified.");
2905
- return;
3443
+ Napi::TypeError::New(env, "No file name is specified.").ThrowAsJavaScriptException();
3444
+ return env.Undefined();
3445
+ }
3446
+
3447
+ // Unwrap
3448
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3449
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3450
+ return env.Undefined();
2906
3451
  }
3452
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3453
+
3454
+ std::string filename;
3455
+ bool errskip = true;
2907
3456
 
2908
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
2909
- string filename;
2910
- bool errskip = true;
2911
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_LOAD]);
3457
+ // initial callback comes from emitter map if set
3458
+ Napi::Function maybeCallback;
3459
+ bool hasCallback = false;
3460
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_LOAD]);
3461
+ if(emitterCbRef){
3462
+ maybeCallback = emitterCbRef->Value();
3463
+ hasCallback = true;
3464
+ }
2912
3465
 
2913
- if(info[0]->IsNull()){
2914
- Nan::ThrowSyntaxError("file name is empty.");
2915
- return;
3466
+ // parse positional optional args
3467
+ if(info[0].IsNull()){
3468
+ Napi::TypeError::New(env, "file name is empty.").ThrowAsJavaScriptException();
3469
+ return env.Undefined();
2916
3470
  }else{
2917
- Nan::Utf8String buf(info[0]);
2918
- filename = std::string(*buf);
3471
+ filename = info[0].ToString().Utf8Value();
2919
3472
  }
3473
+
2920
3474
  if(1 < info.Length()){
2921
- if(info[1]->IsFunction()){
3475
+ if(info[1].IsFunction()){
2922
3476
  if(2 < info.Length()){
2923
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2924
- return;
3477
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
3478
+ return env.Undefined();
2925
3479
  }
2926
- callback = new Nan::Callback(info[1].As<v8::Function>());
2927
- }else if(info[1]->IsBoolean()){
2928
- errskip = Nan::To<bool>(info[1]).ToChecked();
3480
+ maybeCallback = info[1].As<Napi::Function>();
3481
+ hasCallback = true;
3482
+ }else if(info[1].IsBoolean()){
3483
+ errskip = info[1].ToBoolean().Value();
2929
3484
  }else{
2930
- Nan::ThrowSyntaxError("Second parameter must be boolean.");
2931
- return;
3485
+ Napi::TypeError::New(env, "Second parameter must be boolean.").ThrowAsJavaScriptException();
3486
+ return env.Undefined();
2932
3487
  }
2933
3488
  }
3489
+
2934
3490
  if(2 < info.Length()){
2935
- if(3 < info.Length() || !info[2]->IsFunction()){
2936
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2937
- return;
3491
+ if(3 < info.Length() || !info[2].IsFunction()){
3492
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
3493
+ return env.Undefined();
2938
3494
  }
2939
- callback = new Nan::Callback(info[2].As<v8::Function>());
3495
+ maybeCallback = info[2].As<Napi::Function>();
3496
+ hasCallback = true;
2940
3497
  }
2941
3498
 
2942
- // work
2943
- if(callback){
2944
- Nan::AsyncQueueWorker(new ArchiveWorker(callback, &(obj->_k2hshm), filename.c_str(), errskip, true));
2945
- info.GetReturnValue().Set(Nan::True());
3499
+ // Execute
3500
+ if(hasCallback){
3501
+ ArchiveAsyncWorker* worker = new ArchiveAsyncWorker(maybeCallback, &(obj->_k2hshm), filename.c_str(), errskip, true);
3502
+ worker->Queue();
3503
+ return Napi::Boolean::New(env, true);
2946
3504
  }else{
2947
- info.GetReturnValue().Set(Nan::New(k2h_load_archive(reinterpret_cast<k2h_h>(&obj->_k2hshm), filename.c_str(), errskip)));
3505
+ bool res = k2h_load_archive(reinterpret_cast<k2h_h>(&obj->_k2hshm), filename.c_str(), errskip);
3506
+ return Napi::Boolean::New(env, res);
2948
3507
  }
2949
3508
  }
2950
3509
 
@@ -2971,53 +3530,75 @@ NAN_METHOD(K2hNode::LoadArchive)
2971
3530
  *
2972
3531
  */
2973
3532
 
2974
- NAN_METHOD(K2hNode::PutArchive)
3533
+ Napi::Value K2hNode::PutArchive(const Napi::CallbackInfo& info)
2975
3534
  {
3535
+ Napi::Env env = info.Env();
3536
+
2976
3537
  if(info.Length() < 1){
2977
- Nan::ThrowSyntaxError("No file name is specified.");
2978
- return;
3538
+ Napi::TypeError::New(env, "No file name is specified.").ThrowAsJavaScriptException();
3539
+ return env.Undefined();
3540
+ }
3541
+
3542
+ // Unwrap
3543
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3544
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3545
+ return env.Undefined();
2979
3546
  }
3547
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3548
+
3549
+ std::string filename;
3550
+ bool errskip = true;
2980
3551
 
2981
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
2982
- string filename;
2983
- bool errskip = true;
2984
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_PUT]);
3552
+ // initial callback comes from emitter map if set
3553
+ Napi::Function maybeCallback;
3554
+ bool hasCallback = false;
3555
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_PUT]);
3556
+ if(emitterCbRef){
3557
+ maybeCallback = emitterCbRef->Value();
3558
+ hasCallback = true;
3559
+ }
2985
3560
 
2986
- if(info[0]->IsNull()){
2987
- Nan::ThrowSyntaxError("file name is empty.");
2988
- return;
3561
+ // parse positional optional args
3562
+ if(info[0].IsNull()){
3563
+ Napi::TypeError::New(env, "file name is empty.").ThrowAsJavaScriptException();
3564
+ return env.Undefined();
2989
3565
  }else{
2990
- Nan::Utf8String buf(info[0]);
2991
- filename = std::string(*buf);
3566
+ filename = info[0].ToString().Utf8Value();
2992
3567
  }
3568
+
2993
3569
  if(1 < info.Length()){
2994
- if(info[1]->IsFunction()){
3570
+ if(info[1].IsFunction()){
2995
3571
  if(2 < info.Length()){
2996
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
2997
- return;
3572
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
3573
+ return env.Undefined();
2998
3574
  }
2999
- callback = new Nan::Callback(info[1].As<v8::Function>());
3000
- }else if(info[1]->IsBoolean()){
3001
- errskip = Nan::To<bool>(info[1]).ToChecked();
3575
+ maybeCallback = info[1].As<Napi::Function>();
3576
+ hasCallback = true;
3577
+ }else if(info[1].IsBoolean()){
3578
+ errskip = info[1].ToBoolean().Value();
3002
3579
  }else{
3003
- Nan::ThrowSyntaxError("Second parameter must be boolean.");
3004
- return;
3580
+ Napi::TypeError::New(env, "Second parameter must be boolean.").ThrowAsJavaScriptException();
3581
+ return env.Undefined();
3005
3582
  }
3006
3583
  }
3584
+
3007
3585
  if(2 < info.Length()){
3008
- if(3 < info.Length() || !info[2]->IsFunction()){
3009
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
3010
- return;
3586
+ if(3 < info.Length() || !info[2].IsFunction()){
3587
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
3588
+ return env.Undefined();
3011
3589
  }
3012
- callback = new Nan::Callback(info[2].As<v8::Function>());
3590
+ maybeCallback = info[2].As<Napi::Function>();
3591
+ hasCallback = true;
3013
3592
  }
3014
3593
 
3015
- // work
3016
- if(callback){
3017
- Nan::AsyncQueueWorker(new ArchiveWorker(callback, &(obj->_k2hshm), filename.c_str(), errskip, false));
3018
- info.GetReturnValue().Set(Nan::True());
3594
+ // Execute
3595
+ if(hasCallback){
3596
+ ArchiveAsyncWorker* worker = new ArchiveAsyncWorker(maybeCallback, &(obj->_k2hshm), filename.c_str(), errskip, false);
3597
+ worker->Queue();
3598
+ return Napi::Boolean::New(env, true);
3019
3599
  }else{
3020
- info.GetReturnValue().Set(Nan::New(k2h_put_archive(reinterpret_cast<k2h_h>(&obj->_k2hshm), filename.c_str(), errskip)));
3600
+ bool res = k2h_put_archive(reinterpret_cast<k2h_h>(&obj->_k2hshm), filename.c_str(), errskip);
3601
+ return Napi::Boolean::New(env, res);
3021
3602
  }
3022
3603
  }
3023
3604
 
@@ -3038,29 +3619,38 @@ NAN_METHOD(K2hNode::PutArchive)
3038
3619
  * var k2hash = require('bindings')('k2hash') ;
3039
3620
  * var k2h = k2hash() ;
3040
3621
  * k2h.OpenMem() ;
3041
- * var k2hq = k2h.getQueue(false,'++LIFO++') ;
3042
- * k2hq,Push('key','val') ;
3622
+ * var k2hq = k2h.getQueue(false, '++LIFO++') ;
3623
+ * k2hq,Push('key', 'val') ;
3043
3624
  * k2hq.Count() ;
3044
3625
  * k2h.Close() ;
3045
3626
  * @endcode
3046
3627
  */
3047
3628
 
3048
- NAN_METHOD(K2hNode::getQueue)
3629
+ Napi::Value K2hNode::getQueue(const Napi::CallbackInfo& info)
3049
3630
  {
3050
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3631
+ Napi::Env env = info.Env();
3051
3632
 
3052
- K2hQueue::Init();
3053
- Local<Object> retobj = K2hQueue::GetInstance(info);
3054
- K2hQueue* objq = Nan::ObjectWrap::Unwrap<K2hQueue>(retobj->ToObject(Nan::GetCurrentContext()).ToLocalChecked());
3055
- bool is_fifo = info.Length() < 1 ? true : Nan::To<bool>(info[0]).ToChecked();
3056
- std::string prefix;
3633
+ // Unwrap
3634
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3635
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3636
+ return env.Undefined();
3637
+ }
3638
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3639
+
3640
+ // Initialize queue
3641
+ Napi::Object retobj = K2hQueue::GetInstance(info);
3642
+ K2hQueue* objq = Napi::ObjectWrap<K2hQueue>::Unwrap(retobj.As<Napi::Object>());
3643
+
3644
+ // parse positional optional args
3645
+ bool is_fifo = info.Length() < 1 ? true : info[0].ToBoolean().Value();
3646
+ std::string prefix;
3057
3647
  if(2 <= info.Length()){
3058
- Nan::Utf8String buf(info[1]);
3059
- prefix = std::string(*buf);
3648
+ prefix = info[1].ToString().Utf8Value();
3060
3649
  }
3061
- objq->_k2hqueue.Init(&obj->_k2hshm, is_fifo, (prefix.empty() ? NULL : reinterpret_cast<const unsigned char*>(prefix.c_str())), (prefix.empty() ? 0 : (prefix.length() + 1)));
3062
3650
 
3063
- info.GetReturnValue().Set(retobj);
3651
+ // Execute
3652
+ objq->_k2hqueue.Init(&obj->_k2hshm, is_fifo, (prefix.empty() ? NULL : reinterpret_cast<const unsigned char*>(prefix.c_str())), (prefix.empty() ? 0 : (prefix.length() + 1)));
3653
+ return retobj;
3064
3654
  }
3065
3655
 
3066
3656
  /**
@@ -3081,28 +3671,37 @@ NAN_METHOD(K2hNode::getQueue)
3081
3671
  * var k2h = k2hash() ;
3082
3672
  * k2h.OpenMem() ;
3083
3673
  * var k2hkq = k2h.getKeyQueue(false,'++LIFO++') ;
3084
- * k2hkq,Push('key','val') ;
3674
+ * k2hkq,Push('key', 'val') ;
3085
3675
  * k2hkq.Count() ;
3086
3676
  * k2h.Close() ;
3087
3677
  * @endcode
3088
3678
  */
3089
3679
 
3090
- NAN_METHOD(K2hNode::getKeyQueue)
3680
+ Napi::Value K2hNode::getKeyQueue(const Napi::CallbackInfo& info)
3091
3681
  {
3092
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3682
+ Napi::Env env = info.Env();
3093
3683
 
3094
- K2hKeyQueue::Init();
3095
- Local<Object> retobj = K2hKeyQueue::GetInstance(info);
3096
- K2hKeyQueue* objq = Nan::ObjectWrap::Unwrap<K2hKeyQueue>(retobj->ToObject(Nan::GetCurrentContext()).ToLocalChecked());
3097
- bool is_fifo = info.Length() < 1 ? true : Nan::To<bool>(info[0]).ToChecked();
3098
- std::string prefix;
3684
+ // Unwrap
3685
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3686
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3687
+ return env.Undefined();
3688
+ }
3689
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3690
+
3691
+ // Initialize queue
3692
+ Napi::Object retobj = K2hKeyQueue::GetInstance(info);
3693
+ K2hKeyQueue* objq = Napi::ObjectWrap<K2hKeyQueue>::Unwrap(retobj.As<Napi::Object>());
3694
+
3695
+ // parse positional optional args
3696
+ bool is_fifo = info.Length() < 1 ? true : info[0].ToBoolean().Value();
3697
+ std::string prefix;
3099
3698
  if(2 <= info.Length()){
3100
- Nan::Utf8String buf(info[1]);
3101
- prefix = std::string(*buf);
3699
+ prefix = info[1].ToString().Utf8Value();
3102
3700
  }
3103
- objq->_k2hkeyqueue.Init(&obj->_k2hshm, is_fifo, (prefix.empty() ? NULL : reinterpret_cast<const unsigned char*>(prefix.c_str())), (prefix.empty() ? 0 : (prefix.length() + 1)));
3104
3701
 
3105
- info.GetReturnValue().Set(retobj);
3702
+ // Execute
3703
+ objq->_k2hkeyqueue.Init(&obj->_k2hshm, is_fifo, (prefix.empty() ? NULL : reinterpret_cast<const unsigned char*>(prefix.c_str())), (prefix.empty() ? 0 : (prefix.length() + 1)));
3704
+ return retobj;
3106
3705
  }
3107
3706
 
3108
3707
  /**
@@ -3129,38 +3728,75 @@ NAN_METHOD(K2hNode::getKeyQueue)
3129
3728
  * @return return true for success, false for failure
3130
3729
  */
3131
3730
 
3132
- NAN_METHOD(K2hNode::SetCommonAttribute)
3731
+ Napi::Value K2hNode::SetCommonAttribute(const Napi::CallbackInfo& info)
3133
3732
  {
3134
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3733
+ Napi::Env env = info.Env();
3734
+
3735
+ // Unwrap
3736
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3737
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3738
+ return env.Undefined();
3739
+ }
3740
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3741
+
3742
+ // parse positional optional args
3743
+ const bool istrue = true;
3744
+ const bool isfalse = false;
3745
+
3746
+ const bool* pismtime = nullptr;
3747
+ if(0 < info.Length() && info[0].IsNumber()){
3748
+ int32_t val = info[0].ToNumber().Int32Value();
3749
+ if(K2H_VAL_ATTR_ENABLE == val){
3750
+ pismtime = &istrue;
3751
+ }else if(K2H_VAL_ATTR_DISABLE == val){
3752
+ pismtime = &isfalse;
3753
+ }
3754
+ }
3755
+
3756
+ const bool* pishistory = nullptr;
3757
+ if(1 < info.Length() && info[1].IsNumber()){
3758
+ int32_t val = info[1].ToNumber().Int32Value();
3759
+ if(K2H_VAL_ATTR_ENABLE == val){
3760
+ pishistory = &istrue;
3761
+ }else if(K2H_VAL_ATTR_DISABLE == val){
3762
+ pishistory = &isfalse;
3763
+ }
3764
+ }
3135
3765
 
3136
- const bool istrue = true;
3137
- const bool isfalse = false;
3138
- const bool* pismtime = (info.Length() < 1 && !info[0]->IsInt32()) ? NULL :
3139
- K2H_VAL_ATTR_ENABLE == Nan::To<int32_t>(info[0]).ToChecked() ? &istrue :
3140
- K2H_VAL_ATTR_DISABLE == Nan::To<int32_t>(info[0]).ToChecked() ? &isfalse : NULL;
3141
- const bool* pishistory = (info.Length() < 2 && !info[1]->IsInt32()) ? NULL :
3142
- K2H_VAL_ATTR_ENABLE == Nan::To<int32_t>(info[1]).ToChecked() ? &istrue :
3143
- K2H_VAL_ATTR_DISABLE == Nan::To<int32_t>(info[1]).ToChecked() ? &isfalse : NULL;
3144
- const bool* pisencrypt = (info.Length() < 3 && !info[2]->IsInt32()) ? NULL :
3145
- K2H_VAL_ATTR_ENABLE == Nan::To<int32_t>(info[2]).ToChecked() ? &istrue :
3146
- K2H_VAL_ATTR_DISABLE == Nan::To<int32_t>(info[2]).ToChecked() ? &isfalse : NULL;
3147
- bool is_expire = (info.Length() < 5 && !info[4]->IsInt32()) ? false :
3148
- K2H_VAL_ATTR_ENABLE == Nan::To<int32_t>(info[4]).ToChecked() ? true : false;
3766
+ const bool* pisencrypt = nullptr;
3767
+ if(2 < info.Length() && info[2].IsNumber()){
3768
+ int32_t val = info[2].ToNumber().Int32Value();
3769
+ if(K2H_VAL_ATTR_ENABLE == val){
3770
+ pisencrypt = &istrue;
3771
+ }else if(K2H_VAL_ATTR_DISABLE == val){
3772
+ pisencrypt = &isfalse;
3773
+ }
3774
+ }
3149
3775
 
3150
3776
  std::string pass;
3151
- if(4 <= info.Length()){
3152
- Nan::Utf8String buf(info[3]);
3153
- pass = std::string(*buf);
3777
+ if(3 < info.Length() && !info[3].IsUndefined() && !info[3].IsNull()){
3778
+ pass = info[3].ToString().Utf8Value();
3779
+ }
3780
+
3781
+ bool is_expire = false;
3782
+ if(4 < info.Length() && info[4].IsNumber()){
3783
+ int32_t val = info[4].ToNumber().Int32Value();
3784
+ is_expire = (K2H_VAL_ATTR_ENABLE == val);
3154
3785
  }
3155
- time_t expire;
3156
- time_t* pexpire = NULL;
3157
- if(is_expire && 6 <= info.Length() && info[5]->IsNumber()){
3158
- expire = reinterpret_cast<time_t>(info[5]->IntegerValue(Nan::GetCurrentContext()).ToChecked());
3159
- pexpire = &expire;
3786
+
3787
+ // cppcheck-suppress unmatchedSuppression
3788
+ // cppcheck-suppress unreadVariable
3789
+ time_t expire = 0;
3790
+ time_t* pexpire = nullptr;
3791
+ if(is_expire && 5 < info.Length() && info[5].IsNumber()){
3792
+ int64_t val = info[5].ToNumber().Int64Value();
3793
+ expire = static_cast<time_t>(val);
3794
+ pexpire = &expire;
3160
3795
  }
3161
- info.GetReturnValue().Set(Nan::New(
3162
- obj->_k2hshm.SetCommonAttribute(pismtime, pisencrypt, (pass.empty() ? NULL : pass.c_str()), pishistory, pexpire)
3163
- ));
3796
+
3797
+ // Execute
3798
+ bool res = obj->_k2hshm.SetCommonAttribute(pismtime, pisencrypt, (pass.empty() ? NULL : pass.c_str()), pishistory, pexpire);
3799
+ return Napi::Boolean::New(env, res);
3164
3800
  }
3165
3801
 
3166
3802
  /**
@@ -3171,13 +3807,20 @@ NAN_METHOD(K2hNode::SetCommonAttribute)
3171
3807
  * @return return true for success, false for failure
3172
3808
  */
3173
3809
 
3174
- NAN_METHOD(K2hNode::CleanCommonAttribute)
3810
+ Napi::Value K2hNode::CleanCommonAttribute(const Napi::CallbackInfo& info)
3175
3811
  {
3176
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3812
+ Napi::Env env = info.Env();
3813
+
3814
+ // Unwrap
3815
+ if (!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())) {
3816
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3817
+ return env.Undefined();
3818
+ }
3819
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3177
3820
 
3178
- info.GetReturnValue().Set(Nan::New(
3179
- obj->_k2hshm.CleanCommonAttribute()
3180
- ));
3821
+ // Execute
3822
+ bool res = obj->_k2hshm.CleanCommonAttribute();
3823
+ return Napi::Boolean::New(env, res);
3181
3824
  }
3182
3825
 
3183
3826
  /**
@@ -3190,19 +3833,32 @@ NAN_METHOD(K2hNode::CleanCommonAttribute)
3190
3833
  * @return return true for success, false for failure
3191
3834
  */
3192
3835
 
3193
- NAN_METHOD(K2hNode::AddAttrPluginLib)
3836
+ Napi::Value K2hNode::AddAttrPluginLib(const Napi::CallbackInfo& info)
3194
3837
  {
3195
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3838
+ Napi::Env env = info.Env();
3196
3839
 
3197
3840
  if(info.Length() < 1){
3198
- Nan::ThrowSyntaxError("No library file path is specified.");
3199
- return;
3841
+ Napi::TypeError::New(env, "No library file path is specified.").ThrowAsJavaScriptException();
3842
+ return env.Undefined();
3200
3843
  }
3201
- Nan::Utf8String libfile(info[0]);
3202
3844
 
3203
- info.GetReturnValue().Set(Nan::New(
3204
- obj->_k2hshm.AddAttrPluginLib(*libfile)
3205
- ));
3845
+ // Unwrap
3846
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3847
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3848
+ return env.Undefined();
3849
+ }
3850
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3851
+
3852
+ // parse positional optional args
3853
+ if(info[0].IsNull()){
3854
+ Napi::TypeError::New(env, "library file path is empty.").ThrowAsJavaScriptException();
3855
+ return env.Undefined();
3856
+ }
3857
+ std::string libfile = info[0].ToString().Utf8Value();
3858
+
3859
+ // Execute
3860
+ bool res = obj->_k2hshm.AddAttrPluginLib(libfile.c_str());
3861
+ return Napi::Boolean::New(env, res);
3206
3862
  }
3207
3863
 
3208
3864
  /**
@@ -3220,20 +3876,33 @@ NAN_METHOD(K2hNode::AddAttrPluginLib)
3220
3876
  * @return return true for success, false for failure
3221
3877
  */
3222
3878
 
3223
- NAN_METHOD(K2hNode::AddAttrCryptPass)
3879
+ Napi::Value K2hNode::AddAttrCryptPass(const Napi::CallbackInfo& info)
3224
3880
  {
3225
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3881
+ Napi::Env env = info.Env();
3226
3882
 
3227
3883
  if(info.Length() < 1){
3228
- Nan::ThrowSyntaxError("No pass phrase is specified.");
3229
- return;
3884
+ Napi::TypeError::New(env, "No pass phrase is specified.").ThrowAsJavaScriptException();
3885
+ return env.Undefined();
3230
3886
  }
3231
- Nan::Utf8String libfile(info[0]);
3232
- bool is_default_encrypt = (2 <= info.Length() && true == Nan::To<bool>(info[1]).ToChecked());
3233
3887
 
3234
- info.GetReturnValue().Set(Nan::New(
3235
- obj->_k2hshm.AddAttrCryptPass(*libfile, is_default_encrypt)
3236
- ));
3888
+ // Unwrap
3889
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3890
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3891
+ return env.Undefined();
3892
+ }
3893
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3894
+
3895
+ // parse positional optional args
3896
+ if(info[0].IsNull()){
3897
+ Napi::TypeError::New(env, "pass phrase is empty.").ThrowAsJavaScriptException();
3898
+ return env.Undefined();
3899
+ }
3900
+ std::string pass = info[0].ToString().Utf8Value();
3901
+ bool is_default_encrypt = (2 <= info.Length() && info[1].ToBoolean().Value());
3902
+
3903
+ // Execute
3904
+ bool res = obj->_k2hshm.AddAttrCryptPass(pass.c_str(), is_default_encrypt);
3905
+ return Napi::Boolean::New(env, res);
3237
3906
  }
3238
3907
 
3239
3908
  /**
@@ -3246,32 +3915,40 @@ NAN_METHOD(K2hNode::AddAttrCryptPass)
3246
3915
  * @return return true for success, false for failure
3247
3916
  */
3248
3917
 
3249
- NAN_METHOD(K2hNode::GetAttrVersionInfos)
3918
+ Napi::Value K2hNode::GetAttrVersionInfos(const Napi::CallbackInfo& info)
3250
3919
  {
3251
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3920
+ Napi::Env env = info.Env();
3921
+
3922
+ // Unwrap
3923
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3924
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3925
+ return env.Undefined();
3926
+ }
3927
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3252
3928
 
3253
- int fd = (0 < info.Length() && info[0]->IsInt32()) ? Nan::To<int32_t>(info[0]).ToChecked() : -1;
3254
- FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
3929
+ // parse positional optional args
3930
+ int fd = (0 < info.Length() && info[0].IsNumber()) ? info[0].ToNumber().Int32Value() : -1;
3931
+ FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
3255
3932
  if(!fp){
3256
- Nan::ThrowError("could not open output stream.");
3257
- return;
3933
+ Napi::Error::New(env, "could not open output stream.").ThrowAsJavaScriptException();
3934
+ return env.Undefined();
3258
3935
  }
3259
3936
 
3937
+ // Execute
3260
3938
  strarr_t verinfos;
3261
3939
  if(!obj->_k2hshm.GetAttrVersionInfos(verinfos)){
3262
- info.GetReturnValue().Set(Nan::False());
3263
- return;
3940
+ return Napi::Boolean::New(env, false);
3264
3941
  }
3265
3942
 
3266
3943
  fprintf(fp, "K2HASH attribute libraries:");
3267
3944
  for(strarr_t::const_iterator iter = verinfos.begin(); iter != verinfos.end(); ++iter){
3268
- fprintf(fp, " %s\n", iter->c_str());
3945
+ fprintf(fp, " %s\n",iter->c_str());
3269
3946
  }
3270
3947
 
3271
3948
  // Need to flush stream here!
3272
- fflush(fp) ;
3949
+ fflush(fp);
3273
3950
 
3274
- info.GetReturnValue().Set(Nan::True());
3951
+ return Napi::Boolean::New(env, true);
3275
3952
  }
3276
3953
 
3277
3954
  /**
@@ -3284,25 +3961,34 @@ NAN_METHOD(K2hNode::GetAttrVersionInfos)
3284
3961
  * @return return true for success, false for failure
3285
3962
  */
3286
3963
 
3287
- NAN_METHOD(K2hNode::GetAttrInfos)
3964
+ Napi::Value K2hNode::GetAttrInfos(const Napi::CallbackInfo& info)
3288
3965
  {
3289
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3966
+ Napi::Env env = info.Env();
3967
+
3968
+ // Unwrap
3969
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
3970
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
3971
+ return env.Undefined();
3972
+ }
3973
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
3290
3974
 
3291
- int fd = (0 < info.Length() && info[0]->IsInt32()) ? Nan::To<int32_t>(info[0]).ToChecked() : -1;
3292
- FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
3975
+ // parse positional optional args
3976
+ int fd = (0 < info.Length() && info[0].IsNumber()) ? info[0].ToNumber().Int32Value() : -1;
3977
+ FILE* fp = (-1 == fd ? stdout : fdopen(fd, "a"));
3293
3978
  if(!fp){
3294
- Nan::ThrowError("could not open output stream.");
3295
- return;
3979
+ Napi::Error::New(env, "could not open output stream.").ThrowAsJavaScriptException();
3980
+ return env.Undefined();
3296
3981
  }
3297
3982
 
3983
+ // Execute
3298
3984
  std::stringstream ss;
3299
3985
  obj->_k2hshm.GetAttrInfos(ss);
3300
3986
  fprintf(fp, "%s\n", ss.str().c_str());
3301
3987
 
3302
3988
  // Need to flush stream here!
3303
- fflush(fp) ;
3989
+ fflush(fp);
3304
3990
 
3305
- info.GetReturnValue().Set(Nan::True());
3991
+ return Napi::Boolean::New(env, true);
3306
3992
  }
3307
3993
 
3308
3994
  /**
@@ -3324,53 +4010,70 @@ NAN_METHOD(K2hNode::GetAttrInfos)
3324
4010
  *
3325
4011
  */
3326
4012
 
3327
- NAN_METHOD(K2hNode::GetAttrs)
4013
+ Napi::Value K2hNode::GetAttrs(const Napi::CallbackInfo& info)
3328
4014
  {
4015
+ Napi::Env env = info.Env();
4016
+
3329
4017
  if(info.Length() < 1){
3330
- Nan::ThrowSyntaxError("No key name is specified.");
3331
- return;
4018
+ Napi::TypeError::New(env, "No key name is specified.").ThrowAsJavaScriptException();
4019
+ return env.Undefined();
3332
4020
  }
3333
4021
 
3334
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3335
- string strkey;
3336
- Nan::Callback* callback= obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_GETATTRS]);
4022
+ // Unwrap
4023
+ if(!info.This().IsObject()||!info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
4024
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
4025
+ return env.Undefined();
4026
+ }
4027
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
4028
+
4029
+ std::string strkey;
3337
4030
 
3338
- if(info[0]->IsNull()){
3339
- Nan::ThrowSyntaxError("key is empty.");
3340
- return;
4031
+ // initial callback comes from emitter map if set
4032
+ Napi::Function maybeCallback;
4033
+ bool hasCallback = false;
4034
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_GETATTRS]);
4035
+ if(emitterCbRef){
4036
+ maybeCallback = emitterCbRef->Value();
4037
+ hasCallback = true;
4038
+ }
4039
+
4040
+ // parse positional optional args
4041
+ if(info[0].IsNull()){
4042
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
4043
+ return env.Undefined();
3341
4044
  }else{
3342
- Nan::Utf8String buf(info[0]);
3343
- strkey = std::string(*buf);
4045
+ strkey = info[0].ToString().Utf8Value();
3344
4046
  }
4047
+
3345
4048
  if(1 < info.Length()){
3346
- if(2 < info.Length() || !info[1]->IsFunction()){
3347
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
3348
- return;
4049
+ if(2 < info.Length() || !info[1].IsFunction()){
4050
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
4051
+ return env.Undefined();
3349
4052
  }
3350
- callback = new Nan::Callback(info[1].As<v8::Function>());
4053
+ maybeCallback = info[1].As<Napi::Function>();
4054
+ hasCallback = true;
3351
4055
  }
3352
4056
 
3353
- // work
3354
- if(callback){
3355
- Nan::AsyncQueueWorker(new GetAttrsWorker(callback, &(obj->_k2hshm), strkey.c_str()));
3356
- info.GetReturnValue().Set(Nan::True());
4057
+ // Execute
4058
+ if(hasCallback){
4059
+ GetAttrsAsyncWorker* worker = new GetAttrsAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str());
4060
+ worker->Queue();
4061
+ return Napi::Boolean::New(env, true);
3357
4062
  }else{
3358
- K2HAttrs* attrs = obj->_k2hshm.GetAttrs(strkey.c_str());
4063
+ K2HAttrs* attrs = obj->_k2hshm.GetAttrs(strkey.c_str());
3359
4064
  if(!attrs){
3360
- info.GetReturnValue().Set(Nan::Null());
3361
- return;
4065
+ return env.Null();
3362
4066
  }
3363
- Local<Array> retarr = Nan::New<Array>();
3364
- int pos = 0;
3365
- for(K2HAttrs::iterator iter = attrs->begin(); iter != attrs->end(); ++iter, ++pos){
4067
+ Napi::Array retarr = Napi::Array::New(env);
4068
+ uint32_t pos = 0;
4069
+ for(K2HAttrs::iterator iter = attrs->begin(); iter != attrs->end(); ++iter){
3366
4070
  if(0UL == iter->keylength || !iter->pkey){
3367
4071
  continue;
3368
4072
  }
3369
- Nan::Set(retarr, pos, Nan::New<String>(reinterpret_cast<const char*>(iter->pkey)).ToLocalChecked());
4073
+ retarr.Set(pos++, Napi::String::New(env, reinterpret_cast<const char*>(iter->pkey), static_cast<size_t>(strlen(reinterpret_cast<const char*>(iter->pkey)))));
3370
4074
  }
3371
4075
  delete attrs;
3372
-
3373
- info.GetReturnValue().Set(retarr);
4076
+ return retarr;
3374
4077
  }
3375
4078
  }
3376
4079
 
@@ -3395,51 +4098,69 @@ NAN_METHOD(K2hNode::GetAttrs)
3395
4098
  *
3396
4099
  */
3397
4100
 
3398
- NAN_METHOD(K2hNode::GetAttrValue)
4101
+ Napi::Value K2hNode::GetAttrValue(const Napi::CallbackInfo& info)
3399
4102
  {
4103
+ Napi::Env env = info.Env();
4104
+
3400
4105
  if(info.Length() < 2){
3401
- Nan::ThrowSyntaxError("No key name or no attribute name are specified.");
3402
- return;
4106
+ Napi::TypeError::New(env, "No key name or no attribute name are specified.").ThrowAsJavaScriptException();
4107
+ return env.Undefined();
3403
4108
  }
3404
4109
 
3405
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3406
- string strkey;
3407
- string strattr;
3408
- Nan::Callback* callback= obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_GETATTRVAL]);
4110
+ // Unwrap
4111
+ if(!info.This().IsObject() || !info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
4112
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
4113
+ return env.Undefined();
4114
+ }
4115
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
4116
+
4117
+ std::string strkey;
4118
+ std::string strattr;
3409
4119
 
3410
- if(info[0]->IsNull()){
3411
- Nan::ThrowSyntaxError("key is empty.");
3412
- return;
4120
+ // initial callback comes from emitter map if set
4121
+ Napi::Function maybeCallback;
4122
+ bool hasCallback = false;
4123
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_GETATTRVAL]);
4124
+ if(emitterCbRef){
4125
+ maybeCallback = emitterCbRef->Value();
4126
+ hasCallback = true;
4127
+ }
4128
+
4129
+ // parse positional optional args
4130
+ if(info[0].IsNull()){
4131
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
4132
+ return env.Undefined();
3413
4133
  }else{
3414
- Nan::Utf8String buf(info[0]);
3415
- strkey = std::string(*buf);
4134
+ strkey = info[0].ToString().Utf8Value();
3416
4135
  }
3417
- if(info[1]->IsNull()){
3418
- Nan::ThrowSyntaxError("attr key is empty.");
3419
- return;
4136
+
4137
+ if(info[1].IsNull()){
4138
+ Napi::TypeError::New(env, "attr key is empty.").ThrowAsJavaScriptException();
4139
+ return env.Undefined();
3420
4140
  }else{
3421
- Nan::Utf8String buf(info[1]);
3422
- strattr = std::string(*buf);
4141
+ strattr = info[1].ToString().Utf8Value();
3423
4142
  }
4143
+
3424
4144
  if(2 < info.Length()){
3425
- if(3 < info.Length() || !info[2]->IsFunction()){
3426
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
3427
- return;
4145
+ if(3 < info.Length() || !info[2].IsFunction()){
4146
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
4147
+ return env.Undefined();
3428
4148
  }
3429
- callback = new Nan::Callback(info[2].As<v8::Function>());
4149
+ maybeCallback = info[2].As<Napi::Function>();
4150
+ hasCallback = true;
3430
4151
  }
3431
4152
 
3432
- // work
3433
- if(callback){
3434
- Nan::AsyncQueueWorker(new GetAttrValueWorker(callback, &(obj->_k2hshm), strkey.c_str(), strattr.c_str()));
3435
- info.GetReturnValue().Set(Nan::True());
4153
+ // Execute
4154
+ if(hasCallback){
4155
+ GetAttrValueAsyncWorker* worker = new GetAttrValueAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str(), strattr.c_str());
4156
+ worker->Queue();
4157
+ return Napi::Boolean::New(env, true);
3436
4158
  }else{
3437
4159
  K2HAttrs* attrs = obj->_k2hshm.GetAttrs(strkey.c_str());
3438
4160
  if(!attrs){
3439
- info.GetReturnValue().Set(Nan::Null());
3440
- return;
4161
+ return env.Null();
3441
4162
  }
3442
- bool is_found = false;
4163
+
3443
4164
  for(K2HAttrs::iterator iter = attrs->begin(); iter != attrs->end(); ++iter){
3444
4165
  if(0UL == iter->keylength || !iter->pkey){
3445
4166
  continue;
@@ -3450,19 +4171,18 @@ NAN_METHOD(K2hNode::GetAttrValue)
3450
4171
  if(0 == memcmp(iter->pkey, strattr.c_str(), iter->keylength)){
3451
4172
  // found
3452
4173
  if(0 < iter->vallength && iter->pval){
3453
- info.GetReturnValue().Set(Nan::New<String>(reinterpret_cast<const char*>(iter->pval)).ToLocalChecked());
4174
+ Napi::Value val = Napi::String::New(env, reinterpret_cast<const char*>(iter->pval), static_cast<size_t>(strlen(reinterpret_cast<const char*>(iter->pval))));
4175
+ delete attrs;
4176
+ return val;
3454
4177
  }else{
3455
- info.GetReturnValue().Set(Nan::Null());
4178
+ delete attrs;
4179
+ return env.Null();
3456
4180
  }
3457
- is_found = true;
3458
- break;
4181
+ break; // not effort
3459
4182
  }
3460
4183
  }
3461
4184
  delete attrs;
3462
- if(!is_found){
3463
- // not found
3464
- info.GetReturnValue().Set(Nan::Null());
3465
- }
4185
+ return env.Null();
3466
4186
  }
3467
4187
  }
3468
4188
 
@@ -3488,61 +4208,83 @@ NAN_METHOD(K2hNode::GetAttrValue)
3488
4208
  *
3489
4209
  */
3490
4210
 
3491
- NAN_METHOD(K2hNode::AddAttr)
4211
+ Napi::Value K2hNode::AddAttr(const Napi::CallbackInfo& info)
3492
4212
  {
3493
- if(info.Length() < 3){
3494
- Nan::ThrowSyntaxError("No key name or no attribute name/value are specified.");
3495
- return;
4213
+ Napi::Env env = info.Env();
4214
+
4215
+ if(info.Length() < 2){
4216
+ Napi::TypeError::New(env, "No key name or no attribute name/value are specified.").ThrowAsJavaScriptException();
4217
+ return env.Undefined();
4218
+ }
4219
+
4220
+ // Unwrap
4221
+ if(!info.This().IsObject()||!info.This().As<Napi::Object>().InstanceOf(K2hNode::constructor.Value())){
4222
+ Napi::TypeError::New(env, "Invalid this object(K2hNode instance)").ThrowAsJavaScriptException();
4223
+ return env.Undefined();
3496
4224
  }
4225
+ K2hNode* obj = Napi::ObjectWrap<K2hNode>::Unwrap(info.This().As<Napi::Object>());
4226
+
4227
+ std::string strkey;
4228
+ std::string strattr;
4229
+ bool is_val_set = false;
4230
+ std::string strval;
4231
+
3497
4232
 
3498
- K2hNode* obj = Nan::ObjectWrap::Unwrap<K2hNode>(info.This());
3499
- string strkey;
3500
- string strattr;
3501
- bool is_val_set = false;
3502
- string strval;
3503
- Nan::Callback* callback = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_ADDATTR]);
4233
+ // initial callback comes from emitter map if set
4234
+ Napi::Function maybeCallback;
4235
+ bool hasCallback = false;
4236
+ Napi::FunctionReference* emitterCbRef = obj->_cbs.Find(stc_k2h_emitters[K2H_EMITTER_POS_ADDATTR]);
4237
+ if(emitterCbRef){
4238
+ maybeCallback = emitterCbRef->Value();
4239
+ hasCallback = true;
4240
+ }
3504
4241
 
3505
- if(info[0]->IsNull()){
3506
- Nan::ThrowSyntaxError("key is empty.");
3507
- return;
4242
+ // parse positional optional args
4243
+ if(info[0].IsNull()){
4244
+ Napi::TypeError::New(env, "key is empty.").ThrowAsJavaScriptException();
4245
+ return env.Undefined();
3508
4246
  }else{
3509
- Nan::Utf8String buf(info[0]);
3510
- strkey = std::string(*buf);
4247
+ strkey = info[0].ToString().Utf8Value();
3511
4248
  }
3512
- if(info[1]->IsNull()){
3513
- Nan::ThrowSyntaxError("attribute name is empty.");
3514
- return;
4249
+
4250
+ if(info[1].IsNull()){
4251
+ Napi::TypeError::New(env, "attribute name is empty.").ThrowAsJavaScriptException();
4252
+ return env.Undefined();
3515
4253
  }else{
3516
- Nan::Utf8String buf(info[1]);
3517
- strattr = std::string(*buf);
4254
+ strattr = info[1].ToString().Utf8Value();
3518
4255
  }
4256
+
3519
4257
  if(2 < info.Length()){
3520
- if(info[2]->IsFunction()){
4258
+ if(info[2].IsFunction()){
3521
4259
  if(3 < info.Length()){
3522
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
3523
- return;
4260
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
4261
+ return env.Undefined();
3524
4262
  }
3525
- callback = new Nan::Callback(info[2].As<v8::Function>());
3526
- }else if(!info[2]->IsNull()){
3527
- Nan::Utf8String buf(info[2]);
3528
- strval = std::string(*buf);
3529
- is_val_set = true;
4263
+ maybeCallback = info[2].As<Napi::Function>();
4264
+ hasCallback = true;
4265
+ }else if(!info[2].IsNull()){
4266
+ strval = info[2].ToString().Utf8Value();
4267
+ is_val_set = true;
3530
4268
  }
3531
4269
  }
4270
+
3532
4271
  if(3 < info.Length()){
3533
- if(4 < info.Length() || !info[3]->IsFunction()){
3534
- Nan::ThrowSyntaxError("Last parameter is not callback function.");
3535
- return;
4272
+ if(4 < info.Length() || !info[3].IsFunction()){
4273
+ Napi::TypeError::New(env, "Last parameter is not callback function.").ThrowAsJavaScriptException();
4274
+ return env.Undefined();
3536
4275
  }
3537
- callback = new Nan::Callback(info[3].As<v8::Function>());
4276
+ maybeCallback = info[3].As<Napi::Function>();
4277
+ hasCallback = true;
3538
4278
  }
3539
4279
 
3540
- // work
3541
- if(callback){
3542
- Nan::AsyncQueueWorker(new AddAttrWorker(callback, &(obj->_k2hshm), strkey.c_str(), strattr.c_str(), (is_val_set ? strval.c_str() : NULL)));
3543
- info.GetReturnValue().Set(Nan::True());
4280
+ // Execute
4281
+ if(hasCallback){
4282
+ AddAttrAsyncWorker* worker = new AddAttrAsyncWorker(maybeCallback, &(obj->_k2hshm), strkey.c_str(), strattr.c_str(), (is_val_set ? strval.c_str() : NULL));
4283
+ worker->Queue();
4284
+ return Napi::Boolean::New(env, true);
3544
4285
  }else{
3545
- info.GetReturnValue().Set(Nan::New(obj->_k2hshm.AddAttr(strkey.c_str(), strattr.c_str(), (is_val_set ? strval.c_str() : NULL))));
4286
+ bool res = obj->_k2hshm.AddAttr(strkey.c_str(), strattr.c_str(), (is_val_set ? strval.c_str() : NULL));
4287
+ return Napi::Boolean::New(env, res);
3546
4288
  }
3547
4289
  }
3548
4290