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.
@@ -35,63 +35,75 @@
35
35
  // Callback function: function(string error)
36
36
  //
37
37
  //---------------------------------------------------------
38
- class CreateWorker : public Nan::AsyncWorker
38
+ class CreateAsyncWorker : public Napi::AsyncWorker
39
39
  {
40
40
  public:
41
- CreateWorker(Nan::Callback* callback, K2HShm* pobj, const char* k2hfile, bool fullmapping, int mask, int cmask, int element_cnt, size_t page) :
42
- Nan::AsyncWorker(callback), pk2hobj(pobj),
43
- strfile(k2hfile ? k2hfile : ""), isfullmapping(fullmapping), mask_bitcnt(mask), cmask_bitcnt(cmask), max_element_cnt(element_cnt), pagesize(page)
44
- {}
45
- ~CreateWorker() {}
41
+ CreateAsyncWorker(const Napi::Function& callback, K2HShm* k2hshm, const std::string& filename, bool isfullmapping, int mask_bitcnt, int cmask_bitcnt, int max_element_cnt, size_t pagesize) :
42
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(k2hshm),
43
+ _filename(filename), _isfullmapping(isfullmapping), _mask_bitcnt(mask_bitcnt), _cmask_bitcnt(cmask_bitcnt), _max_element_cnt(max_element_cnt), _pagesize(pagesize), _result(false)
44
+ {
45
+ _callbackRef.Ref();
46
+ }
47
+
48
+ ~CreateAsyncWorker() override
49
+ {
50
+ if(_callbackRef){
51
+ _callbackRef.Unref();
52
+ _callbackRef.Reset();
53
+ }
54
+ }
46
55
 
47
- void Execute()
56
+ // Run on worker thread
57
+ void Execute() override
48
58
  {
49
- if(!pk2hobj){
50
- Nan::ReferenceError("No object is associated to async worker");
59
+ if(!_k2hshm){
60
+ SetError("No object is associated to async worker");
51
61
  return;
52
62
  }
53
- if(!pk2hobj->Create(strfile.c_str(), isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize)){
54
- // set error
55
- this->SetErrorMessage("Failed to initialize k2hash object.");
63
+ if(!_k2hshm->Create(_filename.c_str(), _isfullmapping, _mask_bitcnt, _cmask_bitcnt, _max_element_cnt, _pagesize)){
64
+ SetError(std::string("Failed to create K2HASH file: ") + _filename); // call SetError method in Napi::AsyncWorker
65
+ return;
56
66
  }
67
+ _result = true;
57
68
  }
58
69
 
59
- void HandleOKCallback()
70
+ // handler for success
71
+ void OnOK() override
60
72
  {
61
- Nan::HandleScope scope;
62
- const int argc = 1;
63
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
73
+ Napi::Env env = Env();
74
+ Napi::HandleScope scope(env);
64
75
 
65
- if(callback){
66
- callback->Call(argc, argv);
67
- }else{
68
- Nan::ThrowSyntaxError("Internal error in async worker");
69
- return;
76
+ // The first argument is null and the second argument is the result.
77
+ if(!_callbackRef.IsEmpty()){
78
+ _callbackRef.Value().Call({ env.Null(), Napi::Boolean::New(env, _result) });
70
79
  }
71
80
  }
72
81
 
73
- void HandleErrorCallback()
74
- {
75
- Nan::HandleScope scope;
76
- const int argc = 1;
77
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
82
+ // handler for failure (by calling SetError)
83
+ void OnError(const Napi::Error& err) override
84
+ {
85
+ Napi::Env env = Env();
86
+ Napi::HandleScope scope(env);
78
87
 
79
- if(callback){
80
- callback->Call(argc, argv);
88
+ // The first argument is the error message.
89
+ if(!_callbackRef.IsEmpty()){
90
+ _callbackRef.Value().Call({ err.Value() });
81
91
  }else{
82
- Nan::ThrowSyntaxError("Internal error in async worker");
83
- return;
92
+ // Throw error
93
+ err.ThrowAsJavaScriptException();
84
94
  }
85
- }
95
+ }
86
96
 
87
97
  private:
88
- K2HShm* pk2hobj;
89
- std::string strfile;
90
- bool isfullmapping;
91
- int mask_bitcnt;
92
- int cmask_bitcnt;
93
- int max_element_cnt;
94
- size_t pagesize;
98
+ Napi::FunctionReference _callbackRef;
99
+ K2HShm* _k2hshm;
100
+ std::string _filename;
101
+ bool _isfullmapping;
102
+ int _mask_bitcnt;
103
+ int _cmask_bitcnt;
104
+ int _max_element_cnt;
105
+ size_t _pagesize;
106
+ bool _result;
95
107
  };
96
108
 
97
109
  //---------------------------------------------------------
@@ -101,66 +113,78 @@ class CreateWorker : public Nan::AsyncWorker
101
113
  // Callback function: function(string error)
102
114
  //
103
115
  //---------------------------------------------------------
104
- class OpenWorker : public Nan::AsyncWorker
116
+ class OpenAsyncWorker : public Napi::AsyncWorker
105
117
  {
106
118
  public:
107
- OpenWorker(Nan::Callback* callback, K2HShm* pobj, const char* k2hfile, bool readonly, bool create, bool tempfilemode, bool fullmapping, int mask, int cmask, int element_cnt, size_t page) :
108
- Nan::AsyncWorker(callback), pk2hobj(pobj),
109
- strfile(k2hfile ? k2hfile : ""), isReadOnly(readonly), isCreate(create), isTempFile(tempfilemode), isfullmapping(fullmapping), mask_bitcnt(mask), cmask_bitcnt(cmask), max_element_cnt(element_cnt), pagesize(page)
110
- {}
111
- ~OpenWorker() {}
119
+ OpenAsyncWorker(const Napi::Function& callback, K2HShm* k2hshm, const std::string& filename, bool isReadOnly, bool isCreate, bool isTempFile, bool isfullmapping, int mask_bitcnt, int cmask_bitcnt, int max_element_cnt, size_t pagesize) :
120
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(k2hshm),
121
+ _filename(filename), _isReadOnly(isReadOnly), _isCreate(isCreate), _isTempFile(isTempFile), _isfullmapping(isfullmapping), _mask_bitcnt(mask_bitcnt), _cmask_bitcnt(cmask_bitcnt), _max_element_cnt(max_element_cnt), _pagesize(pagesize), _result(false)
122
+ {
123
+ _callbackRef.Ref();
124
+ }
112
125
 
113
- void Execute()
126
+ ~OpenAsyncWorker() override
114
127
  {
115
- if(!pk2hobj){
116
- Nan::ReferenceError("No object is associated to async worker");
128
+ if(_callbackRef){
129
+ _callbackRef.Unref();
130
+ _callbackRef.Reset();
131
+ }
132
+ }
133
+
134
+ // Run on worker thread
135
+ void Execute() override
136
+ {
137
+ if(!_k2hshm){
138
+ SetError("No object is associated to async worker");
117
139
  return;
118
140
  }
119
- if(!pk2hobj->Attach(strfile.c_str(), isReadOnly, isCreate, isTempFile, isfullmapping, mask_bitcnt, cmask_bitcnt, max_element_cnt, pagesize)){
120
- // set error
121
- this->SetErrorMessage("Failed to attach(open) k2hash object.");
141
+ if(!_k2hshm->Attach(_filename.c_str(), _isReadOnly, _isCreate, _isTempFile, _isfullmapping, _mask_bitcnt, _cmask_bitcnt, _max_element_cnt, _pagesize)){
142
+ SetError(std::string("Failed to attach(open) k2hash object.")); // call SetError method in Napi::AsyncWorker
143
+ return;
122
144
  }
145
+ _result = true;
123
146
  }
124
147
 
125
- void HandleOKCallback()
148
+ // handler for success
149
+ void OnOK() override
126
150
  {
127
- Nan::HandleScope scope;
128
- const int argc = 1;
129
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
151
+ Napi::Env env = Env();
152
+ Napi::HandleScope scope(env);
130
153
 
131
- if(callback){
132
- callback->Call(argc, argv);
133
- }else{
134
- Nan::ThrowSyntaxError("Internal error in async worker");
135
- return;
154
+ // The first argument is null and the second argument is the result.
155
+ if(!_callbackRef.IsEmpty()){
156
+ _callbackRef.Value().Call({ env.Null(), Napi::Boolean::New(env, _result) });
136
157
  }
137
158
  }
138
159
 
139
- void HandleErrorCallback()
140
- {
141
- Nan::HandleScope scope;
142
- const int argc = 1;
143
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
160
+ // handler for failure (by calling SetError)
161
+ void OnError(const Napi::Error& err) override
162
+ {
163
+ Napi::Env env = Env();
164
+ Napi::HandleScope scope(env);
144
165
 
145
- if(callback){
146
- callback->Call(argc, argv);
166
+ // The first argument is the error message.
167
+ if(!_callbackRef.IsEmpty()){
168
+ _callbackRef.Value().Call({ err.Value() });
147
169
  }else{
148
- Nan::ThrowSyntaxError("Internal error in async worker");
149
- return;
170
+ // Throw error
171
+ err.ThrowAsJavaScriptException();
150
172
  }
151
- }
173
+ }
152
174
 
153
175
  private:
154
- K2HShm* pk2hobj;
155
- std::string strfile;
156
- bool isReadOnly;
157
- bool isCreate;
158
- bool isTempFile;
159
- bool isfullmapping;
160
- int mask_bitcnt;
161
- int cmask_bitcnt;
162
- int max_element_cnt;
163
- size_t pagesize;
176
+ Napi::FunctionReference _callbackRef;
177
+ K2HShm* _k2hshm;
178
+ std::string _filename;
179
+ bool _isReadOnly;
180
+ bool _isCreate;
181
+ bool _isTempFile;
182
+ bool _isfullmapping;
183
+ int _mask_bitcnt;
184
+ int _cmask_bitcnt;
185
+ int _max_element_cnt;
186
+ size_t _pagesize;
187
+ bool _result;
164
188
  };
165
189
 
166
190
  //---------------------------------------------------------
@@ -170,54 +194,65 @@ class OpenWorker : public Nan::AsyncWorker
170
194
  // Callback function: function(string error)
171
195
  //
172
196
  //---------------------------------------------------------
173
- class CloseWorker : public Nan::AsyncWorker
197
+ class CloseAsyncWorker : public Napi::AsyncWorker
174
198
  {
175
199
  public:
176
- CloseWorker(Nan::Callback* callback, K2HShm* pobj) : Nan::AsyncWorker(callback), pk2hobj(pobj) {}
177
- ~CloseWorker() {}
200
+ CloseAsyncWorker(const Napi::Function& callback, K2HShm* k2hshm) : Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(k2hshm)
201
+ {
202
+ _callbackRef.Ref();
203
+ }
204
+
205
+ ~CloseAsyncWorker() override
206
+ {
207
+ if(_callbackRef){
208
+ _callbackRef.Unref();
209
+ _callbackRef.Reset();
210
+ }
211
+ }
178
212
 
179
- void Execute()
213
+ // Run on worker thread
214
+ void Execute() override
180
215
  {
181
- if(!pk2hobj){
182
- Nan::ReferenceError("No object is associated to async worker");
216
+ if(!_k2hshm){
217
+ SetError("No object is associated to async worker");
183
218
  return;
184
219
  }
185
- if(!pk2hobj->Detach()){
186
- // set error
187
- this->SetErrorMessage("Failed to close k2hash object.");
220
+ if(!_k2hshm->Detach()){
221
+ SetError(std::string("Failed to close k2hash object.")); // call SetError method in Napi::AsyncWorker
222
+ return;
188
223
  }
189
224
  }
190
225
 
191
- void HandleOKCallback()
226
+ // handler for success
227
+ void OnOK() override
192
228
  {
193
- Nan::HandleScope scope;
194
- const int argc = 1;
195
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
229
+ Napi::Env env = Env();
230
+ Napi::HandleScope scope(env);
196
231
 
197
- if(callback){
198
- callback->Call(argc, argv);
199
- }else{
200
- Nan::ThrowSyntaxError("Internal error in async worker");
201
- return;
232
+ // The first argument is null and the second argument is the result.
233
+ if(!_callbackRef.IsEmpty()){
234
+ _callbackRef.Value().Call({ env.Null(), Napi::Boolean::New(env, true) });
202
235
  }
203
236
  }
204
237
 
205
- void HandleErrorCallback()
206
- {
207
- Nan::HandleScope scope;
208
- const int argc = 1;
209
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
238
+ // handler for failure (by calling SetError)
239
+ void OnError(const Napi::Error& err) override
240
+ {
241
+ Napi::Env env = Env();
242
+ Napi::HandleScope scope(env);
210
243
 
211
- if(callback){
212
- callback->Call(argc, argv);
244
+ // The first argument is the error message.
245
+ if(!_callbackRef.IsEmpty()){
246
+ _callbackRef.Value().Call({ err.Value() });
213
247
  }else{
214
- Nan::ThrowSyntaxError("Internal error in async worker");
215
- return;
248
+ // Throw error
249
+ err.ThrowAsJavaScriptException();
216
250
  }
217
- }
251
+ }
218
252
 
219
253
  private:
220
- K2HShm* pk2hobj;
254
+ Napi::FunctionReference _callbackRef;
255
+ K2HShm* _k2hshm;
221
256
  };
222
257
 
223
258
  //---------------------------------------------------------
@@ -227,43 +262,47 @@ class CloseWorker : public Nan::AsyncWorker
227
262
  // Callback function: function(string error[, string value])
228
263
  //
229
264
  //---------------------------------------------------------
230
- class GetValueWorker : public Nan::AsyncWorker
265
+ class GetValueAsyncWorker : public Napi::AsyncWorker
231
266
  {
232
267
  public:
233
- GetValueWorker(Nan::Callback* callback, K2HShm* pobj, const char* pkey, const char* psubkey, bool attrchk, const char* ppass) :
234
- Nan::AsyncWorker(callback), pk2hobj(pobj),
235
- is_key_set(false), strkey(pkey ? pkey : ""), is_skey_set(false), strsubkey(psubkey ? psubkey : ""), is_attr_check(attrchk), is_pass_set(false), strpass(ppass ? ppass : ""), presult(NULL)
268
+ GetValueAsyncWorker(const Napi::Function& callback, K2HShm* k2hshm, const char* pkey, const char* psubkey, bool attrchk, const char* ppass) :
269
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(k2hshm),
270
+ _is_key_set(pkey != nullptr), _strkey(pkey ? pkey : ""), _is_skey_set(psubkey != nullptr), _strsubkey(psubkey ? psubkey : ""), _is_attr_check(attrchk), _is_pass_set(ppass != nullptr), _strpass(ppass ? ppass : ""), _presult(nullptr)
236
271
  {
237
- is_key_set = (NULL != pkey);
238
- is_skey_set = (NULL != psubkey);
239
- is_pass_set = (NULL != ppass);
272
+ _callbackRef.Ref();
240
273
  }
241
- ~GetValueWorker()
274
+
275
+ ~GetValueAsyncWorker() override
242
276
  {
243
- K2H_Free(presult);
277
+ if(_callbackRef){
278
+ _callbackRef.Unref();
279
+ _callbackRef.Reset();
280
+ }
281
+ K2H_Free(_presult);
244
282
  }
245
283
 
246
- void Execute()
284
+ // Run on worker thread
285
+ void Execute() override
247
286
  {
248
- if(!pk2hobj){
249
- Nan::ReferenceError("No object is associated to async worker");
287
+ if(!_k2hshm){
288
+ SetError("No object is associated to async worker");
250
289
  return;
251
290
  }
252
- if(!is_key_set){
253
- Nan::ReferenceError("Specified key is empty(null)");
291
+ if(!_is_key_set){
292
+ SetError("Specified key is empty(null)");
254
293
  return;
255
294
  }
256
295
 
257
296
  // check subkey if specified
258
- if(is_skey_set){
297
+ if(_is_skey_set){
259
298
  // subkey is specified, thus need to check the key has it.
260
299
  bool found = false;
261
- K2HSubKeys* sk = pk2hobj->GetSubKeys(strkey.c_str());
300
+ K2HSubKeys* sk = _k2hshm->GetSubKeys(_strkey.c_str());
262
301
  if(sk){
263
302
  strarr_t strarr;
264
303
  sk->StringArray(strarr);
265
- for(strarr_t::const_iterator iter = strarr.begin(); iter != strarr.end(); ++iter){
266
- if(0 == strcmp(iter->c_str(), strsubkey.c_str())){
304
+ for(const auto &_str : strarr){
305
+ if(_str == _strsubkey){
267
306
  found = true;
268
307
  break;
269
308
  }
@@ -271,60 +310,74 @@ class GetValueWorker : public Nan::AsyncWorker
271
310
  delete sk;
272
311
  }
273
312
  if(!found){
274
- // set error
275
- this->SetErrorMessage("There is no specified subkey in key subkey list.");
313
+ SetError("There is no specified subkey in key subkey list.");
276
314
  return;
277
315
  }
278
- strkey = strsubkey;
316
+ _strkey = _strsubkey;
279
317
  }
280
318
 
281
319
  // get value
282
- presult = pk2hobj->Get(strkey.c_str(), is_attr_check, (is_pass_set ? strpass.c_str() : NULL));
283
- if(!presult){
284
- // set error
285
- this->SetErrorMessage("Failed to get value from key/subkey or the value is empty(null).");
320
+ _presult = _k2hshm->Get(_strkey.c_str(), _is_attr_check, (_is_pass_set ? _strpass.c_str() : NULL));
321
+ if(!_presult){
322
+ SetError("Failed to get value from key/subkey or the value is empty(null).");
286
323
  return;
287
324
  }
288
325
  }
289
326
 
290
- void HandleOKCallback()
327
+ // handler for success
328
+ void OnOK() override
291
329
  {
292
- Nan::HandleScope scope;
293
- const int argc = 2;
294
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::New<v8::String>(presult).ToLocalChecked() };
330
+ Napi::Env env = Env();
331
+ Napi::HandleScope scope(env);
295
332
 
296
- if(callback){
297
- callback->Call(argc, argv);
333
+ // The first argument is null and the second argument is the result.
334
+ if(!_callbackRef.IsEmpty()){
335
+ Napi::String jsValue = Napi::String::New(env, (_presult ? _presult : ""), (_presult ? static_cast<size_t>(strlen(_presult)) : 0));
336
+ _callbackRef.Value().Call({ env.Null(), jsValue });
298
337
  }else{
299
- Nan::ThrowSyntaxError("Internal error in async worker");
300
- return;
338
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
301
339
  }
302
340
  }
303
341
 
304
- void HandleErrorCallback()
305
- {
306
- Nan::HandleScope scope;
307
- const int argc = 2;
308
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked(), Nan::Null() };
342
+ // handler for failure (by calling SetError)
343
+ void OnError(const Napi::Error& err) override
344
+ {
345
+ Napi::Env env = Env();
346
+ Napi::HandleScope scope(env);
347
+
348
+ std::string msg;
349
+ if(err.Value().IsObject()){
350
+ Napi::Object obj = err.Value().As<Napi::Object>();
351
+ Napi::Value msgval = obj.Get("message");
352
+ if(msgval.IsString()){
353
+ msg = msgval.As<Napi::String>().Utf8Value();
354
+ }else{
355
+ Napi::String _str = obj.ToString();
356
+ msg = _str.Utf8Value();
357
+ }
358
+ }else{
359
+ msg = "Unknown error";
360
+ }
309
361
 
310
- if(callback){
311
- callback->Call(argc, argv);
362
+ // The first argument is the error message.
363
+ if(!_callbackRef.IsEmpty()){
364
+ _callbackRef.Value().Call({ Napi::String::New(env, msg), env.Null() });
312
365
  }else{
313
- Nan::ThrowSyntaxError("Internal error in async worker");
314
- return;
366
+ err.ThrowAsJavaScriptException();
315
367
  }
316
- }
368
+ }
317
369
 
318
370
  private:
319
- K2HShm* pk2hobj;
320
- bool is_key_set;
321
- std::string strkey;
322
- bool is_skey_set;
323
- std::string strsubkey;
324
- bool is_attr_check;
325
- bool is_pass_set;
326
- std::string strpass;
327
- char* presult;
371
+ Napi::FunctionReference _callbackRef;
372
+ K2HShm* _k2hshm;
373
+ bool _is_key_set;
374
+ std::string _strkey;
375
+ bool _is_skey_set;
376
+ std::string _strsubkey;
377
+ bool _is_attr_check;
378
+ bool _is_pass_set;
379
+ std::string _strpass;
380
+ char* _presult;
328
381
  };
329
382
 
330
383
  //---------------------------------------------------------
@@ -334,82 +387,101 @@ class GetValueWorker : public Nan::AsyncWorker
334
387
  // Callback function: function(string error, array subkeys)
335
388
  //
336
389
  //---------------------------------------------------------
337
- class GetSubkeysWorker : public Nan::AsyncWorker
390
+ class GetSubkeysAsyncWorker : public Napi::AsyncWorker
338
391
  {
339
392
  public:
340
- GetSubkeysWorker(Nan::Callback* callback, K2HShm* pobj, const char* pkey) : Nan::AsyncWorker(callback), pk2hobj(pobj), is_key_set(false), strkey(pkey ? pkey : "")
393
+ GetSubkeysAsyncWorker(const Napi::Function& callback, K2HShm* pobj, const char* pkey) :
394
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(pobj), _is_key_set(pkey != nullptr), _strkey(pkey ? pkey : ""), _subkey_array()
341
395
  {
342
- is_key_set = (NULL != pkey);
396
+ _callbackRef.Ref();
343
397
  }
344
- ~GetSubkeysWorker() {}
345
398
 
346
- void Execute()
399
+ ~GetSubkeysAsyncWorker() override
347
400
  {
348
- if(!pk2hobj){
349
- Nan::ReferenceError("No object is associated to async worker");
401
+ if(_callbackRef){
402
+ _callbackRef.Unref();
403
+ _callbackRef.Reset();
404
+ }
405
+ }
406
+
407
+ // Run on worker thread
408
+ void Execute() override
409
+ {
410
+ if(!_k2hshm){
411
+ SetError("No object is associated to async worker");
350
412
  return;
351
413
  }
352
- if(!is_key_set){
353
- Nan::ReferenceError("Specified key is empty(null)");
414
+ if(!_is_key_set){
415
+ SetError("Specified key is empty(null)");
354
416
  return;
355
417
  }
356
418
 
357
- // get subkey
358
- K2HSubKeys* sk = pk2hobj->GetSubKeys(strkey.c_str());
419
+ // get subkeys
420
+ K2HSubKeys* sk = _k2hshm->GetSubKeys(_strkey.c_str());
359
421
  if(sk){
360
- subkey_array.clear();
361
- sk->StringArray(subkey_array);
362
- delete sk;
363
- if(0 == subkey_array.size()){
364
- // set error
365
- this->SetErrorMessage("Failed to get subkey because the key does not have any subkey.");
422
+ _subkey_array.clear();
423
+ sk->StringArray(_subkey_array);
424
+ delete sk;
425
+ if(0 == _subkey_array.size()){
426
+ SetError("Failed to get subkey because the key does not have any subkey.");
366
427
  return;
367
428
  }
368
429
  }else{
369
- // set error
370
- this->SetErrorMessage("Failed to get subkey from key or key does not have any subkey.");
430
+ SetError("Failed to get subkey from key or key does not have any subkey.");
371
431
  return;
372
432
  }
373
433
  }
374
434
 
375
- void HandleOKCallback()
435
+ // handler for success
436
+ void OnOK() override
376
437
  {
377
- Nan::HandleScope scope;
378
- v8::Local<v8::Array> retarr = Nan::New<v8::Array>();
379
- int pos = 0 ;
380
- for(strarr_t::const_iterator iter = subkey_array.begin(); iter != subkey_array.end(); ++iter, ++pos){
381
- Nan::Set(retarr, pos, Nan::New<v8::String>(iter->c_str()).ToLocalChecked());
382
- }
383
- const int argc = 2;
384
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), retarr };
385
-
386
- if(callback){
387
- callback->Call(argc, argv);
438
+ Napi::Env env = Env();
439
+ Napi::HandleScope scope(env);
440
+
441
+ if(!_callbackRef.IsEmpty()){
442
+ Napi::Array retarr = Napi::Array::New(env, _subkey_array.size());
443
+ uint32_t idx = 0;
444
+ for(const auto &_str : _subkey_array){
445
+ retarr.Set(idx++, Napi::String::New(env, _str.c_str(), static_cast<size_t>(strlen(_str.c_str()))));
446
+ }
447
+ _callbackRef.Value().Call({ env.Null(), retarr });
388
448
  }else{
389
- Nan::ThrowSyntaxError("Internal error in async worker");
390
- return;
449
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
391
450
  }
392
451
  }
393
452
 
394
- void HandleErrorCallback()
395
- {
396
- Nan::HandleScope scope;
397
- const int argc = 2;
398
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked(), Nan::Null() };
453
+ // handler for failure (by calling SetError)
454
+ void OnError(const Napi::Error& err) override
455
+ {
456
+ Napi::Env env = Env();
457
+ Napi::HandleScope scope(env);
458
+
459
+ std::string msg;
460
+ if(err.Value().IsObject()){
461
+ Napi::Object obj = err.Value().As<Napi::Object>();
462
+ Napi::Value mv = obj.Get("message");
463
+ if(mv.IsString()){
464
+ msg = mv.As<Napi::String>().Utf8Value();
465
+ }else{
466
+ msg = err.Message();
467
+ }
468
+ }else{
469
+ msg = err.Message();
470
+ }
399
471
 
400
- if(callback){
401
- callback->Call(argc, argv);
472
+ if(!_callbackRef.IsEmpty()){
473
+ _callbackRef.Value().Call({ Napi::String::New(env, msg), env.Null() });
402
474
  }else{
403
- Nan::ThrowSyntaxError("Internal error in async worker");
404
- return;
475
+ err.ThrowAsJavaScriptException();
405
476
  }
406
- }
477
+ }
407
478
 
408
479
  private:
409
- K2HShm* pk2hobj;
410
- bool is_key_set;
411
- std::string strkey;
412
- strarr_t subkey_array;
480
+ Napi::FunctionReference _callbackRef;
481
+ K2HShm* _k2hshm;
482
+ bool _is_key_set;
483
+ std::string _strkey;
484
+ strarr_t _subkey_array;
413
485
  };
414
486
 
415
487
  //---------------------------------------------------------
@@ -419,82 +491,101 @@ class GetSubkeysWorker : public Nan::AsyncWorker
419
491
  // Callback function: function(string error, array attrs)
420
492
  //
421
493
  //---------------------------------------------------------
422
- class GetAttrsWorker : public Nan::AsyncWorker
494
+ class GetAttrsAsyncWorker : public Napi::AsyncWorker
423
495
  {
424
496
  public:
425
- GetAttrsWorker(Nan::Callback* callback, K2HShm* pobj, const char* pkey) : Nan::AsyncWorker(callback), pk2hobj(pobj), is_key_set(false), strkey(pkey ? pkey : "")
497
+ GetAttrsAsyncWorker(const Napi::Function& callback, K2HShm* pobj, const char* pkey) :
498
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(pobj), _is_key_set(pkey != nullptr), _strkey(pkey ? pkey : ""), _attrs_array()
499
+ {
500
+ _callbackRef.Ref();
501
+ }
502
+
503
+ ~GetAttrsAsyncWorker() override
426
504
  {
427
- is_key_set = (NULL != pkey);
505
+ if(_callbackRef){
506
+ _callbackRef.Unref();
507
+ _callbackRef.Reset();
508
+ }
428
509
  }
429
- ~GetAttrsWorker() {}
430
510
 
431
- void Execute()
511
+ // Run on worker thread
512
+ void Execute() override
432
513
  {
433
- if(!pk2hobj){
434
- Nan::ReferenceError("No object is associated to async worker");
514
+ if(!_k2hshm){
515
+ SetError("No object is associated to async worker");
435
516
  return;
436
517
  }
437
- if(!is_key_set){
438
- Nan::ReferenceError("Specified key is empty(null)");
518
+ if(!_is_key_set){
519
+ SetError("Specified key is empty(null)");
439
520
  return;
440
521
  }
441
522
 
442
523
  // get attributes
443
- K2HAttrs* attrs = pk2hobj->GetAttrs(strkey.c_str());
524
+ K2HAttrs* attrs = _k2hshm->GetAttrs(_strkey.c_str());
444
525
  if(attrs){
445
- attrs_array.clear();
446
- attrs->KeyStringArray(attrs_array);
526
+ _attrs_array.clear();
527
+ attrs->KeyStringArray(_attrs_array);
447
528
  delete attrs;
448
- if(0 == attrs_array.size()){
449
- // set error
450
- this->SetErrorMessage("Failed to get attributes because the key does not have any attribute.");
529
+ if(0 == _attrs_array.size()){
530
+ SetError("Failed to get attributes because the key does not have any attribute.");
451
531
  return;
452
532
  }
453
533
  }else{
454
- // get error
455
- this->SetErrorMessage("Failed to get attributes from key or key does not have any attribute.");
534
+ SetError("Failed to get attributes from key or key does not have any attribute.");
456
535
  return;
457
536
  }
458
537
  }
459
538
 
460
- void HandleOKCallback()
539
+ // handler for success
540
+ void OnOK() override
461
541
  {
462
- Nan::HandleScope scope;
463
- v8::Local<v8::Array> retarr = Nan::New<v8::Array>();
464
- int pos = 0 ;
465
- for(strarr_t::const_iterator iter = attrs_array.begin(); iter != attrs_array.end(); ++iter, ++pos){
466
- Nan::Set(retarr, pos, Nan::New<v8::String>(iter->c_str()).ToLocalChecked());
467
- }
468
- const int argc = 2;
469
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), retarr };
470
-
471
- if(callback){
472
- callback->Call(argc, argv);
542
+ Napi::Env env = Env();
543
+ Napi::HandleScope scope(env);
544
+
545
+ if(!_callbackRef.IsEmpty()){
546
+ Napi::Array retarr = Napi::Array::New(env, _attrs_array.size());
547
+ uint32_t idx = 0;
548
+ for(const auto &_str: _attrs_array){
549
+ retarr.Set(idx++, Napi::String::New(env, _str.c_str(), static_cast<size_t>(strlen(_str.c_str()))));
550
+ }
551
+ _callbackRef.Value().Call({ env.Null(), retarr });
473
552
  }else{
474
- Nan::ThrowSyntaxError("Internal error in async worker");
475
- return;
553
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
476
554
  }
477
555
  }
478
556
 
479
- void HandleErrorCallback()
480
- {
481
- Nan::HandleScope scope;
482
- const int argc = 2;
483
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked(), Nan::Null() };
557
+ // handler for failure (by calling SetError)
558
+ void OnError(const Napi::Error& err) override
559
+ {
560
+ Napi::Env env = Env();
561
+ Napi::HandleScope scope(env);
562
+
563
+ std::string msg;
564
+ if(err.Value().IsObject()){
565
+ Napi::Object obj = err.Value().As<Napi::Object>();
566
+ Napi::Value mv = obj.Get("message");
567
+ if(mv.IsString()){
568
+ msg = mv.As<Napi::String>().Utf8Value();
569
+ }else{
570
+ msg = err.Message();
571
+ }
572
+ }else{
573
+ msg = err.Message();
574
+ }
484
575
 
485
- if(callback){
486
- callback->Call(argc, argv);
576
+ if(!_callbackRef.IsEmpty()){
577
+ _callbackRef.Value().Call({ Napi::String::New(env, msg), env.Null() });
487
578
  }else{
488
- Nan::ThrowSyntaxError("Internal error in async worker");
489
- return;
579
+ err.ThrowAsJavaScriptException();
490
580
  }
491
- }
581
+ }
492
582
 
493
583
  private:
494
- K2HShm* pk2hobj;
495
- bool is_key_set;
496
- std::string strkey;
497
- strarr_t attrs_array;
584
+ Napi::FunctionReference _callbackRef;
585
+ K2HShm* _k2hshm;
586
+ bool _is_key_set;
587
+ std::string _strkey;
588
+ strarr_t _attrs_array;
498
589
  };
499
590
 
500
591
  //---------------------------------------------------------
@@ -504,100 +595,120 @@ class GetAttrsWorker : public Nan::AsyncWorker
504
595
  // Callback function: function(string error[, string value])
505
596
  //
506
597
  //---------------------------------------------------------
507
- class GetAttrValueWorker : public Nan::AsyncWorker
598
+ class GetAttrValueAsyncWorker : public Napi::AsyncWorker
508
599
  {
509
600
  public:
510
- GetAttrValueWorker(Nan::Callback* callback, K2HShm* pobj, const char* pkey, const char* pattr) : Nan::AsyncWorker(callback), pk2hobj(pobj), is_key_set(false), strkey(pkey ? pkey : ""), is_attr_set(false), strattr(pattr ? pattr : "")
601
+ GetAttrValueAsyncWorker(const Napi::Function& callback, K2HShm* pobj, const char* pkey, const char* pattr) :
602
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(pobj), _is_key_set(pkey != nullptr), _strkey(pkey ? pkey : ""), _is_attr_set(pattr != nullptr), _strattr(pattr ? pattr : ""), _attrval()
603
+ {
604
+ _callbackRef.Ref();
605
+ }
606
+
607
+ ~GetAttrValueAsyncWorker() override
511
608
  {
512
- is_key_set = (NULL != pkey);
513
- is_attr_set = (NULL != pattr);
609
+ if(_callbackRef){
610
+ _callbackRef.Unref();
611
+ _callbackRef.Reset();
612
+ }
514
613
  }
515
- ~GetAttrValueWorker() {}
516
614
 
517
- void Execute()
615
+ // Run on worker thread
616
+ void Execute() override
518
617
  {
519
- if(!pk2hobj){
520
- Nan::ReferenceError("No object is associated to async worker");
618
+ if(!_k2hshm){
619
+ SetError("No object is associated to async worker");
521
620
  return;
522
621
  }
523
- if(!is_key_set){
524
- Nan::ReferenceError("Specified key is empty(null)");
622
+ if(!_is_key_set){
623
+ SetError("Specified key is empty(null)");
525
624
  return;
526
625
  }
527
- if(!is_attr_set){
528
- Nan::ReferenceError("Specified attribute key is empty(null)");
626
+ if(!_is_attr_set){
627
+ SetError("Specified attribute key is empty(null)");
529
628
  return;
530
629
  }
531
630
 
532
631
  // get attributes
533
- K2HAttrs* attrs = pk2hobj->GetAttrs(strkey.c_str());
632
+ K2HAttrs* attrs = _k2hshm->GetAttrs(_strkey.c_str());
534
633
  if(attrs){
535
634
  bool is_found = false;
536
635
  for(K2HAttrs::iterator iter = attrs->begin(); iter != attrs->end(); ++iter){
537
636
  if(0UL == iter->keylength || !iter->pkey){
538
637
  continue;
539
638
  }
540
- if(iter->keylength != static_cast<size_t>(strattr.length() + 1)){
639
+ if(iter->keylength != static_cast<size_t>(_strattr.length() + 1)){
541
640
  continue;
542
641
  }
543
- if(0 == memcmp(iter->pkey, strattr.c_str(), iter->keylength)){
642
+ if(0 == memcmp(iter->pkey, _strattr.c_str(), iter->keylength)){
544
643
  // found
545
644
  if(0 < iter->vallength && iter->pval){
546
- attrval = std::string(reinterpret_cast<const char*>(iter->pval), iter->vallength);
645
+ _attrval.assign(reinterpret_cast<const char*>(iter->pval), iter->vallength);
547
646
  }else{
548
- this->SetErrorMessage("Failed to get attribute value because the attr does not have any value.");
647
+ SetError("Failed to get attribute value because the attr does not have any value.");
549
648
  }
550
- is_found = true;
649
+ is_found = true;
551
650
  break;
552
651
  }
553
652
  }
554
653
  delete attrs;
555
654
  if(!is_found){
556
- // not found
557
- this->SetErrorMessage("Failed to get attribute value because the attr does not have any value.");
655
+ SetError("Failed to get attribute value because the attr does not have any value.");
558
656
  }
559
657
  }else{
560
- // get error
561
- this->SetErrorMessage("Failed to get attribute value from key or key does not have attribute.");
658
+ SetError("Failed to get attribute value from key or key does not have attribute.");
562
659
  return;
563
660
  }
564
661
  }
565
662
 
566
- void HandleOKCallback()
663
+ // handler for success
664
+ void OnOK() override
567
665
  {
568
- Nan::HandleScope scope;
569
- const int argc = 2;
570
- v8::Local<v8::Value> argv[argc] = { Nan::Null(), Nan::New<v8::String>(attrval.c_str()).ToLocalChecked() };
666
+ Napi::Env env = Env();
667
+ Napi::HandleScope scope(env);
571
668
 
572
- if(callback){
573
- callback->Call(argc, argv);
669
+ if(!_callbackRef.IsEmpty()){
670
+ Napi::String jsVal = Napi::String::New(env, _attrval.c_str(), static_cast<size_t>(strlen(_attrval.c_str())));
671
+ _callbackRef.Value().Call({ env.Null(), jsVal });
574
672
  }else{
575
- Nan::ThrowSyntaxError("Internal error in async worker");
576
- return;
673
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
577
674
  }
578
675
  }
579
676
 
580
- void HandleErrorCallback()
581
- {
582
- Nan::HandleScope scope;
583
- const int argc = 1;
584
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
677
+ // handler for failure (by calling SetError)
678
+ void OnError(const Napi::Error& err) override
679
+ {
680
+ Napi::Env env = Env();
681
+ Napi::HandleScope scope(env);
682
+
683
+ // Extract error message
684
+ std::string msg;
685
+ if(err.Value().IsObject()){
686
+ Napi::Object obj = err.Value().As<Napi::Object>();
687
+ Napi::Value mv = obj.Get("message");
688
+ if(mv.IsString()){
689
+ msg = mv.As<Napi::String>().Utf8Value();
690
+ }else{
691
+ msg = err.Message();
692
+ }
693
+ }else{
694
+ msg = err.Message();
695
+ }
585
696
 
586
- if(callback){
587
- callback->Call(argc, argv);
697
+ if(!_callbackRef.IsEmpty()){
698
+ _callbackRef.Value().Call({ Napi::String::New(env, msg) });
588
699
  }else{
589
- Nan::ThrowSyntaxError("Internal error in async worker");
590
- return;
700
+ err.ThrowAsJavaScriptException();
591
701
  }
592
- }
702
+ }
593
703
 
594
704
  private:
595
- K2HShm* pk2hobj;
596
- bool is_key_set;
597
- std::string strkey;
598
- bool is_attr_set;
599
- std::string strattr;
600
- std::string attrval;
705
+ Napi::FunctionReference _callbackRef;
706
+ K2HShm* _k2hshm;
707
+ bool _is_key_set;
708
+ std::string _strkey;
709
+ bool _is_attr_set;
710
+ std::string _strattr;
711
+ std::string _attrval;
601
712
  };
602
713
 
603
714
  //---------------------------------------------------------
@@ -607,84 +718,89 @@ class GetAttrValueWorker : public Nan::AsyncWorker
607
718
  // Callback function: function(string error)
608
719
  //
609
720
  //---------------------------------------------------------
610
- class SetValueWorker : public Nan::AsyncWorker
721
+ class SetValueAsyncWorker : public Napi::AsyncWorker
611
722
  {
612
723
  public:
613
- SetValueWorker(Nan::Callback* callback, K2HShm* pobj, const char* pkey, const char* psubkey, const char* pval, const char* ppass, const time_t* pexpire) :
614
- Nan::AsyncWorker(callback), pk2hobj(pobj),
615
- is_key_set(false), strkey(pkey ? pkey : ""), is_skey_set(false), strsubkey(psubkey ? psubkey : ""), is_val_set(false), strval(pval ? pval : ""), is_pass_set(false), strpass(ppass ? ppass : ""), expire(pexpire ? *pexpire : 0)
724
+ SetValueAsyncWorker(const Napi::Function& callback, K2HShm* pobj, const char* pkey, const char* psubkey, const char* pval, const char* ppass, const time_t* p_expire) :
725
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(pobj),
726
+ _is_key_set(pkey != nullptr), _strkey(pkey ? pkey : ""), _is_skey_set(psubkey != nullptr), _strsubkey(psubkey ? psubkey : ""), _is_val_set(pval != nullptr), _strval(pval ? pval : ""), _is_pass_set(ppass != nullptr), _strpass(ppass ? ppass : ""), _expire(p_expire ? *p_expire : 0)
616
727
  {
617
- is_key_set = (NULL != pkey);
618
- is_skey_set = (NULL != psubkey);
619
- is_val_set = (NULL != pval);
620
- is_pass_set = (NULL != ppass);
728
+ _callbackRef.Ref();
729
+ }
730
+
731
+ ~SetValueAsyncWorker() override
732
+ {
733
+ if(_callbackRef){
734
+ _callbackRef.Unref();
735
+ _callbackRef.Reset();
736
+ }
621
737
  }
622
- ~SetValueWorker() {}
623
738
 
624
- void Execute()
739
+ // Run on worker thread
740
+ void Execute() override
625
741
  {
626
- if(!pk2hobj){
627
- Nan::ReferenceError("No object is associated to async worker");
742
+ if(!_k2hshm){
743
+ SetError("No object is associated to async worker");
628
744
  return;
629
745
  }
630
- if(!is_key_set){
631
- Nan::ReferenceError("Specified key is empty(null)");
746
+ if(!_is_key_set){
747
+ SetError("Specified key is empty(null)");
632
748
  return;
633
749
  }
634
750
 
635
- bool result;
636
- if(is_skey_set){
751
+ bool result = false;
752
+ if(_is_skey_set){
637
753
  // subkey is specified
638
- result = pk2hobj->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));
754
+ result = _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));
639
755
  }else{
640
756
  // subkey is not specified
641
- result = pk2hobj->Set(strkey.c_str(), (is_val_set ? strval.c_str() : NULL), (is_pass_set ? strpass.c_str() : NULL), (expire > 0 ? &expire : NULL));
757
+ result = _k2hshm->Set(_strkey.c_str(), (_is_val_set ? _strval.c_str() : NULL), (_is_pass_set ? _strpass.c_str() : NULL), (_expire > 0 ? &_expire : NULL));
642
758
  }
643
759
  if(!result){
644
- // set error
645
- this->SetErrorMessage("Failed to set key/subkey and value.");
760
+ SetError("Failed to set key/subkey and value.");
761
+ return;
646
762
  }
647
763
  }
648
764
 
649
- void HandleOKCallback()
765
+ // handler for success
766
+ void OnOK() override
650
767
  {
651
- Nan::HandleScope scope;
652
- const int argc = 1;
653
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
768
+ Napi::Env env = Env();
769
+ Napi::HandleScope scope(env);
654
770
 
655
- if(callback){
656
- callback->Call(argc, argv);
771
+ if(!_callbackRef.IsEmpty()){
772
+ _callbackRef.Value().Call({ env.Null() });
657
773
  }else{
658
- Nan::ThrowSyntaxError("Internal error in async worker");
659
- return;
774
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
660
775
  }
661
776
  }
662
777
 
663
- void HandleErrorCallback()
664
- {
665
- Nan::HandleScope scope;
666
- const int argc = 1;
667
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
778
+ // handler for failure (by calling SetError)
779
+ void OnError(const Napi::Error& err) override
780
+ {
781
+ Napi::Env env = Env();
782
+ Napi::HandleScope scope(env);
668
783
 
669
- if(callback){
670
- callback->Call(argc, argv);
784
+ std::string msg = err.Message();
785
+ if(!_callbackRef.IsEmpty()){
786
+ _callbackRef.Value().Call({ Napi::String::New(env, msg) });
671
787
  }else{
672
- Nan::ThrowSyntaxError("Internal error in async worker");
673
- return;
788
+ err.ThrowAsJavaScriptException();
674
789
  }
675
- }
790
+ }
676
791
 
677
792
  private:
678
- K2HShm* pk2hobj;
679
- bool is_key_set;
680
- std::string strkey;
681
- bool is_skey_set;
682
- std::string strsubkey;
683
- bool is_val_set;
684
- std::string strval;
685
- bool is_pass_set;
686
- std::string strpass;
687
- time_t expire;
793
+ Napi::FunctionReference _callbackRef;
794
+ K2HShm* _k2hshm;
795
+ bool _is_key_set;
796
+ std::string _strkey;
797
+ bool _is_skey_set;
798
+ std::string _strsubkey;
799
+ bool _is_val_set;
800
+ std::string _strval;
801
+ bool _is_pass_set;
802
+ std::string _strpass;
803
+ time_t _expire;
688
804
  };
689
805
 
690
806
  //---------------------------------------------------------
@@ -694,77 +810,82 @@ class SetValueWorker : public Nan::AsyncWorker
694
810
  // Callback function: function(string error)
695
811
  //
696
812
  //---------------------------------------------------------
697
- class AddSubkeyWorker : public Nan::AsyncWorker
813
+ class AddSubkeyAsyncWorker : public Napi::AsyncWorker
698
814
  {
699
815
  public:
700
- AddSubkeyWorker(Nan::Callback* callback, K2HShm* pobj, const char* pkey, const char* psubkey, const char* pval) :
701
- Nan::AsyncWorker(callback), pk2hobj(pobj),
702
- is_key_set(false), strkey(pkey ? pkey : ""), is_skey_set(false), strsubkey(psubkey ? psubkey : ""), is_val_set(false), strval(pval ? pval : "")
816
+ AddSubkeyAsyncWorker(const Napi::Function& callback, K2HShm* pobj, const char* pkey, const char* psubkey, const char* pval) :
817
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(pobj), _is_key_set(pkey != nullptr), _strkey(pkey ? pkey : ""), _is_skey_set(psubkey != nullptr), _strsubkey(psubkey ? psubkey : ""), _is_val_set(pval != nullptr), _strval(pval ? pval : "")
703
818
  {
704
- is_key_set = (NULL != pkey);
705
- is_skey_set = (NULL != psubkey);
706
- is_val_set = (NULL != pval);
819
+ _callbackRef.Ref();
820
+ }
821
+
822
+ ~AddSubkeyAsyncWorker() override
823
+ {
824
+ if(_callbackRef){
825
+ _callbackRef.Unref();
826
+ _callbackRef.Reset();
827
+ }
707
828
  }
708
- ~AddSubkeyWorker() {}
709
829
 
710
- void Execute()
830
+ // Run on worker thread
831
+ void Execute() override
711
832
  {
712
- if(!pk2hobj){
713
- Nan::ReferenceError("No object is associated to async worker");
833
+ if(!_k2hshm){
834
+ SetError("No object is associated to async worker");
714
835
  return;
715
836
  }
716
- if(!is_key_set){
717
- Nan::ReferenceError("Specified key is empty(null)");
837
+ if(!_is_key_set){
838
+ SetError("Specified key is empty(null)");
718
839
  return;
719
840
  }
720
- if(!is_skey_set){
721
- Nan::ReferenceError("Specified subkey is empty(null)");
841
+ if(!_is_skey_set){
842
+ SetError("Specified subkey is empty(null)");
722
843
  return;
723
844
  }
724
845
 
725
846
  // add subkey
726
- if(!pk2hobj->AddSubkey(strkey.c_str(), strsubkey.c_str(), (is_val_set ? strval.c_str() : NULL))){
727
- // set error
728
- this->SetErrorMessage("Failed to set subkey and value to key.");
847
+ if(!_k2hshm->AddSubkey(_strkey.c_str(), _strsubkey.c_str(), (_is_val_set ? _strval.c_str() : NULL))){
848
+ SetError("Failed to set subkey and value to key.");
849
+ return;
729
850
  }
730
851
  }
731
852
 
732
- void HandleOKCallback()
853
+ // handler for success
854
+ void OnOK() override
733
855
  {
734
- Nan::HandleScope scope;
735
- const int argc = 1;
736
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
856
+ Napi::Env env = Env();
857
+ Napi::HandleScope scope(env);
737
858
 
738
- if(callback){
739
- callback->Call(argc, argv);
859
+ if(!_callbackRef.IsEmpty()){
860
+ _callbackRef.Value().Call({ env.Null() });
740
861
  }else{
741
- Nan::ThrowSyntaxError("Internal error in async worker");
742
- return;
862
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
743
863
  }
744
864
  }
745
865
 
746
- void HandleErrorCallback()
747
- {
748
- Nan::HandleScope scope;
749
- const int argc = 1;
750
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
866
+ // handler for failure (by calling SetError)
867
+ void OnError(const Napi::Error& err) override
868
+ {
869
+ Napi::Env env = Env();
870
+ Napi::HandleScope scope(env);
751
871
 
752
- if(callback){
753
- callback->Call(argc, argv);
872
+ std::string msg = err.Message();
873
+ if(!_callbackRef.IsEmpty()){
874
+ _callbackRef.Value().Call({ Napi::String::New(env, msg) });
754
875
  }else{
755
- Nan::ThrowSyntaxError("Internal error in async worker");
756
- return;
876
+ err.ThrowAsJavaScriptException();
757
877
  }
758
- }
878
+ }
759
879
 
760
880
  private:
761
- K2HShm* pk2hobj;
762
- bool is_key_set;
763
- std::string strkey;
764
- bool is_skey_set;
765
- std::string strsubkey;
766
- bool is_val_set;
767
- std::string strval;
881
+ Napi::FunctionReference _callbackRef;
882
+ K2HShm* _k2hshm;
883
+ bool _is_key_set;
884
+ std::string _strkey;
885
+ bool _is_skey_set;
886
+ std::string _strsubkey;
887
+ bool _is_val_set;
888
+ std::string _strval;
768
889
  };
769
890
 
770
891
  //---------------------------------------------------------
@@ -774,84 +895,91 @@ class AddSubkeyWorker : public Nan::AsyncWorker
774
895
  // Callback function: function(string error)
775
896
  //
776
897
  //---------------------------------------------------------
777
- class AddSubkeysWorker : public Nan::AsyncWorker
898
+ class AddSubkeysAsyncWorker : public Napi::AsyncWorker
778
899
  {
779
900
  public:
780
- AddSubkeysWorker(Nan::Callback* callback, K2HShm* pobj, const char* pkey, const unsigned char* psubkeys, size_t skey_length) : Nan::AsyncWorker(callback), pk2hobj(pobj), is_key_set(false), strkey(pkey ? pkey : ""), bySubkeys(NULL), skeylen(0), alloc_error(false)
901
+ AddSubkeysAsyncWorker(const Napi::Function& callback, K2HShm* pobj, const char* pkey, const unsigned char* psubkeys, size_t skey_length) :
902
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(pobj), _is_key_set(pkey != nullptr), _strkey(pkey ? pkey : ""), _bySubkeys(nullptr), _skeylen(0), _alloc_error(false)
781
903
  {
782
904
  if(psubkeys && 0UL < skey_length){
783
- if(NULL != (bySubkeys = reinterpret_cast<unsigned char*>(malloc(skey_length)))){
784
- memcpy(bySubkeys, psubkeys, skey_length);
785
- skeylen = skey_length;
905
+ if(nullptr != (_bySubkeys = reinterpret_cast<unsigned char*>(malloc(skey_length)))){
906
+ memcpy(_bySubkeys, psubkeys, skey_length);
907
+ _skeylen = skey_length;
786
908
  }else{
787
909
  // could not allocate memory.
788
- alloc_error = true;
910
+ _alloc_error = true;
789
911
  }
790
912
  }
791
- is_key_set = (NULL != pkey);
913
+ _callbackRef.Ref();
792
914
  }
793
- ~AddSubkeysWorker()
915
+
916
+ ~AddSubkeysAsyncWorker() override
794
917
  {
795
- K2H_Free(bySubkeys);
918
+ if(_callbackRef){
919
+ _callbackRef.Unref();
920
+ _callbackRef.Reset();
921
+ }
922
+ K2H_Free(_bySubkeys);
796
923
  }
797
924
 
798
- void Execute()
925
+ // Run on worker thread
926
+ void Execute() override
799
927
  {
800
- if(!pk2hobj){
801
- Nan::ReferenceError("No object is associated to async worker");
928
+ if(!_k2hshm){
929
+ SetError("No object is associated to async worker");
802
930
  return;
803
931
  }
804
- if(!is_key_set){
805
- Nan::ReferenceError("Specified key is empty(null)");
932
+ if(!_is_key_set){
933
+ SetError("Specified key is empty(null)");
806
934
  return;
807
935
  }
808
- if(alloc_error){
809
- Nan::ReferenceError("Could not allocate memory");
936
+ if(_alloc_error){
937
+ SetError("Could not allocate memory");
810
938
  return;
811
939
  }
812
940
 
813
941
  // add subkeys
814
- if(!pk2hobj->ReplaceSubkeys(reinterpret_cast<const unsigned char*>(strkey.c_str()), strkey.length() + 1, bySubkeys, skeylen)){
815
- // set error
816
- this->SetErrorMessage("Failed to replace subkeys to key.");
942
+ if(!_k2hshm->ReplaceSubkeys(reinterpret_cast<const unsigned char*>(_strkey.c_str()), _strkey.length() + 1, _bySubkeys, _skeylen)){
943
+ SetError("Failed to replace subkeys to key.");
944
+ return;
817
945
  }
818
946
  }
819
947
 
820
- void HandleOKCallback()
948
+ // handler for success
949
+ void OnOK() override
821
950
  {
822
- Nan::HandleScope scope;
823
- const int argc = 1;
824
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
951
+ Napi::Env env = Env();
952
+ Napi::HandleScope scope(env);
825
953
 
826
- if(callback){
827
- callback->Call(argc, argv);
954
+ if(!_callbackRef.IsEmpty()){
955
+ _callbackRef.Value().Call({ env.Null() });
828
956
  }else{
829
- Nan::ThrowSyntaxError("Internal error in async worker");
830
- return;
957
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
831
958
  }
832
959
  }
833
960
 
834
- void HandleErrorCallback()
835
- {
836
- Nan::HandleScope scope;
837
- const int argc = 1;
838
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
961
+ // handler for failure (by calling SetError)
962
+ void OnError(const Napi::Error& err) override
963
+ {
964
+ Napi::Env env = Env();
965
+ Napi::HandleScope scope(env);
839
966
 
840
- if(callback){
841
- callback->Call(argc, argv);
967
+ std::string msg = err.Message();
968
+ if(!_callbackRef.IsEmpty()){
969
+ _callbackRef.Value().Call({ Napi::String::New(env, msg) });
842
970
  }else{
843
- Nan::ThrowSyntaxError("Internal error in async worker");
844
- return;
971
+ err.ThrowAsJavaScriptException();
845
972
  }
846
- }
973
+ }
847
974
 
848
975
  private:
849
- K2HShm* pk2hobj;
850
- bool is_key_set;
851
- std::string strkey;
852
- unsigned char* bySubkeys;
853
- size_t skeylen;
854
- bool alloc_error;
976
+ Napi::FunctionReference _callbackRef;
977
+ K2HShm* _k2hshm;
978
+ bool _is_key_set;
979
+ std::string _strkey;
980
+ unsigned char* _bySubkeys;
981
+ size_t _skeylen;
982
+ bool _alloc_error;
855
983
  };
856
984
 
857
985
  //---------------------------------------------------------
@@ -861,77 +989,95 @@ class AddSubkeysWorker : public Nan::AsyncWorker
861
989
  // Callback function: function(string error)
862
990
  //
863
991
  //---------------------------------------------------------
864
- class AddAttrWorker : public Nan::AsyncWorker
992
+ class AddAttrAsyncWorker : public Napi::AsyncWorker
865
993
  {
866
994
  public:
867
- AddAttrWorker(Nan::Callback* callback, K2HShm* pobj, const char* pkey, const char* pattrkey, const char* pattrval) :
868
- Nan::AsyncWorker(callback), pk2hobj(pobj),
869
- is_key_set(false), strkey(pkey ? pkey : ""), is_attr_set(false), strattr(pattrkey ? pattrkey : ""), is_val_set(false), strval(pattrval ? pattrval : "")
995
+ AddAttrAsyncWorker(const Napi::Function& callback, K2HShm* pobj, const char* pkey, const char* pattrkey, const char* pattrval) :
996
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(pobj), _is_key_set(pkey != nullptr), _strkey(pkey ? pkey : ""), _is_attr_set(pattrkey != nullptr), _strattr(pattrkey ? pattrkey : ""), _is_val_set(pattrval != nullptr), _strval(pattrval ? pattrval : "")
870
997
  {
871
- is_key_set = (NULL != pkey);
872
- is_attr_set = (NULL != pattrkey);
873
- is_val_set = (NULL != pattrval);
998
+ _callbackRef.Ref();
874
999
  }
875
- ~AddAttrWorker() {}
876
1000
 
877
- void Execute()
1001
+ ~AddAttrAsyncWorker() override
878
1002
  {
879
- if(!pk2hobj){
880
- Nan::ReferenceError("No object is associated to async worker");
1003
+ if(_callbackRef){
1004
+ _callbackRef.Unref();
1005
+ _callbackRef.Reset();
1006
+ }
1007
+ }
1008
+
1009
+ // Run on worker thread
1010
+ void Execute() override
1011
+ {
1012
+ if(!_k2hshm){
1013
+ SetError("No object is associated to async worker");
881
1014
  return;
882
1015
  }
883
- if(!is_key_set){
884
- Nan::ReferenceError("Specified key is empty(null)");
1016
+ if(!_is_key_set){
1017
+ SetError("Specified key is empty(null)");
885
1018
  return;
886
1019
  }
887
- if(!is_attr_set){
888
- Nan::ReferenceError("Specified attribute name is empty(null)");
1020
+ if(!_is_attr_set){
1021
+ SetError("Specified attribute name is empty(null)");
889
1022
  return;
890
1023
  }
891
1024
 
892
1025
  // add attribute
893
- if(!pk2hobj->AddAttr(strkey.c_str(), strattr.c_str(), (is_val_set ? strval.c_str() : NULL))){
894
- // set error
895
- this->SetErrorMessage("Failed to set attribute and value to key.");
1026
+ if(!_k2hshm->AddAttr(_strkey.c_str(), _strattr.c_str(), (_is_val_set ? _strval.c_str() : NULL))){
1027
+ SetError("Failed to set attribute and value to key.");
1028
+ return;
896
1029
  }
897
1030
  }
898
1031
 
899
- void HandleOKCallback()
1032
+ // handler for success
1033
+ void OnOK() override
900
1034
  {
901
- Nan::HandleScope scope;
902
- const int argc = 1;
903
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
1035
+ Napi::Env env = Env();
1036
+ Napi::HandleScope scope(env);
904
1037
 
905
- if(callback){
906
- callback->Call(argc, argv);
1038
+ if(!_callbackRef.IsEmpty()){
1039
+ _callbackRef.Value().Call({ env.Null() });
907
1040
  }else{
908
- Nan::ThrowSyntaxError("Internal error in async worker");
909
- return;
1041
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
910
1042
  }
911
1043
  }
912
1044
 
913
- void HandleErrorCallback()
914
- {
915
- Nan::HandleScope scope;
916
- const int argc = 1;
917
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1045
+ // handler for failure (by calling SetError)
1046
+ void OnError(const Napi::Error& err) override
1047
+ {
1048
+ Napi::Env env = Env();
1049
+ Napi::HandleScope scope(env);
1050
+
1051
+ // Extract message
1052
+ std::string msg;
1053
+ if(err.Value().IsObject()){
1054
+ Napi::Object obj = err.Value().As<Napi::Object>();
1055
+ Napi::Value mv = obj.Get("message");
1056
+ if(mv.IsString()){
1057
+ msg = mv.As<Napi::String>().Utf8Value();
1058
+ }else{
1059
+ msg = err.Message();
1060
+ }
1061
+ }else{
1062
+ msg = err.Message();
1063
+ }
918
1064
 
919
- if(callback){
920
- callback->Call(argc, argv);
1065
+ if(!_callbackRef.IsEmpty()){
1066
+ _callbackRef.Value().Call({ Napi::String::New(env, msg) });
921
1067
  }else{
922
- Nan::ThrowSyntaxError("Internal error in async worker");
923
- return;
1068
+ err.ThrowAsJavaScriptException();
924
1069
  }
925
- }
1070
+ }
926
1071
 
927
1072
  private:
928
- K2HShm* pk2hobj;
929
- bool is_key_set;
930
- std::string strkey;
931
- bool is_attr_set;
932
- std::string strattr;
933
- bool is_val_set;
934
- std::string strval;
1073
+ Napi::FunctionReference _callbackRef;
1074
+ K2HShm* _k2hshm;
1075
+ bool _is_key_set;
1076
+ std::string _strkey;
1077
+ bool _is_attr_set;
1078
+ std::string _strattr;
1079
+ bool _is_val_set;
1080
+ std::string _strval;
935
1081
  };
936
1082
 
937
1083
  //---------------------------------------------------------
@@ -941,81 +1087,88 @@ class AddAttrWorker : public Nan::AsyncWorker
941
1087
  // Callback function: function(string error)
942
1088
  //
943
1089
  //---------------------------------------------------------
944
- class RemoveWorker : public Nan::AsyncWorker
1090
+ class RemoveAsyncWorker : public Napi::AsyncWorker
945
1091
  {
946
1092
  public:
947
- RemoveWorker(Nan::Callback* callback, K2HShm* pobj, const char* pkey, const char* psubkey, bool is_all) : Nan::AsyncWorker(callback), pk2hobj(pobj), is_key_set(false), strkey(pkey ? pkey : ""), is_skey_set(false), strsubkey(psubkey ? psubkey : ""), is_remove_all(is_all)
1093
+ RemoveAsyncWorker(const Napi::Function& callback, K2HShm* pobj, const char* pkey, const char* psubkey, bool is_all) :
1094
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(pobj), _is_key_set(pkey != nullptr), _strkey(pkey ? pkey : ""), _is_skey_set(psubkey != nullptr), _strsubkey(psubkey ? psubkey : ""), _is_remove_all(is_all)
948
1095
  {
949
- is_key_set = (NULL != pkey);
950
- if(is_remove_all){
951
- strsubkey.clear();
952
- }else{
953
- is_skey_set = (NULL != psubkey);
1096
+ if(_is_remove_all){
1097
+ _strsubkey.clear();
1098
+ _is_skey_set = false;
1099
+ }
1100
+ _callbackRef.Ref();
1101
+ }
1102
+
1103
+ ~RemoveAsyncWorker() override
1104
+ {
1105
+ if(_callbackRef){
1106
+ _callbackRef.Unref();
1107
+ _callbackRef.Reset();
954
1108
  }
955
1109
  }
956
- ~RemoveWorker() {}
957
1110
 
958
- void Execute()
1111
+ // Run on worker thread
1112
+ void Execute() override
959
1113
  {
960
- if(!pk2hobj){
961
- Nan::ReferenceError("No object is associated to async worker");
1114
+ if(!_k2hshm){
1115
+ SetError("No object is associated to async worker");
962
1116
  return;
963
1117
  }
964
- if(!is_key_set){
965
- Nan::ReferenceError("Specified key is empty(null)");
1118
+ if(!_is_key_set){
1119
+ SetError("Specified key is empty(null)");
966
1120
  return;
967
1121
  }
968
1122
 
969
- // remove
970
- bool result;
971
- if(is_remove_all){
972
- result = pk2hobj->Remove(strkey.c_str(), true);
973
- }else if(is_skey_set){
974
- result = pk2hobj->Remove(strkey.c_str(), strsubkey.c_str());
1123
+ bool result = false;
1124
+ if(_is_remove_all){
1125
+ result = _k2hshm->Remove(_strkey.c_str(), true);
1126
+ }else if(_is_skey_set){
1127
+ result = _k2hshm->Remove(_strkey.c_str(), _strsubkey.c_str());
975
1128
  }else{
976
- result = pk2hobj->Remove(strkey.c_str(), false);
1129
+ result = _k2hshm->Remove(_strkey.c_str(), false);
977
1130
  }
978
1131
  if(!result){
979
- // set error
980
- this->SetErrorMessage("Failed to remove key (and subkey).");
1132
+ SetError("Failed to remove key (and subkey).");
1133
+ return;
981
1134
  }
982
1135
  }
983
1136
 
984
- void HandleOKCallback()
1137
+ // handler for success
1138
+ void OnOK() override
985
1139
  {
986
- Nan::HandleScope scope;
987
- const int argc = 1;
988
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
1140
+ Napi::Env env = Env();
1141
+ Napi::HandleScope scope(env);
989
1142
 
990
- if(callback){
991
- callback->Call(argc, argv);
1143
+ if(!_callbackRef.IsEmpty()){
1144
+ _callbackRef.Value().Call({ env.Null() });
992
1145
  }else{
993
- Nan::ThrowSyntaxError("Internal error in async worker");
994
- return;
1146
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
995
1147
  }
996
1148
  }
997
1149
 
998
- void HandleErrorCallback()
999
- {
1000
- Nan::HandleScope scope;
1001
- const int argc = 1;
1002
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1150
+ // handler for failure (by calling SetError)
1151
+ void OnError(const Napi::Error& err) override
1152
+ {
1153
+ Napi::Env env = Env();
1154
+ Napi::HandleScope scope(env);
1003
1155
 
1004
- if(callback){
1005
- callback->Call(argc, argv);
1156
+ std::string msg = err.Message();
1157
+ if(!_callbackRef.IsEmpty()){
1158
+ _callbackRef.Value().Call({ Napi::String::New(env, msg) });
1006
1159
  }else{
1007
- Nan::ThrowSyntaxError("Internal error in async worker");
1008
- return;
1160
+ err.ThrowAsJavaScriptException();
1009
1161
  }
1010
- }
1162
+ }
1011
1163
 
1012
1164
  private:
1013
- K2HShm* pk2hobj;
1014
- bool is_key_set;
1015
- std::string strkey;
1016
- bool is_skey_set;
1017
- std::string strsubkey;
1018
- bool is_remove_all;
1165
+ Napi::FunctionReference _callbackRef;
1166
+ K2HShm* _k2hshm;
1167
+ bool _is_key_set;
1168
+ std::string _strkey;
1169
+ bool _is_skey_set;
1170
+ std::string _strsubkey;
1171
+ bool _is_remove_all;
1019
1172
  };
1020
1173
 
1021
1174
  //---------------------------------------------------------
@@ -1025,75 +1178,84 @@ class RemoveWorker : public Nan::AsyncWorker
1025
1178
  // Callback function: function(string error)
1026
1179
  //
1027
1180
  //---------------------------------------------------------
1028
- class ArchiveWorker : public Nan::AsyncWorker
1181
+ class ArchiveAsyncWorker : public Napi::AsyncWorker
1029
1182
  {
1030
1183
  public:
1031
- ArchiveWorker(Nan::Callback* callback, K2HShm* pobj, const char* file, bool is_error_skip, bool is_load) : Nan::AsyncWorker(callback), pk2hobj(pobj), is_file_set(false), strfile(file ? file : ""), errskip(is_error_skip), is_load_type(is_load)
1184
+ ArchiveAsyncWorker(const Napi::Function& callback, K2HShm* pobj, const char* file, bool is_error_skip, bool is_load) :
1185
+ Napi::AsyncWorker(callback), _callbackRef(Napi::Persistent(callback)), _k2hshm(pobj), _is_file_set(file != nullptr), _strfile(file ? file : ""), _errskip(is_error_skip), _is_load_type(is_load)
1186
+ {
1187
+ _callbackRef.Ref();
1188
+ }
1189
+
1190
+ ~ArchiveAsyncWorker() override
1032
1191
  {
1033
- is_file_set = (NULL != file);
1192
+ if(_callbackRef){
1193
+ _callbackRef.Unref();
1194
+ _callbackRef.Reset();
1195
+ }
1034
1196
  }
1035
- ~ArchiveWorker() {}
1036
1197
 
1037
- void Execute()
1198
+ // Run on worker thread
1199
+ void Execute() override
1038
1200
  {
1039
- if(!pk2hobj){
1040
- Nan::ReferenceError("No object is associated to async worker");
1201
+ if(!_k2hshm){
1202
+ SetError("No object is associated to async worker");
1041
1203
  return;
1042
1204
  }
1043
- if(!is_file_set){
1044
- Nan::ReferenceError("Specified file name is empty(null)");
1205
+ if(!_is_file_set){
1206
+ SetError("Specified file name is empty(null)");
1045
1207
  return;
1046
1208
  }
1047
1209
 
1048
- if(is_load_type){
1210
+ if(_is_load_type){
1049
1211
  // load archive
1050
- if(!k2h_load_archive(reinterpret_cast<k2h_h>(pk2hobj), strfile.c_str(), errskip)){
1051
- // set error
1052
- this->SetErrorMessage("Failed to load archive file.");
1212
+ if(!k2h_load_archive(reinterpret_cast<k2h_h>(_k2hshm), _strfile.c_str(), _errskip)){
1213
+ SetError("Failed to load archive file.");
1214
+ return;
1053
1215
  }
1054
1216
  }else{
1055
1217
  // put archive
1056
- if(!k2h_put_archive(reinterpret_cast<k2h_h>(pk2hobj), strfile.c_str(), errskip)){
1057
- // set error
1058
- this->SetErrorMessage("Failed to put archive file.");
1218
+ if(!k2h_put_archive(reinterpret_cast<k2h_h>(_k2hshm), _strfile.c_str(), _errskip)){
1219
+ SetError("Failed to put archive file.");
1220
+ return;
1059
1221
  }
1060
1222
  }
1061
1223
  }
1062
1224
 
1063
- void HandleOKCallback()
1225
+ // handler for success
1226
+ void OnOK() override
1064
1227
  {
1065
- Nan::HandleScope scope;
1066
- const int argc = 1;
1067
- v8::Local<v8::Value> argv[argc] = { Nan::Null() };
1228
+ Napi::Env env = Env();
1229
+ Napi::HandleScope scope(env);
1068
1230
 
1069
- if(callback){
1070
- callback->Call(argc, argv);
1231
+ if(!_callbackRef.IsEmpty()){
1232
+ _callbackRef.Value().Call({ env.Null() });
1071
1233
  }else{
1072
- Nan::ThrowSyntaxError("Internal error in async worker");
1073
- return;
1234
+ Napi::TypeError::New(env, "Internal error in async worker").ThrowAsJavaScriptException();
1074
1235
  }
1075
1236
  }
1076
1237
 
1077
- void HandleErrorCallback()
1078
- {
1079
- Nan::HandleScope scope;
1080
- const int argc = 1;
1081
- v8::Local<v8::Value> argv[argc] = { Nan::New<v8::String>(this->ErrorMessage()).ToLocalChecked() };
1238
+ // handler for failure (by calling SetError)
1239
+ void OnError(const Napi::Error& err) override
1240
+ {
1241
+ Napi::Env env = Env();
1242
+ Napi::HandleScope scope(env);
1082
1243
 
1083
- if(callback){
1084
- callback->Call(argc, argv);
1244
+ std::string msg = err.Message();
1245
+ if(!_callbackRef.IsEmpty()){
1246
+ _callbackRef.Value().Call({ Napi::String::New(env, msg) });
1085
1247
  }else{
1086
- Nan::ThrowSyntaxError("Internal error in async worker");
1087
- return;
1248
+ err.ThrowAsJavaScriptException();
1088
1249
  }
1089
- }
1250
+ }
1090
1251
 
1091
1252
  private:
1092
- K2HShm* pk2hobj;
1093
- bool is_file_set;
1094
- std::string strfile;
1095
- bool errskip;
1096
- bool is_load_type;
1253
+ Napi::FunctionReference _callbackRef;
1254
+ K2HShm* _k2hshm;
1255
+ bool _is_file_set;
1256
+ std::string _strfile;
1257
+ bool _errskip;
1258
+ bool _is_load_type;
1097
1259
  };
1098
1260
 
1099
1261
  #endif