From 1fd7b5d1e67a9217f695c252866784a901bc7372 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 2 Aug 2015 08:26:39 +0200 Subject: nodejs: add 0.12 version of node add node-js 0.12 and a few gyp bindings Signed-off-by: John Crispin --- lang/node-hid/Makefile | 62 + lang/node-hid/patches/000-compile.patch | 2457 +++++++++++++++++++++++++++++++ 2 files changed, 2519 insertions(+) create mode 100644 lang/node-hid/Makefile create mode 100644 lang/node-hid/patches/000-compile.patch (limited to 'lang/node-hid') diff --git a/lang/node-hid/Makefile b/lang/node-hid/Makefile new file mode 100644 index 000000000..448535513 --- /dev/null +++ b/lang/node-hid/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (C) 2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NPM_NAME:=hid +PKG_NAME:=node-$(PKG_NPM_NAME) +PKG_VERSION:=0.4.0 + +PKG_RELEASE=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/node-hid/node-hid.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=c56c8aa5d113c6f2574d1f7e64d41745702965bb +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz + +PKG_BUILD_DEPENDS:=node +PKG_NODE_VERSION:=0.12.7 + +PKG_MAINTAINER:=John Crispin +PKG_LICENSE:=MIT + +include $(INCLUDE_DIR)/package.mk + +define Package/node-hid + DEPENDS:=+node + SUBMENU:=Node.js + SECTION:=lang + CATEGORY:=Languages + DEPENDS:=+libusb-1.0 +hidapi +libstdcpp + TITLE:=Node.js package to access HID devices + URL:=https://github.com/node-hid/node-hid +endef + +define Package/node-hid/description + Node.js package to access HID devices +endef + +EXTRA_LDFLAGS+="-lhidapi-libusb" +EXTRA_CFLAGS+="-I$(STAGING_DIR)/usr/include/hidapi/" + +define Build/Compile + $(MAKE_VARS) \ + $(MAKE_FLAGS) \ + npm_config_arch=$(CONFIG_ARCH) \ + npm_config_nodedir=$(BUILD_DIR)/node-v$(PKG_NODE_VERSION)/ \ + PREFIX="$(PKG_INSTALL_DIR)/usr/" \ + $(STAGING_DIR_HOST)/bin/npm install -g $(PKG_BUILD_DIR) +endef + +define Package/node-hid/install + mkdir -p $(1)/usr/lib/node/node-hid/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/node-hid/{index.js,package.json,build,node_modules} $(1)/usr/lib/node/node-hid/ +endef + +$(eval $(call BuildPackage,node-hid)) + diff --git a/lang/node-hid/patches/000-compile.patch b/lang/node-hid/patches/000-compile.patch new file mode 100644 index 000000000..d44e9b30f --- /dev/null +++ b/lang/node-hid/patches/000-compile.patch @@ -0,0 +1,2457 @@ +--- a/package.json ++++ b/package.json +@@ -14,9 +14,6 @@ + "type": "git", + "url": "git://github.com/hanshuebner/node-hid.git" + }, +- "scripts": { +- "prepublish": "git submodule update --init" +- }, + "main": "./index.js", + "engines": { + "node": ">=0.8.0" +--- a/src/wscript ++++ b/src/wscript +@@ -3,10 +3,8 @@ + import sys; + import os; + +-hidapi_home='../hidapi' + + cflags=["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall", "-fPIC" ] +-includes=[ hidapi_home + "/hidapi" ] + + def set_options(opt): + opt.tool_options("compiler_cxx") +@@ -16,24 +14,10 @@ + conf.check_tool("compiler_cxx") + conf.check_tool("node_addon") + conf.check_tool("compiler_cc") +- if sys.platform == 'darwin': +- conf.env.append_value('LINKFLAGS', ['Release/libhidapi.a', '-framework', 'IOKit', '-framework', 'CoreFoundation']) +- else: +- conf.env.append_value('LINKFLAGS', ['Release/libhidapi.a', '-ludev' ]) +- +-def build(bld): +- bld.add_group("hidapi") +- hidapi = bld.new_task_gen("cc", "staticlib") +- hidapi.includes = includes +- hidapi.cflags = cflags +- if sys.platform == 'darwin': +- hidapi.source = "../hidapi/mac/hid.c" +- else: +- hidapi.source = "../hidapi/linux/hid.c" +- hidapi.target = "hidapi" + ++def build(bld): + bld.add_group("adapter") +- adapter = bld.new_task_gen("cxx", "shlib", "node_addon", use = ['hidapi']) ++ adapter = bld.new_task_gen("cxx", "shlib", "node_addon") + adapter.includes = includes + adapter.cxxflags = cflags + adapter.target = "HID" +--- a/binding.gyp ++++ b/binding.gyp +@@ -4,61 +4,8 @@ + }, + 'targets': [ + { +- 'target_name': 'hidapi', +- 'type': 'static_library', +- 'conditions': [ +- [ 'OS=="mac"', { +- 'sources': [ 'hidapi/mac/hid.c' ], +- 'include_dirs+': [ +- '/usr/include/libusb-1.0/' +- ] +- }], +- [ 'OS=="linux"', { +- 'conditions': [ +- [ 'driver=="libusb"', { +- 'sources': [ 'hidapi/libusb/hid.c' ], +- 'include_dirs+': [ +- '/usr/include/libusb-1.0/' +- ] +- }], +- [ 'driver=="hidraw"', { +- 'sources': [ 'hidapi/linux/hid.c' ] +- }] +- ] +- }], +- [ 'OS=="win"', { +- 'sources': [ 'hidapi/windows/hid.c' ], +- 'msvs_settings': { +- 'VCLinkerTool': { +- 'AdditionalDependencies': [ +- 'setupapi.lib', +- ] +- } +- } +- }] +- ], +- 'direct_dependent_settings': { +- 'include_dirs': [ +- 'hidapi/hidapi', +- " ++ * - Benjamin Byholm ++ * - Trevor Norris ++ * - Nathan Rajlich ++ * - Brett Lawson ++ * - Ben Noordhuis ++ * ++ * MIT +no-false-attribs License ++ * ++ * Version 1.3.0: current Node unstable: 0.11.13, Node stable: 0.10.30 ++ * ++ * See https://github.com/rvagg/nan for the latest update to this file ++ **********************************************************************************/ ++ ++#ifndef NAN_H_ ++#define NAN_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(__GNUC__) && !defined(DEBUG) ++# define NAN_INLINE inline __attribute__((always_inline)) ++#elif defined(_MSC_VER) && !defined(DEBUG) ++# define NAN_INLINE __forceinline ++#else ++# define NAN_INLINE inline ++#endif ++ ++#if defined(__GNUC__) && !V8_DISABLE_DEPRECATIONS ++# define NAN_DEPRECATED __attribute__((deprecated)) ++#elif defined(_MSC_VER) && !V8_DISABLE_DEPRECATIONS ++# define NAN_DEPRECATED __declspec(deprecated) ++#else ++# define NAN_DEPRECATED ++#endif ++ ++// some generic helpers ++ ++template NAN_INLINE bool NanSetPointerSafe( ++ T *var ++ , T val ++) { ++ if (var) { ++ *var = val; ++ return true; ++ } else { ++ return false; ++ } ++} ++ ++template NAN_INLINE T NanGetPointerSafe( ++ T *var ++ , T fallback = reinterpret_cast(0) ++) { ++ if (var) { ++ return *var; ++ } else { ++ return fallback; ++ } ++} ++ ++NAN_INLINE bool NanBooleanOptionValue( ++ v8::Local optionsObj ++ , v8::Handle opt, bool def ++) { ++ if (def) { ++ return optionsObj.IsEmpty() ++ || !optionsObj->Has(opt) ++ || optionsObj->Get(opt)->BooleanValue(); ++ } else { ++ return !optionsObj.IsEmpty() ++ && optionsObj->Has(opt) ++ && optionsObj->Get(opt)->BooleanValue(); ++ } ++} ++ ++NAN_INLINE bool NanBooleanOptionValue( ++ v8::Local optionsObj ++ , v8::Handle opt ++) { ++ return NanBooleanOptionValue(optionsObj, opt, false); ++} ++ ++NAN_INLINE uint32_t NanUInt32OptionValue( ++ v8::Local optionsObj ++ , v8::Handle opt ++ , uint32_t def ++) { ++ return !optionsObj.IsEmpty() ++ && optionsObj->Has(opt) ++ && optionsObj->Get(opt)->IsNumber() ++ ? optionsObj->Get(opt)->Uint32Value() ++ : def; ++} ++ ++#if (NODE_MODULE_VERSION > 0x000B) ++// Node 0.11+ (0.11.3 and below won't compile with these) ++ ++# define _NAN_METHOD_ARGS_TYPE const v8::FunctionCallbackInfo& ++# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args ++# define _NAN_METHOD_RETURN_TYPE void ++ ++# define _NAN_GETTER_ARGS_TYPE const v8::PropertyCallbackInfo& ++# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args ++# define _NAN_GETTER_RETURN_TYPE void ++ ++# define _NAN_SETTER_ARGS_TYPE const v8::PropertyCallbackInfo& ++# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args ++# define _NAN_SETTER_RETURN_TYPE void ++ ++# define _NAN_PROPERTY_GETTER_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args ++# define _NAN_PROPERTY_GETTER_RETURN_TYPE void ++ ++# define _NAN_PROPERTY_SETTER_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args ++# define _NAN_PROPERTY_SETTER_RETURN_TYPE void ++ ++# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args ++# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE void ++ ++# define _NAN_PROPERTY_DELETER_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_PROPERTY_DELETER_ARGS \ ++ _NAN_PROPERTY_DELETER_ARGS_TYPE args ++# define _NAN_PROPERTY_DELETER_RETURN_TYPE void ++ ++# define _NAN_PROPERTY_QUERY_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args ++# define _NAN_PROPERTY_QUERY_RETURN_TYPE void ++ ++# define _NAN_INDEX_GETTER_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args ++# define _NAN_INDEX_GETTER_RETURN_TYPE void ++ ++# define _NAN_INDEX_SETTER_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args ++# define _NAN_INDEX_SETTER_RETURN_TYPE void ++ ++# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args ++# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE void ++ ++# define _NAN_INDEX_DELETER_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args ++# define _NAN_INDEX_DELETER_RETURN_TYPE void ++ ++# define _NAN_INDEX_QUERY_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo& ++# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args ++# define _NAN_INDEX_QUERY_RETURN_TYPE void ++ ++ typedef v8::FunctionCallback NanFunctionCallback; ++ ++ template ++ NAN_INLINE v8::Local NanNew() { ++ return T::New(v8::Isolate::GetCurrent()); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew(P arg1) { ++ return T::New(v8::Isolate::GetCurrent(), arg1); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Handle receiver ++ , int argc ++ , v8::Handle argv[] = 0) { ++ return v8::Signature::New(v8::Isolate::GetCurrent(), receiver, argc, argv); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ NanFunctionCallback callback ++ , v8::Handle data = v8::Handle() ++ , v8::Handle signature = v8::Handle()) { ++ return T::New(v8::Isolate::GetCurrent(), callback, data, signature); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew(v8::Handle arg1) { ++ return v8::Local::New(v8::Isolate::GetCurrent(), arg1); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew(const v8::Persistent &arg1) { ++ return v8::Local::New(v8::Isolate::GetCurrent(), arg1); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew(P arg1, int arg2) { ++ return T::New(v8::Isolate::GetCurrent(), arg1, arg2); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew() { ++ return v8::Array::New(v8::Isolate::GetCurrent()); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(int length) { ++ return v8::Array::New(v8::Isolate::GetCurrent(), length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(double time) { ++ return v8::Date::New(v8::Isolate::GetCurrent(), time).As(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(int time) { ++ return v8::Date::New(v8::Isolate::GetCurrent(), time).As(); ++ } ++ ++ typedef v8::UnboundScript NanUnboundScript; ++ typedef v8::Script NanBoundScript; ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ P s ++ , const v8::ScriptOrigin& origin ++ ) { ++ v8::ScriptCompiler::Source source(s, origin); ++ return v8::ScriptCompiler::CompileUnbound( ++ v8::Isolate::GetCurrent(), &source); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ v8::Local s ++ ) { ++ v8::ScriptCompiler::Source source(s); ++ return v8::ScriptCompiler::CompileUnbound( ++ v8::Isolate::GetCurrent(), &source); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(bool value) { ++ return v8::BooleanObject::New(value).As(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local ++ NanNew >( ++ v8::Local value) { ++ return v8::StringObject::New(value).As(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local ++ NanNew >( ++ v8::Handle value) { ++ return v8::StringObject::New(value).As(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(double val) { ++ return v8::NumberObject::New( ++ v8::Isolate::GetCurrent(), val).As(); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Handle pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Local pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Handle pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Local pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(int32_t val) { ++ return v8::Uint32::NewFromUnsigned( ++ v8::Isolate::GetCurrent(), val)->ToUint32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(uint32_t val) { ++ return v8::Uint32::NewFromUnsigned( ++ v8::Isolate::GetCurrent(), val)->ToUint32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(int32_t val) { ++ return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(uint32_t val) { ++ return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ char *arg ++ , int length) { ++ return v8::String::NewFromUtf8( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ const char *arg ++ , int length) { ++ return v8::String::NewFromUtf8( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(char *arg) { ++ return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ const char *arg) { ++ return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ uint8_t *arg ++ , int length) { ++ return v8::String::NewFromOneByte( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ const uint8_t *arg ++ , int length) { ++ return v8::String::NewFromOneByte( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(uint8_t *arg) { ++ return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ const uint8_t *arg) { ++ return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ uint16_t *arg ++ , int length) { ++ return v8::String::NewFromTwoByte( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ const uint16_t *arg ++ , int length) { ++ return v8::String::NewFromTwoByte( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ uint16_t *arg) { ++ return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ const uint16_t *arg) { ++ return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ std::string arg) { ++ return NanNew(arg.c_str(), arg.size()); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew() { ++ return v8::String::Empty(v8::Isolate::GetCurrent()); ++ } ++ ++ NAN_INLINE v8::Local NanNew(const char* arg, int length = -1) { ++ return NanNew(arg, length); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ const uint8_t* arg ++ , int length = -1) { ++ return NanNew(arg, length); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ const uint16_t* arg ++ , int length = -1) { ++ return NanNew(arg, length); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ const std::string& arg) { ++ return NanNew(arg.c_str(), arg.size()); ++ } ++ ++ NAN_INLINE v8::Local NanNew(double val) { ++ return NanNew(val); ++ } ++ ++ NAN_INLINE v8::Local NanNew(int val) { ++ return NanNew(val); ++ } ++ ++ NAN_INLINE v8::Local NanNew(unsigned int val) { ++ return NanNew(val); ++ } ++ ++ NAN_INLINE v8::Local NanNew(bool val) { ++ return NanNew(val); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ v8::String::ExternalStringResource *resource) { ++ return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ v8::String::ExternalAsciiStringResource *resource) { ++ return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource); ++ } ++ ++# define NanScope() v8::HandleScope scope(v8::Isolate::GetCurrent()) ++# define NanEscapableScope() \ ++ v8::EscapableHandleScope scope(v8::Isolate::GetCurrent()) ++ ++ template ++ NAN_INLINE v8::Local _NanEscapeScopeHelper(v8::Handle val) { ++ return NanNew(val); ++ } ++ ++ template ++ NAN_INLINE v8::Local _NanEscapeScopeHelper(v8::Local val) { ++ return val; ++ } ++ ++# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val)) ++# define NanLocker() v8::Locker locker(v8::Isolate::GetCurrent()) ++# define NanUnlocker() v8::Unlocker unlocker(v8::Isolate::GetCurrent()) ++# define NanReturnValue(value) return args.GetReturnValue().Set(value) ++# define NanReturnUndefined() return ++# define NanReturnNull() return args.GetReturnValue().SetNull() ++# define NanReturnEmptyString() return args.GetReturnValue().SetEmptyString() ++ ++# define NanObjectWrapHandle(obj) obj->handle() ++ ++ NAN_INLINE v8::Local NanUndefined() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent()))); ++ } ++ ++ NAN_INLINE v8::Local NanNull() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::Null(v8::Isolate::GetCurrent()))); ++ } ++ ++ NAN_INLINE v8::Local NanTrue() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent()))); ++ } ++ ++ NAN_INLINE v8::Local NanFalse() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::False(v8::Isolate::GetCurrent()))); ++ } ++ ++ NAN_INLINE int NanAdjustExternalMemory(int bc) { ++ return static_cast( ++ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc)); ++ } ++ ++ NAN_INLINE void NanSetTemplate( ++ v8::Handle templ ++ , const char *name ++ , v8::Handle value) { ++ templ->Set(v8::Isolate::GetCurrent(), name, value); ++ } ++ ++ NAN_INLINE void NanSetTemplate( ++ v8::Handle templ ++ , v8::Handle name ++ , v8::Handle value ++ , v8::PropertyAttribute attributes) { ++ templ->Set(name, value, attributes); ++ } ++ ++ NAN_INLINE v8::Local NanGetCurrentContext() { ++ return v8::Isolate::GetCurrent()->GetCurrentContext(); ++ } ++ ++ NAN_INLINE void* NanGetInternalFieldPointer( ++ v8::Handle object ++ , int index) { ++ return object->GetAlignedPointerFromInternalField(index); ++ } ++ ++ NAN_INLINE void NanSetInternalFieldPointer( ++ v8::Handle object ++ , int index ++ , void* value) { ++ object->SetAlignedPointerInInternalField(index, value); ++ } ++ ++ NAN_INLINE void NanAddGCEpilogueCallback( ++ v8::Isolate::GCEpilogueCallback callback ++ , v8::GCType gc_type_filter = v8::kGCTypeAll) { ++ v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter); ++ } ++ ++ NAN_INLINE void NanRemoveGCEpilogueCallback( ++ v8::Isolate::GCEpilogueCallback callback) { ++ v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback); ++ } ++ ++ NAN_INLINE void NanAddGCPrologueCallback( ++ v8::Isolate::GCPrologueCallback callback ++ , v8::GCType gc_type_filter = v8::kGCTypeAll) { ++ v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter); ++ } ++ ++ NAN_INLINE void NanRemoveGCPrologueCallback( ++ v8::Isolate::GCPrologueCallback callback) { ++ v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback); ++ } ++ ++ NAN_INLINE void NanGetHeapStatistics( ++ v8::HeapStatistics *heap_statistics) { ++ v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics); ++ } ++ ++ NAN_DEPRECATED NAN_INLINE v8::Local NanSymbol( ++ const char* data, int length = -1) { ++ return NanNew(data, length); ++ } ++ ++ template ++ NAN_INLINE void NanAssignPersistent( ++ v8::Persistent& handle ++ , v8::Handle obj) { ++ handle.Reset(v8::Isolate::GetCurrent(), obj); ++ } ++ ++ template ++ NAN_INLINE void NanAssignPersistent( ++ v8::Persistent& handle ++ , const v8::Persistent& obj) { ++ handle.Reset(v8::Isolate::GetCurrent(), obj); ++ } ++ ++ template ++ class _NanWeakCallbackData; ++ ++ template ++ struct _NanWeakCallbackInfo { ++ typedef void (*Callback)(const _NanWeakCallbackData& data); ++ NAN_INLINE _NanWeakCallbackInfo(v8::Handle handle, P* param, Callback cb) ++ : parameter(param), callback(cb) { ++ NanAssignPersistent(persistent, handle); ++ } ++ ++ NAN_INLINE ~_NanWeakCallbackInfo() { ++ persistent.Reset(); ++ } ++ ++ P* const parameter; ++ Callback const callback; ++ v8::Persistent persistent; ++ }; ++ ++ template ++ class _NanWeakCallbackData { ++ public: ++ NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo *info) ++ : info_(info) { } ++ ++ NAN_INLINE v8::Local GetValue() const { ++ return NanNew(info_->persistent); ++ } ++ ++ NAN_INLINE P* GetParameter() const { return info_->parameter; } ++ ++ NAN_INLINE bool IsNearDeath() const { ++ return info_->persistent.IsNearDeath(); ++ } ++ ++ NAN_INLINE void Revive() const; ++ ++ NAN_INLINE _NanWeakCallbackInfo* GetCallbackInfo() const { ++ return info_; ++ } ++ ++ NAN_DEPRECATED NAN_INLINE void Dispose() const { ++ } ++ ++ private: ++ _NanWeakCallbackInfo* info_; ++ }; ++ ++ template ++ static void _NanWeakCallbackDispatcher( ++ const v8::WeakCallbackData > &data) { ++ _NanWeakCallbackInfo *info = data.GetParameter(); ++ _NanWeakCallbackData wcbd(info); ++ info->callback(wcbd); ++ if (wcbd.IsNearDeath()) { ++ delete wcbd.GetCallbackInfo(); ++ } ++ } ++ ++ template ++ NAN_INLINE void _NanWeakCallbackData::Revive() const { ++ info_->persistent.SetWeak(info_, &_NanWeakCallbackDispatcher); ++ } ++ ++template ++NAN_INLINE _NanWeakCallbackInfo* NanMakeWeakPersistent( ++ v8::Handle handle ++ , P* parameter ++ , typename _NanWeakCallbackInfo::Callback callback) { ++ _NanWeakCallbackInfo *cbinfo = ++ new _NanWeakCallbackInfo(handle, parameter, callback); ++ cbinfo->persistent.SetWeak(cbinfo, &_NanWeakCallbackDispatcher); ++ return cbinfo; ++} ++ ++# define NAN_WEAK_CALLBACK(name) \ ++ template \ ++ static void name(const _NanWeakCallbackData &data) ++ ++# define _NAN_ERROR(fun, errmsg) fun(NanNew(errmsg)) ++ ++# define _NAN_THROW_ERROR(fun, errmsg) \ ++ do { \ ++ NanScope(); \ ++ v8::Isolate::GetCurrent()->ThrowException(_NAN_ERROR(fun, errmsg)); \ ++ } while (0); ++ ++ NAN_INLINE v8::Local NanError(const char* errmsg) { ++ return _NAN_ERROR(v8::Exception::Error, errmsg); ++ } ++ ++ NAN_INLINE void NanThrowError(const char* errmsg) { ++ _NAN_THROW_ERROR(v8::Exception::Error, errmsg); ++ } ++ ++ NAN_INLINE void NanThrowError(v8::Handle error) { ++ NanScope(); ++ v8::Isolate::GetCurrent()->ThrowException(error); ++ } ++ ++ NAN_INLINE v8::Local NanError( ++ const char *msg ++ , const int errorNumber ++ ) { ++ v8::Local err = v8::Exception::Error(NanNew(msg)); ++ v8::Local obj = err.As(); ++ obj->Set(NanNew("code"), NanNew(errorNumber)); ++ return err; ++ } ++ ++ NAN_INLINE void NanThrowError( ++ const char *msg ++ , const int errorNumber ++ ) { ++ NanThrowError(NanError(msg, errorNumber)); ++ } ++ ++ NAN_INLINE v8::Local NanTypeError(const char* errmsg) { ++ return _NAN_ERROR(v8::Exception::TypeError, errmsg); ++ } ++ ++ NAN_INLINE void NanThrowTypeError(const char* errmsg) { ++ _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg); ++ } ++ ++ NAN_INLINE v8::Local NanRangeError(const char* errmsg) { ++ return _NAN_ERROR(v8::Exception::RangeError, errmsg); ++ } ++ ++ NAN_INLINE void NanThrowRangeError(const char* errmsg) { ++ _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg); ++ } ++ ++ template NAN_INLINE void NanDisposePersistent( ++ v8::Persistent &handle ++ ) { ++ handle.Reset(); ++ } ++ ++ NAN_INLINE v8::Local NanNewBufferHandle ( ++ char *data ++ , size_t length ++ , node::smalloc::FreeCallback callback ++ , void *hint ++ ) { ++ return node::Buffer::New( ++ v8::Isolate::GetCurrent(), data, length, callback, hint); ++ } ++ ++ NAN_INLINE v8::Local NanNewBufferHandle ( ++ const char *data ++ , uint32_t size ++ ) { ++ return node::Buffer::New(v8::Isolate::GetCurrent(), data, size); ++ } ++ ++ NAN_INLINE v8::Local NanNewBufferHandle (uint32_t size) { ++ return node::Buffer::New(v8::Isolate::GetCurrent(), size); ++ } ++ ++ NAN_INLINE v8::Local NanBufferUse( ++ char* data ++ , uint32_t size ++ ) { ++ return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size); ++ } ++ ++ NAN_INLINE bool NanHasInstance( ++ v8::Persistent& function_template ++ , v8::Handle value ++ ) { ++ return NanNew(function_template)->HasInstance(value); ++ } ++ ++ NAN_INLINE v8::Local NanNewContextHandle( ++ v8::ExtensionConfiguration* extensions = NULL ++ , v8::Handle tmpl = v8::Handle() ++ , v8::Handle obj = v8::Handle() ++ ) { ++ v8::Isolate* isolate = v8::Isolate::GetCurrent(); ++ return v8::Local::New( ++ isolate ++ , v8::Context::New(isolate, extensions, tmpl, obj) ++ ); ++ } ++ ++ NAN_INLINE v8::Local NanCompileScript( ++ v8::Local s ++ , const v8::ScriptOrigin& origin ++ ) { ++ v8::ScriptCompiler::Source source(s, origin); ++ return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source); ++ } ++ ++ NAN_INLINE v8::Local NanCompileScript( ++ v8::Local s ++ ) { ++ v8::ScriptCompiler::Source source(s); ++ return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source); ++ } ++ ++ NAN_INLINE v8::Local NanRunScript( ++ v8::Handle script ++ ) { ++ return script->BindToCurrentContext()->Run(); ++ } ++ ++ NAN_INLINE v8::Local NanRunScript( ++ v8::Handle script ++ ) { ++ return script->Run(); ++ } ++ ++ NAN_INLINE v8::Local NanMakeCallback( ++ v8::Handle target ++ , v8::Handle func ++ , int argc ++ , v8::Handle* argv) { ++ return NanNew(node::MakeCallback( ++ v8::Isolate::GetCurrent(), target, func, argc, argv)); ++ } ++ ++ NAN_INLINE v8::Local NanMakeCallback( ++ v8::Handle target ++ , v8::Handle symbol ++ , int argc ++ , v8::Handle* argv) { ++ return NanNew(node::MakeCallback( ++ v8::Isolate::GetCurrent(), target, symbol, argc, argv)); ++ } ++ ++ NAN_INLINE v8::Local NanMakeCallback( ++ v8::Handle target ++ , const char* method ++ , int argc ++ , v8::Handle* argv) { ++ return NanNew(node::MakeCallback( ++ v8::Isolate::GetCurrent(), target, method, argc, argv)); ++ } ++ ++ template ++ NAN_INLINE void NanSetIsolateData( ++ v8::Isolate *isolate ++ , T *data ++ ) { ++ isolate->SetData(0, data); ++ } ++ ++ template ++ NAN_INLINE T *NanGetIsolateData( ++ v8::Isolate *isolate ++ ) { ++ return static_cast(isolate->GetData(0)); ++ } ++ ++ class NanAsciiString { ++ public: ++ NAN_INLINE explicit NanAsciiString(v8::Handle from) { ++ v8::Local toStr = from->ToString(); ++ int buf_size = toStr->Length() + 1; ++ buf = new char[buf_size]; ++ size = toStr->WriteOneByte( ++ reinterpret_cast(buf), 0, buf_size); ++ } ++ ++ NAN_INLINE int Size() const { ++ return size; ++ } ++ ++ NAN_INLINE char* operator*() { return buf; } ++ ++ NAN_INLINE ~NanAsciiString() { ++ delete[] buf; ++ } ++ ++ private: ++ char *buf; ++ int size; ++ }; ++ ++ class NanUtf8String { ++ public: ++ NAN_INLINE explicit NanUtf8String(v8::Handle from) { ++ v8::Local toStr = from->ToString(); ++ int buf_size = toStr->Utf8Length() + 1; ++ buf = new char[buf_size]; ++ size = toStr->WriteUtf8(buf, buf_size); ++ } ++ ++ NAN_INLINE int Size() const { ++ return size; ++ } ++ ++ NAN_INLINE char* operator*() { return buf; } ++ ++ NAN_INLINE ~NanUtf8String() { ++ delete[] buf; ++ } ++ ++ private: ++ char *buf; ++ int size; ++ }; ++ ++ class NanUcs2String { ++ public: ++ NAN_INLINE explicit NanUcs2String(v8::Handle from) { ++ v8::Local toStr = from->ToString(); ++ int buf_size = toStr->Length() + 1; ++ buf = new uint16_t[buf_size]; ++ size = toStr->Write(buf, 0, buf_size); ++ } ++ ++ NAN_INLINE int Size() const { ++ return size; ++ } ++ ++ NAN_INLINE uint16_t* operator*() { return buf; } ++ ++ NAN_INLINE ~NanUcs2String() { ++ delete[] buf; ++ } ++ ++ private: ++ uint16_t *buf; ++ int size; ++ }; ++ ++#else ++// Node 0.8 and 0.10 ++ ++# define _NAN_METHOD_ARGS_TYPE const v8::Arguments& ++# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args ++# define _NAN_METHOD_RETURN_TYPE v8::Handle ++ ++# define _NAN_GETTER_ARGS_TYPE const v8::AccessorInfo & ++# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args ++# define _NAN_GETTER_RETURN_TYPE v8::Handle ++ ++# define _NAN_SETTER_ARGS_TYPE const v8::AccessorInfo & ++# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args ++# define _NAN_SETTER_RETURN_TYPE void ++ ++# define _NAN_PROPERTY_GETTER_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args ++# define _NAN_PROPERTY_GETTER_RETURN_TYPE v8::Handle ++ ++# define _NAN_PROPERTY_SETTER_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args ++# define _NAN_PROPERTY_SETTER_RETURN_TYPE v8::Handle ++ ++# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args ++# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE v8::Handle ++ ++# define _NAN_PROPERTY_DELETER_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_PROPERTY_DELETER_ARGS _NAN_PROPERTY_DELETER_ARGS_TYPE args ++# define _NAN_PROPERTY_DELETER_RETURN_TYPE v8::Handle ++ ++# define _NAN_PROPERTY_QUERY_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args ++# define _NAN_PROPERTY_QUERY_RETURN_TYPE v8::Handle ++ ++# define _NAN_INDEX_GETTER_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args ++# define _NAN_INDEX_GETTER_RETURN_TYPE v8::Handle ++ ++# define _NAN_INDEX_SETTER_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args ++# define _NAN_INDEX_SETTER_RETURN_TYPE v8::Handle ++ ++# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args ++# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE v8::Handle ++ ++# define _NAN_INDEX_DELETER_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args ++# define _NAN_INDEX_DELETER_RETURN_TYPE v8::Handle ++ ++# define _NAN_INDEX_QUERY_ARGS_TYPE const v8::AccessorInfo& ++# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args ++# define _NAN_INDEX_QUERY_RETURN_TYPE v8::Handle ++ ++ typedef v8::InvocationCallback NanFunctionCallback; ++ ++ NAN_DEPRECATED NAN_INLINE v8::Local NanSymbol( ++ const char* data, int length = -1) { ++ return v8::String::NewSymbol(data, length); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew() { ++ return v8::Local::New(T::New()); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew(v8::Handle arg) { ++ return v8::Local::New(arg); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Handle receiver ++ , int argc ++ , v8::Handle argv[] = 0) { ++ return v8::Signature::New(receiver, argc, argv); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ NanFunctionCallback callback ++ , v8::Handle data = v8::Handle() ++ , v8::Handle signature = v8::Handle()) { ++ return T::New(callback, data, signature); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew(const v8::Persistent &arg) { ++ return v8::Local::New(arg); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew(P arg) { ++ return v8::Local::New(T::New(arg)); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew(P arg, int length) { ++ return v8::Local::New(T::New(arg, length)); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Handle pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Local pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Handle pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ v8::Local pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew() { ++ return v8::Array::New(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(int length) { ++ return v8::Array::New(length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(double time) { ++ return v8::Date::New(time).As(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(int time) { ++ return v8::Date::New(time).As(); ++ } ++ ++ typedef v8::Script NanUnboundScript; ++ typedef v8::Script NanBoundScript; ++ ++ template ++ NAN_INLINE v8::Local NanNew( ++ P s ++ , const v8::ScriptOrigin& origin ++ ) { ++ return v8::Script::New(s, const_cast(&origin)); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ v8::Local s ++ ) { ++ return v8::Script::New(s); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(bool value) { ++ return v8::BooleanObject::New(value).As(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local ++ NanNew >( ++ v8::Local value) { ++ return v8::StringObject::New(value).As(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local ++ NanNew >( ++ v8::Handle value) { ++ return v8::StringObject::New(value).As(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(double val) { ++ return v8::NumberObject::New(val).As(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(int32_t val) { ++ return v8::Uint32::NewFromUnsigned(val)->ToUint32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(uint32_t val) { ++ return v8::Uint32::NewFromUnsigned(val)->ToUint32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(int32_t val) { ++ return v8::Int32::New(val)->ToInt32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(uint32_t val) { ++ return v8::Int32::New(val)->ToInt32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ uint8_t *arg ++ , int length) { ++ int len = length; ++ if (len < 0) { ++ size_t temp = strlen(reinterpret_cast(arg)); ++ assert(temp <= INT_MAX && "too long string"); ++ len = static_cast(temp); ++ } ++ uint16_t *warg = new uint16_t[len]; ++ for (int i = 0; i < len; i++) { ++ warg[i] = arg[i]; ++ } ++ v8::Local retval = v8::String::New(warg, len); ++ delete[] warg; ++ return retval; ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ const uint8_t *arg ++ , int length) { ++ int len = length; ++ if (len < 0) { ++ size_t temp = strlen(reinterpret_cast(arg)); ++ assert(temp <= INT_MAX && "too long string"); ++ len = static_cast(temp); ++ } ++ uint16_t *warg = new uint16_t[len]; ++ for (int i = 0; i < len; i++) { ++ warg[i] = arg[i]; ++ } ++ v8::Local retval = v8::String::New(warg, len); ++ delete[] warg; ++ return retval; ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew(uint8_t *arg) { ++ size_t temp = strlen(reinterpret_cast(arg)); ++ assert(temp <= INT_MAX && "too long string"); ++ int length = static_cast(temp); ++ uint16_t *warg = new uint16_t[length]; ++ for (int i = 0; i < length; i++) { ++ warg[i] = arg[i]; ++ } ++ ++ v8::Local retval = v8::String::New(warg, length); ++ delete[] warg; ++ return retval; ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ const uint8_t *arg) { ++ size_t temp = strlen(reinterpret_cast(arg)); ++ assert(temp <= INT_MAX && "too long string"); ++ int length = static_cast(temp); ++ uint16_t *warg = new uint16_t[length]; ++ for (int i = 0; i < length; i++) { ++ warg[i] = arg[i]; ++ } ++ v8::Local retval = v8::String::New(warg, length); ++ delete[] warg; ++ return retval; ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew( ++ std::string arg) { ++ return NanNew(arg.c_str(), arg.size()); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local NanNew() { ++ return v8::String::Empty(); ++ } ++ ++ NAN_INLINE v8::Local NanNew(const char* arg, int length = -1) { ++ return NanNew(arg, length); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ const uint8_t* arg ++ , int length = -1) { ++ return NanNew(arg, length); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ const uint16_t* arg ++ , int length = -1) { ++ return NanNew(arg, length); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ std::string& arg) { ++ return NanNew(arg.c_str(), arg.size()); ++ } ++ ++ NAN_INLINE v8::Local NanNew(double val) { ++ return NanNew(val); ++ } ++ ++ NAN_INLINE v8::Local NanNew(int val) { ++ return NanNew(val); ++ } ++ ++ NAN_INLINE v8::Local NanNew(unsigned int val) { ++ return NanNew(val); ++ } ++ ++ NAN_INLINE v8::Local NanNew(bool val) { ++ return NanNew(val); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ v8::String::ExternalStringResource *resource) { ++ return v8::String::NewExternal(resource); ++ } ++ ++ NAN_INLINE v8::Local NanNew( ++ v8::String::ExternalAsciiStringResource *resource) { ++ return v8::String::NewExternal(resource); ++ } ++ ++# define NanScope() v8::HandleScope scope ++# define NanEscapableScope() v8::HandleScope scope ++# define NanEscapeScope(val) scope.Close(val) ++# define NanLocker() v8::Locker locker ++# define NanUnlocker() v8::Unlocker unlocker ++# define NanReturnValue(value) return scope.Close(value) ++# define NanReturnUndefined() return v8::Undefined() ++# define NanReturnNull() return v8::Null() ++# define NanReturnEmptyString() return v8::String::Empty() ++# define NanObjectWrapHandle(obj) v8::Local::New(obj->handle_) ++ ++ NAN_INLINE v8::Local NanUndefined() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::Undefined())); ++ } ++ ++ NAN_INLINE v8::Local NanNull() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::Null())); ++ } ++ ++ NAN_INLINE v8::Local NanTrue() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::True())); ++ } ++ ++ NAN_INLINE v8::Local NanFalse() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::False())); ++ } ++ ++ NAN_INLINE int NanAdjustExternalMemory(int bc) { ++ return static_cast(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc)); ++ } ++ ++ NAN_INLINE void NanSetTemplate( ++ v8::Handle templ ++ , const char *name ++ , v8::Handle value) { ++ templ->Set(name, value); ++ } ++ ++ NAN_INLINE void NanSetTemplate( ++ v8::Handle templ ++ , v8::Handle name ++ , v8::Handle value ++ , v8::PropertyAttribute attributes) { ++ templ->Set(name, value, attributes); ++ } ++ ++ NAN_INLINE v8::Local NanGetCurrentContext() { ++ return v8::Context::GetCurrent(); ++ } ++ ++ NAN_INLINE void* NanGetInternalFieldPointer( ++ v8::Handle object ++ , int index) { ++ return object->GetPointerFromInternalField(index); ++ } ++ ++ NAN_INLINE void NanSetInternalFieldPointer( ++ v8::Handle object ++ , int index ++ , void* value) { ++ object->SetPointerInInternalField(index, value); ++ } ++ ++ NAN_INLINE void NanAddGCEpilogueCallback( ++ v8::GCEpilogueCallback callback ++ , v8::GCType gc_type_filter = v8::kGCTypeAll) { ++ v8::V8::AddGCEpilogueCallback(callback, gc_type_filter); ++ } ++ NAN_INLINE void NanRemoveGCEpilogueCallback( ++ v8::GCEpilogueCallback callback) { ++ v8::V8::RemoveGCEpilogueCallback(callback); ++ } ++ NAN_INLINE void NanAddGCPrologueCallback( ++ v8::GCPrologueCallback callback ++ , v8::GCType gc_type_filter = v8::kGCTypeAll) { ++ v8::V8::AddGCPrologueCallback(callback, gc_type_filter); ++ } ++ NAN_INLINE void NanRemoveGCPrologueCallback( ++ v8::GCPrologueCallback callback) { ++ v8::V8::RemoveGCPrologueCallback(callback); ++ } ++ NAN_INLINE void NanGetHeapStatistics( ++ v8::HeapStatistics *heap_statistics) { ++ v8::V8::GetHeapStatistics(heap_statistics); ++ } ++ ++ template ++ NAN_INLINE void NanAssignPersistent( ++ v8::Persistent& handle ++ , v8::Handle obj) { ++ handle.Dispose(); ++ handle = v8::Persistent::New(obj); ++ } ++ ++ template ++ class _NanWeakCallbackData; ++ ++ template ++ struct _NanWeakCallbackInfo { ++ typedef void (*Callback)(const _NanWeakCallbackData &data); ++ NAN_INLINE _NanWeakCallbackInfo(v8::Handle handle, P* param, Callback cb) ++ : parameter(param) ++ , callback(cb) ++ , persistent(v8::Persistent::New(handle)) { } ++ ++ NAN_INLINE ~_NanWeakCallbackInfo() { ++ persistent.Dispose(); ++ persistent.Clear(); ++ } ++ ++ P* const parameter; ++ Callback const callback; ++ v8::Persistent persistent; ++ }; ++ ++ template ++ class _NanWeakCallbackData { ++ public: ++ NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo *info) ++ : info_(info) { } ++ ++ NAN_INLINE v8::Local GetValue() const { ++ return NanNew(info_->persistent); ++ } ++ ++ NAN_INLINE P* GetParameter() const { return info_->parameter; } ++ ++ NAN_INLINE bool IsNearDeath() const { ++ return info_->persistent.IsNearDeath(); ++ } ++ ++ NAN_INLINE void Revive() const; ++ ++ NAN_INLINE _NanWeakCallbackInfo* GetCallbackInfo() const { ++ return info_; ++ } ++ ++ NAN_DEPRECATED NAN_INLINE void Dispose() const { ++ } ++ ++ private: ++ _NanWeakCallbackInfo* info_; ++ }; ++ ++ template ++ static void _NanWeakPersistentDispatcher( ++ v8::Persistent object, void *data) { ++ _NanWeakCallbackInfo* info = ++ static_cast<_NanWeakCallbackInfo*>(data); ++ _NanWeakCallbackData wcbd(info); ++ info->callback(wcbd); ++ if (wcbd.IsNearDeath()) { ++ delete wcbd.GetCallbackInfo(); ++ } ++ } ++ ++ template ++ NAN_INLINE void _NanWeakCallbackData::Revive() const { ++ info_->persistent.MakeWeak( ++ info_ ++ , &_NanWeakPersistentDispatcher); ++ } ++ ++ template ++ NAN_INLINE _NanWeakCallbackInfo* NanMakeWeakPersistent( ++ v8::Handle handle ++ , P* parameter ++ , typename _NanWeakCallbackInfo::Callback callback) { ++ _NanWeakCallbackInfo *cbinfo = ++ new _NanWeakCallbackInfo(handle, parameter, callback); ++ cbinfo->persistent.MakeWeak( ++ cbinfo ++ , &_NanWeakPersistentDispatcher); ++ return cbinfo; ++ } ++ ++# define NAN_WEAK_CALLBACK(name) \ ++ template \ ++ static void name(const _NanWeakCallbackData &data) ++ ++# define _NAN_ERROR(fun, errmsg) \ ++ fun(v8::String::New(errmsg)) ++ ++# define _NAN_THROW_ERROR(fun, errmsg) \ ++ do { \ ++ NanScope(); \ ++ return v8::Local::New( \ ++ v8::ThrowException(_NAN_ERROR(fun, errmsg))); \ ++ } while (0); ++ ++ NAN_INLINE v8::Local NanError(const char* errmsg) { ++ return _NAN_ERROR(v8::Exception::Error, errmsg); ++ } ++ ++ NAN_INLINE v8::Local NanThrowError(const char* errmsg) { ++ _NAN_THROW_ERROR(v8::Exception::Error, errmsg); ++ } ++ ++ NAN_INLINE v8::Local NanThrowError( ++ v8::Handle error ++ ) { ++ NanScope(); ++ return v8::Local::New(v8::ThrowException(error)); ++ } ++ ++ NAN_INLINE v8::Local NanError( ++ const char *msg ++ , const int errorNumber ++ ) { ++ v8::Local err = v8::Exception::Error(v8::String::New(msg)); ++ v8::Local obj = err.As(); ++ obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber)); ++ return err; ++ } ++ ++ NAN_INLINE v8::Local NanThrowError( ++ const char *msg ++ , const int errorNumber ++ ) { ++ return NanThrowError(NanError(msg, errorNumber)); ++ } ++ ++ NAN_INLINE v8::Local NanTypeError(const char* errmsg) { ++ return _NAN_ERROR(v8::Exception::TypeError, errmsg); ++ } ++ ++ NAN_INLINE v8::Local NanThrowTypeError( ++ const char* errmsg ++ ) { ++ _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg); ++ } ++ ++ NAN_INLINE v8::Local NanRangeError( ++ const char* errmsg ++ ) { ++ return _NAN_ERROR(v8::Exception::RangeError, errmsg); ++ } ++ ++ NAN_INLINE v8::Local NanThrowRangeError( ++ const char* errmsg ++ ) { ++ _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg); ++ } ++ ++ template ++ NAN_INLINE void NanDisposePersistent( ++ v8::Persistent &handle) { // NOLINT(runtime/references) ++ handle.Dispose(); ++ handle.Clear(); ++ } ++ ++ NAN_INLINE v8::Local NanNewBufferHandle ( ++ char *data ++ , size_t length ++ , node::Buffer::free_callback callback ++ , void *hint ++ ) { ++ return NanNew( ++ node::Buffer::New(data, length, callback, hint)->handle_); ++ } ++ ++ NAN_INLINE v8::Local NanNewBufferHandle ( ++ const char *data ++ , uint32_t size ++ ) { ++#if NODE_MODULE_VERSION >= 0x000B ++ return NanNew(node::Buffer::New(data, size)->handle_); ++#else ++ return NanNew( ++ node::Buffer::New(const_cast(data), size)->handle_); ++#endif ++ } ++ ++ NAN_INLINE v8::Local NanNewBufferHandle (uint32_t size) { ++ return NanNew(node::Buffer::New(size)->handle_); ++ } ++ ++ NAN_INLINE void FreeData(char *data, void *hint) { ++ delete[] data; ++ } ++ ++ NAN_INLINE v8::Local NanBufferUse( ++ char* data ++ , uint32_t size ++ ) { ++ return NanNew( ++ node::Buffer::New(data, size, FreeData, NULL)->handle_); ++ } ++ ++ NAN_INLINE bool NanHasInstance( ++ v8::Persistent& function_template ++ , v8::Handle value ++ ) { ++ return function_template->HasInstance(value); ++ } ++ ++ NAN_INLINE v8::Local NanNewContextHandle( ++ v8::ExtensionConfiguration* extensions = NULL ++ , v8::Handle tmpl = v8::Handle() ++ , v8::Handle obj = v8::Handle() ++ ) { ++ v8::Persistent ctx = v8::Context::New(extensions, tmpl, obj); ++ v8::Local lctx = NanNew(ctx); ++ ctx.Dispose(); ++ return lctx; ++ } ++ ++ NAN_INLINE v8::Local NanCompileScript( ++ v8::Local s ++ , const v8::ScriptOrigin& origin ++ ) { ++ return v8::Script::Compile(s, const_cast(&origin)); ++ } ++ ++ NAN_INLINE v8::Local NanCompileScript( ++ v8::Local s ++ ) { ++ return v8::Script::Compile(s); ++ } ++ ++ NAN_INLINE v8::Local NanRunScript(v8::Handle script) { ++ return script->Run(); ++ } ++ ++ NAN_INLINE v8::Local NanMakeCallback( ++ v8::Handle target ++ , v8::Handle func ++ , int argc ++ , v8::Handle* argv) { ++# if NODE_VERSION_AT_LEAST(0, 8, 0) ++ return NanNew(node::MakeCallback(target, func, argc, argv)); ++# else ++ v8::TryCatch try_catch; ++ v8::Local result = NanNew(func->Call(target, argc, argv)); ++ if (try_catch.HasCaught()) { ++ node::FatalException(try_catch); ++ } ++ return result; ++# endif ++ } ++ ++ NAN_INLINE v8::Local NanMakeCallback( ++ v8::Handle target ++ , v8::Handle symbol ++ , int argc ++ , v8::Handle* argv) { ++# if NODE_VERSION_AT_LEAST(0, 8, 0) ++ return NanNew(node::MakeCallback(target, symbol, argc, argv)); ++# else ++ v8::Local callback = target->Get(symbol).As(); ++ return NanMakeCallback(target, callback, argc, argv); ++# endif ++ } ++ ++ NAN_INLINE v8::Local NanMakeCallback( ++ v8::Handle target ++ , const char* method ++ , int argc ++ , v8::Handle* argv) { ++# if NODE_VERSION_AT_LEAST(0, 8, 0) ++ return NanNew(node::MakeCallback(target, method, argc, argv)); ++# else ++ return NanMakeCallback(target, NanNew(method), argc, argv); ++# endif ++ } ++ ++ template ++ NAN_INLINE void NanSetIsolateData( ++ v8::Isolate *isolate ++ , T *data ++ ) { ++ isolate->SetData(data); ++ } ++ ++ template ++ NAN_INLINE T *NanGetIsolateData( ++ v8::Isolate *isolate ++ ) { ++ return static_cast(isolate->GetData()); ++ } ++ ++ class NanAsciiString { ++ public: ++ NAN_INLINE explicit NanAsciiString(v8::Handle from) { ++ v8::Local toStr = from->ToString(); ++ int buf_size = toStr->Length() + 1; ++ buf = new char[buf_size]; ++ size = toStr->WriteAscii(buf, 0, buf_size); ++ } ++ ++ NAN_INLINE int Size() const { ++ return size; ++ } ++ ++ NAN_INLINE char* operator*() { return buf; } ++ ++ NAN_INLINE ~NanAsciiString() { ++ delete[] buf; ++ } ++ ++ private: ++ char *buf; ++ int size; ++ }; ++ ++ class NanUtf8String { ++ public: ++ NAN_INLINE explicit NanUtf8String(v8::Handle from) { ++ v8::Local toStr = from->ToString(); ++ int buf_size = toStr->Utf8Length() + 1; ++ buf = new char[buf_size]; ++ size = toStr->WriteUtf8(buf, buf_size); ++ } ++ ++ NAN_INLINE int Size() const { ++ return size; ++ } ++ ++ NAN_INLINE char* operator*() { return buf; } ++ ++ NAN_INLINE ~NanUtf8String() { ++ delete[] buf; ++ } ++ ++ private: ++ char *buf; ++ int size; ++ }; ++ ++ class NanUcs2String { ++ public: ++ NAN_INLINE explicit NanUcs2String(v8::Handle from) { ++ v8::Local toStr = from->ToString(); ++ int buf_size = toStr->Length() + 1; ++ buf = new uint16_t[buf_size]; ++ size = toStr->Write(buf, 0, buf_size); ++ } ++ ++ NAN_INLINE int Size() const { ++ return size; ++ } ++ ++ NAN_INLINE uint16_t* operator*() { return buf; } ++ ++ NAN_INLINE ~NanUcs2String() { ++ delete[] buf; ++ } ++ ++ private: ++ uint16_t *buf; ++ int size; ++ }; ++ ++#endif // NODE_MODULE_VERSION ++ ++typedef void (*NanFreeCallback)(char *data, void *hint); ++ ++#define NAN_METHOD(name) _NAN_METHOD_RETURN_TYPE name(_NAN_METHOD_ARGS) ++#define NAN_GETTER(name) \ ++ _NAN_GETTER_RETURN_TYPE name( \ ++ v8::Local property \ ++ , _NAN_GETTER_ARGS) ++#define NAN_SETTER(name) \ ++ _NAN_SETTER_RETURN_TYPE name( \ ++ v8::Local property \ ++ , v8::Local value \ ++ , _NAN_SETTER_ARGS) ++#define NAN_PROPERTY_GETTER(name) \ ++ _NAN_PROPERTY_GETTER_RETURN_TYPE name( \ ++ v8::Local property \ ++ , _NAN_PROPERTY_GETTER_ARGS) ++#define NAN_PROPERTY_SETTER(name) \ ++ _NAN_PROPERTY_SETTER_RETURN_TYPE name( \ ++ v8::Local property \ ++ , v8::Local value \ ++ , _NAN_PROPERTY_SETTER_ARGS) ++#define NAN_PROPERTY_ENUMERATOR(name) \ ++ _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name(_NAN_PROPERTY_ENUMERATOR_ARGS) ++#define NAN_PROPERTY_DELETER(name) \ ++ _NAN_PROPERTY_DELETER_RETURN_TYPE name( \ ++ v8::Local property \ ++ , _NAN_PROPERTY_DELETER_ARGS) ++#define NAN_PROPERTY_QUERY(name) \ ++ _NAN_PROPERTY_QUERY_RETURN_TYPE name( \ ++ v8::Local property \ ++ , _NAN_PROPERTY_QUERY_ARGS) ++# define NAN_INDEX_GETTER(name) \ ++ _NAN_INDEX_GETTER_RETURN_TYPE name(uint32_t index, _NAN_INDEX_GETTER_ARGS) ++#define NAN_INDEX_SETTER(name) \ ++ _NAN_INDEX_SETTER_RETURN_TYPE name( \ ++ uint32_t index \ ++ , v8::Local value \ ++ , _NAN_INDEX_SETTER_ARGS) ++#define NAN_INDEX_ENUMERATOR(name) \ ++ _NAN_INDEX_ENUMERATOR_RETURN_TYPE name(_NAN_INDEX_ENUMERATOR_ARGS) ++#define NAN_INDEX_DELETER(name) \ ++ _NAN_INDEX_DELETER_RETURN_TYPE name( \ ++ uint32_t index \ ++ , _NAN_INDEX_DELETER_ARGS) ++#define NAN_INDEX_QUERY(name) \ ++ _NAN_INDEX_QUERY_RETURN_TYPE name(uint32_t index, _NAN_INDEX_QUERY_ARGS) ++ ++class NanCallback { ++ public: ++ NanCallback() { ++ NanScope(); ++ v8::Local obj = NanNew(); ++ NanAssignPersistent(handle, obj); ++ } ++ ++ explicit NanCallback(const v8::Handle &fn) { ++ NanScope(); ++ v8::Local obj = NanNew(); ++ NanAssignPersistent(handle, obj); ++ SetFunction(fn); ++ } ++ ++ ~NanCallback() { ++ if (handle.IsEmpty()) return; ++ NanDisposePersistent(handle); ++ } ++ ++ NAN_INLINE void SetFunction(const v8::Handle &fn) { ++ NanScope(); ++ NanNew(handle)->Set(kCallbackIndex, fn); ++ } ++ ++ NAN_INLINE v8::Local GetFunction() const { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(handle)->Get(kCallbackIndex) ++ .As()); ++ } ++ ++ NAN_INLINE bool IsEmpty() const { ++ NanScope(); ++ return NanNew(handle)->Get(kCallbackIndex)->IsUndefined(); ++ } ++ ++ v8::Handle Call(int argc, v8::Handle argv[]) const { ++ NanEscapableScope(); ++#if (NODE_MODULE_VERSION > 0x000B) // 0.11.12+ ++ v8::Isolate* isolate = v8::Isolate::GetCurrent(); ++ v8::Local callback = NanNew(handle)-> ++ Get(kCallbackIndex).As(); ++ return NanEscapeScope(node::MakeCallback( ++ isolate ++ , isolate->GetCurrentContext()->Global() ++ , callback ++ , argc ++ , argv ++ )); ++#else ++#if NODE_VERSION_AT_LEAST(0, 8, 0) ++ v8::Local callback = handle-> ++ Get(kCallbackIndex).As(); ++ return NanEscapeScope(node::MakeCallback( ++ v8::Context::GetCurrent()->Global() ++ , callback ++ , argc ++ , argv ++ )); ++#else ++ v8::Local callback = handle-> ++ Get(kCallbackIndex).As(); ++ return NanEscapeScope(NanMakeCallback( ++ v8::Context::GetCurrent()->Global(), callback, argc, argv)); ++#endif ++#endif ++ } ++ ++ private: ++ v8::Persistent handle; ++ static const uint32_t kCallbackIndex = 0; ++}; ++ ++/* abstract */ class NanAsyncWorker { ++ public: ++ explicit NanAsyncWorker(NanCallback *callback) ++ : callback(callback), errmsg_(NULL) { ++ request.data = this; ++ ++ NanScope(); ++ v8::Local obj = NanNew(); ++ NanAssignPersistent(persistentHandle, obj); ++ } ++ ++ virtual ~NanAsyncWorker() { ++ NanScope(); ++ ++ if (!persistentHandle.IsEmpty()) ++ NanDisposePersistent(persistentHandle); ++ if (callback) ++ delete callback; ++ if (errmsg_) ++ delete[] errmsg_; ++ } ++ ++ virtual void WorkComplete() { ++ NanScope(); ++ ++ if (errmsg_ == NULL) ++ HandleOKCallback(); ++ else ++ HandleErrorCallback(); ++ delete callback; ++ callback = NULL; ++ } ++ ++ NAN_INLINE void SaveToPersistent( ++ const char *key, const v8::Local &obj) { ++ v8::Local handle = NanNew(persistentHandle); ++ handle->Set(NanNew(key), obj); ++ } ++ ++ v8::Local GetFromPersistent(const char *key) const { ++ NanEscapableScope(); ++ v8::Local handle = NanNew(persistentHandle); ++ return NanEscapeScope(handle->Get(NanNew(key)).As()); ++ } ++ ++ virtual void Execute() = 0; ++ ++ uv_work_t request; ++ ++ protected: ++ v8::Persistent persistentHandle; ++ NanCallback *callback; ++ ++ virtual void HandleOKCallback() { ++ NanScope(); ++ ++ callback->Call(0, NULL); ++ } ++ ++ virtual void HandleErrorCallback() { ++ NanScope(); ++ ++ v8::Local argv[] = { ++ v8::Exception::Error(NanNew(ErrorMessage())) ++ }; ++ callback->Call(1, argv); ++ } ++ ++ void SetErrorMessage(const char *msg) { ++ if (errmsg_) { ++ delete[] errmsg_; ++ } ++ ++ size_t size = strlen(msg) + 1; ++ errmsg_ = new char[size]; ++ memcpy(errmsg_, msg, size); ++ } ++ ++ const char* ErrorMessage() const { ++ return errmsg_; ++ } ++ ++ private: ++ char *errmsg_; ++}; ++ ++NAN_INLINE void NanAsyncExecute (uv_work_t* req) { ++ NanAsyncWorker *worker = static_cast(req->data); ++ worker->Execute(); ++} ++ ++NAN_INLINE void NanAsyncExecuteComplete (uv_work_t* req) { ++ NanAsyncWorker* worker = static_cast(req->data); ++ worker->WorkComplete(); ++ delete worker; ++} ++ ++NAN_INLINE void NanAsyncQueueWorker (NanAsyncWorker* worker) { ++ uv_queue_work( ++ uv_default_loop() ++ , &worker->request ++ , NanAsyncExecute ++ , (uv_after_work_cb)NanAsyncExecuteComplete ++ ); ++} ++ ++//// Base 64 //// ++ ++#define _nan_base64_encoded_size(size) ((size + 2 - ((size + 2) % 3)) / 3 * 4) ++ ++// Doesn't check for padding at the end. Can be 1-2 bytes over. ++NAN_INLINE size_t _nan_base64_decoded_size_fast(size_t size) { ++ size_t remainder = size % 4; ++ ++ size = (size / 4) * 3; ++ if (remainder) { ++ if (size == 0 && remainder == 1) { ++ // special case: 1-byte input cannot be decoded ++ size = 0; ++ } else { ++ // non-padded input, add 1 or 2 extra bytes ++ size += 1 + (remainder == 3); ++ } ++ } ++ ++ return size; ++} ++ ++template ++NAN_INLINE size_t _nan_base64_decoded_size( ++ const T* src ++ , size_t size ++) { ++ if (size == 0) ++ return 0; ++ ++ if (src[size - 1] == '=') ++ size--; ++ if (size > 0 && src[size - 1] == '=') ++ size--; ++ ++ return _nan_base64_decoded_size_fast(size); ++} ++ ++// supports regular and URL-safe base64 ++static const int _nan_unbase64_table[] = { ++ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1 ++ , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ++ , -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63 ++ , 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1 ++ , -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ++ , 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63 ++ , -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 ++ , 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 ++ , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ++ , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ++ , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ++ , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ++ , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ++ , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ++ , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ++ , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ++}; ++ ++#define _nan_unbase64(x) _nan_unbase64_table[(uint8_t)(x)] ++ ++template static size_t _nan_base64_decode( ++ char* buf ++ , size_t len ++ , const T* src ++ , const size_t srcLen ++) { ++ char* dst = buf; ++ char* dstEnd = buf + len; ++ const T* srcEnd = src + srcLen; ++ ++ while (src < srcEnd && dst < dstEnd) { ++ ptrdiff_t remaining = srcEnd - src; ++ char a, b, c, d; ++ ++ while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; ++ if (remaining == 0 || *src == '=') break; ++ a = _nan_unbase64(*src++); ++ ++ while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; ++ if (remaining <= 1 || *src == '=') break; ++ b = _nan_unbase64(*src++); ++ ++ *dst++ = (a << 2) | ((b & 0x30) >> 4); ++ if (dst == dstEnd) break; ++ ++ while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; ++ if (remaining <= 2 || *src == '=') break; ++ c = _nan_unbase64(*src++); ++ ++ *dst++ = ((b & 0x0F) << 4) | ((c & 0x3C) >> 2); ++ if (dst == dstEnd) break; ++ ++ while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; ++ if (remaining <= 3 || *src == '=') break; ++ d = _nan_unbase64(*src++); ++ ++ *dst++ = ((c & 0x03) << 6) | (d & 0x3F); ++ } ++ ++ return dst - buf; ++} ++ ++//// HEX //// ++ ++template unsigned _nan_hex2bin(T c) { ++ if (c >= '0' && c <= '9') return c - '0'; ++ if (c >= 'A' && c <= 'F') return 10 + (c - 'A'); ++ if (c >= 'a' && c <= 'f') return 10 + (c - 'a'); ++ return static_cast(-1); ++} ++ ++template static size_t _nan_hex_decode( ++ char* buf ++ , size_t len ++ , const T* src ++ , const size_t srcLen ++) { ++ size_t i; ++ for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) { ++ unsigned a = _nan_hex2bin(src[i * 2 + 0]); ++ unsigned b = _nan_hex2bin(src[i * 2 + 1]); ++ if (!~a || !~b) return i; ++ buf[i] = a * 16 + b; ++ } ++ ++ return i; ++} ++ ++static bool _NanGetExternalParts( ++ v8::Handle val ++ , const char** data ++ , size_t* len ++) { ++ if (node::Buffer::HasInstance(val)) { ++ *data = node::Buffer::Data(val.As()); ++ *len = node::Buffer::Length(val.As()); ++ return true; ++ } ++ ++ assert(val->IsString()); ++ v8::Local str = NanNew(val.As()); ++ ++ if (str->IsExternalAscii()) { ++ const v8::String::ExternalAsciiStringResource* ext; ++ ext = str->GetExternalAsciiStringResource(); ++ *data = ext->data(); ++ *len = ext->length(); ++ return true; ++ ++ } else if (str->IsExternal()) { ++ const v8::String::ExternalStringResource* ext; ++ ext = str->GetExternalStringResource(); ++ *data = reinterpret_cast(ext->data()); ++ *len = ext->length(); ++ return true; ++ } ++ ++ return false; ++} ++ ++namespace Nan { ++ enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER}; ++} ++ ++/* NAN_DEPRECATED */ NAN_INLINE void* _NanRawString( ++ v8::Handle from ++ , enum Nan::Encoding encoding ++ , size_t *datalen ++ , void *buf ++ , size_t buflen ++ , int flags ++) { ++ NanScope(); ++ ++ size_t sz_; ++ size_t term_len = !(flags & v8::String::NO_NULL_TERMINATION); ++ char *data = NULL; ++ size_t len; ++ bool is_extern = _NanGetExternalParts( ++ from ++ , const_cast(&data) ++ , &len); ++ ++ if (is_extern && !term_len) { ++ NanSetPointerSafe(datalen, len); ++ return data; ++ } ++ ++ v8::Local toStr = from->ToString(); ++ ++ char *to = static_cast(buf); ++ ++ switch (encoding) { ++ case Nan::ASCII: ++#if NODE_MODULE_VERSION < 0x000C ++ sz_ = toStr->Length(); ++ if (to == NULL) { ++ to = new char[sz_ + term_len]; ++ } else { ++ assert(buflen >= sz_ + term_len && "too small buffer"); ++ } ++ NanSetPointerSafe( ++ datalen ++ , toStr->WriteAscii(to, 0, static_cast(sz_ + term_len), flags)); ++ return to; ++#endif ++ case Nan::BINARY: ++ case Nan::BUFFER: ++ sz_ = toStr->Length(); ++ if (to == NULL) { ++ to = new char[sz_ + term_len]; ++ } else { ++ assert(buflen >= sz_ + term_len && "too small buffer"); ++ } ++#if NODE_MODULE_VERSION < 0x000C ++ { ++ uint16_t* twobytebuf = new uint16_t[sz_ + term_len]; ++ ++ size_t len = toStr->Write(twobytebuf, 0, ++ static_cast(sz_ + term_len), flags); ++ ++ for (size_t i = 0; i < sz_ + term_len && i < len + term_len; i++) { ++ unsigned char *b = reinterpret_cast(&twobytebuf[i]); ++ to[i] = *b; ++ } ++ ++ NanSetPointerSafe(datalen, len); ++ ++ delete[] twobytebuf; ++ return to; ++ } ++#else ++ NanSetPointerSafe( ++ datalen, ++ toStr->WriteOneByte( ++ reinterpret_cast(to) ++ , 0 ++ , static_cast(sz_ + term_len) ++ , flags)); ++ return to; ++#endif ++ case Nan::UTF8: ++ sz_ = toStr->Utf8Length(); ++ if (to == NULL) { ++ to = new char[sz_ + term_len]; ++ } else { ++ assert(buflen >= sz_ + term_len && "too small buffer"); ++ } ++ NanSetPointerSafe( ++ datalen ++ , toStr->WriteUtf8(to, static_cast(sz_ + term_len) ++ , NULL, flags) ++ - term_len); ++ return to; ++ case Nan::BASE64: ++ { ++ v8::String::Value value(toStr); ++ sz_ = _nan_base64_decoded_size(*value, value.length()); ++ if (to == NULL) { ++ to = new char[sz_ + term_len]; ++ } else { ++ assert(buflen >= sz_ + term_len); ++ } ++ NanSetPointerSafe( ++ datalen ++ , _nan_base64_decode(to, sz_, *value, value.length())); ++ if (term_len) { ++ to[sz_] = '\0'; ++ } ++ return to; ++ } ++ case Nan::UCS2: ++ { ++ sz_ = toStr->Length(); ++ if (to == NULL) { ++ to = new char[(sz_ + term_len) * 2]; ++ } else { ++ assert(buflen >= (sz_ + term_len) * 2 && "too small buffer"); ++ } ++ ++ int bc = 2 * toStr->Write( ++ reinterpret_cast(to) ++ , 0 ++ , static_cast(sz_ + term_len) ++ , flags); ++ NanSetPointerSafe(datalen, bc); ++ return to; ++ } ++ case Nan::HEX: ++ { ++ v8::String::Value value(toStr); ++ sz_ = value.length(); ++ assert(!(sz_ & 1) && "bad hex data"); ++ if (to == NULL) { ++ to = new char[sz_ / 2 + term_len]; ++ } else { ++ assert(buflen >= sz_ / 2 + term_len && "too small buffer"); ++ } ++ NanSetPointerSafe( ++ datalen ++ , _nan_hex_decode(to, sz_ / 2, *value, value.length())); ++ } ++ if (term_len) { ++ to[sz_ / 2] = '\0'; ++ } ++ return to; ++ default: ++ assert(0 && "unknown encoding"); ++ } ++ return to; ++} ++ ++NAN_DEPRECATED NAN_INLINE void* NanRawString( ++ v8::Handle from ++ , enum Nan::Encoding encoding ++ , size_t *datalen ++ , void *buf ++ , size_t buflen ++ , int flags ++) { ++ return _NanRawString(from, encoding, datalen, buf, buflen, flags); ++} ++ ++ ++NAN_DEPRECATED NAN_INLINE char* NanCString( ++ v8::Handle from ++ , size_t *datalen ++ , char *buf = NULL ++ , size_t buflen = 0 ++ , int flags = v8::String::NO_OPTIONS ++) { ++ return static_cast( ++ _NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags) ++ ); ++} ++ ++NAN_INLINE void NanSetPrototypeTemplate( ++ v8::Local templ ++ , const char *name ++ , v8::Handle value ++) { ++ NanSetTemplate(templ->PrototypeTemplate(), name, value); ++} ++ ++NAN_INLINE void NanSetPrototypeTemplate( ++ v8::Local templ ++ , v8::Handle name ++ , v8::Handle value ++ , v8::PropertyAttribute attributes ++) { ++ NanSetTemplate(templ->PrototypeTemplate(), name, value, attributes); ++} ++ ++NAN_INLINE void NanSetInstanceTemplate( ++ v8::Local templ ++ , const char *name ++ , v8::Handle value ++) { ++ NanSetTemplate(templ->InstanceTemplate(), name, value); ++} ++ ++NAN_INLINE void NanSetInstanceTemplate( ++ v8::Local templ ++ , v8::Handle name ++ , v8::Handle value ++ , v8::PropertyAttribute attributes ++) { ++ NanSetTemplate(templ->InstanceTemplate(), name, value, attributes); ++} ++ ++#endif // NAN_H_ -- cgit v1.2.3