diff options
author | John Crispin <blogic@openwrt.org> | 2015-08-02 08:26:39 +0200 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2015-10-19 12:20:11 +0200 |
commit | 1fd7b5d1e67a9217f695c252866784a901bc7372 (patch) | |
tree | ee9df06d2bb34ac0e5c415f82925f193ec1c3d07 /lang/node-hid | |
parent | 23bee2145ff377b48d3e49613f93b3b8c7a82dda (diff) |
nodejs: add 0.12 version of node
add node-js 0.12 and a few gyp bindings
Signed-off-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'lang/node-hid')
-rw-r--r-- | lang/node-hid/Makefile | 62 | ||||
-rw-r--r-- | lang/node-hid/patches/000-compile.patch | 2457 |
2 files changed, 2519 insertions, 0 deletions
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 <blogic@openwrt.org> +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',
+- "<!(node -e \"require('nan')\")"
+- ]
+- },
+- 'include_dirs': [
+- 'hidapi/hidapi'
+- ],
+- 'defines': [
+- '_LARGEFILE_SOURCE',
+- '_FILE_OFFSET_BITS=64',
+- ],
+- 'cflags': ['-g'],
+- 'cflags!': [
+- '-ansi'
+- ]
+- },
+- {
+ 'target_name': 'HID',
+ 'sources': [ 'src/HID.cc' ],
+- 'dependencies': ['hidapi'],
+ 'defines': [
+ '_LARGEFILE_SOURCE',
+ '_FILE_OFFSET_BITS=64',
+@@ -108,4 +55,4 @@ + 'cflags_cc': ['-g', '-exceptions']
+ }
+ ]
+-} +\ No newline at end of file ++}
+--- /dev/null ++++ b/src/nan.h +@@ -0,0 +1,2331 @@ ++/********************************************************************************** ++ * NAN - Native Abstractions for Node.js ++ * ++ * Copyright (c) 2014 NAN contributors: ++ * - Rod Vagg <https://github.com/rvagg> ++ * - Benjamin Byholm <https://github.com/kkoopa> ++ * - Trevor Norris <https://github.com/trevnorris> ++ * - Nathan Rajlich <https://github.com/TooTallNate> ++ * - Brett Lawson <https://github.com/brett19> ++ * - Ben Noordhuis <https://github.com/bnoordhuis> ++ * ++ * MIT +no-false-attribs License <https://github.com/rvagg/nan/blob/master/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 <uv.h> ++#include <node.h> ++#include <node_buffer.h> ++#include <node_version.h> ++#include <node_object_wrap.h> ++#include <string.h> ++#include <limits.h> ++#include <string> ++ ++#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<typename T> NAN_INLINE bool NanSetPointerSafe( ++ T *var ++ , T val ++) { ++ if (var) { ++ *var = val; ++ return true; ++ } else { ++ return false; ++ } ++} ++ ++template<typename T> NAN_INLINE T NanGetPointerSafe( ++ T *var ++ , T fallback = reinterpret_cast<T>(0) ++) { ++ if (var) { ++ return *var; ++ } else { ++ return fallback; ++ } ++} ++ ++NAN_INLINE bool NanBooleanOptionValue( ++ v8::Local<v8::Object> optionsObj ++ , v8::Handle<v8::String> 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<v8::Object> optionsObj ++ , v8::Handle<v8::String> opt ++) { ++ return NanBooleanOptionValue(optionsObj, opt, false); ++} ++ ++NAN_INLINE uint32_t NanUInt32OptionValue( ++ v8::Local<v8::Object> optionsObj ++ , v8::Handle<v8::String> 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<v8::Value>& ++# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args ++# define _NAN_METHOD_RETURN_TYPE void ++ ++# define _NAN_GETTER_ARGS_TYPE const v8::PropertyCallbackInfo<v8::Value>& ++# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args ++# define _NAN_GETTER_RETURN_TYPE void ++ ++# define _NAN_SETTER_ARGS_TYPE const v8::PropertyCallbackInfo<void>& ++# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args ++# define _NAN_SETTER_RETURN_TYPE void ++ ++# define _NAN_PROPERTY_GETTER_ARGS_TYPE \ ++ const v8::PropertyCallbackInfo<v8::Value>& ++# 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<v8::Value>& ++# 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<v8::Array>& ++# 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<v8::Boolean>& ++# 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<v8::Integer>& ++# 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<v8::Value>& ++# 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<v8::Value>& ++# 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<v8::Array>& ++# 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<v8::Boolean>& ++# 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<v8::Integer>& ++# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args ++# define _NAN_INDEX_QUERY_RETURN_TYPE void ++ ++ typedef v8::FunctionCallback NanFunctionCallback; ++ ++ template<typename T> ++ NAN_INLINE v8::Local<T> NanNew() { ++ return T::New(v8::Isolate::GetCurrent()); ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<T> NanNew(P arg1) { ++ return T::New(v8::Isolate::GetCurrent(), arg1); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<v8::Signature> NanNew( ++ v8::Handle<v8::FunctionTemplate> receiver ++ , int argc ++ , v8::Handle<v8::FunctionTemplate> argv[] = 0) { ++ return v8::Signature::New(v8::Isolate::GetCurrent(), receiver, argc, argv); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<v8::FunctionTemplate> NanNew( ++ NanFunctionCallback callback ++ , v8::Handle<v8::Value> data = v8::Handle<v8::Value>() ++ , v8::Handle<v8::Signature> signature = v8::Handle<v8::Signature>()) { ++ return T::New(v8::Isolate::GetCurrent(), callback, data, signature); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<T> NanNew(v8::Handle<T> arg1) { ++ return v8::Local<T>::New(v8::Isolate::GetCurrent(), arg1); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<T> NanNew(const v8::Persistent<T> &arg1) { ++ return v8::Local<T>::New(v8::Isolate::GetCurrent(), arg1); ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<T> NanNew(P arg1, int arg2) { ++ return T::New(v8::Isolate::GetCurrent(), arg1, arg2); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>() { ++ return v8::Array::New(v8::Isolate::GetCurrent()); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>(int length) { ++ return v8::Array::New(v8::Isolate::GetCurrent(), length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(double time) { ++ return v8::Date::New(v8::Isolate::GetCurrent(), time).As<v8::Date>(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(int time) { ++ return v8::Date::New(v8::Isolate::GetCurrent(), time).As<v8::Date>(); ++ } ++ ++ typedef v8::UnboundScript NanUnboundScript; ++ typedef v8::Script NanBoundScript; ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<T> 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<NanUnboundScript> NanNew<NanUnboundScript>( ++ v8::Local<v8::String> s ++ ) { ++ v8::ScriptCompiler::Source source(s); ++ return v8::ScriptCompiler::CompileUnbound( ++ v8::Isolate::GetCurrent(), &source); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::BooleanObject> NanNew(bool value) { ++ return v8::BooleanObject::New(value).As<v8::BooleanObject>(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::StringObject> ++ NanNew<v8::StringObject, v8::Local<v8::String> >( ++ v8::Local<v8::String> value) { ++ return v8::StringObject::New(value).As<v8::StringObject>(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::StringObject> ++ NanNew<v8::StringObject, v8::Handle<v8::String> >( ++ v8::Handle<v8::String> value) { ++ return v8::StringObject::New(value).As<v8::StringObject>(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::NumberObject> NanNew<v8::NumberObject>(double val) { ++ return v8::NumberObject::New( ++ v8::Isolate::GetCurrent(), val).As<v8::NumberObject>(); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<v8::RegExp> NanNew( ++ v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<v8::RegExp> NanNew( ++ v8::Local<v8::String> pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<v8::RegExp> NanNew( ++ v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<v8::RegExp> NanNew( ++ v8::Local<v8::String> pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, int32_t>(int32_t val) { ++ return v8::Uint32::NewFromUnsigned( ++ v8::Isolate::GetCurrent(), val)->ToUint32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, uint32_t>(uint32_t val) { ++ return v8::Uint32::NewFromUnsigned( ++ v8::Isolate::GetCurrent(), val)->ToUint32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, int32_t>(int32_t val) { ++ return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, uint32_t>(uint32_t val) { ++ return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, char *>( ++ char *arg ++ , int length) { ++ return v8::String::NewFromUtf8( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const char *>( ++ const char *arg ++ , int length) { ++ return v8::String::NewFromUtf8( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, char *>(char *arg) { ++ return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const char *>( ++ const char *arg) { ++ return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>( ++ uint8_t *arg ++ , int length) { ++ return v8::String::NewFromOneByte( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>( ++ const uint8_t *arg ++ , int length) { ++ return v8::String::NewFromOneByte( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(uint8_t *arg) { ++ return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>( ++ const uint8_t *arg) { ++ return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint16_t *>( ++ uint16_t *arg ++ , int length) { ++ return v8::String::NewFromTwoByte( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint16_t *>( ++ const uint16_t *arg ++ , int length) { ++ return v8::String::NewFromTwoByte( ++ v8::Isolate::GetCurrent() ++ , arg ++ , v8::String::kNormalString ++ , length); ++ } ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint16_t *>( ++ uint16_t *arg) { ++ return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint16_t *>( ++ const uint16_t *arg) { ++ return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, std::string>( ++ std::string arg) { ++ return NanNew<v8::String>(arg.c_str(), arg.size()); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String>() { ++ return v8::String::Empty(v8::Isolate::GetCurrent()); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew(const char* arg, int length = -1) { ++ return NanNew<v8::String>(arg, length); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew( ++ const uint8_t* arg ++ , int length = -1) { ++ return NanNew<v8::String>(arg, length); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew( ++ const uint16_t* arg ++ , int length = -1) { ++ return NanNew<v8::String>(arg, length); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew( ++ const std::string& arg) { ++ return NanNew<v8::String>(arg.c_str(), arg.size()); ++ } ++ ++ NAN_INLINE v8::Local<v8::Number> NanNew(double val) { ++ return NanNew<v8::Number>(val); ++ } ++ ++ NAN_INLINE v8::Local<v8::Integer> NanNew(int val) { ++ return NanNew<v8::Integer>(val); ++ } ++ ++ NAN_INLINE v8::Local<v8::Uint32> NanNew(unsigned int val) { ++ return NanNew<v8::Uint32>(val); ++ } ++ ++ NAN_INLINE v8::Local<v8::Boolean> NanNew(bool val) { ++ return NanNew<v8::Boolean>(val); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew( ++ v8::String::ExternalStringResource *resource) { ++ return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> 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<typename T> ++ NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Handle<T> val) { ++ return NanNew(val); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> 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<v8::Primitive> NanUndefined() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent()))); ++ } ++ ++ NAN_INLINE v8::Local<v8::Primitive> NanNull() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::Null(v8::Isolate::GetCurrent()))); ++ } ++ ++ NAN_INLINE v8::Local<v8::Boolean> NanTrue() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent()))); ++ } ++ ++ NAN_INLINE v8::Local<v8::Boolean> NanFalse() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::False(v8::Isolate::GetCurrent()))); ++ } ++ ++ NAN_INLINE int NanAdjustExternalMemory(int bc) { ++ return static_cast<int>( ++ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc)); ++ } ++ ++ NAN_INLINE void NanSetTemplate( ++ v8::Handle<v8::Template> templ ++ , const char *name ++ , v8::Handle<v8::Data> value) { ++ templ->Set(v8::Isolate::GetCurrent(), name, value); ++ } ++ ++ NAN_INLINE void NanSetTemplate( ++ v8::Handle<v8::Template> templ ++ , v8::Handle<v8::String> name ++ , v8::Handle<v8::Data> value ++ , v8::PropertyAttribute attributes) { ++ templ->Set(name, value, attributes); ++ } ++ ++ NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() { ++ return v8::Isolate::GetCurrent()->GetCurrentContext(); ++ } ++ ++ NAN_INLINE void* NanGetInternalFieldPointer( ++ v8::Handle<v8::Object> object ++ , int index) { ++ return object->GetAlignedPointerFromInternalField(index); ++ } ++ ++ NAN_INLINE void NanSetInternalFieldPointer( ++ v8::Handle<v8::Object> 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<v8::String> NanSymbol( ++ const char* data, int length = -1) { ++ return NanNew<v8::String>(data, length); ++ } ++ ++ template<typename T> ++ NAN_INLINE void NanAssignPersistent( ++ v8::Persistent<T>& handle ++ , v8::Handle<T> obj) { ++ handle.Reset(v8::Isolate::GetCurrent(), obj); ++ } ++ ++ template<typename T> ++ NAN_INLINE void NanAssignPersistent( ++ v8::Persistent<T>& handle ++ , const v8::Persistent<T>& obj) { ++ handle.Reset(v8::Isolate::GetCurrent(), obj); ++ } ++ ++ template<typename T, typename P> ++ class _NanWeakCallbackData; ++ ++ template<typename T, typename P> ++ struct _NanWeakCallbackInfo { ++ typedef void (*Callback)(const _NanWeakCallbackData<T, P>& data); ++ NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> 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<T> persistent; ++ }; ++ ++ template<typename T, typename P> ++ class _NanWeakCallbackData { ++ public: ++ NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info) ++ : info_(info) { } ++ ++ NAN_INLINE v8::Local<T> 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<T, P>* GetCallbackInfo() const { ++ return info_; ++ } ++ ++ NAN_DEPRECATED NAN_INLINE void Dispose() const { ++ } ++ ++ private: ++ _NanWeakCallbackInfo<T, P>* info_; ++ }; ++ ++ template<typename T, typename P> ++ static void _NanWeakCallbackDispatcher( ++ const v8::WeakCallbackData<T, _NanWeakCallbackInfo<T, P> > &data) { ++ _NanWeakCallbackInfo<T, P> *info = data.GetParameter(); ++ _NanWeakCallbackData<T, P> wcbd(info); ++ info->callback(wcbd); ++ if (wcbd.IsNearDeath()) { ++ delete wcbd.GetCallbackInfo(); ++ } ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const { ++ info_->persistent.SetWeak(info_, &_NanWeakCallbackDispatcher<T, P>); ++ } ++ ++template<typename T, typename P> ++NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent( ++ v8::Handle<T> handle ++ , P* parameter ++ , typename _NanWeakCallbackInfo<T, P>::Callback callback) { ++ _NanWeakCallbackInfo<T, P> *cbinfo = ++ new _NanWeakCallbackInfo<T, P>(handle, parameter, callback); ++ cbinfo->persistent.SetWeak(cbinfo, &_NanWeakCallbackDispatcher<T, P>); ++ return cbinfo; ++} ++ ++# define NAN_WEAK_CALLBACK(name) \ ++ template<typename T, typename P> \ ++ static void name(const _NanWeakCallbackData<T, P> &data) ++ ++# define _NAN_ERROR(fun, errmsg) fun(NanNew<v8::String>(errmsg)) ++ ++# define _NAN_THROW_ERROR(fun, errmsg) \ ++ do { \ ++ NanScope(); \ ++ v8::Isolate::GetCurrent()->ThrowException(_NAN_ERROR(fun, errmsg)); \ ++ } while (0); ++ ++ NAN_INLINE v8::Local<v8::Value> 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<v8::Value> error) { ++ NanScope(); ++ v8::Isolate::GetCurrent()->ThrowException(error); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanError( ++ const char *msg ++ , const int errorNumber ++ ) { ++ v8::Local<v8::Value> err = v8::Exception::Error(NanNew<v8::String>(msg)); ++ v8::Local<v8::Object> obj = err.As<v8::Object>(); ++ obj->Set(NanNew<v8::String>("code"), NanNew<v8::Integer>(errorNumber)); ++ return err; ++ } ++ ++ NAN_INLINE void NanThrowError( ++ const char *msg ++ , const int errorNumber ++ ) { ++ NanThrowError(NanError(msg, errorNumber)); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> 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<v8::Value> 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<typename T> NAN_INLINE void NanDisposePersistent( ++ v8::Persistent<T> &handle ++ ) { ++ handle.Reset(); ++ } ++ ++ NAN_INLINE v8::Local<v8::Object> 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<v8::Object> NanNewBufferHandle ( ++ const char *data ++ , uint32_t size ++ ) { ++ return node::Buffer::New(v8::Isolate::GetCurrent(), data, size); ++ } ++ ++ NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) { ++ return node::Buffer::New(v8::Isolate::GetCurrent(), size); ++ } ++ ++ NAN_INLINE v8::Local<v8::Object> NanBufferUse( ++ char* data ++ , uint32_t size ++ ) { ++ return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size); ++ } ++ ++ NAN_INLINE bool NanHasInstance( ++ v8::Persistent<v8::FunctionTemplate>& function_template ++ , v8::Handle<v8::Value> value ++ ) { ++ return NanNew(function_template)->HasInstance(value); ++ } ++ ++ NAN_INLINE v8::Local<v8::Context> NanNewContextHandle( ++ v8::ExtensionConfiguration* extensions = NULL ++ , v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>() ++ , v8::Handle<v8::Value> obj = v8::Handle<v8::Value>() ++ ) { ++ v8::Isolate* isolate = v8::Isolate::GetCurrent(); ++ return v8::Local<v8::Context>::New( ++ isolate ++ , v8::Context::New(isolate, extensions, tmpl, obj) ++ ); ++ } ++ ++ NAN_INLINE v8::Local<NanBoundScript> NanCompileScript( ++ v8::Local<v8::String> s ++ , const v8::ScriptOrigin& origin ++ ) { ++ v8::ScriptCompiler::Source source(s, origin); ++ return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source); ++ } ++ ++ NAN_INLINE v8::Local<NanBoundScript> NanCompileScript( ++ v8::Local<v8::String> s ++ ) { ++ v8::ScriptCompiler::Source source(s); ++ return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanRunScript( ++ v8::Handle<NanUnboundScript> script ++ ) { ++ return script->BindToCurrentContext()->Run(); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanRunScript( ++ v8::Handle<NanBoundScript> script ++ ) { ++ return script->Run(); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanMakeCallback( ++ v8::Handle<v8::Object> target ++ , v8::Handle<v8::Function> func ++ , int argc ++ , v8::Handle<v8::Value>* argv) { ++ return NanNew(node::MakeCallback( ++ v8::Isolate::GetCurrent(), target, func, argc, argv)); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanMakeCallback( ++ v8::Handle<v8::Object> target ++ , v8::Handle<v8::String> symbol ++ , int argc ++ , v8::Handle<v8::Value>* argv) { ++ return NanNew(node::MakeCallback( ++ v8::Isolate::GetCurrent(), target, symbol, argc, argv)); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanMakeCallback( ++ v8::Handle<v8::Object> target ++ , const char* method ++ , int argc ++ , v8::Handle<v8::Value>* argv) { ++ return NanNew(node::MakeCallback( ++ v8::Isolate::GetCurrent(), target, method, argc, argv)); ++ } ++ ++ template<typename T> ++ NAN_INLINE void NanSetIsolateData( ++ v8::Isolate *isolate ++ , T *data ++ ) { ++ isolate->SetData(0, data); ++ } ++ ++ template<typename T> ++ NAN_INLINE T *NanGetIsolateData( ++ v8::Isolate *isolate ++ ) { ++ return static_cast<T*>(isolate->GetData(0)); ++ } ++ ++ class NanAsciiString { ++ public: ++ NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) { ++ v8::Local<v8::String> toStr = from->ToString(); ++ int buf_size = toStr->Length() + 1; ++ buf = new char[buf_size]; ++ size = toStr->WriteOneByte( ++ reinterpret_cast<unsigned char*>(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<v8::Value> from) { ++ v8::Local<v8::String> 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<v8::Value> from) { ++ v8::Local<v8::String> 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<v8::Value> ++ ++# define _NAN_GETTER_ARGS_TYPE const v8::AccessorInfo & ++# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args ++# define _NAN_GETTER_RETURN_TYPE v8::Handle<v8::Value> ++ ++# 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<v8::Value> ++ ++# 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<v8::Value> ++ ++# 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<v8::Array> ++ ++# 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<v8::Boolean> ++ ++# 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<v8::Integer> ++ ++# 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<v8::Value> ++ ++# 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<v8::Value> ++ ++# 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<v8::Array> ++ ++# 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<v8::Boolean> ++ ++# 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<v8::Integer> ++ ++ typedef v8::InvocationCallback NanFunctionCallback; ++ ++ NAN_DEPRECATED NAN_INLINE v8::Local<v8::String> NanSymbol( ++ const char* data, int length = -1) { ++ return v8::String::NewSymbol(data, length); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<T> NanNew() { ++ return v8::Local<T>::New(T::New()); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<T> NanNew(v8::Handle<T> arg) { ++ return v8::Local<T>::New(arg); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<v8::Signature> NanNew( ++ v8::Handle<v8::FunctionTemplate> receiver ++ , int argc ++ , v8::Handle<v8::FunctionTemplate> argv[] = 0) { ++ return v8::Signature::New(receiver, argc, argv); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<v8::FunctionTemplate> NanNew( ++ NanFunctionCallback callback ++ , v8::Handle<v8::Value> data = v8::Handle<v8::Value>() ++ , v8::Handle<v8::Signature> signature = v8::Handle<v8::Signature>()) { ++ return T::New(callback, data, signature); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<T> NanNew(const v8::Persistent<T> &arg) { ++ return v8::Local<T>::New(arg); ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<T> NanNew(P arg) { ++ return v8::Local<T>::New(T::New(arg)); ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<T> NanNew(P arg, int length) { ++ return v8::Local<T>::New(T::New(arg, length)); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<v8::RegExp> NanNew( ++ v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<typename T> ++ NAN_INLINE v8::Local<v8::RegExp> NanNew( ++ v8::Local<v8::String> pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<v8::RegExp> NanNew( ++ v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<v8::RegExp> NanNew( ++ v8::Local<v8::String> pattern, v8::RegExp::Flags flags) { ++ return v8::RegExp::New(pattern, flags); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>() { ++ return v8::Array::New(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>(int length) { ++ return v8::Array::New(length); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(double time) { ++ return v8::Date::New(time).As<v8::Date>(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(int time) { ++ return v8::Date::New(time).As<v8::Date>(); ++ } ++ ++ typedef v8::Script NanUnboundScript; ++ typedef v8::Script NanBoundScript; ++ ++ template<typename T, typename P> ++ NAN_INLINE v8::Local<T> NanNew( ++ P s ++ , const v8::ScriptOrigin& origin ++ ) { ++ return v8::Script::New(s, const_cast<v8::ScriptOrigin *>(&origin)); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<NanUnboundScript> NanNew<NanUnboundScript>( ++ v8::Local<v8::String> s ++ ) { ++ return v8::Script::New(s); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::BooleanObject> NanNew(bool value) { ++ return v8::BooleanObject::New(value).As<v8::BooleanObject>(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::StringObject> ++ NanNew<v8::StringObject, v8::Local<v8::String> >( ++ v8::Local<v8::String> value) { ++ return v8::StringObject::New(value).As<v8::StringObject>(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::StringObject> ++ NanNew<v8::StringObject, v8::Handle<v8::String> >( ++ v8::Handle<v8::String> value) { ++ return v8::StringObject::New(value).As<v8::StringObject>(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::NumberObject> NanNew<v8::NumberObject>(double val) { ++ return v8::NumberObject::New(val).As<v8::NumberObject>(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, int32_t>(int32_t val) { ++ return v8::Uint32::NewFromUnsigned(val)->ToUint32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, uint32_t>(uint32_t val) { ++ return v8::Uint32::NewFromUnsigned(val)->ToUint32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, int32_t>(int32_t val) { ++ return v8::Int32::New(val)->ToInt32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, uint32_t>(uint32_t val) { ++ return v8::Int32::New(val)->ToInt32(); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>( ++ uint8_t *arg ++ , int length) { ++ int len = length; ++ if (len < 0) { ++ size_t temp = strlen(reinterpret_cast<const char *>(arg)); ++ assert(temp <= INT_MAX && "too long string"); ++ len = static_cast<int>(temp); ++ } ++ uint16_t *warg = new uint16_t[len]; ++ for (int i = 0; i < len; i++) { ++ warg[i] = arg[i]; ++ } ++ v8::Local<v8::String> retval = v8::String::New(warg, len); ++ delete[] warg; ++ return retval; ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>( ++ const uint8_t *arg ++ , int length) { ++ int len = length; ++ if (len < 0) { ++ size_t temp = strlen(reinterpret_cast<const char *>(arg)); ++ assert(temp <= INT_MAX && "too long string"); ++ len = static_cast<int>(temp); ++ } ++ uint16_t *warg = new uint16_t[len]; ++ for (int i = 0; i < len; i++) { ++ warg[i] = arg[i]; ++ } ++ v8::Local<v8::String> retval = v8::String::New(warg, len); ++ delete[] warg; ++ return retval; ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(uint8_t *arg) { ++ size_t temp = strlen(reinterpret_cast<char *>(arg)); ++ assert(temp <= INT_MAX && "too long string"); ++ int length = static_cast<int>(temp); ++ uint16_t *warg = new uint16_t[length]; ++ for (int i = 0; i < length; i++) { ++ warg[i] = arg[i]; ++ } ++ ++ v8::Local<v8::String> retval = v8::String::New(warg, length); ++ delete[] warg; ++ return retval; ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>( ++ const uint8_t *arg) { ++ size_t temp = strlen(reinterpret_cast<const char *>(arg)); ++ assert(temp <= INT_MAX && "too long string"); ++ int length = static_cast<int>(temp); ++ uint16_t *warg = new uint16_t[length]; ++ for (int i = 0; i < length; i++) { ++ warg[i] = arg[i]; ++ } ++ v8::Local<v8::String> retval = v8::String::New(warg, length); ++ delete[] warg; ++ return retval; ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String, std::string>( ++ std::string arg) { ++ return NanNew<v8::String>(arg.c_str(), arg.size()); ++ } ++ ++ template<> ++ NAN_INLINE v8::Local<v8::String> NanNew<v8::String>() { ++ return v8::String::Empty(); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew(const char* arg, int length = -1) { ++ return NanNew<v8::String>(arg, length); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew( ++ const uint8_t* arg ++ , int length = -1) { ++ return NanNew<v8::String>(arg, length); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew( ++ const uint16_t* arg ++ , int length = -1) { ++ return NanNew<v8::String>(arg, length); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew( ++ std::string& arg) { ++ return NanNew<v8::String>(arg.c_str(), arg.size()); ++ } ++ ++ NAN_INLINE v8::Local<v8::Number> NanNew(double val) { ++ return NanNew<v8::Number>(val); ++ } ++ ++ NAN_INLINE v8::Local<v8::Integer> NanNew(int val) { ++ return NanNew<v8::Integer>(val); ++ } ++ ++ NAN_INLINE v8::Local<v8::Uint32> NanNew(unsigned int val) { ++ return NanNew<v8::Uint32>(val); ++ } ++ ++ NAN_INLINE v8::Local<v8::Boolean> NanNew(bool val) { ++ return NanNew<v8::Boolean>(val); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> NanNew( ++ v8::String::ExternalStringResource *resource) { ++ return v8::String::NewExternal(resource); ++ } ++ ++ NAN_INLINE v8::Local<v8::String> 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<v8::Object>::New(obj->handle_) ++ ++ NAN_INLINE v8::Local<v8::Primitive> NanUndefined() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::Undefined())); ++ } ++ ++ NAN_INLINE v8::Local<v8::Primitive> NanNull() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::Null())); ++ } ++ ++ NAN_INLINE v8::Local<v8::Boolean> NanTrue() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::True())); ++ } ++ ++ NAN_INLINE v8::Local<v8::Boolean> NanFalse() { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(v8::False())); ++ } ++ ++ NAN_INLINE int NanAdjustExternalMemory(int bc) { ++ return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc)); ++ } ++ ++ NAN_INLINE void NanSetTemplate( ++ v8::Handle<v8::Template> templ ++ , const char *name ++ , v8::Handle<v8::Data> value) { ++ templ->Set(name, value); ++ } ++ ++ NAN_INLINE void NanSetTemplate( ++ v8::Handle<v8::Template> templ ++ , v8::Handle<v8::String> name ++ , v8::Handle<v8::Data> value ++ , v8::PropertyAttribute attributes) { ++ templ->Set(name, value, attributes); ++ } ++ ++ NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() { ++ return v8::Context::GetCurrent(); ++ } ++ ++ NAN_INLINE void* NanGetInternalFieldPointer( ++ v8::Handle<v8::Object> object ++ , int index) { ++ return object->GetPointerFromInternalField(index); ++ } ++ ++ NAN_INLINE void NanSetInternalFieldPointer( ++ v8::Handle<v8::Object> 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<typename T> ++ NAN_INLINE void NanAssignPersistent( ++ v8::Persistent<T>& handle ++ , v8::Handle<T> obj) { ++ handle.Dispose(); ++ handle = v8::Persistent<T>::New(obj); ++ } ++ ++ template<typename T, typename P> ++ class _NanWeakCallbackData; ++ ++ template<typename T, typename P> ++ struct _NanWeakCallbackInfo { ++ typedef void (*Callback)(const _NanWeakCallbackData<T, P> &data); ++ NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> handle, P* param, Callback cb) ++ : parameter(param) ++ , callback(cb) ++ , persistent(v8::Persistent<T>::New(handle)) { } ++ ++ NAN_INLINE ~_NanWeakCallbackInfo() { ++ persistent.Dispose(); ++ persistent.Clear(); ++ } ++ ++ P* const parameter; ++ Callback const callback; ++ v8::Persistent<T> persistent; ++ }; ++ ++ template<typename T, typename P> ++ class _NanWeakCallbackData { ++ public: ++ NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info) ++ : info_(info) { } ++ ++ NAN_INLINE v8::Local<T> 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<T, P>* GetCallbackInfo() const { ++ return info_; ++ } ++ ++ NAN_DEPRECATED NAN_INLINE void Dispose() const { ++ } ++ ++ private: ++ _NanWeakCallbackInfo<T, P>* info_; ++ }; ++ ++ template<typename T, typename P> ++ static void _NanWeakPersistentDispatcher( ++ v8::Persistent<v8::Value> object, void *data) { ++ _NanWeakCallbackInfo<T, P>* info = ++ static_cast<_NanWeakCallbackInfo<T, P>*>(data); ++ _NanWeakCallbackData<T, P> wcbd(info); ++ info->callback(wcbd); ++ if (wcbd.IsNearDeath()) { ++ delete wcbd.GetCallbackInfo(); ++ } ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const { ++ info_->persistent.MakeWeak( ++ info_ ++ , &_NanWeakPersistentDispatcher<T, P>); ++ } ++ ++ template<typename T, typename P> ++ NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent( ++ v8::Handle<T> handle ++ , P* parameter ++ , typename _NanWeakCallbackInfo<T, P>::Callback callback) { ++ _NanWeakCallbackInfo<T, P> *cbinfo = ++ new _NanWeakCallbackInfo<T, P>(handle, parameter, callback); ++ cbinfo->persistent.MakeWeak( ++ cbinfo ++ , &_NanWeakPersistentDispatcher<T, P>); ++ return cbinfo; ++ } ++ ++# define NAN_WEAK_CALLBACK(name) \ ++ template<typename T, typename P> \ ++ static void name(const _NanWeakCallbackData<T, P> &data) ++ ++# define _NAN_ERROR(fun, errmsg) \ ++ fun(v8::String::New(errmsg)) ++ ++# define _NAN_THROW_ERROR(fun, errmsg) \ ++ do { \ ++ NanScope(); \ ++ return v8::Local<v8::Value>::New( \ ++ v8::ThrowException(_NAN_ERROR(fun, errmsg))); \ ++ } while (0); ++ ++ NAN_INLINE v8::Local<v8::Value> NanError(const char* errmsg) { ++ return _NAN_ERROR(v8::Exception::Error, errmsg); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanThrowError(const char* errmsg) { ++ _NAN_THROW_ERROR(v8::Exception::Error, errmsg); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanThrowError( ++ v8::Handle<v8::Value> error ++ ) { ++ NanScope(); ++ return v8::Local<v8::Value>::New(v8::ThrowException(error)); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanError( ++ const char *msg ++ , const int errorNumber ++ ) { ++ v8::Local<v8::Value> err = v8::Exception::Error(v8::String::New(msg)); ++ v8::Local<v8::Object> obj = err.As<v8::Object>(); ++ obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber)); ++ return err; ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanThrowError( ++ const char *msg ++ , const int errorNumber ++ ) { ++ return NanThrowError(NanError(msg, errorNumber)); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanTypeError(const char* errmsg) { ++ return _NAN_ERROR(v8::Exception::TypeError, errmsg); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanThrowTypeError( ++ const char* errmsg ++ ) { ++ _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanRangeError( ++ const char* errmsg ++ ) { ++ return _NAN_ERROR(v8::Exception::RangeError, errmsg); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanThrowRangeError( ++ const char* errmsg ++ ) { ++ _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg); ++ } ++ ++ template<typename T> ++ NAN_INLINE void NanDisposePersistent( ++ v8::Persistent<T> &handle) { // NOLINT(runtime/references) ++ handle.Dispose(); ++ handle.Clear(); ++ } ++ ++ NAN_INLINE v8::Local<v8::Object> 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<v8::Object> 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<char*>(data), size)->handle_); ++#endif ++ } ++ ++ NAN_INLINE v8::Local<v8::Object> 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<v8::Object> NanBufferUse( ++ char* data ++ , uint32_t size ++ ) { ++ return NanNew( ++ node::Buffer::New(data, size, FreeData, NULL)->handle_); ++ } ++ ++ NAN_INLINE bool NanHasInstance( ++ v8::Persistent<v8::FunctionTemplate>& function_template ++ , v8::Handle<v8::Value> value ++ ) { ++ return function_template->HasInstance(value); ++ } ++ ++ NAN_INLINE v8::Local<v8::Context> NanNewContextHandle( ++ v8::ExtensionConfiguration* extensions = NULL ++ , v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>() ++ , v8::Handle<v8::Value> obj = v8::Handle<v8::Value>() ++ ) { ++ v8::Persistent<v8::Context> ctx = v8::Context::New(extensions, tmpl, obj); ++ v8::Local<v8::Context> lctx = NanNew(ctx); ++ ctx.Dispose(); ++ return lctx; ++ } ++ ++ NAN_INLINE v8::Local<NanBoundScript> NanCompileScript( ++ v8::Local<v8::String> s ++ , const v8::ScriptOrigin& origin ++ ) { ++ return v8::Script::Compile(s, const_cast<v8::ScriptOrigin *>(&origin)); ++ } ++ ++ NAN_INLINE v8::Local<NanBoundScript> NanCompileScript( ++ v8::Local<v8::String> s ++ ) { ++ return v8::Script::Compile(s); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanRunScript(v8::Handle<v8::Script> script) { ++ return script->Run(); ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanMakeCallback( ++ v8::Handle<v8::Object> target ++ , v8::Handle<v8::Function> func ++ , int argc ++ , v8::Handle<v8::Value>* argv) { ++# if NODE_VERSION_AT_LEAST(0, 8, 0) ++ return NanNew(node::MakeCallback(target, func, argc, argv)); ++# else ++ v8::TryCatch try_catch; ++ v8::Local<v8::Value> result = NanNew(func->Call(target, argc, argv)); ++ if (try_catch.HasCaught()) { ++ node::FatalException(try_catch); ++ } ++ return result; ++# endif ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanMakeCallback( ++ v8::Handle<v8::Object> target ++ , v8::Handle<v8::String> symbol ++ , int argc ++ , v8::Handle<v8::Value>* argv) { ++# if NODE_VERSION_AT_LEAST(0, 8, 0) ++ return NanNew(node::MakeCallback(target, symbol, argc, argv)); ++# else ++ v8::Local<v8::Function> callback = target->Get(symbol).As<v8::Function>(); ++ return NanMakeCallback(target, callback, argc, argv); ++# endif ++ } ++ ++ NAN_INLINE v8::Local<v8::Value> NanMakeCallback( ++ v8::Handle<v8::Object> target ++ , const char* method ++ , int argc ++ , v8::Handle<v8::Value>* 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<typename T> ++ NAN_INLINE void NanSetIsolateData( ++ v8::Isolate *isolate ++ , T *data ++ ) { ++ isolate->SetData(data); ++ } ++ ++ template<typename T> ++ NAN_INLINE T *NanGetIsolateData( ++ v8::Isolate *isolate ++ ) { ++ return static_cast<T*>(isolate->GetData()); ++ } ++ ++ class NanAsciiString { ++ public: ++ NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) { ++ v8::Local<v8::String> 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<v8::Value> from) { ++ v8::Local<v8::String> 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<v8::Value> from) { ++ v8::Local<v8::String> 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<v8::String> property \ ++ , _NAN_GETTER_ARGS) ++#define NAN_SETTER(name) \ ++ _NAN_SETTER_RETURN_TYPE name( \ ++ v8::Local<v8::String> property \ ++ , v8::Local<v8::Value> value \ ++ , _NAN_SETTER_ARGS) ++#define NAN_PROPERTY_GETTER(name) \ ++ _NAN_PROPERTY_GETTER_RETURN_TYPE name( \ ++ v8::Local<v8::String> property \ ++ , _NAN_PROPERTY_GETTER_ARGS) ++#define NAN_PROPERTY_SETTER(name) \ ++ _NAN_PROPERTY_SETTER_RETURN_TYPE name( \ ++ v8::Local<v8::String> property \ ++ , v8::Local<v8::Value> 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<v8::String> property \ ++ , _NAN_PROPERTY_DELETER_ARGS) ++#define NAN_PROPERTY_QUERY(name) \ ++ _NAN_PROPERTY_QUERY_RETURN_TYPE name( \ ++ v8::Local<v8::String> 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<v8::Value> 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<v8::Object> obj = NanNew<v8::Object>(); ++ NanAssignPersistent(handle, obj); ++ } ++ ++ explicit NanCallback(const v8::Handle<v8::Function> &fn) { ++ NanScope(); ++ v8::Local<v8::Object> obj = NanNew<v8::Object>(); ++ NanAssignPersistent(handle, obj); ++ SetFunction(fn); ++ } ++ ++ ~NanCallback() { ++ if (handle.IsEmpty()) return; ++ NanDisposePersistent(handle); ++ } ++ ++ NAN_INLINE void SetFunction(const v8::Handle<v8::Function> &fn) { ++ NanScope(); ++ NanNew(handle)->Set(kCallbackIndex, fn); ++ } ++ ++ NAN_INLINE v8::Local<v8::Function> GetFunction() const { ++ NanEscapableScope(); ++ return NanEscapeScope(NanNew(handle)->Get(kCallbackIndex) ++ .As<v8::Function>()); ++ } ++ ++ NAN_INLINE bool IsEmpty() const { ++ NanScope(); ++ return NanNew(handle)->Get(kCallbackIndex)->IsUndefined(); ++ } ++ ++ v8::Handle<v8::Value> Call(int argc, v8::Handle<v8::Value> argv[]) const { ++ NanEscapableScope(); ++#if (NODE_MODULE_VERSION > 0x000B) // 0.11.12+ ++ v8::Isolate* isolate = v8::Isolate::GetCurrent(); ++ v8::Local<v8::Function> callback = NanNew(handle)-> ++ Get(kCallbackIndex).As<v8::Function>(); ++ return NanEscapeScope(node::MakeCallback( ++ isolate ++ , isolate->GetCurrentContext()->Global() ++ , callback ++ , argc ++ , argv ++ )); ++#else ++#if NODE_VERSION_AT_LEAST(0, 8, 0) ++ v8::Local<v8::Function> callback = handle-> ++ Get(kCallbackIndex).As<v8::Function>(); ++ return NanEscapeScope(node::MakeCallback( ++ v8::Context::GetCurrent()->Global() ++ , callback ++ , argc ++ , argv ++ )); ++#else ++ v8::Local<v8::Function> callback = handle-> ++ Get(kCallbackIndex).As<v8::Function>(); ++ return NanEscapeScope(NanMakeCallback( ++ v8::Context::GetCurrent()->Global(), callback, argc, argv)); ++#endif ++#endif ++ } ++ ++ private: ++ v8::Persistent<v8::Object> 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<v8::Object> obj = NanNew<v8::Object>(); ++ 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<v8::Object> &obj) { ++ v8::Local<v8::Object> handle = NanNew(persistentHandle); ++ handle->Set(NanNew<v8::String>(key), obj); ++ } ++ ++ v8::Local<v8::Object> GetFromPersistent(const char *key) const { ++ NanEscapableScope(); ++ v8::Local<v8::Object> handle = NanNew(persistentHandle); ++ return NanEscapeScope(handle->Get(NanNew(key)).As<v8::Object>()); ++ } ++ ++ virtual void Execute() = 0; ++ ++ uv_work_t request; ++ ++ protected: ++ v8::Persistent<v8::Object> persistentHandle; ++ NanCallback *callback; ++ ++ virtual void HandleOKCallback() { ++ NanScope(); ++ ++ callback->Call(0, NULL); ++ } ++ ++ virtual void HandleErrorCallback() { ++ NanScope(); ++ ++ v8::Local<v8::Value> argv[] = { ++ v8::Exception::Error(NanNew<v8::String>(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<NanAsyncWorker*>(req->data); ++ worker->Execute(); ++} ++ ++NAN_INLINE void NanAsyncExecuteComplete (uv_work_t* req) { ++ NanAsyncWorker* worker = static_cast<NanAsyncWorker*>(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<typename T> ++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<typename T> 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<typename T> 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<unsigned>(-1); ++} ++ ++template<typename T> 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<v8::Value> val ++ , const char** data ++ , size_t* len ++) { ++ if (node::Buffer::HasInstance(val)) { ++ *data = node::Buffer::Data(val.As<v8::Object>()); ++ *len = node::Buffer::Length(val.As<v8::Object>()); ++ return true; ++ } ++ ++ assert(val->IsString()); ++ v8::Local<v8::String> str = NanNew(val.As<v8::String>()); ++ ++ 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<const char*>(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<v8::Value> 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<const char**>(&data) ++ , &len); ++ ++ if (is_extern && !term_len) { ++ NanSetPointerSafe(datalen, len); ++ return data; ++ } ++ ++ v8::Local<v8::String> toStr = from->ToString(); ++ ++ char *to = static_cast<char *>(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<size_t>( ++ datalen ++ , toStr->WriteAscii(to, 0, static_cast<int>(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<int>(sz_ + term_len), flags); ++ ++ for (size_t i = 0; i < sz_ + term_len && i < len + term_len; i++) { ++ unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]); ++ to[i] = *b; ++ } ++ ++ NanSetPointerSafe<size_t>(datalen, len); ++ ++ delete[] twobytebuf; ++ return to; ++ } ++#else ++ NanSetPointerSafe<size_t>( ++ datalen, ++ toStr->WriteOneByte( ++ reinterpret_cast<uint8_t *>(to) ++ , 0 ++ , static_cast<int>(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<size_t>( ++ datalen ++ , toStr->WriteUtf8(to, static_cast<int>(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<size_t>( ++ 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<uint16_t *>(to) ++ , 0 ++ , static_cast<int>(sz_ + term_len) ++ , flags); ++ NanSetPointerSafe<size_t>(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<size_t>( ++ 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<v8::Value> 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<v8::Value> from ++ , size_t *datalen ++ , char *buf = NULL ++ , size_t buflen = 0 ++ , int flags = v8::String::NO_OPTIONS ++) { ++ return static_cast<char *>( ++ _NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags) ++ ); ++} ++ ++NAN_INLINE void NanSetPrototypeTemplate( ++ v8::Local<v8::FunctionTemplate> templ ++ , const char *name ++ , v8::Handle<v8::Data> value ++) { ++ NanSetTemplate(templ->PrototypeTemplate(), name, value); ++} ++ ++NAN_INLINE void NanSetPrototypeTemplate( ++ v8::Local<v8::FunctionTemplate> templ ++ , v8::Handle<v8::String> name ++ , v8::Handle<v8::Data> value ++ , v8::PropertyAttribute attributes ++) { ++ NanSetTemplate(templ->PrototypeTemplate(), name, value, attributes); ++} ++ ++NAN_INLINE void NanSetInstanceTemplate( ++ v8::Local<v8::FunctionTemplate> templ ++ , const char *name ++ , v8::Handle<v8::Data> value ++) { ++ NanSetTemplate(templ->InstanceTemplate(), name, value); ++} ++ ++NAN_INLINE void NanSetInstanceTemplate( ++ v8::Local<v8::FunctionTemplate> templ ++ , v8::Handle<v8::String> name ++ , v8::Handle<v8::Data> value ++ , v8::PropertyAttribute attributes ++) { ++ NanSetTemplate(templ->InstanceTemplate(), name, value, attributes); ++} ++ ++#endif // NAN_H_ |