react / wstein / node_modules / jest-cli / node_modules / jsdom / node_modules / contextify / node_modules / nan / nan.h
81145 views/*********************************************************************1* NAN - Native Abstractions for Node.js2*3* Copyright (c) 2015 NAN contributors:4* - Rod Vagg <https://github.com/rvagg>5* - Benjamin Byholm <https://github.com/kkoopa>6* - Trevor Norris <https://github.com/trevnorris>7* - Nathan Rajlich <https://github.com/TooTallNate>8* - Brett Lawson <https://github.com/brett19>9* - Ben Noordhuis <https://github.com/bnoordhuis>10* - David Siegel <https://github.com/agnat>11*12* MIT License <https://github.com/rvagg/nan/blob/master/LICENSE.md>13*14* Version 1.8.4: current Node 12: 0.12.2, Node 10: 0.10.38, io.js: 1.8.115*16* See https://github.com/rvagg/nan for the latest update to this file17**********************************************************************************/1819#ifndef NAN_H_20#define NAN_H_2122#include <uv.h>23#include <node.h>24#include <node_buffer.h>25#include <node_version.h>26#include <node_object_wrap.h>27#include <cstring>28#include <climits>29#include <cstdlib>30#if defined(_MSC_VER)31# pragma warning( push )32# pragma warning( disable : 4530 )33# include <string>34# pragma warning( pop )35#else36# include <string>37#endif3839#if defined(__GNUC__) && !(defined(DEBUG) && DEBUG)40# define NAN_INLINE inline __attribute__((always_inline))41#elif defined(_MSC_VER) && !(defined(DEBUG) && DEBUG)42# define NAN_INLINE __forceinline43#else44# define NAN_INLINE inline45#endif4647#if defined(__GNUC__) && \48!(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)49# define NAN_DEPRECATED __attribute__((deprecated))50#elif defined(_MSC_VER) && \51!(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)52# define NAN_DEPRECATED __declspec(deprecated)53#else54# define NAN_DEPRECATED55#endif5657#define NODE_0_10_MODULE_VERSION 1158#define NODE_0_12_MODULE_VERSION 1259#define ATOM_0_21_MODULE_VERSION 4160#define IOJS_1_0_MODULE_VERSION 4261#define IOJS_1_1_MODULE_VERSION 436263#if (NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION)64typedef v8::InvocationCallback NanFunctionCallback;65typedef v8::Script NanUnboundScript;66typedef v8::Script NanBoundScript;67#else68typedef v8::FunctionCallback NanFunctionCallback;69typedef v8::UnboundScript NanUnboundScript;70typedef v8::Script NanBoundScript;71#endif7273#if (NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION)74typedef v8::String::ExternalAsciiStringResource75NanExternalOneByteStringResource;76#else77typedef v8::String::ExternalOneByteStringResource78NanExternalOneByteStringResource;79#endif8081#include "nan_new.h" // NOLINT(build/include)8283// uv helpers84#ifdef UV_VERSION_MAJOR85#ifndef UV_VERSION_PATCH86#define UV_VERSION_PATCH 087#endif88#define NAUV_UVVERSION ((UV_VERSION_MAJOR << 16) | \89(UV_VERSION_MINOR << 8) | \90(UV_VERSION_PATCH))91#else92#define NAUV_UVVERSION 0x000b0093#endif949596#if NAUV_UVVERSION < 0x000b1797#define NAUV_WORK_CB(func) \98void func(uv_async_t *async, int)99#else100#define NAUV_WORK_CB(func) \101void func(uv_async_t *async)102#endif103104#if NAUV_UVVERSION >= 0x000b0b105106typedef uv_key_t nauv_key_t;107108inline int nauv_key_create(nauv_key_t *key) {109return uv_key_create(key);110}111112inline void nauv_key_delete(nauv_key_t *key) {113uv_key_delete(key);114}115116inline void* nauv_key_get(nauv_key_t *key) {117return uv_key_get(key);118}119120inline void nauv_key_set(nauv_key_t *key, void *value) {121uv_key_set(key, value);122}123124#else125126/* Implement thread local storage for older versions of libuv.127* This is essentially a backport of libuv commit 5d2434bf128* written by Ben Noordhuis, adjusted for names and inline.129*/130131#ifndef WIN32132133#include <pthread.h>134135typedef pthread_key_t nauv_key_t;136137inline int nauv_key_create(nauv_key_t* key) {138return -pthread_key_create(key, NULL);139}140141inline void nauv_key_delete(nauv_key_t* key) {142if (pthread_key_delete(*key))143abort();144}145146inline void* nauv_key_get(nauv_key_t* key) {147return pthread_getspecific(*key);148}149150inline void nauv_key_set(nauv_key_t* key, void* value) {151if (pthread_setspecific(*key, value))152abort();153}154155#else156157#include <windows.h>158159typedef struct {160DWORD tls_index;161} nauv_key_t;162163inline int nauv_key_create(nauv_key_t* key) {164key->tls_index = TlsAlloc();165if (key->tls_index == TLS_OUT_OF_INDEXES)166return UV_ENOMEM;167return 0;168}169170inline void nauv_key_delete(nauv_key_t* key) {171if (TlsFree(key->tls_index) == FALSE)172abort();173key->tls_index = TLS_OUT_OF_INDEXES;174}175176inline void* nauv_key_get(nauv_key_t* key) {177void* value = TlsGetValue(key->tls_index);178if (value == NULL)179if (GetLastError() != ERROR_SUCCESS)180abort();181return value;182}183184inline void nauv_key_set(nauv_key_t* key, void* value) {185if (TlsSetValue(key->tls_index, value) == FALSE)186abort();187}188189#endif190#endif191192// some generic helpers193194template<typename T> NAN_INLINE bool NanSetPointerSafe(195T *var196, T val197) {198if (var) {199*var = val;200return true;201} else {202return false;203}204}205206template<typename T> NAN_INLINE T NanGetPointerSafe(207T *var208, T fallback = reinterpret_cast<T>(0)209) {210if (var) {211return *var;212} else {213return fallback;214}215}216217NAN_INLINE bool NanBooleanOptionValue(218v8::Local<v8::Object> optionsObj219, v8::Handle<v8::String> opt, bool def220) {221if (def) {222return optionsObj.IsEmpty()223|| !optionsObj->Has(opt)224|| optionsObj->Get(opt)->BooleanValue();225} else {226return !optionsObj.IsEmpty()227&& optionsObj->Has(opt)228&& optionsObj->Get(opt)->BooleanValue();229}230}231232NAN_INLINE bool NanBooleanOptionValue(233v8::Local<v8::Object> optionsObj234, v8::Handle<v8::String> opt235) {236return NanBooleanOptionValue(optionsObj, opt, false);237}238239NAN_INLINE uint32_t NanUInt32OptionValue(240v8::Local<v8::Object> optionsObj241, v8::Handle<v8::String> opt242, uint32_t def243) {244return !optionsObj.IsEmpty()245&& optionsObj->Has(opt)246&& optionsObj->Get(opt)->IsNumber()247? optionsObj->Get(opt)->Uint32Value()248: def;249}250251template<typename T>252v8::Local<T> NanNew(v8::Handle<T>);253254template<typename T>255NAN_INLINE v8::Local<T> _NanEnsureLocal(v8::Handle<T> val) {256return NanNew(val);257}258259template<typename T>260NAN_INLINE v8::Local<T> _NanEnsureLocal(v8::Local<T> val) {261return val;262}263264template<typename T>265NAN_INLINE v8::Local<v8::Value> _NanEnsureLocal(T val) {266return NanNew(val);267}268269/* io.js 1.0 */270#if NODE_MODULE_VERSION >= IOJS_1_0_MODULE_VERSION \271|| NODE_VERSION_AT_LEAST(0, 11, 15)272NAN_INLINE273void NanSetCounterFunction(v8::CounterLookupCallback cb) {274v8::Isolate::GetCurrent()->SetCounterFunction(cb);275}276277NAN_INLINE278void NanSetCreateHistogramFunction(v8::CreateHistogramCallback cb) {279v8::Isolate::GetCurrent()->SetCreateHistogramFunction(cb);280}281282NAN_INLINE283void NanSetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {284v8::Isolate::GetCurrent()->SetAddHistogramSampleFunction(cb);285}286287NAN_INLINE bool NanIdleNotification(int idle_time_in_ms) {288return v8::Isolate::GetCurrent()->IdleNotification(idle_time_in_ms);289}290291NAN_INLINE void NanLowMemoryNotification() {292v8::Isolate::GetCurrent()->LowMemoryNotification();293}294295NAN_INLINE void NanContextDisposedNotification() {296v8::Isolate::GetCurrent()->ContextDisposedNotification();297}298#else299NAN_INLINE300void NanSetCounterFunction(v8::CounterLookupCallback cb) {301v8::V8::SetCounterFunction(cb);302}303304NAN_INLINE305void NanSetCreateHistogramFunction(v8::CreateHistogramCallback cb) {306v8::V8::SetCreateHistogramFunction(cb);307}308309NAN_INLINE310void NanSetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {311v8::V8::SetAddHistogramSampleFunction(cb);312}313314NAN_INLINE bool NanIdleNotification(int idle_time_in_ms) {315return v8::V8::IdleNotification(idle_time_in_ms);316}317318NAN_INLINE void NanLowMemoryNotification() {319v8::V8::LowMemoryNotification();320}321322NAN_INLINE void NanContextDisposedNotification() {323v8::V8::ContextDisposedNotification();324}325#endif326327#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)328// Node 0.11+ (0.11.12 and below won't compile with these)329330# define _NAN_METHOD_ARGS_TYPE const v8::FunctionCallbackInfo<v8::Value>&331# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args332# define _NAN_METHOD_RETURN_TYPE void333334# define _NAN_GETTER_ARGS_TYPE const v8::PropertyCallbackInfo<v8::Value>&335# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args336# define _NAN_GETTER_RETURN_TYPE void337338# define _NAN_SETTER_ARGS_TYPE const v8::PropertyCallbackInfo<void>&339# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args340# define _NAN_SETTER_RETURN_TYPE void341342# define _NAN_PROPERTY_GETTER_ARGS_TYPE \343const v8::PropertyCallbackInfo<v8::Value>&344# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args345# define _NAN_PROPERTY_GETTER_RETURN_TYPE void346347# define _NAN_PROPERTY_SETTER_ARGS_TYPE \348const v8::PropertyCallbackInfo<v8::Value>&349# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args350# define _NAN_PROPERTY_SETTER_RETURN_TYPE void351352# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE \353const v8::PropertyCallbackInfo<v8::Array>&354# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args355# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE void356357# define _NAN_PROPERTY_DELETER_ARGS_TYPE \358const v8::PropertyCallbackInfo<v8::Boolean>&359# define _NAN_PROPERTY_DELETER_ARGS \360_NAN_PROPERTY_DELETER_ARGS_TYPE args361# define _NAN_PROPERTY_DELETER_RETURN_TYPE void362363# define _NAN_PROPERTY_QUERY_ARGS_TYPE \364const v8::PropertyCallbackInfo<v8::Integer>&365# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args366# define _NAN_PROPERTY_QUERY_RETURN_TYPE void367368# define _NAN_INDEX_GETTER_ARGS_TYPE \369const v8::PropertyCallbackInfo<v8::Value>&370# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args371# define _NAN_INDEX_GETTER_RETURN_TYPE void372373# define _NAN_INDEX_SETTER_ARGS_TYPE \374const v8::PropertyCallbackInfo<v8::Value>&375# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args376# define _NAN_INDEX_SETTER_RETURN_TYPE void377378# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE \379const v8::PropertyCallbackInfo<v8::Array>&380# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args381# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE void382383# define _NAN_INDEX_DELETER_ARGS_TYPE \384const v8::PropertyCallbackInfo<v8::Boolean>&385# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args386# define _NAN_INDEX_DELETER_RETURN_TYPE void387388# define _NAN_INDEX_QUERY_ARGS_TYPE \389const v8::PropertyCallbackInfo<v8::Integer>&390# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args391# define _NAN_INDEX_QUERY_RETURN_TYPE void392393# define NanScope() v8::HandleScope scope(v8::Isolate::GetCurrent())394# define NanEscapableScope() \395v8::EscapableHandleScope scope(v8::Isolate::GetCurrent())396397# define NanEscapeScope(val) scope.Escape(_NanEnsureLocal(val))398# define NanLocker() v8::Locker locker(v8::Isolate::GetCurrent())399# define NanUnlocker() v8::Unlocker unlocker(v8::Isolate::GetCurrent())400# define NanReturnValue(value) return args.GetReturnValue().Set(_NanEnsureLocal(value))401# define NanReturnUndefined() return402# define NanReturnHolder() NanReturnValue(args.Holder())403# define NanReturnThis() NanReturnValue(args.This())404# define NanReturnNull() return args.GetReturnValue().SetNull()405# define NanReturnEmptyString() return args.GetReturnValue().SetEmptyString()406407NAN_INLINE v8::Local<v8::Object> NanObjectWrapHandle(const node::ObjectWrap *obj) {408return const_cast<node::ObjectWrap*>(obj)->handle();409}410411NAN_INLINE v8::Local<v8::Primitive> NanUndefined() {412NanEscapableScope();413return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent())));414}415416NAN_INLINE v8::Local<v8::Primitive> NanNull() {417NanEscapableScope();418return NanEscapeScope(NanNew(v8::Null(v8::Isolate::GetCurrent())));419}420421NAN_INLINE v8::Local<v8::Boolean> NanTrue() {422NanEscapableScope();423return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent())));424}425426NAN_INLINE v8::Local<v8::Boolean> NanFalse() {427NanEscapableScope();428return NanEscapeScope(NanNew(v8::False(v8::Isolate::GetCurrent())));429}430431NAN_INLINE int NanAdjustExternalMemory(int bc) {432return static_cast<int>(433v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));434}435436NAN_INLINE void NanSetTemplate(437v8::Handle<v8::Template> templ438, const char *name439, v8::Handle<v8::Data> value) {440templ->Set(v8::Isolate::GetCurrent(), name, value);441}442443NAN_INLINE void NanSetTemplate(444v8::Handle<v8::Template> templ445, v8::Handle<v8::String> name446, v8::Handle<v8::Data> value447, v8::PropertyAttribute attributes) {448templ->Set(name, value, attributes);449}450451NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {452return v8::Isolate::GetCurrent()->GetCurrentContext();453}454455NAN_INLINE void* NanGetInternalFieldPointer(456v8::Handle<v8::Object> object457, int index) {458return object->GetAlignedPointerFromInternalField(index);459}460461NAN_INLINE void NanSetInternalFieldPointer(462v8::Handle<v8::Object> object463, int index464, void* value) {465object->SetAlignedPointerInInternalField(index, value);466}467468# define NAN_GC_CALLBACK(name) \469void name(v8::Isolate *isolate, v8::GCType type, v8::GCCallbackFlags flags)470471NAN_INLINE void NanAddGCEpilogueCallback(472v8::Isolate::GCEpilogueCallback callback473, v8::GCType gc_type_filter = v8::kGCTypeAll) {474v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter);475}476477NAN_INLINE void NanRemoveGCEpilogueCallback(478v8::Isolate::GCEpilogueCallback callback) {479v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback);480}481482NAN_INLINE void NanAddGCPrologueCallback(483v8::Isolate::GCPrologueCallback callback484, v8::GCType gc_type_filter = v8::kGCTypeAll) {485v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter);486}487488NAN_INLINE void NanRemoveGCPrologueCallback(489v8::Isolate::GCPrologueCallback callback) {490v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback);491}492493NAN_INLINE void NanGetHeapStatistics(494v8::HeapStatistics *heap_statistics) {495v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics);496}497498NAN_DEPRECATED NAN_INLINE v8::Local<v8::String> NanSymbol(499const char* data, int length = -1) {500return NanNew<v8::String>(data, length);501}502503template<typename T>504NAN_INLINE void NanAssignPersistent(505v8::Persistent<T>& handle506, v8::Handle<T> obj) {507handle.Reset(v8::Isolate::GetCurrent(), obj);508}509510template<typename T>511NAN_INLINE void NanAssignPersistent(512v8::Persistent<T>& handle513, const v8::Persistent<T>& obj) {514handle.Reset(v8::Isolate::GetCurrent(), obj);515}516517template<typename T, typename P>518class _NanWeakCallbackData;519520template<typename T, typename P>521struct _NanWeakCallbackInfo {522typedef void (*Callback)(const _NanWeakCallbackData<T, P>& data);523NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> handle, P* param, Callback cb)524: parameter(param), callback(cb) {525NanAssignPersistent(persistent, handle);526}527528NAN_INLINE ~_NanWeakCallbackInfo() {529persistent.Reset();530}531532P* const parameter;533Callback const callback;534v8::Persistent<T> persistent;535};536537template<typename T, typename P>538class _NanWeakCallbackData {539public:540NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info)541: info_(info) { }542543NAN_INLINE v8::Local<T> GetValue() const {544return NanNew(info_->persistent);545}546547NAN_INLINE P* GetParameter() const { return info_->parameter; }548549NAN_INLINE bool IsNearDeath() const {550return info_->persistent.IsNearDeath();551}552553NAN_INLINE void Revive() const;554555NAN_INLINE _NanWeakCallbackInfo<T, P>* GetCallbackInfo() const {556return info_;557}558559NAN_DEPRECATED NAN_INLINE void Dispose() const {560}561562private:563_NanWeakCallbackInfo<T, P>* info_;564};565566template<typename T, typename P>567static void _NanWeakCallbackDispatcher(568const v8::WeakCallbackData<T, _NanWeakCallbackInfo<T, P> > &data) {569_NanWeakCallbackInfo<T, P> *info = data.GetParameter();570_NanWeakCallbackData<T, P> wcbd(info);571info->callback(wcbd);572if (wcbd.IsNearDeath()) {573delete wcbd.GetCallbackInfo();574}575}576577template<typename T, typename P>578NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const {579info_->persistent.SetWeak(info_, &_NanWeakCallbackDispatcher<T, P>);580}581582template<typename T, typename P>583NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(584v8::Handle<T> handle585, P* parameter586, typename _NanWeakCallbackInfo<T, P>::Callback callback) {587_NanWeakCallbackInfo<T, P> *cbinfo =588new _NanWeakCallbackInfo<T, P>(handle, parameter, callback);589cbinfo->persistent.SetWeak(cbinfo, &_NanWeakCallbackDispatcher<T, P>);590return cbinfo;591}592593# define NAN_WEAK_CALLBACK(name) \594template<typename T, typename P> \595static void name(const _NanWeakCallbackData<T, P> &data)596597# define _NAN_ERROR(fun, errmsg) fun(NanNew<v8::String>(errmsg))598599# define _NAN_THROW_ERROR(fun, errmsg) \600do { \601NanScope(); \602v8::Isolate::GetCurrent()->ThrowException(_NAN_ERROR(fun, errmsg)); \603} while (0);604605NAN_INLINE v8::Local<v8::Value> NanError(const char* errmsg) {606return _NAN_ERROR(v8::Exception::Error, errmsg);607}608609NAN_INLINE void NanThrowError(const char* errmsg) {610_NAN_THROW_ERROR(v8::Exception::Error, errmsg);611}612613NAN_INLINE void NanThrowError(v8::Handle<v8::Value> error) {614NanScope();615v8::Isolate::GetCurrent()->ThrowException(error);616}617618NAN_INLINE v8::Local<v8::Value> NanError(619const char *msg620, const int errorNumber621) {622v8::Local<v8::Value> err = v8::Exception::Error(NanNew<v8::String>(msg));623v8::Local<v8::Object> obj = err.As<v8::Object>();624obj->Set(NanNew<v8::String>("code"), NanNew<v8::Integer>(errorNumber));625return err;626}627628NAN_INLINE void NanThrowError(629const char *msg630, const int errorNumber631) {632NanThrowError(NanError(msg, errorNumber));633}634635NAN_INLINE v8::Local<v8::Value> NanTypeError(const char* errmsg) {636return _NAN_ERROR(v8::Exception::TypeError, errmsg);637}638639NAN_INLINE void NanThrowTypeError(const char* errmsg) {640_NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);641}642643NAN_INLINE v8::Local<v8::Value> NanRangeError(const char* errmsg) {644return _NAN_ERROR(v8::Exception::RangeError, errmsg);645}646647NAN_INLINE void NanThrowRangeError(const char* errmsg) {648_NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);649}650651template<typename T> NAN_INLINE void NanDisposePersistent(652v8::Persistent<T> &handle653) {654handle.Reset();655}656657NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (658char *data659, size_t length660, node::smalloc::FreeCallback callback661, void *hint662) {663return node::Buffer::New(664v8::Isolate::GetCurrent(), data, length, callback, hint);665}666667NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (668const char *data669, uint32_t size670) {671return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);672}673674NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {675return node::Buffer::New(v8::Isolate::GetCurrent(), size);676}677678NAN_INLINE v8::Local<v8::Object> NanBufferUse(679char* data680, uint32_t size681) {682return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);683}684685NAN_INLINE bool NanHasInstance(686const v8::Persistent<v8::FunctionTemplate>& function_template687, v8::Handle<v8::Value> value688) {689return NanNew(function_template)->HasInstance(value);690}691692NAN_DEPRECATED NAN_INLINE v8::Local<v8::Context> NanNewContextHandle(693v8::ExtensionConfiguration* extensions = NULL694, v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>()695, v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()696) {697v8::Isolate* isolate = v8::Isolate::GetCurrent();698return v8::Local<v8::Context>::New(699isolate700, v8::Context::New(isolate, extensions, tmpl, obj)701);702}703704NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(705v8::Local<v8::String> s706, const v8::ScriptOrigin& origin707) {708v8::ScriptCompiler::Source source(s, origin);709return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);710}711712NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(713v8::Local<v8::String> s714) {715v8::ScriptCompiler::Source source(s);716return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);717}718719NAN_INLINE v8::Local<v8::Value> NanRunScript(720v8::Handle<NanUnboundScript> script721) {722return script->BindToCurrentContext()->Run();723}724725NAN_INLINE v8::Local<v8::Value> NanRunScript(726v8::Handle<NanBoundScript> script727) {728return script->Run();729}730731NAN_INLINE v8::Local<v8::Value> NanMakeCallback(732v8::Handle<v8::Object> target733, v8::Handle<v8::Function> func734, int argc735, v8::Handle<v8::Value>* argv) {736return NanNew(node::MakeCallback(737v8::Isolate::GetCurrent(), target, func, argc, argv));738}739740NAN_INLINE v8::Local<v8::Value> NanMakeCallback(741v8::Handle<v8::Object> target742, v8::Handle<v8::String> symbol743, int argc744, v8::Handle<v8::Value>* argv) {745return NanNew(node::MakeCallback(746v8::Isolate::GetCurrent(), target, symbol, argc, argv));747}748749NAN_INLINE v8::Local<v8::Value> NanMakeCallback(750v8::Handle<v8::Object> target751, const char* method752, int argc753, v8::Handle<v8::Value>* argv) {754return NanNew(node::MakeCallback(755v8::Isolate::GetCurrent(), target, method, argc, argv));756}757758template<typename T>759NAN_INLINE void NanSetIsolateData(760v8::Isolate *isolate761, T *data762) {763isolate->SetData(0, data);764}765766template<typename T>767NAN_INLINE T *NanGetIsolateData(768v8::Isolate *isolate769) {770return static_cast<T*>(isolate->GetData(0));771}772773class NanAsciiString {774public:775NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {776v8::Local<v8::String> toStr = from->ToString();777size = toStr->Length();778buf = new char[size + 1];779size = toStr->WriteOneByte(reinterpret_cast<unsigned char*>(buf));780}781782NAN_DEPRECATED NAN_INLINE int Size() const {783return size;784}785786NAN_INLINE int length() const {787return size;788}789790791NAN_INLINE char* operator*() { return buf; }792NAN_INLINE const char* operator*() const { return buf; }793794NAN_INLINE ~NanAsciiString() {795delete[] buf;796}797798private:799// disallow copying and assigning800NanAsciiString(const NanAsciiString&);801void operator=(const NanAsciiString&);802803char *buf;804int size;805};806807class NanUtf8String {808public:809NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {810v8::Local<v8::String> toStr = from->ToString();811size = toStr->Utf8Length();812buf = new char[size + 1];813toStr->WriteUtf8(buf);814}815816NAN_DEPRECATED NAN_INLINE int Size() const {817return size;818}819820NAN_INLINE int length() const {821return size;822}823824NAN_INLINE char* operator*() { return buf; }825NAN_INLINE const char* operator*() const { return buf; }826827NAN_INLINE ~NanUtf8String() {828delete[] buf;829}830831private:832// disallow copying and assigning833NanUtf8String(const NanUtf8String&);834void operator=(const NanUtf8String&);835836char *buf;837int size;838};839840class NanUcs2String {841public:842NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {843v8::Local<v8::String> toStr = from->ToString();844size = toStr->Length();845buf = new uint16_t[size + 1];846toStr->Write(buf);847}848849NAN_DEPRECATED NAN_INLINE int Size() const {850return size;851}852853NAN_INLINE int length() const {854return size;855}856857NAN_INLINE uint16_t* operator*() { return buf; }858NAN_INLINE const uint16_t* operator*() const { return buf; }859860NAN_INLINE ~NanUcs2String() {861delete[] buf;862}863864private:865// disallow copying and assigning866NanUcs2String(const NanUcs2String&);867void operator=(const NanUcs2String&);868869uint16_t *buf;870int size;871};872873#else874// Node 0.8 and 0.10875876# define _NAN_METHOD_ARGS_TYPE const v8::Arguments&877# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args878# define _NAN_METHOD_RETURN_TYPE v8::Handle<v8::Value>879880# define _NAN_GETTER_ARGS_TYPE const v8::AccessorInfo &881# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args882# define _NAN_GETTER_RETURN_TYPE v8::Handle<v8::Value>883884# define _NAN_SETTER_ARGS_TYPE const v8::AccessorInfo &885# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args886# define _NAN_SETTER_RETURN_TYPE void887888# define _NAN_PROPERTY_GETTER_ARGS_TYPE const v8::AccessorInfo&889# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args890# define _NAN_PROPERTY_GETTER_RETURN_TYPE v8::Handle<v8::Value>891892# define _NAN_PROPERTY_SETTER_ARGS_TYPE const v8::AccessorInfo&893# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args894# define _NAN_PROPERTY_SETTER_RETURN_TYPE v8::Handle<v8::Value>895896# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo&897# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args898# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE v8::Handle<v8::Array>899900# define _NAN_PROPERTY_DELETER_ARGS_TYPE const v8::AccessorInfo&901# define _NAN_PROPERTY_DELETER_ARGS _NAN_PROPERTY_DELETER_ARGS_TYPE args902# define _NAN_PROPERTY_DELETER_RETURN_TYPE v8::Handle<v8::Boolean>903904# define _NAN_PROPERTY_QUERY_ARGS_TYPE const v8::AccessorInfo&905# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args906# define _NAN_PROPERTY_QUERY_RETURN_TYPE v8::Handle<v8::Integer>907908# define _NAN_INDEX_GETTER_ARGS_TYPE const v8::AccessorInfo&909# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args910# define _NAN_INDEX_GETTER_RETURN_TYPE v8::Handle<v8::Value>911912# define _NAN_INDEX_SETTER_ARGS_TYPE const v8::AccessorInfo&913# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args914# define _NAN_INDEX_SETTER_RETURN_TYPE v8::Handle<v8::Value>915916# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo&917# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args918# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE v8::Handle<v8::Array>919920# define _NAN_INDEX_DELETER_ARGS_TYPE const v8::AccessorInfo&921# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args922# define _NAN_INDEX_DELETER_RETURN_TYPE v8::Handle<v8::Boolean>923924# define _NAN_INDEX_QUERY_ARGS_TYPE const v8::AccessorInfo&925# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args926# define _NAN_INDEX_QUERY_RETURN_TYPE v8::Handle<v8::Integer>927928NAN_DEPRECATED NAN_INLINE v8::Local<v8::String> NanSymbol(929const char* data, int length = -1) {930return v8::String::NewSymbol(data, length);931}932933# define NanScope() v8::HandleScope scope934# define NanEscapableScope() v8::HandleScope scope935# define NanEscapeScope(val) scope.Close(val)936# define NanLocker() v8::Locker locker937# define NanUnlocker() v8::Unlocker unlocker938# define NanReturnValue(value) return scope.Close(_NanEnsureLocal(value))939# define NanReturnHolder() NanReturnValue(args.Holder())940# define NanReturnThis() NanReturnValue(args.This())941# define NanReturnUndefined() return v8::Undefined()942# define NanReturnNull() return v8::Null()943# define NanReturnEmptyString() return v8::String::Empty()944945NAN_INLINE v8::Local<v8::Object> NanObjectWrapHandle(const node::ObjectWrap *obj) {946return v8::Local<v8::Object>::New(obj->handle_);947}948949NAN_INLINE v8::Local<v8::Primitive> NanUndefined() {950NanEscapableScope();951return NanEscapeScope(NanNew(v8::Undefined()));952}953954NAN_INLINE v8::Local<v8::Primitive> NanNull() {955NanEscapableScope();956return NanEscapeScope(NanNew(v8::Null()));957}958959NAN_INLINE v8::Local<v8::Boolean> NanTrue() {960NanEscapableScope();961return NanEscapeScope(NanNew(v8::True()));962}963964NAN_INLINE v8::Local<v8::Boolean> NanFalse() {965NanEscapableScope();966return NanEscapeScope(NanNew(v8::False()));967}968969NAN_INLINE int NanAdjustExternalMemory(int bc) {970return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));971}972973NAN_INLINE void NanSetTemplate(974v8::Handle<v8::Template> templ975, const char *name976, v8::Handle<v8::Data> value) {977templ->Set(name, value);978}979980NAN_INLINE void NanSetTemplate(981v8::Handle<v8::Template> templ982, v8::Handle<v8::String> name983, v8::Handle<v8::Data> value984, v8::PropertyAttribute attributes) {985templ->Set(name, value, attributes);986}987988NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {989return v8::Context::GetCurrent();990}991992NAN_INLINE void* NanGetInternalFieldPointer(993v8::Handle<v8::Object> object994, int index) {995return object->GetPointerFromInternalField(index);996}997998NAN_INLINE void NanSetInternalFieldPointer(999v8::Handle<v8::Object> object1000, int index1001, void* value) {1002object->SetPointerInInternalField(index, value);1003}10041005# define NAN_GC_CALLBACK(name) \1006void name(v8::GCType type, v8::GCCallbackFlags flags)10071008NAN_INLINE void NanAddGCEpilogueCallback(1009v8::GCEpilogueCallback callback1010, v8::GCType gc_type_filter = v8::kGCTypeAll) {1011v8::V8::AddGCEpilogueCallback(callback, gc_type_filter);1012}1013NAN_INLINE void NanRemoveGCEpilogueCallback(1014v8::GCEpilogueCallback callback) {1015v8::V8::RemoveGCEpilogueCallback(callback);1016}1017NAN_INLINE void NanAddGCPrologueCallback(1018v8::GCPrologueCallback callback1019, v8::GCType gc_type_filter = v8::kGCTypeAll) {1020v8::V8::AddGCPrologueCallback(callback, gc_type_filter);1021}1022NAN_INLINE void NanRemoveGCPrologueCallback(1023v8::GCPrologueCallback callback) {1024v8::V8::RemoveGCPrologueCallback(callback);1025}1026NAN_INLINE void NanGetHeapStatistics(1027v8::HeapStatistics *heap_statistics) {1028v8::V8::GetHeapStatistics(heap_statistics);1029}10301031template<typename T>1032NAN_INLINE void NanAssignPersistent(1033v8::Persistent<T>& handle1034, v8::Handle<T> obj) {1035handle.Dispose();1036handle = v8::Persistent<T>::New(obj);1037}10381039template<typename T, typename P>1040class _NanWeakCallbackData;10411042template<typename T, typename P>1043struct _NanWeakCallbackInfo {1044typedef void (*Callback)(const _NanWeakCallbackData<T, P> &data);1045NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> handle, P* param, Callback cb)1046: parameter(param)1047, callback(cb)1048, persistent(v8::Persistent<T>::New(handle)) { }10491050NAN_INLINE ~_NanWeakCallbackInfo() {1051persistent.Dispose();1052persistent.Clear();1053}10541055P* const parameter;1056Callback const callback;1057v8::Persistent<T> persistent;1058};10591060template<typename T, typename P>1061class _NanWeakCallbackData {1062public:1063NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info)1064: info_(info) { }10651066NAN_INLINE v8::Local<T> GetValue() const {1067return NanNew(info_->persistent);1068}10691070NAN_INLINE P* GetParameter() const { return info_->parameter; }10711072NAN_INLINE bool IsNearDeath() const {1073return info_->persistent.IsNearDeath();1074}10751076NAN_INLINE void Revive() const;10771078NAN_INLINE _NanWeakCallbackInfo<T, P>* GetCallbackInfo() const {1079return info_;1080}10811082NAN_DEPRECATED NAN_INLINE void Dispose() const {1083}10841085private:1086_NanWeakCallbackInfo<T, P>* info_;1087};10881089template<typename T, typename P>1090static void _NanWeakPersistentDispatcher(1091v8::Persistent<v8::Value> object, void *data) {1092_NanWeakCallbackInfo<T, P>* info =1093static_cast<_NanWeakCallbackInfo<T, P>*>(data);1094_NanWeakCallbackData<T, P> wcbd(info);1095info->callback(wcbd);1096if (wcbd.IsNearDeath()) {1097delete wcbd.GetCallbackInfo();1098}1099}11001101template<typename T, typename P>1102NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const {1103info_->persistent.MakeWeak(1104info_1105, &_NanWeakPersistentDispatcher<T, P>);1106}11071108template<typename T, typename P>1109NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(1110v8::Handle<T> handle1111, P* parameter1112, typename _NanWeakCallbackInfo<T, P>::Callback callback) {1113_NanWeakCallbackInfo<T, P> *cbinfo =1114new _NanWeakCallbackInfo<T, P>(handle, parameter, callback);1115cbinfo->persistent.MakeWeak(1116cbinfo1117, &_NanWeakPersistentDispatcher<T, P>);1118return cbinfo;1119}11201121# define NAN_WEAK_CALLBACK(name) \1122template<typename T, typename P> \1123static void name(const _NanWeakCallbackData<T, P> &data)11241125# define _NAN_ERROR(fun, errmsg) \1126fun(v8::String::New(errmsg))11271128# define _NAN_THROW_ERROR(fun, errmsg) \1129do { \1130NanScope(); \1131return v8::Local<v8::Value>::New( \1132v8::ThrowException(_NAN_ERROR(fun, errmsg))); \1133} while (0);11341135NAN_INLINE v8::Local<v8::Value> NanError(const char* errmsg) {1136return _NAN_ERROR(v8::Exception::Error, errmsg);1137}11381139NAN_INLINE v8::Local<v8::Value> NanThrowError(const char* errmsg) {1140_NAN_THROW_ERROR(v8::Exception::Error, errmsg);1141}11421143NAN_INLINE v8::Local<v8::Value> NanThrowError(1144v8::Handle<v8::Value> error1145) {1146NanScope();1147return v8::Local<v8::Value>::New(v8::ThrowException(error));1148}11491150NAN_INLINE v8::Local<v8::Value> NanError(1151const char *msg1152, const int errorNumber1153) {1154v8::Local<v8::Value> err = v8::Exception::Error(v8::String::New(msg));1155v8::Local<v8::Object> obj = err.As<v8::Object>();1156obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber));1157return err;1158}11591160NAN_INLINE v8::Local<v8::Value> NanThrowError(1161const char *msg1162, const int errorNumber1163) {1164return NanThrowError(NanError(msg, errorNumber));1165}11661167NAN_INLINE v8::Local<v8::Value> NanTypeError(const char* errmsg) {1168return _NAN_ERROR(v8::Exception::TypeError, errmsg);1169}11701171NAN_INLINE v8::Local<v8::Value> NanThrowTypeError(1172const char* errmsg1173) {1174_NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);1175}11761177NAN_INLINE v8::Local<v8::Value> NanRangeError(1178const char* errmsg1179) {1180return _NAN_ERROR(v8::Exception::RangeError, errmsg);1181}11821183NAN_INLINE v8::Local<v8::Value> NanThrowRangeError(1184const char* errmsg1185) {1186_NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);1187}11881189template<typename T>1190NAN_INLINE void NanDisposePersistent(1191v8::Persistent<T> &handle) { // NOLINT(runtime/references)1192handle.Dispose();1193handle.Clear();1194}11951196NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (1197char *data1198, size_t length1199, node::Buffer::free_callback callback1200, void *hint1201) {1202return NanNew(1203node::Buffer::New(data, length, callback, hint)->handle_);1204}12051206NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (1207const char *data1208, uint32_t size1209) {1210#if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION1211return NanNew(node::Buffer::New(data, size)->handle_);1212#else1213return NanNew(1214node::Buffer::New(const_cast<char*>(data), size)->handle_);1215#endif1216}12171218NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {1219return NanNew(node::Buffer::New(size)->handle_);1220}12211222NAN_INLINE void FreeData(char *data, void *hint) {1223delete[] data;1224}12251226NAN_INLINE v8::Local<v8::Object> NanBufferUse(1227char* data1228, uint32_t size1229) {1230return NanNew(1231node::Buffer::New(data, size, FreeData, NULL)->handle_);1232}12331234NAN_INLINE bool NanHasInstance(1235const v8::Persistent<v8::FunctionTemplate>& function_template1236, v8::Handle<v8::Value> value1237) {1238return function_template->HasInstance(value);1239}12401241NAN_DEPRECATED NAN_INLINE v8::Local<v8::Context> NanNewContextHandle(1242v8::ExtensionConfiguration* extensions = NULL1243, v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>()1244, v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()1245) {1246v8::Persistent<v8::Context> ctx = v8::Context::New(extensions, tmpl, obj);1247v8::Local<v8::Context> lctx = NanNew(ctx);1248ctx.Dispose();1249return lctx;1250}12511252NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(1253v8::Local<v8::String> s1254, const v8::ScriptOrigin& origin1255) {1256return v8::Script::Compile(s, const_cast<v8::ScriptOrigin *>(&origin));1257}12581259NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(1260v8::Local<v8::String> s1261) {1262return v8::Script::Compile(s);1263}12641265NAN_INLINE v8::Local<v8::Value> NanRunScript(v8::Handle<v8::Script> script) {1266return script->Run();1267}12681269NAN_INLINE v8::Local<v8::Value> NanMakeCallback(1270v8::Handle<v8::Object> target1271, v8::Handle<v8::Function> func1272, int argc1273, v8::Handle<v8::Value>* argv) {1274# if NODE_VERSION_AT_LEAST(0, 8, 0)1275return NanNew(node::MakeCallback(target, func, argc, argv));1276# else1277v8::TryCatch try_catch;1278v8::Local<v8::Value> result = func->Call(target, argc, argv);1279if (try_catch.HasCaught()) {1280node::FatalException(try_catch);1281}1282return result;1283# endif1284}12851286NAN_INLINE v8::Local<v8::Value> NanMakeCallback(1287v8::Handle<v8::Object> target1288, v8::Handle<v8::String> symbol1289, int argc1290, v8::Handle<v8::Value>* argv) {1291# if NODE_VERSION_AT_LEAST(0, 8, 0)1292return NanNew(node::MakeCallback(target, symbol, argc, argv));1293# else1294v8::Local<v8::Function> callback = target->Get(symbol).As<v8::Function>();1295return NanMakeCallback(target, callback, argc, argv);1296# endif1297}12981299NAN_INLINE v8::Local<v8::Value> NanMakeCallback(1300v8::Handle<v8::Object> target1301, const char* method1302, int argc1303, v8::Handle<v8::Value>* argv) {1304# if NODE_VERSION_AT_LEAST(0, 8, 0)1305return NanNew(node::MakeCallback(target, method, argc, argv));1306# else1307return NanMakeCallback(target, NanNew(method), argc, argv);1308# endif1309}13101311template<typename T>1312NAN_INLINE void NanSetIsolateData(1313v8::Isolate *isolate1314, T *data1315) {1316isolate->SetData(data);1317}13181319template<typename T>1320NAN_INLINE T *NanGetIsolateData(1321v8::Isolate *isolate1322) {1323return static_cast<T*>(isolate->GetData());1324}13251326class NanAsciiString {1327public:1328NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {1329v8::Local<v8::String> toStr = from->ToString();1330size = toStr->Length();1331buf = new char[size + 1];1332size = toStr->WriteAscii(buf);1333}13341335NAN_DEPRECATED NAN_INLINE int Size() const {1336return size;1337}13381339NAN_INLINE int length() const {1340return size;1341}134213431344NAN_INLINE char* operator*() { return buf; }1345NAN_INLINE const char* operator*() const { return buf; }13461347NAN_INLINE ~NanAsciiString() {1348delete[] buf;1349}13501351private:1352// disallow copying and assigning1353NanAsciiString(const NanAsciiString&);1354void operator=(const NanAsciiString&);13551356char *buf;1357int size;1358};13591360class NanUtf8String {1361public:1362NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {1363v8::Local<v8::String> toStr = from->ToString();1364size = toStr->Utf8Length();1365buf = new char[size + 1];1366toStr->WriteUtf8(buf);1367}13681369NAN_DEPRECATED NAN_INLINE int Size() const {1370return size;1371}13721373NAN_INLINE int length() const {1374return size;1375}13761377NAN_INLINE char* operator*() { return buf; }1378NAN_INLINE const char* operator*() const { return buf; }13791380NAN_INLINE ~NanUtf8String() {1381delete[] buf;1382}13831384private:1385// disallow copying and assigning1386NanUtf8String(const NanUtf8String&);1387void operator=(const NanUtf8String&);13881389char *buf;1390int size;1391};13921393class NanUcs2String {1394public:1395NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {1396v8::Local<v8::String> toStr = from->ToString();1397size = toStr->Length();1398buf = new uint16_t[size + 1];1399toStr->Write(buf);1400}14011402NAN_DEPRECATED NAN_INLINE int Size() const {1403return size;1404}14051406NAN_INLINE int length() const {1407return size;1408}14091410NAN_INLINE uint16_t* operator*() { return buf; }1411NAN_INLINE const uint16_t* operator*() const { return buf; }14121413NAN_INLINE ~NanUcs2String() {1414delete[] buf;1415}14161417private:1418// disallow copying and assigning1419NanUcs2String(const NanUcs2String&);1420void operator=(const NanUcs2String&);14211422uint16_t *buf;1423int size;1424};14251426#endif // NODE_MODULE_VERSION14271428typedef void (*NanFreeCallback)(char *data, void *hint);14291430#define NAN_METHOD(name) _NAN_METHOD_RETURN_TYPE name(_NAN_METHOD_ARGS)1431#define NAN_GETTER(name) \1432_NAN_GETTER_RETURN_TYPE name( \1433v8::Local<v8::String> property \1434, _NAN_GETTER_ARGS)1435#define NAN_SETTER(name) \1436_NAN_SETTER_RETURN_TYPE name( \1437v8::Local<v8::String> property \1438, v8::Local<v8::Value> value \1439, _NAN_SETTER_ARGS)1440#define NAN_PROPERTY_GETTER(name) \1441_NAN_PROPERTY_GETTER_RETURN_TYPE name( \1442v8::Local<v8::String> property \1443, _NAN_PROPERTY_GETTER_ARGS)1444#define NAN_PROPERTY_SETTER(name) \1445_NAN_PROPERTY_SETTER_RETURN_TYPE name( \1446v8::Local<v8::String> property \1447, v8::Local<v8::Value> value \1448, _NAN_PROPERTY_SETTER_ARGS)1449#define NAN_PROPERTY_ENUMERATOR(name) \1450_NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name(_NAN_PROPERTY_ENUMERATOR_ARGS)1451#define NAN_PROPERTY_DELETER(name) \1452_NAN_PROPERTY_DELETER_RETURN_TYPE name( \1453v8::Local<v8::String> property \1454, _NAN_PROPERTY_DELETER_ARGS)1455#define NAN_PROPERTY_QUERY(name) \1456_NAN_PROPERTY_QUERY_RETURN_TYPE name( \1457v8::Local<v8::String> property \1458, _NAN_PROPERTY_QUERY_ARGS)1459# define NAN_INDEX_GETTER(name) \1460_NAN_INDEX_GETTER_RETURN_TYPE name(uint32_t index, _NAN_INDEX_GETTER_ARGS)1461#define NAN_INDEX_SETTER(name) \1462_NAN_INDEX_SETTER_RETURN_TYPE name( \1463uint32_t index \1464, v8::Local<v8::Value> value \1465, _NAN_INDEX_SETTER_ARGS)1466#define NAN_INDEX_ENUMERATOR(name) \1467_NAN_INDEX_ENUMERATOR_RETURN_TYPE name(_NAN_INDEX_ENUMERATOR_ARGS)1468#define NAN_INDEX_DELETER(name) \1469_NAN_INDEX_DELETER_RETURN_TYPE name( \1470uint32_t index \1471, _NAN_INDEX_DELETER_ARGS)1472#define NAN_INDEX_QUERY(name) \1473_NAN_INDEX_QUERY_RETURN_TYPE name(uint32_t index, _NAN_INDEX_QUERY_ARGS)14741475class NanCallback {1476public:1477NanCallback() {1478NanScope();1479v8::Local<v8::Object> obj = NanNew<v8::Object>();1480NanAssignPersistent(handle, obj);1481}14821483explicit NanCallback(const v8::Handle<v8::Function> &fn) {1484NanScope();1485v8::Local<v8::Object> obj = NanNew<v8::Object>();1486NanAssignPersistent(handle, obj);1487SetFunction(fn);1488}14891490~NanCallback() {1491if (handle.IsEmpty()) return;1492NanDisposePersistent(handle);1493}14941495bool operator==(const NanCallback &other) const {1496NanScope();1497v8::Local<v8::Value> a = NanNew(handle)->Get(kCallbackIndex);1498v8::Local<v8::Value> b = NanNew(other.handle)->Get(kCallbackIndex);1499return a->StrictEquals(b);1500}15011502bool operator!=(const NanCallback &other) const {1503return !this->operator==(other);1504}15051506NAN_INLINE void SetFunction(const v8::Handle<v8::Function> &fn) {1507NanScope();1508NanNew(handle)->Set(kCallbackIndex, fn);1509}15101511NAN_INLINE v8::Local<v8::Function> GetFunction() const {1512NanEscapableScope();1513return NanEscapeScope(NanNew(handle)->Get(kCallbackIndex)1514.As<v8::Function>());1515}15161517NAN_INLINE bool IsEmpty() const {1518NanScope();1519return NanNew(handle)->Get(kCallbackIndex)->IsUndefined();1520}15211522NAN_INLINE v8::Handle<v8::Value>1523Call(v8::Handle<v8::Object> target1524, int argc1525, v8::Handle<v8::Value> argv[]) const {1526#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)1527v8::Isolate *isolate = v8::Isolate::GetCurrent();1528return Call_(isolate, target, argc, argv);1529#else1530return Call_(target, argc, argv);1531#endif1532}15331534NAN_INLINE v8::Handle<v8::Value>1535Call(int argc, v8::Handle<v8::Value> argv[]) const {1536#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)1537v8::Isolate *isolate = v8::Isolate::GetCurrent();1538return Call_(isolate, isolate->GetCurrentContext()->Global(), argc, argv);1539#else1540return Call_(v8::Context::GetCurrent()->Global(), argc, argv);1541#endif1542}15431544private:1545v8::Persistent<v8::Object> handle;1546static const uint32_t kCallbackIndex = 0;15471548#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)1549v8::Handle<v8::Value> Call_(v8::Isolate *isolate1550, v8::Handle<v8::Object> target1551, int argc1552, v8::Handle<v8::Value> argv[]) const {1553#else1554v8::Handle<v8::Value> Call_(v8::Handle<v8::Object> target1555, int argc1556, v8::Handle<v8::Value> argv[]) const {1557#endif1558NanEscapableScope();1559#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)1560v8::Local<v8::Function> callback = NanNew(handle)->1561Get(kCallbackIndex).As<v8::Function>();1562return NanEscapeScope(node::MakeCallback(1563isolate1564, target1565, callback1566, argc1567, argv1568));1569#else1570#if NODE_VERSION_AT_LEAST(0, 8, 0)1571v8::Local<v8::Function> callback = handle->1572Get(kCallbackIndex).As<v8::Function>();1573return NanEscapeScope(node::MakeCallback(1574target1575, callback1576, argc1577, argv1578));1579#else1580v8::Local<v8::Function> callback = handle->1581Get(kCallbackIndex).As<v8::Function>();1582return NanEscapeScope(NanMakeCallback(1583target, callback, argc, argv));1584#endif1585#endif1586}1587};15881589/* abstract */ class NanAsyncWorker {1590public:1591explicit NanAsyncWorker(NanCallback *callback_)1592: callback(callback_), errmsg_(NULL) {1593request.data = this;15941595NanScope();1596v8::Local<v8::Object> obj = NanNew<v8::Object>();1597NanAssignPersistent(persistentHandle, obj);1598}15991600virtual ~NanAsyncWorker() {1601NanScope();16021603if (!persistentHandle.IsEmpty())1604NanDisposePersistent(persistentHandle);1605if (callback)1606delete callback;1607if (errmsg_)1608delete[] errmsg_;1609}16101611virtual void WorkComplete() {1612NanScope();16131614if (errmsg_ == NULL)1615HandleOKCallback();1616else1617HandleErrorCallback();1618delete callback;1619callback = NULL;1620}16211622NAN_INLINE void SaveToPersistent(1623const char *key, const v8::Local<v8::Object> &obj) {1624v8::Local<v8::Object> handle = NanNew(persistentHandle);1625handle->Set(NanNew<v8::String>(key), obj);1626}16271628v8::Local<v8::Object> GetFromPersistent(const char *key) const {1629NanEscapableScope();1630v8::Local<v8::Object> handle = NanNew(persistentHandle);1631return NanEscapeScope(handle->Get(NanNew(key)).As<v8::Object>());1632}16331634virtual void Execute() = 0;16351636uv_work_t request;16371638virtual void Destroy() {1639delete this;1640}16411642protected:1643v8::Persistent<v8::Object> persistentHandle;1644NanCallback *callback;16451646virtual void HandleOKCallback() {1647callback->Call(0, NULL);1648}16491650virtual void HandleErrorCallback() {1651NanScope();16521653v8::Local<v8::Value> argv[] = {1654v8::Exception::Error(NanNew<v8::String>(ErrorMessage()))1655};1656callback->Call(1, argv);1657}16581659void SetErrorMessage(const char *msg) {1660if (errmsg_) {1661delete[] errmsg_;1662}16631664size_t size = strlen(msg) + 1;1665errmsg_ = new char[size];1666memcpy(errmsg_, msg, size);1667}16681669const char* ErrorMessage() const {1670return errmsg_;1671}16721673private:1674char *errmsg_;1675};16761677/* abstract */ class NanAsyncProgressWorker : public NanAsyncWorker {1678public:1679explicit NanAsyncProgressWorker(NanCallback *callback_)1680: NanAsyncWorker(callback_), asyncdata_(NULL), asyncsize_(0) {1681async = new uv_async_t;1682uv_async_init(1683uv_default_loop()1684, async1685, AsyncProgress_1686);1687async->data = this;16881689uv_mutex_init(&async_lock);1690}16911692virtual ~NanAsyncProgressWorker() {1693uv_mutex_destroy(&async_lock);16941695if (asyncdata_) {1696delete[] asyncdata_;1697}1698}16991700void WorkProgress() {1701uv_mutex_lock(&async_lock);1702char *data = asyncdata_;1703size_t size = asyncsize_;1704asyncdata_ = NULL;1705uv_mutex_unlock(&async_lock);17061707// Dont send progress events after we've already completed.1708if (callback) {1709HandleProgressCallback(data, size);1710}1711delete[] data;1712}17131714class ExecutionProgress {1715friend class NanAsyncProgressWorker;1716public:1717// You could do fancy generics with templates here.1718void Send(const char* data, size_t size) const {1719that_->SendProgress_(data, size);1720}17211722private:1723explicit ExecutionProgress(NanAsyncProgressWorker* that) : that_(that) {}1724// Prohibit copying and assignment.1725ExecutionProgress(const ExecutionProgress&);1726void operator=(const ExecutionProgress&);1727#if __cplusplus >= 201103L1728// Prohibit C++11 move semantics.1729ExecutionProgress(ExecutionProgress&&) = delete;1730void operator=(ExecutionProgress&&) = delete;1731#endif1732NanAsyncProgressWorker* const that_;1733};17341735virtual void Execute(const ExecutionProgress& progress) = 0;1736virtual void HandleProgressCallback(const char *data, size_t size) = 0;17371738virtual void Destroy() {1739uv_close(reinterpret_cast<uv_handle_t*>(async), AsyncClose_);1740}17411742private:1743void Execute() /*final override*/ {1744ExecutionProgress progress(this);1745Execute(progress);1746}17471748void SendProgress_(const char *data, size_t size) {1749char *new_data = new char[size];1750memcpy(new_data, data, size);17511752uv_mutex_lock(&async_lock);1753char *old_data = asyncdata_;1754asyncdata_ = new_data;1755asyncsize_ = size;1756uv_mutex_unlock(&async_lock);17571758if (old_data) {1759delete[] old_data;1760}1761uv_async_send(async);1762}17631764NAN_INLINE static NAUV_WORK_CB(AsyncProgress_) {1765NanAsyncProgressWorker *worker =1766static_cast<NanAsyncProgressWorker*>(async->data);1767worker->WorkProgress();1768}17691770NAN_INLINE static void AsyncClose_(uv_handle_t* handle) {1771NanAsyncProgressWorker *worker =1772static_cast<NanAsyncProgressWorker*>(handle->data);1773delete reinterpret_cast<uv_async_t*>(handle);1774delete worker;1775}17761777uv_async_t *async;1778uv_mutex_t async_lock;1779char *asyncdata_;1780size_t asyncsize_;1781};17821783NAN_INLINE void NanAsyncExecute (uv_work_t* req) {1784NanAsyncWorker *worker = static_cast<NanAsyncWorker*>(req->data);1785worker->Execute();1786}17871788NAN_INLINE void NanAsyncExecuteComplete (uv_work_t* req) {1789NanAsyncWorker* worker = static_cast<NanAsyncWorker*>(req->data);1790worker->WorkComplete();1791worker->Destroy();1792}17931794NAN_INLINE void NanAsyncQueueWorker (NanAsyncWorker* worker) {1795uv_queue_work(1796uv_default_loop()1797, &worker->request1798, NanAsyncExecute1799, (uv_after_work_cb)NanAsyncExecuteComplete1800);1801}18021803//// Base 64 ////18041805#define _nan_base64_encoded_size(size) ((size + 2 - ((size + 2) % 3)) / 3 * 4)18061807// Doesn't check for padding at the end. Can be 1-2 bytes over.1808NAN_INLINE size_t _nan_base64_decoded_size_fast(size_t size) {1809size_t remainder = size % 4;18101811size = (size / 4) * 3;1812if (remainder) {1813if (size == 0 && remainder == 1) {1814// special case: 1-byte input cannot be decoded1815size = 0;1816} else {1817// non-padded input, add 1 or 2 extra bytes1818size += 1 + (remainder == 3);1819}1820}18211822return size;1823}18241825template<typename T>1826NAN_INLINE size_t _nan_base64_decoded_size(1827const T* src1828, size_t size1829) {1830if (size == 0)1831return 0;18321833if (src[size - 1] == '=')1834size--;1835if (size > 0 && src[size - 1] == '=')1836size--;18371838return _nan_base64_decoded_size_fast(size);1839}18401841// supports regular and URL-safe base641842static const int _nan_unbase64_table[] = {1843-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -11844, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -11845, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 631846, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -11847, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 141848, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 631849, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 401850, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -11851, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -11852, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -11853, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -11854, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -11855, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -11856, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -11857, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -11858, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -11859};18601861#define _nan_unbase64(x) _nan_unbase64_table[(uint8_t)(x)]18621863template<typename T> static size_t _nan_base64_decode(1864char* buf1865, size_t len1866, const T* src1867, const size_t srcLen1868) {1869char* dst = buf;1870char* dstEnd = buf + len;1871const T* srcEnd = src + srcLen;18721873while (src < srcEnd && dst < dstEnd) {1874ptrdiff_t remaining = srcEnd - src;1875char a, b, c, d;18761877while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;1878if (remaining == 0 || *src == '=') break;1879a = _nan_unbase64(*src++);18801881while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;1882if (remaining <= 1 || *src == '=') break;1883b = _nan_unbase64(*src++);18841885*dst++ = (a << 2) | ((b & 0x30) >> 4);1886if (dst == dstEnd) break;18871888while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;1889if (remaining <= 2 || *src == '=') break;1890c = _nan_unbase64(*src++);18911892*dst++ = ((b & 0x0F) << 4) | ((c & 0x3C) >> 2);1893if (dst == dstEnd) break;18941895while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;1896if (remaining <= 3 || *src == '=') break;1897d = _nan_unbase64(*src++);18981899*dst++ = ((c & 0x03) << 6) | (d & 0x3F);1900}19011902return dst - buf;1903}19041905//// HEX ////19061907template<typename T> unsigned _nan_hex2bin(T c) {1908if (c >= '0' && c <= '9') return c - '0';1909if (c >= 'A' && c <= 'F') return 10 + (c - 'A');1910if (c >= 'a' && c <= 'f') return 10 + (c - 'a');1911return static_cast<unsigned>(-1);1912}19131914template<typename T> static size_t _nan_hex_decode(1915char* buf1916, size_t len1917, const T* src1918, const size_t srcLen1919) {1920size_t i;1921for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) {1922unsigned a = _nan_hex2bin(src[i * 2 + 0]);1923unsigned b = _nan_hex2bin(src[i * 2 + 1]);1924if (!~a || !~b) return i;1925buf[i] = a * 16 + b;1926}19271928return i;1929}19301931namespace NanIntern {19321933inline1934NanExternalOneByteStringResource const*1935GetExternalResource(v8::Local<v8::String> str) {1936#if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION1937return str->GetExternalAsciiStringResource();1938#else1939return str->GetExternalOneByteStringResource();1940#endif1941}19421943inline1944bool1945IsExternal(v8::Local<v8::String> str) {1946#if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION1947return str->IsExternalAscii();1948#else1949return str->IsExternalOneByte();1950#endif1951}19521953} // end of namespace NanIntern19541955static bool _NanGetExternalParts(1956v8::Handle<v8::Value> val1957, const char** data1958, size_t* len1959) {1960if (node::Buffer::HasInstance(val)) {1961*data = node::Buffer::Data(val.As<v8::Object>());1962*len = node::Buffer::Length(val.As<v8::Object>());1963return true;1964}19651966assert(val->IsString());1967v8::Local<v8::String> str = NanNew(val.As<v8::String>());19681969if (NanIntern::IsExternal(str)) {1970const NanExternalOneByteStringResource* ext;1971ext = NanIntern::GetExternalResource(str);1972*data = ext->data();1973*len = ext->length();1974return true;1975}19761977if (str->IsExternal()) {1978const v8::String::ExternalStringResource* ext;1979ext = str->GetExternalStringResource();1980*data = reinterpret_cast<const char*>(ext->data());1981*len = ext->length();1982return true;1983}19841985return false;1986}19871988namespace Nan {1989enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};1990}19911992#if !NODE_VERSION_AT_LEAST(0, 10, 0)1993# include "nan_string_bytes.h" // NOLINT(build/include)1994#endif19951996NAN_INLINE v8::Local<v8::Value> NanEncode(1997const void *buf, size_t len, enum Nan::Encoding encoding = Nan::BINARY) {1998#if (NODE_MODULE_VERSION >= ATOM_0_21_MODULE_VERSION)1999v8::Isolate* isolate = v8::Isolate::GetCurrent();2000node::encoding node_enc = static_cast<node::encoding>(encoding);20012002if (encoding == Nan::UCS2) {2003return node::Encode(2004isolate2005, reinterpret_cast<const uint16_t *>(buf)2006, len / 2);2007} else {2008return node::Encode(2009isolate2010, reinterpret_cast<const char *>(buf)2011, len2012, node_enc);2013}2014#elif (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)2015return node::Encode(2016v8::Isolate::GetCurrent()2017, buf, len2018, static_cast<node::encoding>(encoding));2019#else2020# if NODE_VERSION_AT_LEAST(0, 10, 0)2021return node::Encode(buf, len, static_cast<node::encoding>(encoding));2022# else2023return NanIntern::Encode(reinterpret_cast<const char*>(buf), len, encoding);2024# endif2025#endif2026}20272028NAN_INLINE ssize_t NanDecodeBytes(2029v8::Handle<v8::Value> val, enum Nan::Encoding encoding = Nan::BINARY) {2030#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)2031return node::DecodeBytes(2032v8::Isolate::GetCurrent()2033, val2034, static_cast<node::encoding>(encoding));2035#else2036# if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)2037if (encoding == Nan::BUFFER) {2038return node::DecodeBytes(val, node::BINARY);2039}2040# endif2041return node::DecodeBytes(val, static_cast<node::encoding>(encoding));2042#endif2043}20442045NAN_INLINE ssize_t NanDecodeWrite(2046char *buf2047, size_t len2048, v8::Handle<v8::Value> val2049, enum Nan::Encoding encoding = Nan::BINARY) {2050#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)2051return node::DecodeWrite(2052v8::Isolate::GetCurrent()2053, buf2054, len2055, val2056, static_cast<node::encoding>(encoding));2057#else2058# if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)2059if (encoding == Nan::BUFFER) {2060return node::DecodeWrite(buf, len, val, node::BINARY);2061}2062# endif2063return node::DecodeWrite(2064buf2065, len2066, val2067, static_cast<node::encoding>(encoding));2068#endif2069}20702071/* NAN_DEPRECATED */ NAN_INLINE void* _NanRawString(2072v8::Handle<v8::Value> from2073, enum Nan::Encoding encoding2074, size_t *datalen2075, void *buf2076, size_t buflen2077, int flags2078) {2079NanScope();20802081size_t sz_;2082size_t term_len = !(flags & v8::String::NO_NULL_TERMINATION);2083char *data = NULL;2084size_t len;2085bool is_extern = _NanGetExternalParts(2086from2087, const_cast<const char**>(&data)2088, &len);20892090if (is_extern && !term_len) {2091NanSetPointerSafe(datalen, len);2092return data;2093}20942095v8::Local<v8::String> toStr = from->ToString();20962097char *to = static_cast<char *>(buf);20982099switch (encoding) {2100case Nan::ASCII:2101#if NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION2102sz_ = toStr->Length();2103if (to == NULL) {2104to = new char[sz_ + term_len];2105} else {2106assert(buflen >= sz_ + term_len && "too small buffer");2107}2108NanSetPointerSafe<size_t>(2109datalen2110, toStr->WriteAscii(to, 0, static_cast<int>(sz_ + term_len), flags));2111return to;2112#endif2113case Nan::BINARY:2114case Nan::BUFFER:2115sz_ = toStr->Length();2116if (to == NULL) {2117to = new char[sz_ + term_len];2118} else {2119assert(buflen >= sz_ + term_len && "too small buffer");2120}2121#if NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION2122{2123uint16_t* twobytebuf = new uint16_t[sz_ + term_len];21242125size_t somelen = toStr->Write(twobytebuf, 0,2126static_cast<int>(sz_ + term_len), flags);21272128for (size_t i = 0; i < sz_ + term_len && i < somelen + term_len; i++) {2129unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);2130to[i] = *b;2131}21322133NanSetPointerSafe<size_t>(datalen, somelen);21342135delete[] twobytebuf;2136return to;2137}2138#else2139NanSetPointerSafe<size_t>(2140datalen,2141toStr->WriteOneByte(2142reinterpret_cast<uint8_t *>(to)2143, 02144, static_cast<int>(sz_ + term_len)2145, flags));2146return to;2147#endif2148case Nan::UTF8:2149sz_ = toStr->Utf8Length();2150if (to == NULL) {2151to = new char[sz_ + term_len];2152} else {2153assert(buflen >= sz_ + term_len && "too small buffer");2154}2155NanSetPointerSafe<size_t>(2156datalen2157, toStr->WriteUtf8(to, static_cast<int>(sz_ + term_len)2158, NULL, flags)2159- term_len);2160return to;2161case Nan::BASE64:2162{2163v8::String::Value value(toStr);2164sz_ = _nan_base64_decoded_size(*value, value.length());2165if (to == NULL) {2166to = new char[sz_ + term_len];2167} else {2168assert(buflen >= sz_ + term_len);2169}2170NanSetPointerSafe<size_t>(2171datalen2172, _nan_base64_decode(to, sz_, *value, value.length()));2173if (term_len) {2174to[sz_] = '\0';2175}2176return to;2177}2178case Nan::UCS2:2179{2180sz_ = toStr->Length();2181if (to == NULL) {2182to = new char[(sz_ + term_len) * 2];2183} else {2184assert(buflen >= (sz_ + term_len) * 2 && "too small buffer");2185}21862187int bc = 2 * toStr->Write(2188reinterpret_cast<uint16_t *>(to)2189, 02190, static_cast<int>(sz_ + term_len)2191, flags);2192NanSetPointerSafe<size_t>(datalen, bc);2193return to;2194}2195case Nan::HEX:2196{2197v8::String::Value value(toStr);2198sz_ = value.length();2199assert(!(sz_ & 1) && "bad hex data");2200if (to == NULL) {2201to = new char[sz_ / 2 + term_len];2202} else {2203assert(buflen >= sz_ / 2 + term_len && "too small buffer");2204}2205NanSetPointerSafe<size_t>(2206datalen2207, _nan_hex_decode(to, sz_ / 2, *value, value.length()));2208}2209if (term_len) {2210to[sz_ / 2] = '\0';2211}2212return to;2213default:2214assert(0 && "unknown encoding");2215}2216return to;2217}22182219NAN_DEPRECATED NAN_INLINE void* NanRawString(2220v8::Handle<v8::Value> from2221, enum Nan::Encoding encoding2222, size_t *datalen2223, void *buf2224, size_t buflen2225, int flags2226) {2227return _NanRawString(from, encoding, datalen, buf, buflen, flags);2228}222922302231NAN_DEPRECATED NAN_INLINE char* NanCString(2232v8::Handle<v8::Value> from2233, size_t *datalen2234, char *buf = NULL2235, size_t buflen = 02236, int flags = v8::String::NO_OPTIONS2237) {2238return static_cast<char *>(2239_NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags)2240);2241}22422243NAN_INLINE void NanSetPrototypeTemplate(2244v8::Local<v8::FunctionTemplate> templ2245, const char *name2246, v8::Handle<v8::Data> value2247) {2248NanSetTemplate(templ->PrototypeTemplate(), name, value);2249}22502251NAN_INLINE void NanSetPrototypeTemplate(2252v8::Local<v8::FunctionTemplate> templ2253, v8::Handle<v8::String> name2254, v8::Handle<v8::Data> value2255, v8::PropertyAttribute attributes2256) {2257NanSetTemplate(templ->PrototypeTemplate(), name, value, attributes);2258}22592260NAN_INLINE void NanSetInstanceTemplate(2261v8::Local<v8::FunctionTemplate> templ2262, const char *name2263, v8::Handle<v8::Data> value2264) {2265NanSetTemplate(templ->InstanceTemplate(), name, value);2266}22672268NAN_INLINE void NanSetInstanceTemplate(2269v8::Local<v8::FunctionTemplate> templ2270, v8::Handle<v8::String> name2271, v8::Handle<v8::Data> value2272, v8::PropertyAttribute attributes2273) {2274NanSetTemplate(templ->InstanceTemplate(), name, value, attributes);2275}22762277//=== Export ==================================================================22782279inline2280void2281NanExport(v8::Handle<v8::Object> target, const char * name,2282NanFunctionCallback f) {2283target->Set(NanNew<v8::String>(name),2284NanNew<v8::FunctionTemplate>(f)->GetFunction());2285}22862287//=== Tap Reverse Binding =====================================================22882289struct NanTap {2290explicit NanTap(v8::Handle<v8::Value> t) : t_() {2291NanAssignPersistent(t_, t->ToObject());2292}22932294~NanTap() { NanDisposePersistent(t_); } // not sure if neccessary22952296inline void plan(int i) {2297v8::Handle<v8::Value> arg = NanNew(i);2298NanMakeCallback(NanNew(t_), "plan", 1, &arg);2299}23002301inline void ok(bool isOk, const char * msg = NULL) {2302v8::Handle<v8::Value> args[2];2303args[0] = NanNew(isOk);2304if (msg) args[1] = NanNew(msg);2305NanMakeCallback(NanNew(t_), "ok", msg ? 2 : 1, args);2306}23072308private:2309v8::Persistent<v8::Object> t_;2310};23112312#define NAN_STRINGIZE2(x) #x2313#define NAN_STRINGIZE(x) NAN_STRINGIZE2(x)2314#define NAN_TEST_EXPRESSION(expression) \2315( expression ), __FILE__ ":" NAN_STRINGIZE(__LINE__) ": " #expression23162317#define return_NanValue(v) NanReturnValue(v)2318#define return_NanUndefined() NanReturnUndefined()2319#define NAN_EXPORT(target, function) NanExport(target, #function, function)23202321#endif // NAN_H_232223232324