Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81145 views
1
/*********************************************************************
2
* NAN - Native Abstractions for Node.js
3
*
4
* Copyright (c) 2015 NAN contributors:
5
* - Rod Vagg <https://github.com/rvagg>
6
* - Benjamin Byholm <https://github.com/kkoopa>
7
* - Trevor Norris <https://github.com/trevnorris>
8
* - Nathan Rajlich <https://github.com/TooTallNate>
9
* - Brett Lawson <https://github.com/brett19>
10
* - Ben Noordhuis <https://github.com/bnoordhuis>
11
* - David Siegel <https://github.com/agnat>
12
*
13
* MIT License <https://github.com/rvagg/nan/blob/master/LICENSE.md>
14
*
15
* Version 1.8.4: current Node 12: 0.12.2, Node 10: 0.10.38, io.js: 1.8.1
16
*
17
* See https://github.com/rvagg/nan for the latest update to this file
18
**********************************************************************************/
19
20
#ifndef NAN_H_
21
#define NAN_H_
22
23
#include <uv.h>
24
#include <node.h>
25
#include <node_buffer.h>
26
#include <node_version.h>
27
#include <node_object_wrap.h>
28
#include <cstring>
29
#include <climits>
30
#include <cstdlib>
31
#if defined(_MSC_VER)
32
# pragma warning( push )
33
# pragma warning( disable : 4530 )
34
# include <string>
35
# pragma warning( pop )
36
#else
37
# include <string>
38
#endif
39
40
#if defined(__GNUC__) && !(defined(DEBUG) && DEBUG)
41
# define NAN_INLINE inline __attribute__((always_inline))
42
#elif defined(_MSC_VER) && !(defined(DEBUG) && DEBUG)
43
# define NAN_INLINE __forceinline
44
#else
45
# define NAN_INLINE inline
46
#endif
47
48
#if defined(__GNUC__) && \
49
!(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
50
# define NAN_DEPRECATED __attribute__((deprecated))
51
#elif defined(_MSC_VER) && \
52
!(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
53
# define NAN_DEPRECATED __declspec(deprecated)
54
#else
55
# define NAN_DEPRECATED
56
#endif
57
58
#define NODE_0_10_MODULE_VERSION 11
59
#define NODE_0_12_MODULE_VERSION 12
60
#define ATOM_0_21_MODULE_VERSION 41
61
#define IOJS_1_0_MODULE_VERSION 42
62
#define IOJS_1_1_MODULE_VERSION 43
63
64
#if (NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION)
65
typedef v8::InvocationCallback NanFunctionCallback;
66
typedef v8::Script NanUnboundScript;
67
typedef v8::Script NanBoundScript;
68
#else
69
typedef v8::FunctionCallback NanFunctionCallback;
70
typedef v8::UnboundScript NanUnboundScript;
71
typedef v8::Script NanBoundScript;
72
#endif
73
74
#if (NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION)
75
typedef v8::String::ExternalAsciiStringResource
76
NanExternalOneByteStringResource;
77
#else
78
typedef v8::String::ExternalOneByteStringResource
79
NanExternalOneByteStringResource;
80
#endif
81
82
#include "nan_new.h" // NOLINT(build/include)
83
84
// uv helpers
85
#ifdef UV_VERSION_MAJOR
86
#ifndef UV_VERSION_PATCH
87
#define UV_VERSION_PATCH 0
88
#endif
89
#define NAUV_UVVERSION ((UV_VERSION_MAJOR << 16) | \
90
(UV_VERSION_MINOR << 8) | \
91
(UV_VERSION_PATCH))
92
#else
93
#define NAUV_UVVERSION 0x000b00
94
#endif
95
96
97
#if NAUV_UVVERSION < 0x000b17
98
#define NAUV_WORK_CB(func) \
99
void func(uv_async_t *async, int)
100
#else
101
#define NAUV_WORK_CB(func) \
102
void func(uv_async_t *async)
103
#endif
104
105
#if NAUV_UVVERSION >= 0x000b0b
106
107
typedef uv_key_t nauv_key_t;
108
109
inline int nauv_key_create(nauv_key_t *key) {
110
return uv_key_create(key);
111
}
112
113
inline void nauv_key_delete(nauv_key_t *key) {
114
uv_key_delete(key);
115
}
116
117
inline void* nauv_key_get(nauv_key_t *key) {
118
return uv_key_get(key);
119
}
120
121
inline void nauv_key_set(nauv_key_t *key, void *value) {
122
uv_key_set(key, value);
123
}
124
125
#else
126
127
/* Implement thread local storage for older versions of libuv.
128
* This is essentially a backport of libuv commit 5d2434bf
129
* written by Ben Noordhuis, adjusted for names and inline.
130
*/
131
132
#ifndef WIN32
133
134
#include <pthread.h>
135
136
typedef pthread_key_t nauv_key_t;
137
138
inline int nauv_key_create(nauv_key_t* key) {
139
return -pthread_key_create(key, NULL);
140
}
141
142
inline void nauv_key_delete(nauv_key_t* key) {
143
if (pthread_key_delete(*key))
144
abort();
145
}
146
147
inline void* nauv_key_get(nauv_key_t* key) {
148
return pthread_getspecific(*key);
149
}
150
151
inline void nauv_key_set(nauv_key_t* key, void* value) {
152
if (pthread_setspecific(*key, value))
153
abort();
154
}
155
156
#else
157
158
#include <windows.h>
159
160
typedef struct {
161
DWORD tls_index;
162
} nauv_key_t;
163
164
inline int nauv_key_create(nauv_key_t* key) {
165
key->tls_index = TlsAlloc();
166
if (key->tls_index == TLS_OUT_OF_INDEXES)
167
return UV_ENOMEM;
168
return 0;
169
}
170
171
inline void nauv_key_delete(nauv_key_t* key) {
172
if (TlsFree(key->tls_index) == FALSE)
173
abort();
174
key->tls_index = TLS_OUT_OF_INDEXES;
175
}
176
177
inline void* nauv_key_get(nauv_key_t* key) {
178
void* value = TlsGetValue(key->tls_index);
179
if (value == NULL)
180
if (GetLastError() != ERROR_SUCCESS)
181
abort();
182
return value;
183
}
184
185
inline void nauv_key_set(nauv_key_t* key, void* value) {
186
if (TlsSetValue(key->tls_index, value) == FALSE)
187
abort();
188
}
189
190
#endif
191
#endif
192
193
// some generic helpers
194
195
template<typename T> NAN_INLINE bool NanSetPointerSafe(
196
T *var
197
, T val
198
) {
199
if (var) {
200
*var = val;
201
return true;
202
} else {
203
return false;
204
}
205
}
206
207
template<typename T> NAN_INLINE T NanGetPointerSafe(
208
T *var
209
, T fallback = reinterpret_cast<T>(0)
210
) {
211
if (var) {
212
return *var;
213
} else {
214
return fallback;
215
}
216
}
217
218
NAN_INLINE bool NanBooleanOptionValue(
219
v8::Local<v8::Object> optionsObj
220
, v8::Handle<v8::String> opt, bool def
221
) {
222
if (def) {
223
return optionsObj.IsEmpty()
224
|| !optionsObj->Has(opt)
225
|| optionsObj->Get(opt)->BooleanValue();
226
} else {
227
return !optionsObj.IsEmpty()
228
&& optionsObj->Has(opt)
229
&& optionsObj->Get(opt)->BooleanValue();
230
}
231
}
232
233
NAN_INLINE bool NanBooleanOptionValue(
234
v8::Local<v8::Object> optionsObj
235
, v8::Handle<v8::String> opt
236
) {
237
return NanBooleanOptionValue(optionsObj, opt, false);
238
}
239
240
NAN_INLINE uint32_t NanUInt32OptionValue(
241
v8::Local<v8::Object> optionsObj
242
, v8::Handle<v8::String> opt
243
, uint32_t def
244
) {
245
return !optionsObj.IsEmpty()
246
&& optionsObj->Has(opt)
247
&& optionsObj->Get(opt)->IsNumber()
248
? optionsObj->Get(opt)->Uint32Value()
249
: def;
250
}
251
252
template<typename T>
253
v8::Local<T> NanNew(v8::Handle<T>);
254
255
template<typename T>
256
NAN_INLINE v8::Local<T> _NanEnsureLocal(v8::Handle<T> val) {
257
return NanNew(val);
258
}
259
260
template<typename T>
261
NAN_INLINE v8::Local<T> _NanEnsureLocal(v8::Local<T> val) {
262
return val;
263
}
264
265
template<typename T>
266
NAN_INLINE v8::Local<v8::Value> _NanEnsureLocal(T val) {
267
return NanNew(val);
268
}
269
270
/* io.js 1.0 */
271
#if NODE_MODULE_VERSION >= IOJS_1_0_MODULE_VERSION \
272
|| NODE_VERSION_AT_LEAST(0, 11, 15)
273
NAN_INLINE
274
void NanSetCounterFunction(v8::CounterLookupCallback cb) {
275
v8::Isolate::GetCurrent()->SetCounterFunction(cb);
276
}
277
278
NAN_INLINE
279
void NanSetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
280
v8::Isolate::GetCurrent()->SetCreateHistogramFunction(cb);
281
}
282
283
NAN_INLINE
284
void NanSetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
285
v8::Isolate::GetCurrent()->SetAddHistogramSampleFunction(cb);
286
}
287
288
NAN_INLINE bool NanIdleNotification(int idle_time_in_ms) {
289
return v8::Isolate::GetCurrent()->IdleNotification(idle_time_in_ms);
290
}
291
292
NAN_INLINE void NanLowMemoryNotification() {
293
v8::Isolate::GetCurrent()->LowMemoryNotification();
294
}
295
296
NAN_INLINE void NanContextDisposedNotification() {
297
v8::Isolate::GetCurrent()->ContextDisposedNotification();
298
}
299
#else
300
NAN_INLINE
301
void NanSetCounterFunction(v8::CounterLookupCallback cb) {
302
v8::V8::SetCounterFunction(cb);
303
}
304
305
NAN_INLINE
306
void NanSetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
307
v8::V8::SetCreateHistogramFunction(cb);
308
}
309
310
NAN_INLINE
311
void NanSetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
312
v8::V8::SetAddHistogramSampleFunction(cb);
313
}
314
315
NAN_INLINE bool NanIdleNotification(int idle_time_in_ms) {
316
return v8::V8::IdleNotification(idle_time_in_ms);
317
}
318
319
NAN_INLINE void NanLowMemoryNotification() {
320
v8::V8::LowMemoryNotification();
321
}
322
323
NAN_INLINE void NanContextDisposedNotification() {
324
v8::V8::ContextDisposedNotification();
325
}
326
#endif
327
328
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
329
// Node 0.11+ (0.11.12 and below won't compile with these)
330
331
# define _NAN_METHOD_ARGS_TYPE const v8::FunctionCallbackInfo<v8::Value>&
332
# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args
333
# define _NAN_METHOD_RETURN_TYPE void
334
335
# define _NAN_GETTER_ARGS_TYPE const v8::PropertyCallbackInfo<v8::Value>&
336
# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args
337
# define _NAN_GETTER_RETURN_TYPE void
338
339
# define _NAN_SETTER_ARGS_TYPE const v8::PropertyCallbackInfo<void>&
340
# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args
341
# define _NAN_SETTER_RETURN_TYPE void
342
343
# define _NAN_PROPERTY_GETTER_ARGS_TYPE \
344
const v8::PropertyCallbackInfo<v8::Value>&
345
# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args
346
# define _NAN_PROPERTY_GETTER_RETURN_TYPE void
347
348
# define _NAN_PROPERTY_SETTER_ARGS_TYPE \
349
const v8::PropertyCallbackInfo<v8::Value>&
350
# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args
351
# define _NAN_PROPERTY_SETTER_RETURN_TYPE void
352
353
# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE \
354
const v8::PropertyCallbackInfo<v8::Array>&
355
# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args
356
# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE void
357
358
# define _NAN_PROPERTY_DELETER_ARGS_TYPE \
359
const v8::PropertyCallbackInfo<v8::Boolean>&
360
# define _NAN_PROPERTY_DELETER_ARGS \
361
_NAN_PROPERTY_DELETER_ARGS_TYPE args
362
# define _NAN_PROPERTY_DELETER_RETURN_TYPE void
363
364
# define _NAN_PROPERTY_QUERY_ARGS_TYPE \
365
const v8::PropertyCallbackInfo<v8::Integer>&
366
# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args
367
# define _NAN_PROPERTY_QUERY_RETURN_TYPE void
368
369
# define _NAN_INDEX_GETTER_ARGS_TYPE \
370
const v8::PropertyCallbackInfo<v8::Value>&
371
# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args
372
# define _NAN_INDEX_GETTER_RETURN_TYPE void
373
374
# define _NAN_INDEX_SETTER_ARGS_TYPE \
375
const v8::PropertyCallbackInfo<v8::Value>&
376
# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args
377
# define _NAN_INDEX_SETTER_RETURN_TYPE void
378
379
# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE \
380
const v8::PropertyCallbackInfo<v8::Array>&
381
# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args
382
# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE void
383
384
# define _NAN_INDEX_DELETER_ARGS_TYPE \
385
const v8::PropertyCallbackInfo<v8::Boolean>&
386
# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args
387
# define _NAN_INDEX_DELETER_RETURN_TYPE void
388
389
# define _NAN_INDEX_QUERY_ARGS_TYPE \
390
const v8::PropertyCallbackInfo<v8::Integer>&
391
# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args
392
# define _NAN_INDEX_QUERY_RETURN_TYPE void
393
394
# define NanScope() v8::HandleScope scope(v8::Isolate::GetCurrent())
395
# define NanEscapableScope() \
396
v8::EscapableHandleScope scope(v8::Isolate::GetCurrent())
397
398
# define NanEscapeScope(val) scope.Escape(_NanEnsureLocal(val))
399
# define NanLocker() v8::Locker locker(v8::Isolate::GetCurrent())
400
# define NanUnlocker() v8::Unlocker unlocker(v8::Isolate::GetCurrent())
401
# define NanReturnValue(value) return args.GetReturnValue().Set(_NanEnsureLocal(value))
402
# define NanReturnUndefined() return
403
# define NanReturnHolder() NanReturnValue(args.Holder())
404
# define NanReturnThis() NanReturnValue(args.This())
405
# define NanReturnNull() return args.GetReturnValue().SetNull()
406
# define NanReturnEmptyString() return args.GetReturnValue().SetEmptyString()
407
408
NAN_INLINE v8::Local<v8::Object> NanObjectWrapHandle(const node::ObjectWrap *obj) {
409
return const_cast<node::ObjectWrap*>(obj)->handle();
410
}
411
412
NAN_INLINE v8::Local<v8::Primitive> NanUndefined() {
413
NanEscapableScope();
414
return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent())));
415
}
416
417
NAN_INLINE v8::Local<v8::Primitive> NanNull() {
418
NanEscapableScope();
419
return NanEscapeScope(NanNew(v8::Null(v8::Isolate::GetCurrent())));
420
}
421
422
NAN_INLINE v8::Local<v8::Boolean> NanTrue() {
423
NanEscapableScope();
424
return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent())));
425
}
426
427
NAN_INLINE v8::Local<v8::Boolean> NanFalse() {
428
NanEscapableScope();
429
return NanEscapeScope(NanNew(v8::False(v8::Isolate::GetCurrent())));
430
}
431
432
NAN_INLINE int NanAdjustExternalMemory(int bc) {
433
return static_cast<int>(
434
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));
435
}
436
437
NAN_INLINE void NanSetTemplate(
438
v8::Handle<v8::Template> templ
439
, const char *name
440
, v8::Handle<v8::Data> value) {
441
templ->Set(v8::Isolate::GetCurrent(), name, value);
442
}
443
444
NAN_INLINE void NanSetTemplate(
445
v8::Handle<v8::Template> templ
446
, v8::Handle<v8::String> name
447
, v8::Handle<v8::Data> value
448
, v8::PropertyAttribute attributes) {
449
templ->Set(name, value, attributes);
450
}
451
452
NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {
453
return v8::Isolate::GetCurrent()->GetCurrentContext();
454
}
455
456
NAN_INLINE void* NanGetInternalFieldPointer(
457
v8::Handle<v8::Object> object
458
, int index) {
459
return object->GetAlignedPointerFromInternalField(index);
460
}
461
462
NAN_INLINE void NanSetInternalFieldPointer(
463
v8::Handle<v8::Object> object
464
, int index
465
, void* value) {
466
object->SetAlignedPointerInInternalField(index, value);
467
}
468
469
# define NAN_GC_CALLBACK(name) \
470
void name(v8::Isolate *isolate, v8::GCType type, v8::GCCallbackFlags flags)
471
472
NAN_INLINE void NanAddGCEpilogueCallback(
473
v8::Isolate::GCEpilogueCallback callback
474
, v8::GCType gc_type_filter = v8::kGCTypeAll) {
475
v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter);
476
}
477
478
NAN_INLINE void NanRemoveGCEpilogueCallback(
479
v8::Isolate::GCEpilogueCallback callback) {
480
v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback);
481
}
482
483
NAN_INLINE void NanAddGCPrologueCallback(
484
v8::Isolate::GCPrologueCallback callback
485
, v8::GCType gc_type_filter = v8::kGCTypeAll) {
486
v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter);
487
}
488
489
NAN_INLINE void NanRemoveGCPrologueCallback(
490
v8::Isolate::GCPrologueCallback callback) {
491
v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback);
492
}
493
494
NAN_INLINE void NanGetHeapStatistics(
495
v8::HeapStatistics *heap_statistics) {
496
v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics);
497
}
498
499
NAN_DEPRECATED NAN_INLINE v8::Local<v8::String> NanSymbol(
500
const char* data, int length = -1) {
501
return NanNew<v8::String>(data, length);
502
}
503
504
template<typename T>
505
NAN_INLINE void NanAssignPersistent(
506
v8::Persistent<T>& handle
507
, v8::Handle<T> obj) {
508
handle.Reset(v8::Isolate::GetCurrent(), obj);
509
}
510
511
template<typename T>
512
NAN_INLINE void NanAssignPersistent(
513
v8::Persistent<T>& handle
514
, const v8::Persistent<T>& obj) {
515
handle.Reset(v8::Isolate::GetCurrent(), obj);
516
}
517
518
template<typename T, typename P>
519
class _NanWeakCallbackData;
520
521
template<typename T, typename P>
522
struct _NanWeakCallbackInfo {
523
typedef void (*Callback)(const _NanWeakCallbackData<T, P>& data);
524
NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> handle, P* param, Callback cb)
525
: parameter(param), callback(cb) {
526
NanAssignPersistent(persistent, handle);
527
}
528
529
NAN_INLINE ~_NanWeakCallbackInfo() {
530
persistent.Reset();
531
}
532
533
P* const parameter;
534
Callback const callback;
535
v8::Persistent<T> persistent;
536
};
537
538
template<typename T, typename P>
539
class _NanWeakCallbackData {
540
public:
541
NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info)
542
: info_(info) { }
543
544
NAN_INLINE v8::Local<T> GetValue() const {
545
return NanNew(info_->persistent);
546
}
547
548
NAN_INLINE P* GetParameter() const { return info_->parameter; }
549
550
NAN_INLINE bool IsNearDeath() const {
551
return info_->persistent.IsNearDeath();
552
}
553
554
NAN_INLINE void Revive() const;
555
556
NAN_INLINE _NanWeakCallbackInfo<T, P>* GetCallbackInfo() const {
557
return info_;
558
}
559
560
NAN_DEPRECATED NAN_INLINE void Dispose() const {
561
}
562
563
private:
564
_NanWeakCallbackInfo<T, P>* info_;
565
};
566
567
template<typename T, typename P>
568
static void _NanWeakCallbackDispatcher(
569
const v8::WeakCallbackData<T, _NanWeakCallbackInfo<T, P> > &data) {
570
_NanWeakCallbackInfo<T, P> *info = data.GetParameter();
571
_NanWeakCallbackData<T, P> wcbd(info);
572
info->callback(wcbd);
573
if (wcbd.IsNearDeath()) {
574
delete wcbd.GetCallbackInfo();
575
}
576
}
577
578
template<typename T, typename P>
579
NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const {
580
info_->persistent.SetWeak(info_, &_NanWeakCallbackDispatcher<T, P>);
581
}
582
583
template<typename T, typename P>
584
NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
585
v8::Handle<T> handle
586
, P* parameter
587
, typename _NanWeakCallbackInfo<T, P>::Callback callback) {
588
_NanWeakCallbackInfo<T, P> *cbinfo =
589
new _NanWeakCallbackInfo<T, P>(handle, parameter, callback);
590
cbinfo->persistent.SetWeak(cbinfo, &_NanWeakCallbackDispatcher<T, P>);
591
return cbinfo;
592
}
593
594
# define NAN_WEAK_CALLBACK(name) \
595
template<typename T, typename P> \
596
static void name(const _NanWeakCallbackData<T, P> &data)
597
598
# define _NAN_ERROR(fun, errmsg) fun(NanNew<v8::String>(errmsg))
599
600
# define _NAN_THROW_ERROR(fun, errmsg) \
601
do { \
602
NanScope(); \
603
v8::Isolate::GetCurrent()->ThrowException(_NAN_ERROR(fun, errmsg)); \
604
} while (0);
605
606
NAN_INLINE v8::Local<v8::Value> NanError(const char* errmsg) {
607
return _NAN_ERROR(v8::Exception::Error, errmsg);
608
}
609
610
NAN_INLINE void NanThrowError(const char* errmsg) {
611
_NAN_THROW_ERROR(v8::Exception::Error, errmsg);
612
}
613
614
NAN_INLINE void NanThrowError(v8::Handle<v8::Value> error) {
615
NanScope();
616
v8::Isolate::GetCurrent()->ThrowException(error);
617
}
618
619
NAN_INLINE v8::Local<v8::Value> NanError(
620
const char *msg
621
, const int errorNumber
622
) {
623
v8::Local<v8::Value> err = v8::Exception::Error(NanNew<v8::String>(msg));
624
v8::Local<v8::Object> obj = err.As<v8::Object>();
625
obj->Set(NanNew<v8::String>("code"), NanNew<v8::Integer>(errorNumber));
626
return err;
627
}
628
629
NAN_INLINE void NanThrowError(
630
const char *msg
631
, const int errorNumber
632
) {
633
NanThrowError(NanError(msg, errorNumber));
634
}
635
636
NAN_INLINE v8::Local<v8::Value> NanTypeError(const char* errmsg) {
637
return _NAN_ERROR(v8::Exception::TypeError, errmsg);
638
}
639
640
NAN_INLINE void NanThrowTypeError(const char* errmsg) {
641
_NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);
642
}
643
644
NAN_INLINE v8::Local<v8::Value> NanRangeError(const char* errmsg) {
645
return _NAN_ERROR(v8::Exception::RangeError, errmsg);
646
}
647
648
NAN_INLINE void NanThrowRangeError(const char* errmsg) {
649
_NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);
650
}
651
652
template<typename T> NAN_INLINE void NanDisposePersistent(
653
v8::Persistent<T> &handle
654
) {
655
handle.Reset();
656
}
657
658
NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
659
char *data
660
, size_t length
661
, node::smalloc::FreeCallback callback
662
, void *hint
663
) {
664
return node::Buffer::New(
665
v8::Isolate::GetCurrent(), data, length, callback, hint);
666
}
667
668
NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
669
const char *data
670
, uint32_t size
671
) {
672
return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
673
}
674
675
NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {
676
return node::Buffer::New(v8::Isolate::GetCurrent(), size);
677
}
678
679
NAN_INLINE v8::Local<v8::Object> NanBufferUse(
680
char* data
681
, uint32_t size
682
) {
683
return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);
684
}
685
686
NAN_INLINE bool NanHasInstance(
687
const v8::Persistent<v8::FunctionTemplate>& function_template
688
, v8::Handle<v8::Value> value
689
) {
690
return NanNew(function_template)->HasInstance(value);
691
}
692
693
NAN_DEPRECATED NAN_INLINE v8::Local<v8::Context> NanNewContextHandle(
694
v8::ExtensionConfiguration* extensions = NULL
695
, v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>()
696
, v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()
697
) {
698
v8::Isolate* isolate = v8::Isolate::GetCurrent();
699
return v8::Local<v8::Context>::New(
700
isolate
701
, v8::Context::New(isolate, extensions, tmpl, obj)
702
);
703
}
704
705
NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
706
v8::Local<v8::String> s
707
, const v8::ScriptOrigin& origin
708
) {
709
v8::ScriptCompiler::Source source(s, origin);
710
return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
711
}
712
713
NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
714
v8::Local<v8::String> s
715
) {
716
v8::ScriptCompiler::Source source(s);
717
return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
718
}
719
720
NAN_INLINE v8::Local<v8::Value> NanRunScript(
721
v8::Handle<NanUnboundScript> script
722
) {
723
return script->BindToCurrentContext()->Run();
724
}
725
726
NAN_INLINE v8::Local<v8::Value> NanRunScript(
727
v8::Handle<NanBoundScript> script
728
) {
729
return script->Run();
730
}
731
732
NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
733
v8::Handle<v8::Object> target
734
, v8::Handle<v8::Function> func
735
, int argc
736
, v8::Handle<v8::Value>* argv) {
737
return NanNew(node::MakeCallback(
738
v8::Isolate::GetCurrent(), target, func, argc, argv));
739
}
740
741
NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
742
v8::Handle<v8::Object> target
743
, v8::Handle<v8::String> symbol
744
, int argc
745
, v8::Handle<v8::Value>* argv) {
746
return NanNew(node::MakeCallback(
747
v8::Isolate::GetCurrent(), target, symbol, argc, argv));
748
}
749
750
NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
751
v8::Handle<v8::Object> target
752
, const char* method
753
, int argc
754
, v8::Handle<v8::Value>* argv) {
755
return NanNew(node::MakeCallback(
756
v8::Isolate::GetCurrent(), target, method, argc, argv));
757
}
758
759
template<typename T>
760
NAN_INLINE void NanSetIsolateData(
761
v8::Isolate *isolate
762
, T *data
763
) {
764
isolate->SetData(0, data);
765
}
766
767
template<typename T>
768
NAN_INLINE T *NanGetIsolateData(
769
v8::Isolate *isolate
770
) {
771
return static_cast<T*>(isolate->GetData(0));
772
}
773
774
class NanAsciiString {
775
public:
776
NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {
777
v8::Local<v8::String> toStr = from->ToString();
778
size = toStr->Length();
779
buf = new char[size + 1];
780
size = toStr->WriteOneByte(reinterpret_cast<unsigned char*>(buf));
781
}
782
783
NAN_DEPRECATED NAN_INLINE int Size() const {
784
return size;
785
}
786
787
NAN_INLINE int length() const {
788
return size;
789
}
790
791
792
NAN_INLINE char* operator*() { return buf; }
793
NAN_INLINE const char* operator*() const { return buf; }
794
795
NAN_INLINE ~NanAsciiString() {
796
delete[] buf;
797
}
798
799
private:
800
// disallow copying and assigning
801
NanAsciiString(const NanAsciiString&);
802
void operator=(const NanAsciiString&);
803
804
char *buf;
805
int size;
806
};
807
808
class NanUtf8String {
809
public:
810
NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {
811
v8::Local<v8::String> toStr = from->ToString();
812
size = toStr->Utf8Length();
813
buf = new char[size + 1];
814
toStr->WriteUtf8(buf);
815
}
816
817
NAN_DEPRECATED NAN_INLINE int Size() const {
818
return size;
819
}
820
821
NAN_INLINE int length() const {
822
return size;
823
}
824
825
NAN_INLINE char* operator*() { return buf; }
826
NAN_INLINE const char* operator*() const { return buf; }
827
828
NAN_INLINE ~NanUtf8String() {
829
delete[] buf;
830
}
831
832
private:
833
// disallow copying and assigning
834
NanUtf8String(const NanUtf8String&);
835
void operator=(const NanUtf8String&);
836
837
char *buf;
838
int size;
839
};
840
841
class NanUcs2String {
842
public:
843
NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {
844
v8::Local<v8::String> toStr = from->ToString();
845
size = toStr->Length();
846
buf = new uint16_t[size + 1];
847
toStr->Write(buf);
848
}
849
850
NAN_DEPRECATED NAN_INLINE int Size() const {
851
return size;
852
}
853
854
NAN_INLINE int length() const {
855
return size;
856
}
857
858
NAN_INLINE uint16_t* operator*() { return buf; }
859
NAN_INLINE const uint16_t* operator*() const { return buf; }
860
861
NAN_INLINE ~NanUcs2String() {
862
delete[] buf;
863
}
864
865
private:
866
// disallow copying and assigning
867
NanUcs2String(const NanUcs2String&);
868
void operator=(const NanUcs2String&);
869
870
uint16_t *buf;
871
int size;
872
};
873
874
#else
875
// Node 0.8 and 0.10
876
877
# define _NAN_METHOD_ARGS_TYPE const v8::Arguments&
878
# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args
879
# define _NAN_METHOD_RETURN_TYPE v8::Handle<v8::Value>
880
881
# define _NAN_GETTER_ARGS_TYPE const v8::AccessorInfo &
882
# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args
883
# define _NAN_GETTER_RETURN_TYPE v8::Handle<v8::Value>
884
885
# define _NAN_SETTER_ARGS_TYPE const v8::AccessorInfo &
886
# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args
887
# define _NAN_SETTER_RETURN_TYPE void
888
889
# define _NAN_PROPERTY_GETTER_ARGS_TYPE const v8::AccessorInfo&
890
# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args
891
# define _NAN_PROPERTY_GETTER_RETURN_TYPE v8::Handle<v8::Value>
892
893
# define _NAN_PROPERTY_SETTER_ARGS_TYPE const v8::AccessorInfo&
894
# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args
895
# define _NAN_PROPERTY_SETTER_RETURN_TYPE v8::Handle<v8::Value>
896
897
# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo&
898
# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args
899
# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE v8::Handle<v8::Array>
900
901
# define _NAN_PROPERTY_DELETER_ARGS_TYPE const v8::AccessorInfo&
902
# define _NAN_PROPERTY_DELETER_ARGS _NAN_PROPERTY_DELETER_ARGS_TYPE args
903
# define _NAN_PROPERTY_DELETER_RETURN_TYPE v8::Handle<v8::Boolean>
904
905
# define _NAN_PROPERTY_QUERY_ARGS_TYPE const v8::AccessorInfo&
906
# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args
907
# define _NAN_PROPERTY_QUERY_RETURN_TYPE v8::Handle<v8::Integer>
908
909
# define _NAN_INDEX_GETTER_ARGS_TYPE const v8::AccessorInfo&
910
# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args
911
# define _NAN_INDEX_GETTER_RETURN_TYPE v8::Handle<v8::Value>
912
913
# define _NAN_INDEX_SETTER_ARGS_TYPE const v8::AccessorInfo&
914
# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args
915
# define _NAN_INDEX_SETTER_RETURN_TYPE v8::Handle<v8::Value>
916
917
# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo&
918
# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args
919
# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE v8::Handle<v8::Array>
920
921
# define _NAN_INDEX_DELETER_ARGS_TYPE const v8::AccessorInfo&
922
# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args
923
# define _NAN_INDEX_DELETER_RETURN_TYPE v8::Handle<v8::Boolean>
924
925
# define _NAN_INDEX_QUERY_ARGS_TYPE const v8::AccessorInfo&
926
# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args
927
# define _NAN_INDEX_QUERY_RETURN_TYPE v8::Handle<v8::Integer>
928
929
NAN_DEPRECATED NAN_INLINE v8::Local<v8::String> NanSymbol(
930
const char* data, int length = -1) {
931
return v8::String::NewSymbol(data, length);
932
}
933
934
# define NanScope() v8::HandleScope scope
935
# define NanEscapableScope() v8::HandleScope scope
936
# define NanEscapeScope(val) scope.Close(val)
937
# define NanLocker() v8::Locker locker
938
# define NanUnlocker() v8::Unlocker unlocker
939
# define NanReturnValue(value) return scope.Close(_NanEnsureLocal(value))
940
# define NanReturnHolder() NanReturnValue(args.Holder())
941
# define NanReturnThis() NanReturnValue(args.This())
942
# define NanReturnUndefined() return v8::Undefined()
943
# define NanReturnNull() return v8::Null()
944
# define NanReturnEmptyString() return v8::String::Empty()
945
946
NAN_INLINE v8::Local<v8::Object> NanObjectWrapHandle(const node::ObjectWrap *obj) {
947
return v8::Local<v8::Object>::New(obj->handle_);
948
}
949
950
NAN_INLINE v8::Local<v8::Primitive> NanUndefined() {
951
NanEscapableScope();
952
return NanEscapeScope(NanNew(v8::Undefined()));
953
}
954
955
NAN_INLINE v8::Local<v8::Primitive> NanNull() {
956
NanEscapableScope();
957
return NanEscapeScope(NanNew(v8::Null()));
958
}
959
960
NAN_INLINE v8::Local<v8::Boolean> NanTrue() {
961
NanEscapableScope();
962
return NanEscapeScope(NanNew(v8::True()));
963
}
964
965
NAN_INLINE v8::Local<v8::Boolean> NanFalse() {
966
NanEscapableScope();
967
return NanEscapeScope(NanNew(v8::False()));
968
}
969
970
NAN_INLINE int NanAdjustExternalMemory(int bc) {
971
return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));
972
}
973
974
NAN_INLINE void NanSetTemplate(
975
v8::Handle<v8::Template> templ
976
, const char *name
977
, v8::Handle<v8::Data> value) {
978
templ->Set(name, value);
979
}
980
981
NAN_INLINE void NanSetTemplate(
982
v8::Handle<v8::Template> templ
983
, v8::Handle<v8::String> name
984
, v8::Handle<v8::Data> value
985
, v8::PropertyAttribute attributes) {
986
templ->Set(name, value, attributes);
987
}
988
989
NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {
990
return v8::Context::GetCurrent();
991
}
992
993
NAN_INLINE void* NanGetInternalFieldPointer(
994
v8::Handle<v8::Object> object
995
, int index) {
996
return object->GetPointerFromInternalField(index);
997
}
998
999
NAN_INLINE void NanSetInternalFieldPointer(
1000
v8::Handle<v8::Object> object
1001
, int index
1002
, void* value) {
1003
object->SetPointerInInternalField(index, value);
1004
}
1005
1006
# define NAN_GC_CALLBACK(name) \
1007
void name(v8::GCType type, v8::GCCallbackFlags flags)
1008
1009
NAN_INLINE void NanAddGCEpilogueCallback(
1010
v8::GCEpilogueCallback callback
1011
, v8::GCType gc_type_filter = v8::kGCTypeAll) {
1012
v8::V8::AddGCEpilogueCallback(callback, gc_type_filter);
1013
}
1014
NAN_INLINE void NanRemoveGCEpilogueCallback(
1015
v8::GCEpilogueCallback callback) {
1016
v8::V8::RemoveGCEpilogueCallback(callback);
1017
}
1018
NAN_INLINE void NanAddGCPrologueCallback(
1019
v8::GCPrologueCallback callback
1020
, v8::GCType gc_type_filter = v8::kGCTypeAll) {
1021
v8::V8::AddGCPrologueCallback(callback, gc_type_filter);
1022
}
1023
NAN_INLINE void NanRemoveGCPrologueCallback(
1024
v8::GCPrologueCallback callback) {
1025
v8::V8::RemoveGCPrologueCallback(callback);
1026
}
1027
NAN_INLINE void NanGetHeapStatistics(
1028
v8::HeapStatistics *heap_statistics) {
1029
v8::V8::GetHeapStatistics(heap_statistics);
1030
}
1031
1032
template<typename T>
1033
NAN_INLINE void NanAssignPersistent(
1034
v8::Persistent<T>& handle
1035
, v8::Handle<T> obj) {
1036
handle.Dispose();
1037
handle = v8::Persistent<T>::New(obj);
1038
}
1039
1040
template<typename T, typename P>
1041
class _NanWeakCallbackData;
1042
1043
template<typename T, typename P>
1044
struct _NanWeakCallbackInfo {
1045
typedef void (*Callback)(const _NanWeakCallbackData<T, P> &data);
1046
NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> handle, P* param, Callback cb)
1047
: parameter(param)
1048
, callback(cb)
1049
, persistent(v8::Persistent<T>::New(handle)) { }
1050
1051
NAN_INLINE ~_NanWeakCallbackInfo() {
1052
persistent.Dispose();
1053
persistent.Clear();
1054
}
1055
1056
P* const parameter;
1057
Callback const callback;
1058
v8::Persistent<T> persistent;
1059
};
1060
1061
template<typename T, typename P>
1062
class _NanWeakCallbackData {
1063
public:
1064
NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info)
1065
: info_(info) { }
1066
1067
NAN_INLINE v8::Local<T> GetValue() const {
1068
return NanNew(info_->persistent);
1069
}
1070
1071
NAN_INLINE P* GetParameter() const { return info_->parameter; }
1072
1073
NAN_INLINE bool IsNearDeath() const {
1074
return info_->persistent.IsNearDeath();
1075
}
1076
1077
NAN_INLINE void Revive() const;
1078
1079
NAN_INLINE _NanWeakCallbackInfo<T, P>* GetCallbackInfo() const {
1080
return info_;
1081
}
1082
1083
NAN_DEPRECATED NAN_INLINE void Dispose() const {
1084
}
1085
1086
private:
1087
_NanWeakCallbackInfo<T, P>* info_;
1088
};
1089
1090
template<typename T, typename P>
1091
static void _NanWeakPersistentDispatcher(
1092
v8::Persistent<v8::Value> object, void *data) {
1093
_NanWeakCallbackInfo<T, P>* info =
1094
static_cast<_NanWeakCallbackInfo<T, P>*>(data);
1095
_NanWeakCallbackData<T, P> wcbd(info);
1096
info->callback(wcbd);
1097
if (wcbd.IsNearDeath()) {
1098
delete wcbd.GetCallbackInfo();
1099
}
1100
}
1101
1102
template<typename T, typename P>
1103
NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const {
1104
info_->persistent.MakeWeak(
1105
info_
1106
, &_NanWeakPersistentDispatcher<T, P>);
1107
}
1108
1109
template<typename T, typename P>
1110
NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
1111
v8::Handle<T> handle
1112
, P* parameter
1113
, typename _NanWeakCallbackInfo<T, P>::Callback callback) {
1114
_NanWeakCallbackInfo<T, P> *cbinfo =
1115
new _NanWeakCallbackInfo<T, P>(handle, parameter, callback);
1116
cbinfo->persistent.MakeWeak(
1117
cbinfo
1118
, &_NanWeakPersistentDispatcher<T, P>);
1119
return cbinfo;
1120
}
1121
1122
# define NAN_WEAK_CALLBACK(name) \
1123
template<typename T, typename P> \
1124
static void name(const _NanWeakCallbackData<T, P> &data)
1125
1126
# define _NAN_ERROR(fun, errmsg) \
1127
fun(v8::String::New(errmsg))
1128
1129
# define _NAN_THROW_ERROR(fun, errmsg) \
1130
do { \
1131
NanScope(); \
1132
return v8::Local<v8::Value>::New( \
1133
v8::ThrowException(_NAN_ERROR(fun, errmsg))); \
1134
} while (0);
1135
1136
NAN_INLINE v8::Local<v8::Value> NanError(const char* errmsg) {
1137
return _NAN_ERROR(v8::Exception::Error, errmsg);
1138
}
1139
1140
NAN_INLINE v8::Local<v8::Value> NanThrowError(const char* errmsg) {
1141
_NAN_THROW_ERROR(v8::Exception::Error, errmsg);
1142
}
1143
1144
NAN_INLINE v8::Local<v8::Value> NanThrowError(
1145
v8::Handle<v8::Value> error
1146
) {
1147
NanScope();
1148
return v8::Local<v8::Value>::New(v8::ThrowException(error));
1149
}
1150
1151
NAN_INLINE v8::Local<v8::Value> NanError(
1152
const char *msg
1153
, const int errorNumber
1154
) {
1155
v8::Local<v8::Value> err = v8::Exception::Error(v8::String::New(msg));
1156
v8::Local<v8::Object> obj = err.As<v8::Object>();
1157
obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber));
1158
return err;
1159
}
1160
1161
NAN_INLINE v8::Local<v8::Value> NanThrowError(
1162
const char *msg
1163
, const int errorNumber
1164
) {
1165
return NanThrowError(NanError(msg, errorNumber));
1166
}
1167
1168
NAN_INLINE v8::Local<v8::Value> NanTypeError(const char* errmsg) {
1169
return _NAN_ERROR(v8::Exception::TypeError, errmsg);
1170
}
1171
1172
NAN_INLINE v8::Local<v8::Value> NanThrowTypeError(
1173
const char* errmsg
1174
) {
1175
_NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);
1176
}
1177
1178
NAN_INLINE v8::Local<v8::Value> NanRangeError(
1179
const char* errmsg
1180
) {
1181
return _NAN_ERROR(v8::Exception::RangeError, errmsg);
1182
}
1183
1184
NAN_INLINE v8::Local<v8::Value> NanThrowRangeError(
1185
const char* errmsg
1186
) {
1187
_NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);
1188
}
1189
1190
template<typename T>
1191
NAN_INLINE void NanDisposePersistent(
1192
v8::Persistent<T> &handle) { // NOLINT(runtime/references)
1193
handle.Dispose();
1194
handle.Clear();
1195
}
1196
1197
NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
1198
char *data
1199
, size_t length
1200
, node::Buffer::free_callback callback
1201
, void *hint
1202
) {
1203
return NanNew(
1204
node::Buffer::New(data, length, callback, hint)->handle_);
1205
}
1206
1207
NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
1208
const char *data
1209
, uint32_t size
1210
) {
1211
#if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION
1212
return NanNew(node::Buffer::New(data, size)->handle_);
1213
#else
1214
return NanNew(
1215
node::Buffer::New(const_cast<char*>(data), size)->handle_);
1216
#endif
1217
}
1218
1219
NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {
1220
return NanNew(node::Buffer::New(size)->handle_);
1221
}
1222
1223
NAN_INLINE void FreeData(char *data, void *hint) {
1224
delete[] data;
1225
}
1226
1227
NAN_INLINE v8::Local<v8::Object> NanBufferUse(
1228
char* data
1229
, uint32_t size
1230
) {
1231
return NanNew(
1232
node::Buffer::New(data, size, FreeData, NULL)->handle_);
1233
}
1234
1235
NAN_INLINE bool NanHasInstance(
1236
const v8::Persistent<v8::FunctionTemplate>& function_template
1237
, v8::Handle<v8::Value> value
1238
) {
1239
return function_template->HasInstance(value);
1240
}
1241
1242
NAN_DEPRECATED NAN_INLINE v8::Local<v8::Context> NanNewContextHandle(
1243
v8::ExtensionConfiguration* extensions = NULL
1244
, v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>()
1245
, v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()
1246
) {
1247
v8::Persistent<v8::Context> ctx = v8::Context::New(extensions, tmpl, obj);
1248
v8::Local<v8::Context> lctx = NanNew(ctx);
1249
ctx.Dispose();
1250
return lctx;
1251
}
1252
1253
NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
1254
v8::Local<v8::String> s
1255
, const v8::ScriptOrigin& origin
1256
) {
1257
return v8::Script::Compile(s, const_cast<v8::ScriptOrigin *>(&origin));
1258
}
1259
1260
NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
1261
v8::Local<v8::String> s
1262
) {
1263
return v8::Script::Compile(s);
1264
}
1265
1266
NAN_INLINE v8::Local<v8::Value> NanRunScript(v8::Handle<v8::Script> script) {
1267
return script->Run();
1268
}
1269
1270
NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
1271
v8::Handle<v8::Object> target
1272
, v8::Handle<v8::Function> func
1273
, int argc
1274
, v8::Handle<v8::Value>* argv) {
1275
# if NODE_VERSION_AT_LEAST(0, 8, 0)
1276
return NanNew(node::MakeCallback(target, func, argc, argv));
1277
# else
1278
v8::TryCatch try_catch;
1279
v8::Local<v8::Value> result = func->Call(target, argc, argv);
1280
if (try_catch.HasCaught()) {
1281
node::FatalException(try_catch);
1282
}
1283
return result;
1284
# endif
1285
}
1286
1287
NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
1288
v8::Handle<v8::Object> target
1289
, v8::Handle<v8::String> symbol
1290
, int argc
1291
, v8::Handle<v8::Value>* argv) {
1292
# if NODE_VERSION_AT_LEAST(0, 8, 0)
1293
return NanNew(node::MakeCallback(target, symbol, argc, argv));
1294
# else
1295
v8::Local<v8::Function> callback = target->Get(symbol).As<v8::Function>();
1296
return NanMakeCallback(target, callback, argc, argv);
1297
# endif
1298
}
1299
1300
NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
1301
v8::Handle<v8::Object> target
1302
, const char* method
1303
, int argc
1304
, v8::Handle<v8::Value>* argv) {
1305
# if NODE_VERSION_AT_LEAST(0, 8, 0)
1306
return NanNew(node::MakeCallback(target, method, argc, argv));
1307
# else
1308
return NanMakeCallback(target, NanNew(method), argc, argv);
1309
# endif
1310
}
1311
1312
template<typename T>
1313
NAN_INLINE void NanSetIsolateData(
1314
v8::Isolate *isolate
1315
, T *data
1316
) {
1317
isolate->SetData(data);
1318
}
1319
1320
template<typename T>
1321
NAN_INLINE T *NanGetIsolateData(
1322
v8::Isolate *isolate
1323
) {
1324
return static_cast<T*>(isolate->GetData());
1325
}
1326
1327
class NanAsciiString {
1328
public:
1329
NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {
1330
v8::Local<v8::String> toStr = from->ToString();
1331
size = toStr->Length();
1332
buf = new char[size + 1];
1333
size = toStr->WriteAscii(buf);
1334
}
1335
1336
NAN_DEPRECATED NAN_INLINE int Size() const {
1337
return size;
1338
}
1339
1340
NAN_INLINE int length() const {
1341
return size;
1342
}
1343
1344
1345
NAN_INLINE char* operator*() { return buf; }
1346
NAN_INLINE const char* operator*() const { return buf; }
1347
1348
NAN_INLINE ~NanAsciiString() {
1349
delete[] buf;
1350
}
1351
1352
private:
1353
// disallow copying and assigning
1354
NanAsciiString(const NanAsciiString&);
1355
void operator=(const NanAsciiString&);
1356
1357
char *buf;
1358
int size;
1359
};
1360
1361
class NanUtf8String {
1362
public:
1363
NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {
1364
v8::Local<v8::String> toStr = from->ToString();
1365
size = toStr->Utf8Length();
1366
buf = new char[size + 1];
1367
toStr->WriteUtf8(buf);
1368
}
1369
1370
NAN_DEPRECATED NAN_INLINE int Size() const {
1371
return size;
1372
}
1373
1374
NAN_INLINE int length() const {
1375
return size;
1376
}
1377
1378
NAN_INLINE char* operator*() { return buf; }
1379
NAN_INLINE const char* operator*() const { return buf; }
1380
1381
NAN_INLINE ~NanUtf8String() {
1382
delete[] buf;
1383
}
1384
1385
private:
1386
// disallow copying and assigning
1387
NanUtf8String(const NanUtf8String&);
1388
void operator=(const NanUtf8String&);
1389
1390
char *buf;
1391
int size;
1392
};
1393
1394
class NanUcs2String {
1395
public:
1396
NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {
1397
v8::Local<v8::String> toStr = from->ToString();
1398
size = toStr->Length();
1399
buf = new uint16_t[size + 1];
1400
toStr->Write(buf);
1401
}
1402
1403
NAN_DEPRECATED NAN_INLINE int Size() const {
1404
return size;
1405
}
1406
1407
NAN_INLINE int length() const {
1408
return size;
1409
}
1410
1411
NAN_INLINE uint16_t* operator*() { return buf; }
1412
NAN_INLINE const uint16_t* operator*() const { return buf; }
1413
1414
NAN_INLINE ~NanUcs2String() {
1415
delete[] buf;
1416
}
1417
1418
private:
1419
// disallow copying and assigning
1420
NanUcs2String(const NanUcs2String&);
1421
void operator=(const NanUcs2String&);
1422
1423
uint16_t *buf;
1424
int size;
1425
};
1426
1427
#endif // NODE_MODULE_VERSION
1428
1429
typedef void (*NanFreeCallback)(char *data, void *hint);
1430
1431
#define NAN_METHOD(name) _NAN_METHOD_RETURN_TYPE name(_NAN_METHOD_ARGS)
1432
#define NAN_GETTER(name) \
1433
_NAN_GETTER_RETURN_TYPE name( \
1434
v8::Local<v8::String> property \
1435
, _NAN_GETTER_ARGS)
1436
#define NAN_SETTER(name) \
1437
_NAN_SETTER_RETURN_TYPE name( \
1438
v8::Local<v8::String> property \
1439
, v8::Local<v8::Value> value \
1440
, _NAN_SETTER_ARGS)
1441
#define NAN_PROPERTY_GETTER(name) \
1442
_NAN_PROPERTY_GETTER_RETURN_TYPE name( \
1443
v8::Local<v8::String> property \
1444
, _NAN_PROPERTY_GETTER_ARGS)
1445
#define NAN_PROPERTY_SETTER(name) \
1446
_NAN_PROPERTY_SETTER_RETURN_TYPE name( \
1447
v8::Local<v8::String> property \
1448
, v8::Local<v8::Value> value \
1449
, _NAN_PROPERTY_SETTER_ARGS)
1450
#define NAN_PROPERTY_ENUMERATOR(name) \
1451
_NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name(_NAN_PROPERTY_ENUMERATOR_ARGS)
1452
#define NAN_PROPERTY_DELETER(name) \
1453
_NAN_PROPERTY_DELETER_RETURN_TYPE name( \
1454
v8::Local<v8::String> property \
1455
, _NAN_PROPERTY_DELETER_ARGS)
1456
#define NAN_PROPERTY_QUERY(name) \
1457
_NAN_PROPERTY_QUERY_RETURN_TYPE name( \
1458
v8::Local<v8::String> property \
1459
, _NAN_PROPERTY_QUERY_ARGS)
1460
# define NAN_INDEX_GETTER(name) \
1461
_NAN_INDEX_GETTER_RETURN_TYPE name(uint32_t index, _NAN_INDEX_GETTER_ARGS)
1462
#define NAN_INDEX_SETTER(name) \
1463
_NAN_INDEX_SETTER_RETURN_TYPE name( \
1464
uint32_t index \
1465
, v8::Local<v8::Value> value \
1466
, _NAN_INDEX_SETTER_ARGS)
1467
#define NAN_INDEX_ENUMERATOR(name) \
1468
_NAN_INDEX_ENUMERATOR_RETURN_TYPE name(_NAN_INDEX_ENUMERATOR_ARGS)
1469
#define NAN_INDEX_DELETER(name) \
1470
_NAN_INDEX_DELETER_RETURN_TYPE name( \
1471
uint32_t index \
1472
, _NAN_INDEX_DELETER_ARGS)
1473
#define NAN_INDEX_QUERY(name) \
1474
_NAN_INDEX_QUERY_RETURN_TYPE name(uint32_t index, _NAN_INDEX_QUERY_ARGS)
1475
1476
class NanCallback {
1477
public:
1478
NanCallback() {
1479
NanScope();
1480
v8::Local<v8::Object> obj = NanNew<v8::Object>();
1481
NanAssignPersistent(handle, obj);
1482
}
1483
1484
explicit NanCallback(const v8::Handle<v8::Function> &fn) {
1485
NanScope();
1486
v8::Local<v8::Object> obj = NanNew<v8::Object>();
1487
NanAssignPersistent(handle, obj);
1488
SetFunction(fn);
1489
}
1490
1491
~NanCallback() {
1492
if (handle.IsEmpty()) return;
1493
NanDisposePersistent(handle);
1494
}
1495
1496
bool operator==(const NanCallback &other) const {
1497
NanScope();
1498
v8::Local<v8::Value> a = NanNew(handle)->Get(kCallbackIndex);
1499
v8::Local<v8::Value> b = NanNew(other.handle)->Get(kCallbackIndex);
1500
return a->StrictEquals(b);
1501
}
1502
1503
bool operator!=(const NanCallback &other) const {
1504
return !this->operator==(other);
1505
}
1506
1507
NAN_INLINE void SetFunction(const v8::Handle<v8::Function> &fn) {
1508
NanScope();
1509
NanNew(handle)->Set(kCallbackIndex, fn);
1510
}
1511
1512
NAN_INLINE v8::Local<v8::Function> GetFunction() const {
1513
NanEscapableScope();
1514
return NanEscapeScope(NanNew(handle)->Get(kCallbackIndex)
1515
.As<v8::Function>());
1516
}
1517
1518
NAN_INLINE bool IsEmpty() const {
1519
NanScope();
1520
return NanNew(handle)->Get(kCallbackIndex)->IsUndefined();
1521
}
1522
1523
NAN_INLINE v8::Handle<v8::Value>
1524
Call(v8::Handle<v8::Object> target
1525
, int argc
1526
, v8::Handle<v8::Value> argv[]) const {
1527
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1528
v8::Isolate *isolate = v8::Isolate::GetCurrent();
1529
return Call_(isolate, target, argc, argv);
1530
#else
1531
return Call_(target, argc, argv);
1532
#endif
1533
}
1534
1535
NAN_INLINE v8::Handle<v8::Value>
1536
Call(int argc, v8::Handle<v8::Value> argv[]) const {
1537
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1538
v8::Isolate *isolate = v8::Isolate::GetCurrent();
1539
return Call_(isolate, isolate->GetCurrentContext()->Global(), argc, argv);
1540
#else
1541
return Call_(v8::Context::GetCurrent()->Global(), argc, argv);
1542
#endif
1543
}
1544
1545
private:
1546
v8::Persistent<v8::Object> handle;
1547
static const uint32_t kCallbackIndex = 0;
1548
1549
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1550
v8::Handle<v8::Value> Call_(v8::Isolate *isolate
1551
, v8::Handle<v8::Object> target
1552
, int argc
1553
, v8::Handle<v8::Value> argv[]) const {
1554
#else
1555
v8::Handle<v8::Value> Call_(v8::Handle<v8::Object> target
1556
, int argc
1557
, v8::Handle<v8::Value> argv[]) const {
1558
#endif
1559
NanEscapableScope();
1560
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1561
v8::Local<v8::Function> callback = NanNew(handle)->
1562
Get(kCallbackIndex).As<v8::Function>();
1563
return NanEscapeScope(node::MakeCallback(
1564
isolate
1565
, target
1566
, callback
1567
, argc
1568
, argv
1569
));
1570
#else
1571
#if NODE_VERSION_AT_LEAST(0, 8, 0)
1572
v8::Local<v8::Function> callback = handle->
1573
Get(kCallbackIndex).As<v8::Function>();
1574
return NanEscapeScope(node::MakeCallback(
1575
target
1576
, callback
1577
, argc
1578
, argv
1579
));
1580
#else
1581
v8::Local<v8::Function> callback = handle->
1582
Get(kCallbackIndex).As<v8::Function>();
1583
return NanEscapeScope(NanMakeCallback(
1584
target, callback, argc, argv));
1585
#endif
1586
#endif
1587
}
1588
};
1589
1590
/* abstract */ class NanAsyncWorker {
1591
public:
1592
explicit NanAsyncWorker(NanCallback *callback_)
1593
: callback(callback_), errmsg_(NULL) {
1594
request.data = this;
1595
1596
NanScope();
1597
v8::Local<v8::Object> obj = NanNew<v8::Object>();
1598
NanAssignPersistent(persistentHandle, obj);
1599
}
1600
1601
virtual ~NanAsyncWorker() {
1602
NanScope();
1603
1604
if (!persistentHandle.IsEmpty())
1605
NanDisposePersistent(persistentHandle);
1606
if (callback)
1607
delete callback;
1608
if (errmsg_)
1609
delete[] errmsg_;
1610
}
1611
1612
virtual void WorkComplete() {
1613
NanScope();
1614
1615
if (errmsg_ == NULL)
1616
HandleOKCallback();
1617
else
1618
HandleErrorCallback();
1619
delete callback;
1620
callback = NULL;
1621
}
1622
1623
NAN_INLINE void SaveToPersistent(
1624
const char *key, const v8::Local<v8::Object> &obj) {
1625
v8::Local<v8::Object> handle = NanNew(persistentHandle);
1626
handle->Set(NanNew<v8::String>(key), obj);
1627
}
1628
1629
v8::Local<v8::Object> GetFromPersistent(const char *key) const {
1630
NanEscapableScope();
1631
v8::Local<v8::Object> handle = NanNew(persistentHandle);
1632
return NanEscapeScope(handle->Get(NanNew(key)).As<v8::Object>());
1633
}
1634
1635
virtual void Execute() = 0;
1636
1637
uv_work_t request;
1638
1639
virtual void Destroy() {
1640
delete this;
1641
}
1642
1643
protected:
1644
v8::Persistent<v8::Object> persistentHandle;
1645
NanCallback *callback;
1646
1647
virtual void HandleOKCallback() {
1648
callback->Call(0, NULL);
1649
}
1650
1651
virtual void HandleErrorCallback() {
1652
NanScope();
1653
1654
v8::Local<v8::Value> argv[] = {
1655
v8::Exception::Error(NanNew<v8::String>(ErrorMessage()))
1656
};
1657
callback->Call(1, argv);
1658
}
1659
1660
void SetErrorMessage(const char *msg) {
1661
if (errmsg_) {
1662
delete[] errmsg_;
1663
}
1664
1665
size_t size = strlen(msg) + 1;
1666
errmsg_ = new char[size];
1667
memcpy(errmsg_, msg, size);
1668
}
1669
1670
const char* ErrorMessage() const {
1671
return errmsg_;
1672
}
1673
1674
private:
1675
char *errmsg_;
1676
};
1677
1678
/* abstract */ class NanAsyncProgressWorker : public NanAsyncWorker {
1679
public:
1680
explicit NanAsyncProgressWorker(NanCallback *callback_)
1681
: NanAsyncWorker(callback_), asyncdata_(NULL), asyncsize_(0) {
1682
async = new uv_async_t;
1683
uv_async_init(
1684
uv_default_loop()
1685
, async
1686
, AsyncProgress_
1687
);
1688
async->data = this;
1689
1690
uv_mutex_init(&async_lock);
1691
}
1692
1693
virtual ~NanAsyncProgressWorker() {
1694
uv_mutex_destroy(&async_lock);
1695
1696
if (asyncdata_) {
1697
delete[] asyncdata_;
1698
}
1699
}
1700
1701
void WorkProgress() {
1702
uv_mutex_lock(&async_lock);
1703
char *data = asyncdata_;
1704
size_t size = asyncsize_;
1705
asyncdata_ = NULL;
1706
uv_mutex_unlock(&async_lock);
1707
1708
// Dont send progress events after we've already completed.
1709
if (callback) {
1710
HandleProgressCallback(data, size);
1711
}
1712
delete[] data;
1713
}
1714
1715
class ExecutionProgress {
1716
friend class NanAsyncProgressWorker;
1717
public:
1718
// You could do fancy generics with templates here.
1719
void Send(const char* data, size_t size) const {
1720
that_->SendProgress_(data, size);
1721
}
1722
1723
private:
1724
explicit ExecutionProgress(NanAsyncProgressWorker* that) : that_(that) {}
1725
// Prohibit copying and assignment.
1726
ExecutionProgress(const ExecutionProgress&);
1727
void operator=(const ExecutionProgress&);
1728
#if __cplusplus >= 201103L
1729
// Prohibit C++11 move semantics.
1730
ExecutionProgress(ExecutionProgress&&) = delete;
1731
void operator=(ExecutionProgress&&) = delete;
1732
#endif
1733
NanAsyncProgressWorker* const that_;
1734
};
1735
1736
virtual void Execute(const ExecutionProgress& progress) = 0;
1737
virtual void HandleProgressCallback(const char *data, size_t size) = 0;
1738
1739
virtual void Destroy() {
1740
uv_close(reinterpret_cast<uv_handle_t*>(async), AsyncClose_);
1741
}
1742
1743
private:
1744
void Execute() /*final override*/ {
1745
ExecutionProgress progress(this);
1746
Execute(progress);
1747
}
1748
1749
void SendProgress_(const char *data, size_t size) {
1750
char *new_data = new char[size];
1751
memcpy(new_data, data, size);
1752
1753
uv_mutex_lock(&async_lock);
1754
char *old_data = asyncdata_;
1755
asyncdata_ = new_data;
1756
asyncsize_ = size;
1757
uv_mutex_unlock(&async_lock);
1758
1759
if (old_data) {
1760
delete[] old_data;
1761
}
1762
uv_async_send(async);
1763
}
1764
1765
NAN_INLINE static NAUV_WORK_CB(AsyncProgress_) {
1766
NanAsyncProgressWorker *worker =
1767
static_cast<NanAsyncProgressWorker*>(async->data);
1768
worker->WorkProgress();
1769
}
1770
1771
NAN_INLINE static void AsyncClose_(uv_handle_t* handle) {
1772
NanAsyncProgressWorker *worker =
1773
static_cast<NanAsyncProgressWorker*>(handle->data);
1774
delete reinterpret_cast<uv_async_t*>(handle);
1775
delete worker;
1776
}
1777
1778
uv_async_t *async;
1779
uv_mutex_t async_lock;
1780
char *asyncdata_;
1781
size_t asyncsize_;
1782
};
1783
1784
NAN_INLINE void NanAsyncExecute (uv_work_t* req) {
1785
NanAsyncWorker *worker = static_cast<NanAsyncWorker*>(req->data);
1786
worker->Execute();
1787
}
1788
1789
NAN_INLINE void NanAsyncExecuteComplete (uv_work_t* req) {
1790
NanAsyncWorker* worker = static_cast<NanAsyncWorker*>(req->data);
1791
worker->WorkComplete();
1792
worker->Destroy();
1793
}
1794
1795
NAN_INLINE void NanAsyncQueueWorker (NanAsyncWorker* worker) {
1796
uv_queue_work(
1797
uv_default_loop()
1798
, &worker->request
1799
, NanAsyncExecute
1800
, (uv_after_work_cb)NanAsyncExecuteComplete
1801
);
1802
}
1803
1804
//// Base 64 ////
1805
1806
#define _nan_base64_encoded_size(size) ((size + 2 - ((size + 2) % 3)) / 3 * 4)
1807
1808
// Doesn't check for padding at the end. Can be 1-2 bytes over.
1809
NAN_INLINE size_t _nan_base64_decoded_size_fast(size_t size) {
1810
size_t remainder = size % 4;
1811
1812
size = (size / 4) * 3;
1813
if (remainder) {
1814
if (size == 0 && remainder == 1) {
1815
// special case: 1-byte input cannot be decoded
1816
size = 0;
1817
} else {
1818
// non-padded input, add 1 or 2 extra bytes
1819
size += 1 + (remainder == 3);
1820
}
1821
}
1822
1823
return size;
1824
}
1825
1826
template<typename T>
1827
NAN_INLINE size_t _nan_base64_decoded_size(
1828
const T* src
1829
, size_t size
1830
) {
1831
if (size == 0)
1832
return 0;
1833
1834
if (src[size - 1] == '=')
1835
size--;
1836
if (size > 0 && src[size - 1] == '=')
1837
size--;
1838
1839
return _nan_base64_decoded_size_fast(size);
1840
}
1841
1842
// supports regular and URL-safe base64
1843
static const int _nan_unbase64_table[] = {
1844
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1
1845
, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1846
, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63
1847
, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1
1848
, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
1849
, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63
1850
, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40
1851
, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
1852
, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1853
, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1854
, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1855
, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1856
, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1857
, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1858
, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1859
, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1860
};
1861
1862
#define _nan_unbase64(x) _nan_unbase64_table[(uint8_t)(x)]
1863
1864
template<typename T> static size_t _nan_base64_decode(
1865
char* buf
1866
, size_t len
1867
, const T* src
1868
, const size_t srcLen
1869
) {
1870
char* dst = buf;
1871
char* dstEnd = buf + len;
1872
const T* srcEnd = src + srcLen;
1873
1874
while (src < srcEnd && dst < dstEnd) {
1875
ptrdiff_t remaining = srcEnd - src;
1876
char a, b, c, d;
1877
1878
while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
1879
if (remaining == 0 || *src == '=') break;
1880
a = _nan_unbase64(*src++);
1881
1882
while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
1883
if (remaining <= 1 || *src == '=') break;
1884
b = _nan_unbase64(*src++);
1885
1886
*dst++ = (a << 2) | ((b & 0x30) >> 4);
1887
if (dst == dstEnd) break;
1888
1889
while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
1890
if (remaining <= 2 || *src == '=') break;
1891
c = _nan_unbase64(*src++);
1892
1893
*dst++ = ((b & 0x0F) << 4) | ((c & 0x3C) >> 2);
1894
if (dst == dstEnd) break;
1895
1896
while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
1897
if (remaining <= 3 || *src == '=') break;
1898
d = _nan_unbase64(*src++);
1899
1900
*dst++ = ((c & 0x03) << 6) | (d & 0x3F);
1901
}
1902
1903
return dst - buf;
1904
}
1905
1906
//// HEX ////
1907
1908
template<typename T> unsigned _nan_hex2bin(T c) {
1909
if (c >= '0' && c <= '9') return c - '0';
1910
if (c >= 'A' && c <= 'F') return 10 + (c - 'A');
1911
if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
1912
return static_cast<unsigned>(-1);
1913
}
1914
1915
template<typename T> static size_t _nan_hex_decode(
1916
char* buf
1917
, size_t len
1918
, const T* src
1919
, const size_t srcLen
1920
) {
1921
size_t i;
1922
for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) {
1923
unsigned a = _nan_hex2bin(src[i * 2 + 0]);
1924
unsigned b = _nan_hex2bin(src[i * 2 + 1]);
1925
if (!~a || !~b) return i;
1926
buf[i] = a * 16 + b;
1927
}
1928
1929
return i;
1930
}
1931
1932
namespace NanIntern {
1933
1934
inline
1935
NanExternalOneByteStringResource const*
1936
GetExternalResource(v8::Local<v8::String> str) {
1937
#if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION
1938
return str->GetExternalAsciiStringResource();
1939
#else
1940
return str->GetExternalOneByteStringResource();
1941
#endif
1942
}
1943
1944
inline
1945
bool
1946
IsExternal(v8::Local<v8::String> str) {
1947
#if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION
1948
return str->IsExternalAscii();
1949
#else
1950
return str->IsExternalOneByte();
1951
#endif
1952
}
1953
1954
} // end of namespace NanIntern
1955
1956
static bool _NanGetExternalParts(
1957
v8::Handle<v8::Value> val
1958
, const char** data
1959
, size_t* len
1960
) {
1961
if (node::Buffer::HasInstance(val)) {
1962
*data = node::Buffer::Data(val.As<v8::Object>());
1963
*len = node::Buffer::Length(val.As<v8::Object>());
1964
return true;
1965
}
1966
1967
assert(val->IsString());
1968
v8::Local<v8::String> str = NanNew(val.As<v8::String>());
1969
1970
if (NanIntern::IsExternal(str)) {
1971
const NanExternalOneByteStringResource* ext;
1972
ext = NanIntern::GetExternalResource(str);
1973
*data = ext->data();
1974
*len = ext->length();
1975
return true;
1976
}
1977
1978
if (str->IsExternal()) {
1979
const v8::String::ExternalStringResource* ext;
1980
ext = str->GetExternalStringResource();
1981
*data = reinterpret_cast<const char*>(ext->data());
1982
*len = ext->length();
1983
return true;
1984
}
1985
1986
return false;
1987
}
1988
1989
namespace Nan {
1990
enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
1991
}
1992
1993
#if !NODE_VERSION_AT_LEAST(0, 10, 0)
1994
# include "nan_string_bytes.h" // NOLINT(build/include)
1995
#endif
1996
1997
NAN_INLINE v8::Local<v8::Value> NanEncode(
1998
const void *buf, size_t len, enum Nan::Encoding encoding = Nan::BINARY) {
1999
#if (NODE_MODULE_VERSION >= ATOM_0_21_MODULE_VERSION)
2000
v8::Isolate* isolate = v8::Isolate::GetCurrent();
2001
node::encoding node_enc = static_cast<node::encoding>(encoding);
2002
2003
if (encoding == Nan::UCS2) {
2004
return node::Encode(
2005
isolate
2006
, reinterpret_cast<const uint16_t *>(buf)
2007
, len / 2);
2008
} else {
2009
return node::Encode(
2010
isolate
2011
, reinterpret_cast<const char *>(buf)
2012
, len
2013
, node_enc);
2014
}
2015
#elif (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
2016
return node::Encode(
2017
v8::Isolate::GetCurrent()
2018
, buf, len
2019
, static_cast<node::encoding>(encoding));
2020
#else
2021
# if NODE_VERSION_AT_LEAST(0, 10, 0)
2022
return node::Encode(buf, len, static_cast<node::encoding>(encoding));
2023
# else
2024
return NanIntern::Encode(reinterpret_cast<const char*>(buf), len, encoding);
2025
# endif
2026
#endif
2027
}
2028
2029
NAN_INLINE ssize_t NanDecodeBytes(
2030
v8::Handle<v8::Value> val, enum Nan::Encoding encoding = Nan::BINARY) {
2031
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
2032
return node::DecodeBytes(
2033
v8::Isolate::GetCurrent()
2034
, val
2035
, static_cast<node::encoding>(encoding));
2036
#else
2037
# if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)
2038
if (encoding == Nan::BUFFER) {
2039
return node::DecodeBytes(val, node::BINARY);
2040
}
2041
# endif
2042
return node::DecodeBytes(val, static_cast<node::encoding>(encoding));
2043
#endif
2044
}
2045
2046
NAN_INLINE ssize_t NanDecodeWrite(
2047
char *buf
2048
, size_t len
2049
, v8::Handle<v8::Value> val
2050
, enum Nan::Encoding encoding = Nan::BINARY) {
2051
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
2052
return node::DecodeWrite(
2053
v8::Isolate::GetCurrent()
2054
, buf
2055
, len
2056
, val
2057
, static_cast<node::encoding>(encoding));
2058
#else
2059
# if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)
2060
if (encoding == Nan::BUFFER) {
2061
return node::DecodeWrite(buf, len, val, node::BINARY);
2062
}
2063
# endif
2064
return node::DecodeWrite(
2065
buf
2066
, len
2067
, val
2068
, static_cast<node::encoding>(encoding));
2069
#endif
2070
}
2071
2072
/* NAN_DEPRECATED */ NAN_INLINE void* _NanRawString(
2073
v8::Handle<v8::Value> from
2074
, enum Nan::Encoding encoding
2075
, size_t *datalen
2076
, void *buf
2077
, size_t buflen
2078
, int flags
2079
) {
2080
NanScope();
2081
2082
size_t sz_;
2083
size_t term_len = !(flags & v8::String::NO_NULL_TERMINATION);
2084
char *data = NULL;
2085
size_t len;
2086
bool is_extern = _NanGetExternalParts(
2087
from
2088
, const_cast<const char**>(&data)
2089
, &len);
2090
2091
if (is_extern && !term_len) {
2092
NanSetPointerSafe(datalen, len);
2093
return data;
2094
}
2095
2096
v8::Local<v8::String> toStr = from->ToString();
2097
2098
char *to = static_cast<char *>(buf);
2099
2100
switch (encoding) {
2101
case Nan::ASCII:
2102
#if NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION
2103
sz_ = toStr->Length();
2104
if (to == NULL) {
2105
to = new char[sz_ + term_len];
2106
} else {
2107
assert(buflen >= sz_ + term_len && "too small buffer");
2108
}
2109
NanSetPointerSafe<size_t>(
2110
datalen
2111
, toStr->WriteAscii(to, 0, static_cast<int>(sz_ + term_len), flags));
2112
return to;
2113
#endif
2114
case Nan::BINARY:
2115
case Nan::BUFFER:
2116
sz_ = toStr->Length();
2117
if (to == NULL) {
2118
to = new char[sz_ + term_len];
2119
} else {
2120
assert(buflen >= sz_ + term_len && "too small buffer");
2121
}
2122
#if NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION
2123
{
2124
uint16_t* twobytebuf = new uint16_t[sz_ + term_len];
2125
2126
size_t somelen = toStr->Write(twobytebuf, 0,
2127
static_cast<int>(sz_ + term_len), flags);
2128
2129
for (size_t i = 0; i < sz_ + term_len && i < somelen + term_len; i++) {
2130
unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
2131
to[i] = *b;
2132
}
2133
2134
NanSetPointerSafe<size_t>(datalen, somelen);
2135
2136
delete[] twobytebuf;
2137
return to;
2138
}
2139
#else
2140
NanSetPointerSafe<size_t>(
2141
datalen,
2142
toStr->WriteOneByte(
2143
reinterpret_cast<uint8_t *>(to)
2144
, 0
2145
, static_cast<int>(sz_ + term_len)
2146
, flags));
2147
return to;
2148
#endif
2149
case Nan::UTF8:
2150
sz_ = toStr->Utf8Length();
2151
if (to == NULL) {
2152
to = new char[sz_ + term_len];
2153
} else {
2154
assert(buflen >= sz_ + term_len && "too small buffer");
2155
}
2156
NanSetPointerSafe<size_t>(
2157
datalen
2158
, toStr->WriteUtf8(to, static_cast<int>(sz_ + term_len)
2159
, NULL, flags)
2160
- term_len);
2161
return to;
2162
case Nan::BASE64:
2163
{
2164
v8::String::Value value(toStr);
2165
sz_ = _nan_base64_decoded_size(*value, value.length());
2166
if (to == NULL) {
2167
to = new char[sz_ + term_len];
2168
} else {
2169
assert(buflen >= sz_ + term_len);
2170
}
2171
NanSetPointerSafe<size_t>(
2172
datalen
2173
, _nan_base64_decode(to, sz_, *value, value.length()));
2174
if (term_len) {
2175
to[sz_] = '\0';
2176
}
2177
return to;
2178
}
2179
case Nan::UCS2:
2180
{
2181
sz_ = toStr->Length();
2182
if (to == NULL) {
2183
to = new char[(sz_ + term_len) * 2];
2184
} else {
2185
assert(buflen >= (sz_ + term_len) * 2 && "too small buffer");
2186
}
2187
2188
int bc = 2 * toStr->Write(
2189
reinterpret_cast<uint16_t *>(to)
2190
, 0
2191
, static_cast<int>(sz_ + term_len)
2192
, flags);
2193
NanSetPointerSafe<size_t>(datalen, bc);
2194
return to;
2195
}
2196
case Nan::HEX:
2197
{
2198
v8::String::Value value(toStr);
2199
sz_ = value.length();
2200
assert(!(sz_ & 1) && "bad hex data");
2201
if (to == NULL) {
2202
to = new char[sz_ / 2 + term_len];
2203
} else {
2204
assert(buflen >= sz_ / 2 + term_len && "too small buffer");
2205
}
2206
NanSetPointerSafe<size_t>(
2207
datalen
2208
, _nan_hex_decode(to, sz_ / 2, *value, value.length()));
2209
}
2210
if (term_len) {
2211
to[sz_ / 2] = '\0';
2212
}
2213
return to;
2214
default:
2215
assert(0 && "unknown encoding");
2216
}
2217
return to;
2218
}
2219
2220
NAN_DEPRECATED NAN_INLINE void* NanRawString(
2221
v8::Handle<v8::Value> from
2222
, enum Nan::Encoding encoding
2223
, size_t *datalen
2224
, void *buf
2225
, size_t buflen
2226
, int flags
2227
) {
2228
return _NanRawString(from, encoding, datalen, buf, buflen, flags);
2229
}
2230
2231
2232
NAN_DEPRECATED NAN_INLINE char* NanCString(
2233
v8::Handle<v8::Value> from
2234
, size_t *datalen
2235
, char *buf = NULL
2236
, size_t buflen = 0
2237
, int flags = v8::String::NO_OPTIONS
2238
) {
2239
return static_cast<char *>(
2240
_NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags)
2241
);
2242
}
2243
2244
NAN_INLINE void NanSetPrototypeTemplate(
2245
v8::Local<v8::FunctionTemplate> templ
2246
, const char *name
2247
, v8::Handle<v8::Data> value
2248
) {
2249
NanSetTemplate(templ->PrototypeTemplate(), name, value);
2250
}
2251
2252
NAN_INLINE void NanSetPrototypeTemplate(
2253
v8::Local<v8::FunctionTemplate> templ
2254
, v8::Handle<v8::String> name
2255
, v8::Handle<v8::Data> value
2256
, v8::PropertyAttribute attributes
2257
) {
2258
NanSetTemplate(templ->PrototypeTemplate(), name, value, attributes);
2259
}
2260
2261
NAN_INLINE void NanSetInstanceTemplate(
2262
v8::Local<v8::FunctionTemplate> templ
2263
, const char *name
2264
, v8::Handle<v8::Data> value
2265
) {
2266
NanSetTemplate(templ->InstanceTemplate(), name, value);
2267
}
2268
2269
NAN_INLINE void NanSetInstanceTemplate(
2270
v8::Local<v8::FunctionTemplate> templ
2271
, v8::Handle<v8::String> name
2272
, v8::Handle<v8::Data> value
2273
, v8::PropertyAttribute attributes
2274
) {
2275
NanSetTemplate(templ->InstanceTemplate(), name, value, attributes);
2276
}
2277
2278
//=== Export ==================================================================
2279
2280
inline
2281
void
2282
NanExport(v8::Handle<v8::Object> target, const char * name,
2283
NanFunctionCallback f) {
2284
target->Set(NanNew<v8::String>(name),
2285
NanNew<v8::FunctionTemplate>(f)->GetFunction());
2286
}
2287
2288
//=== Tap Reverse Binding =====================================================
2289
2290
struct NanTap {
2291
explicit NanTap(v8::Handle<v8::Value> t) : t_() {
2292
NanAssignPersistent(t_, t->ToObject());
2293
}
2294
2295
~NanTap() { NanDisposePersistent(t_); } // not sure if neccessary
2296
2297
inline void plan(int i) {
2298
v8::Handle<v8::Value> arg = NanNew(i);
2299
NanMakeCallback(NanNew(t_), "plan", 1, &arg);
2300
}
2301
2302
inline void ok(bool isOk, const char * msg = NULL) {
2303
v8::Handle<v8::Value> args[2];
2304
args[0] = NanNew(isOk);
2305
if (msg) args[1] = NanNew(msg);
2306
NanMakeCallback(NanNew(t_), "ok", msg ? 2 : 1, args);
2307
}
2308
2309
private:
2310
v8::Persistent<v8::Object> t_;
2311
};
2312
2313
#define NAN_STRINGIZE2(x) #x
2314
#define NAN_STRINGIZE(x) NAN_STRINGIZE2(x)
2315
#define NAN_TEST_EXPRESSION(expression) \
2316
( expression ), __FILE__ ":" NAN_STRINGIZE(__LINE__) ": " #expression
2317
2318
#define return_NanValue(v) NanReturnValue(v)
2319
#define return_NanUndefined() NanReturnUndefined()
2320
#define NAN_EXPORT(target, function) NanExport(target, #function, function)
2321
2322
#endif // NAN_H_
2323
2324