芝麻web文件管理V1.00
编辑当前文件:/home/freeclou/app.optimyar.com/backend/node_modules/node-addon-api/napi-inl.h
#ifndef SRC_NAPI_INL_H_ #define SRC_NAPI_INL_H_ //////////////////////////////////////////////////////////////////////////////// // Node-API C++ Wrapper Classes // // Inline header-only implementations for "Node-API" ABI-stable C APIs for // Node.js. //////////////////////////////////////////////////////////////////////////////// // Note: Do not include this file directly! Include "napi.h" instead. #include
#include
#include
#include
namespace Napi { // Helpers to handle functions exposed from C++. namespace details { // Attach a data item to an object and delete it when the object gets // garbage-collected. // TODO: Replace this code with `napi_add_finalizer()` whenever it becomes // available on all supported versions of Node.js. template
static inline napi_status AttachData(napi_env env, napi_value obj, FreeType* data, napi_finalize finalizer = nullptr, void* hint = nullptr) { napi_status status; if (finalizer == nullptr) { finalizer = [](napi_env /*env*/, void* data, void* /*hint*/) { delete static_cast
(data); }; } #if (NAPI_VERSION < 5) napi_value symbol, external; status = napi_create_symbol(env, nullptr, &symbol); if (status == napi_ok) { status = napi_create_external(env, data, finalizer, hint, &external); if (status == napi_ok) { napi_property_descriptor desc = { nullptr, symbol, nullptr, nullptr, nullptr, external, napi_default, nullptr }; status = napi_define_properties(env, obj, 1, &desc); } } #else // NAPI_VERSION >= 5 status = napi_add_finalizer(env, obj, data, finalizer, hint, nullptr); #endif return status; } // For use in JS to C++ callback wrappers to catch any Napi::Error exceptions // and rethrow them as JavaScript exceptions before returning from the callback. template
inline napi_value WrapCallback(Callable callback) { #ifdef NAPI_CPP_EXCEPTIONS try { return callback(); } catch (const Error& e) { e.ThrowAsJavaScriptException(); return nullptr; } #else // NAPI_CPP_EXCEPTIONS // When C++ exceptions are disabled, errors are immediately thrown as JS // exceptions, so there is no need to catch and rethrow them here. return callback(); #endif // NAPI_CPP_EXCEPTIONS } // For use in JS to C++ void callback wrappers to catch any Napi::Error // exceptions and rethrow them as JavaScript exceptions before returning from the // callback. template
inline void WrapVoidCallback(Callable callback) { #ifdef NAPI_CPP_EXCEPTIONS try { callback(); } catch (const Error& e) { e.ThrowAsJavaScriptException(); } #else // NAPI_CPP_EXCEPTIONS // When C++ exceptions are disabled, errors are immediately thrown as JS // exceptions, so there is no need to catch and rethrow them here. callback(); #endif // NAPI_CPP_EXCEPTIONS } template
struct CallbackData { static inline napi_value Wrapper(napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); CallbackData* callbackData = static_cast
(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); return callbackData->callback(callbackInfo); }); } Callable callback; void* data; }; template
struct CallbackData
{ static inline napi_value Wrapper(napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); CallbackData* callbackData = static_cast
(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); callbackData->callback(callbackInfo); return nullptr; }); } Callable callback; void* data; }; template
static napi_value TemplatedVoidCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { return details::WrapCallback([&] { CallbackInfo cbInfo(env, info); Callback(cbInfo); return nullptr; }); } template
static napi_value TemplatedCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { return details::WrapCallback([&] { CallbackInfo cbInfo(env, info); return Callback(cbInfo); }); } template
static napi_value TemplatedInstanceCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { return details::WrapCallback([&] { CallbackInfo cbInfo(env, info); T* instance = T::Unwrap(cbInfo.This().As
()); return (instance->*UnwrapCallback)(cbInfo); }); } template
static napi_value TemplatedInstanceVoidCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { return details::WrapCallback([&] { CallbackInfo cbInfo(env, info); T* instance = T::Unwrap(cbInfo.This().As
()); (instance->*UnwrapCallback)(cbInfo); return nullptr; }); } template
struct FinalizeData { static inline void Wrapper(napi_env env, void* data, void* finalizeHint) NAPI_NOEXCEPT { WrapVoidCallback([&] { FinalizeData* finalizeData = static_cast
(finalizeHint); finalizeData->callback(Env(env), static_cast
(data)); delete finalizeData; }); } static inline void WrapperWithHint(napi_env env, void* data, void* finalizeHint) NAPI_NOEXCEPT { WrapVoidCallback([&] { FinalizeData* finalizeData = static_cast
(finalizeHint); finalizeData->callback(Env(env), static_cast
(data), finalizeData->hint); delete finalizeData; }); } Finalizer callback; Hint* hint; }; #if (NAPI_VERSION > 3 && !defined(__wasm32__)) template
, typename FinalizerDataType=void> struct ThreadSafeFinalize { static inline void Wrapper(napi_env env, void* rawFinalizeData, void* /* rawContext */) { if (rawFinalizeData == nullptr) return; ThreadSafeFinalize* finalizeData = static_cast
(rawFinalizeData); finalizeData->callback(Env(env)); delete finalizeData; } static inline void FinalizeWrapperWithData(napi_env env, void* rawFinalizeData, void* /* rawContext */) { if (rawFinalizeData == nullptr) return; ThreadSafeFinalize* finalizeData = static_cast
(rawFinalizeData); finalizeData->callback(Env(env), finalizeData->data); delete finalizeData; } static inline void FinalizeWrapperWithContext(napi_env env, void* rawFinalizeData, void* rawContext) { if (rawFinalizeData == nullptr) return; ThreadSafeFinalize* finalizeData = static_cast
(rawFinalizeData); finalizeData->callback(Env(env), static_cast
(rawContext)); delete finalizeData; } static inline void FinalizeFinalizeWrapperWithDataAndContext(napi_env env, void* rawFinalizeData, void* rawContext) { if (rawFinalizeData == nullptr) return; ThreadSafeFinalize* finalizeData = static_cast
(rawFinalizeData); finalizeData->callback(Env(env), finalizeData->data, static_cast
(rawContext)); delete finalizeData; } FinalizerDataType* data; Finalizer callback; }; template
typename std::enable_if
::type static inline CallJsWrapper( napi_env env, napi_value jsCallback, void* context, void* data) { call(env, Function(env, jsCallback), static_cast
(context), static_cast
(data)); } template
typename std::enable_if
::type static inline CallJsWrapper( napi_env env, napi_value jsCallback, void* /*context*/, void* /*data*/) { if (jsCallback != nullptr) { Function(env, jsCallback).Call(0, nullptr); } } #if NAPI_VERSION > 4 template
napi_value DefaultCallbackWrapper(napi_env /*env*/, std::nullptr_t /*cb*/) { return nullptr; } template
napi_value DefaultCallbackWrapper(napi_env /*env*/, Napi::Function cb) { return cb; } #else template
napi_value DefaultCallbackWrapper(napi_env env, Napi::Function cb) { if (cb.IsEmpty()) { return TSFN::EmptyFunctionFactory(env); } return cb; } #endif // NAPI_VERSION > 4 #endif // NAPI_VERSION > 3 && !defined(__wasm32__) template
struct AccessorCallbackData { static inline napi_value GetterWrapper(napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); AccessorCallbackData* callbackData = static_cast
(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); return callbackData->getterCallback(callbackInfo); }); } static inline napi_value SetterWrapper(napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); AccessorCallbackData* callbackData = static_cast
(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); callbackData->setterCallback(callbackInfo); return nullptr; }); } Getter getterCallback; Setter setterCallback; void* data; }; } // namespace details #ifndef NODE_ADDON_API_DISABLE_DEPRECATED # include "napi-inl.deprecated.h" #endif // !NODE_ADDON_API_DISABLE_DEPRECATED //////////////////////////////////////////////////////////////////////////////// // Module registration //////////////////////////////////////////////////////////////////////////////// // Register an add-on based on an initializer function. #define NODE_API_MODULE(modname, regfunc) \ static napi_value __napi_##regfunc(napi_env env, napi_value exports) { \ return Napi::RegisterModule(env, exports, regfunc); \ } \ NAPI_MODULE(modname, __napi_##regfunc) // Register an add-on based on a subclass of `Addon
` with a custom Node.js // module name. #define NODE_API_NAMED_ADDON(modname, classname) \ static napi_value __napi_ ## classname(napi_env env, \ napi_value exports) { \ return Napi::RegisterModule(env, exports, &classname::Init); \ } \ NAPI_MODULE(modname, __napi_ ## classname) // Register an add-on based on a subclass of `Addon
` with the Node.js module // name given by node-gyp from the `target_name` in binding.gyp. #define NODE_API_ADDON(classname) \ NODE_API_NAMED_ADDON(NODE_GYP_MODULE_NAME, classname) // Adapt the NAPI_MODULE registration function: // - Wrap the arguments in NAPI wrappers. // - Catch any NAPI errors and rethrow as JS exceptions. inline napi_value RegisterModule(napi_env env, napi_value exports, ModuleRegisterCallback registerCallback) { return details::WrapCallback([&] { return napi_value(registerCallback(Napi::Env(env), Napi::Object(env, exports))); }); } //////////////////////////////////////////////////////////////////////////////// // Env class //////////////////////////////////////////////////////////////////////////////// inline Env::Env(napi_env env) : _env(env) { } inline Env::operator napi_env() const { return _env; } inline Object Env::Global() const { napi_value value; napi_status status = napi_get_global(*this, &value); NAPI_THROW_IF_FAILED(*this, status, Object()); return Object(*this, value); } inline Value Env::Undefined() const { napi_value value; napi_status status = napi_get_undefined(*this, &value); NAPI_THROW_IF_FAILED(*this, status, Value()); return Value(*this, value); } inline Value Env::Null() const { napi_value value; napi_status status = napi_get_null(*this, &value); NAPI_THROW_IF_FAILED(*this, status, Value()); return Value(*this, value); } inline bool Env::IsExceptionPending() const { bool result; napi_status status = napi_is_exception_pending(_env, &result); if (status != napi_ok) result = false; // Checking for a pending exception shouldn't throw. return result; } inline Error Env::GetAndClearPendingException() { napi_value value; napi_status status = napi_get_and_clear_last_exception(_env, &value); if (status != napi_ok) { // Don't throw another exception when failing to get the exception! return Error(); } return Error(_env, value); } inline Value Env::RunScript(const char* utf8script) { String script = String::New(_env, utf8script); return RunScript(script); } inline Value Env::RunScript(const std::string& utf8script) { return RunScript(utf8script.c_str()); } inline Value Env::RunScript(String script) { napi_value result; napi_status status = napi_run_script(_env, script, &result); NAPI_THROW_IF_FAILED(_env, status, Undefined()); return Value(_env, result); } #if NAPI_VERSION > 5 template
fini> inline void Env::SetInstanceData(T* data) { napi_status status = napi_set_instance_data(_env, data, [](napi_env env, void* data, void*) { fini(env, static_cast
(data)); }, nullptr); NAPI_THROW_IF_FAILED_VOID(_env, status); } template
fini> inline void Env::SetInstanceData(DataType* data, HintType* hint) { napi_status status = napi_set_instance_data(_env, data, [](napi_env env, void* data, void* hint) { fini(env, static_cast
(data), static_cast
(hint)); }, hint); NAPI_THROW_IF_FAILED_VOID(_env, status); } template
inline T* Env::GetInstanceData() { void* data = nullptr; napi_status status = napi_get_instance_data(_env, &data); NAPI_THROW_IF_FAILED(_env, status, nullptr); return static_cast
(data); } template
void Env::DefaultFini(Env, T* data) { delete data; } template
void Env::DefaultFiniWithHint(Env, DataType* data, HintType*) { delete data; } #endif // NAPI_VERSION > 5 //////////////////////////////////////////////////////////////////////////////// // Value class //////////////////////////////////////////////////////////////////////////////// inline Value::Value() : _env(nullptr), _value(nullptr) { } inline Value::Value(napi_env env, napi_value value) : _env(env), _value(value) { } inline Value::operator napi_value() const { return _value; } inline bool Value::operator ==(const Value& other) const { return StrictEquals(other); } inline bool Value::operator !=(const Value& other) const { return !this->operator ==(other); } inline bool Value::StrictEquals(const Value& other) const { bool result; napi_status status = napi_strict_equals(_env, *this, other, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline Napi::Env Value::Env() const { return Napi::Env(_env); } inline bool Value::IsEmpty() const { return _value == nullptr; } inline napi_valuetype Value::Type() const { if (IsEmpty()) { return napi_undefined; } napi_valuetype type; napi_status status = napi_typeof(_env, _value, &type); NAPI_THROW_IF_FAILED(_env, status, napi_undefined); return type; } inline bool Value::IsUndefined() const { return Type() == napi_undefined; } inline bool Value::IsNull() const { return Type() == napi_null; } inline bool Value::IsBoolean() const { return Type() == napi_boolean; } inline bool Value::IsNumber() const { return Type() == napi_number; } #if NAPI_VERSION > 5 inline bool Value::IsBigInt() const { return Type() == napi_bigint; } #endif // NAPI_VERSION > 5 #if (NAPI_VERSION > 4) inline bool Value::IsDate() const { if (IsEmpty()) { return false; } bool result; napi_status status = napi_is_date(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } #endif inline bool Value::IsString() const { return Type() == napi_string; } inline bool Value::IsSymbol() const { return Type() == napi_symbol; } inline bool Value::IsArray() const { if (IsEmpty()) { return false; } bool result; napi_status status = napi_is_array(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Value::IsArrayBuffer() const { if (IsEmpty()) { return false; } bool result; napi_status status = napi_is_arraybuffer(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Value::IsTypedArray() const { if (IsEmpty()) { return false; } bool result; napi_status status = napi_is_typedarray(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Value::IsObject() const { return Type() == napi_object || IsFunction(); } inline bool Value::IsFunction() const { return Type() == napi_function; } inline bool Value::IsPromise() const { if (IsEmpty()) { return false; } bool result; napi_status status = napi_is_promise(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Value::IsDataView() const { if (IsEmpty()) { return false; } bool result; napi_status status = napi_is_dataview(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Value::IsBuffer() const { if (IsEmpty()) { return false; } bool result; napi_status status = napi_is_buffer(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Value::IsExternal() const { return Type() == napi_external; } template
inline T Value::As() const { return T(_env, _value); } inline Boolean Value::ToBoolean() const { napi_value result; napi_status status = napi_coerce_to_bool(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, Boolean()); return Boolean(_env, result); } inline Number Value::ToNumber() const { napi_value result; napi_status status = napi_coerce_to_number(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, Number()); return Number(_env, result); } inline String Value::ToString() const { napi_value result; napi_status status = napi_coerce_to_string(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, String()); return String(_env, result); } inline Object Value::ToObject() const { napi_value result; napi_status status = napi_coerce_to_object(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, Object()); return Object(_env, result); } //////////////////////////////////////////////////////////////////////////////// // Boolean class //////////////////////////////////////////////////////////////////////////////// inline Boolean Boolean::New(napi_env env, bool val) { napi_value value; napi_status status = napi_get_boolean(env, val, &value); NAPI_THROW_IF_FAILED(env, status, Boolean()); return Boolean(env, value); } inline Boolean::Boolean() : Napi::Value() { } inline Boolean::Boolean(napi_env env, napi_value value) : Napi::Value(env, value) { } inline Boolean::operator bool() const { return Value(); } inline bool Boolean::Value() const { bool result; napi_status status = napi_get_value_bool(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } //////////////////////////////////////////////////////////////////////////////// // Number class //////////////////////////////////////////////////////////////////////////////// inline Number Number::New(napi_env env, double val) { napi_value value; napi_status status = napi_create_double(env, val, &value); NAPI_THROW_IF_FAILED(env, status, Number()); return Number(env, value); } inline Number::Number() : Value() { } inline Number::Number(napi_env env, napi_value value) : Value(env, value) { } inline Number::operator int32_t() const { return Int32Value(); } inline Number::operator uint32_t() const { return Uint32Value(); } inline Number::operator int64_t() const { return Int64Value(); } inline Number::operator float() const { return FloatValue(); } inline Number::operator double() const { return DoubleValue(); } inline int32_t Number::Int32Value() const { int32_t result; napi_status status = napi_get_value_int32(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } inline uint32_t Number::Uint32Value() const { uint32_t result; napi_status status = napi_get_value_uint32(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } inline int64_t Number::Int64Value() const { int64_t result; napi_status status = napi_get_value_int64(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } inline float Number::FloatValue() const { return static_cast
(DoubleValue()); } inline double Number::DoubleValue() const { double result; napi_status status = napi_get_value_double(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } #if NAPI_VERSION > 5 //////////////////////////////////////////////////////////////////////////////// // BigInt Class //////////////////////////////////////////////////////////////////////////////// inline BigInt BigInt::New(napi_env env, int64_t val) { napi_value value; napi_status status = napi_create_bigint_int64(env, val, &value); NAPI_THROW_IF_FAILED(env, status, BigInt()); return BigInt(env, value); } inline BigInt BigInt::New(napi_env env, uint64_t val) { napi_value value; napi_status status = napi_create_bigint_uint64(env, val, &value); NAPI_THROW_IF_FAILED(env, status, BigInt()); return BigInt(env, value); } inline BigInt BigInt::New(napi_env env, int sign_bit, size_t word_count, const uint64_t* words) { napi_value value; napi_status status = napi_create_bigint_words(env, sign_bit, word_count, words, &value); NAPI_THROW_IF_FAILED(env, status, BigInt()); return BigInt(env, value); } inline BigInt::BigInt() : Value() { } inline BigInt::BigInt(napi_env env, napi_value value) : Value(env, value) { } inline int64_t BigInt::Int64Value(bool* lossless) const { int64_t result; napi_status status = napi_get_value_bigint_int64( _env, _value, &result, lossless); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } inline uint64_t BigInt::Uint64Value(bool* lossless) const { uint64_t result; napi_status status = napi_get_value_bigint_uint64( _env, _value, &result, lossless); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } inline size_t BigInt::WordCount() const { size_t word_count; napi_status status = napi_get_value_bigint_words( _env, _value, nullptr, &word_count, nullptr); NAPI_THROW_IF_FAILED(_env, status, 0); return word_count; } inline void BigInt::ToWords(int* sign_bit, size_t* word_count, uint64_t* words) { napi_status status = napi_get_value_bigint_words( _env, _value, sign_bit, word_count, words); NAPI_THROW_IF_FAILED_VOID(_env, status); } #endif // NAPI_VERSION > 5 #if (NAPI_VERSION > 4) //////////////////////////////////////////////////////////////////////////////// // Date Class //////////////////////////////////////////////////////////////////////////////// inline Date Date::New(napi_env env, double val) { napi_value value; napi_status status = napi_create_date(env, val, &value); NAPI_THROW_IF_FAILED(env, status, Date()); return Date(env, value); } inline Date::Date() : Value() { } inline Date::Date(napi_env env, napi_value value) : Value(env, value) { } inline Date::operator double() const { return ValueOf(); } inline double Date::ValueOf() const { double result; napi_status status = napi_get_date_value( _env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } #endif //////////////////////////////////////////////////////////////////////////////// // Name class //////////////////////////////////////////////////////////////////////////////// inline Name::Name() : Value() { } inline Name::Name(napi_env env, napi_value value) : Value(env, value) { } //////////////////////////////////////////////////////////////////////////////// // String class //////////////////////////////////////////////////////////////////////////////// inline String String::New(napi_env env, const std::string& val) { return String::New(env, val.c_str(), val.size()); } inline String String::New(napi_env env, const std::u16string& val) { return String::New(env, val.c_str(), val.size()); } inline String String::New(napi_env env, const char* val) { napi_value value; napi_status status = napi_create_string_utf8(env, val, std::strlen(val), &value); NAPI_THROW_IF_FAILED(env, status, String()); return String(env, value); } inline String String::New(napi_env env, const char16_t* val) { napi_value value; napi_status status = napi_create_string_utf16(env, val, std::u16string(val).size(), &value); NAPI_THROW_IF_FAILED(env, status, String()); return String(env, value); } inline String String::New(napi_env env, const char* val, size_t length) { napi_value value; napi_status status = napi_create_string_utf8(env, val, length, &value); NAPI_THROW_IF_FAILED(env, status, String()); return String(env, value); } inline String String::New(napi_env env, const char16_t* val, size_t length) { napi_value value; napi_status status = napi_create_string_utf16(env, val, length, &value); NAPI_THROW_IF_FAILED(env, status, String()); return String(env, value); } inline String::String() : Name() { } inline String::String(napi_env env, napi_value value) : Name(env, value) { } inline String::operator std::string() const { return Utf8Value(); } inline String::operator std::u16string() const { return Utf16Value(); } inline std::string String::Utf8Value() const { size_t length; napi_status status = napi_get_value_string_utf8(_env, _value, nullptr, 0, &length); NAPI_THROW_IF_FAILED(_env, status, ""); std::string value; value.reserve(length + 1); value.resize(length); status = napi_get_value_string_utf8(_env, _value, &value[0], value.capacity(), nullptr); NAPI_THROW_IF_FAILED(_env, status, ""); return value; } inline std::u16string String::Utf16Value() const { size_t length; napi_status status = napi_get_value_string_utf16(_env, _value, nullptr, 0, &length); NAPI_THROW_IF_FAILED(_env, status, NAPI_WIDE_TEXT("")); std::u16string value; value.reserve(length + 1); value.resize(length); status = napi_get_value_string_utf16(_env, _value, &value[0], value.capacity(), nullptr); NAPI_THROW_IF_FAILED(_env, status, NAPI_WIDE_TEXT("")); return value; } //////////////////////////////////////////////////////////////////////////////// // Symbol class //////////////////////////////////////////////////////////////////////////////// inline Symbol Symbol::New(napi_env env, const char* description) { napi_value descriptionValue = description != nullptr ? String::New(env, description) : static_cast
(nullptr); return Symbol::New(env, descriptionValue); } inline Symbol Symbol::New(napi_env env, const std::string& description) { napi_value descriptionValue = String::New(env, description); return Symbol::New(env, descriptionValue); } inline Symbol Symbol::New(napi_env env, String description) { napi_value descriptionValue = description; return Symbol::New(env, descriptionValue); } inline Symbol Symbol::New(napi_env env, napi_value description) { napi_value value; napi_status status = napi_create_symbol(env, description, &value); NAPI_THROW_IF_FAILED(env, status, Symbol()); return Symbol(env, value); } inline Symbol Symbol::WellKnown(napi_env env, const std::string& name) { return Napi::Env(env).Global().Get("Symbol").As
().Get(name).As
(); } inline Symbol::Symbol() : Name() { } inline Symbol::Symbol(napi_env env, napi_value value) : Name(env, value) { } //////////////////////////////////////////////////////////////////////////////// // Automagic value creation //////////////////////////////////////////////////////////////////////////////// namespace details { template
struct vf_number { static Number From(napi_env env, T value) { return Number::New(env, static_cast
(value)); } }; template<> struct vf_number
{ static Boolean From(napi_env env, bool value) { return Boolean::New(env, value); } }; struct vf_utf8_charp { static String From(napi_env env, const char* value) { return String::New(env, value); } }; struct vf_utf16_charp { static String From(napi_env env, const char16_t* value) { return String::New(env, value); } }; struct vf_utf8_string { static String From(napi_env env, const std::string& value) { return String::New(env, value); } }; struct vf_utf16_string { static String From(napi_env env, const std::u16string& value) { return String::New(env, value); } }; template
struct vf_fallback { static Value From(napi_env env, const T& value) { return Value(env, value); } }; template
struct disjunction : std::false_type {}; template
struct disjunction
: B {}; template
struct disjunction
: std::conditional
>::type {}; template
struct can_make_string : disjunction
::type, typename std::is_convertible
::type, typename std::is_convertible
::type, typename std::is_convertible
::type> {}; } template
Value Value::From(napi_env env, const T& value) { using Helper = typename std::conditional< std::is_integral
::value || std::is_floating_point
::value, details::vf_number
, typename std::conditional< details::can_make_string
::value, String, details::vf_fallback
>::type >::type; return Helper::From(env, value); } template
String String::From(napi_env env, const T& value) { struct Dummy {}; using Helper = typename std::conditional< std::is_convertible
::value, details::vf_utf8_charp, typename std::conditional< std::is_convertible
::value, details::vf_utf16_charp, typename std::conditional< std::is_convertible
::value, details::vf_utf8_string, typename std::conditional< std::is_convertible
::value, details::vf_utf16_string, Dummy >::type >::type >::type >::type; return Helper::From(env, value); } //////////////////////////////////////////////////////////////////////////////// // Object class //////////////////////////////////////////////////////////////////////////////// template
inline Object::PropertyLValue
::operator Value() const { return Object(_env, _object).Get(_key); } template
template
inline Object::PropertyLValue
& Object::PropertyLValue
::operator =(ValueType value) { Object(_env, _object).Set(_key, value); return *this; } template
inline Object::PropertyLValue
::PropertyLValue(Object object, Key key) : _env(object.Env()), _object(object), _key(key) {} inline Object Object::New(napi_env env) { napi_value value; napi_status status = napi_create_object(env, &value); NAPI_THROW_IF_FAILED(env, status, Object()); return Object(env, value); } inline Object::Object() : Value() { } inline Object::Object(napi_env env, napi_value value) : Value(env, value) { } inline Object::PropertyLValue
Object::operator [](const char* utf8name) { return PropertyLValue
(*this, utf8name); } inline Object::PropertyLValue
Object::operator [](const std::string& utf8name) { return PropertyLValue
(*this, utf8name); } inline Object::PropertyLValue
Object::operator [](uint32_t index) { return PropertyLValue
(*this, index); } inline Value Object::operator [](const char* utf8name) const { return Get(utf8name); } inline Value Object::operator [](const std::string& utf8name) const { return Get(utf8name); } inline Value Object::operator [](uint32_t index) const { return Get(index); } inline bool Object::Has(napi_value key) const { bool result; napi_status status = napi_has_property(_env, _value, key, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Object::Has(Value key) const { bool result; napi_status status = napi_has_property(_env, _value, key, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Object::Has(const char* utf8name) const { bool result; napi_status status = napi_has_named_property(_env, _value, utf8name, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Object::Has(const std::string& utf8name) const { return Has(utf8name.c_str()); } inline bool Object::HasOwnProperty(napi_value key) const { bool result; napi_status status = napi_has_own_property(_env, _value, key, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Object::HasOwnProperty(Value key) const { bool result; napi_status status = napi_has_own_property(_env, _value, key, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Object::HasOwnProperty(const char* utf8name) const { napi_value key; napi_status status = napi_create_string_utf8(_env, utf8name, std::strlen(utf8name), &key); NAPI_THROW_IF_FAILED(_env, status, false); return HasOwnProperty(key); } inline bool Object::HasOwnProperty(const std::string& utf8name) const { return HasOwnProperty(utf8name.c_str()); } inline Value Object::Get(napi_value key) const { napi_value result; napi_status status = napi_get_property(_env, _value, key, &result); NAPI_THROW_IF_FAILED(_env, status, Value()); return Value(_env, result); } inline Value Object::Get(Value key) const { napi_value result; napi_status status = napi_get_property(_env, _value, key, &result); NAPI_THROW_IF_FAILED(_env, status, Value()); return Value(_env, result); } inline Value Object::Get(const char* utf8name) const { napi_value result; napi_status status = napi_get_named_property(_env, _value, utf8name, &result); NAPI_THROW_IF_FAILED(_env, status, Value()); return Value(_env, result); } inline Value Object::Get(const std::string& utf8name) const { return Get(utf8name.c_str()); } template
inline bool Object::Set(napi_value key, const ValueType& value) { napi_status status = napi_set_property(_env, _value, key, Value::From(_env, value)); NAPI_THROW_IF_FAILED(_env, status, false); return true; } template
inline bool Object::Set(Value key, const ValueType& value) { napi_status status = napi_set_property(_env, _value, key, Value::From(_env, value)); NAPI_THROW_IF_FAILED(_env, status, false); return true; } template
inline bool Object::Set(const char* utf8name, const ValueType& value) { napi_status status = napi_set_named_property(_env, _value, utf8name, Value::From(_env, value)); NAPI_THROW_IF_FAILED(_env, status, false); return true; } template
inline bool Object::Set(const std::string& utf8name, const ValueType& value) { return Set(utf8name.c_str(), value); } inline bool Object::Delete(napi_value key) { bool result; napi_status status = napi_delete_property(_env, _value, key, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Object::Delete(Value key) { bool result; napi_status status = napi_delete_property(_env, _value, key, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline bool Object::Delete(const char* utf8name) { return Delete(String::New(_env, utf8name)); } inline bool Object::Delete(const std::string& utf8name) { return Delete(String::New(_env, utf8name)); } inline bool Object::Has(uint32_t index) const { bool result; napi_status status = napi_has_element(_env, _value, index, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline Value Object::Get(uint32_t index) const { napi_value value; napi_status status = napi_get_element(_env, _value, index, &value); NAPI_THROW_IF_FAILED(_env, status, Value()); return Value(_env, value); } template
inline bool Object::Set(uint32_t index, const ValueType& value) { napi_status status = napi_set_element(_env, _value, index, Value::From(_env, value)); NAPI_THROW_IF_FAILED(_env, status, false); return true; } inline bool Object::Delete(uint32_t index) { bool result; napi_status status = napi_delete_element(_env, _value, index, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } inline Array Object::GetPropertyNames() const { napi_value result; napi_status status = napi_get_property_names(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, Array()); return Array(_env, result); } inline bool Object::DefineProperty(const PropertyDescriptor& property) { napi_status status = napi_define_properties(_env, _value, 1, reinterpret_cast
(&property)); NAPI_THROW_IF_FAILED(_env, status, false); return true; } inline bool Object::DefineProperties( const std::initializer_list
& properties) { napi_status status = napi_define_properties(_env, _value, properties.size(), reinterpret_cast
(properties.begin())); NAPI_THROW_IF_FAILED(_env, status, false); return true; } inline bool Object::DefineProperties( const std::vector
& properties) { napi_status status = napi_define_properties(_env, _value, properties.size(), reinterpret_cast
(properties.data())); NAPI_THROW_IF_FAILED(_env, status, false); return true; } inline bool Object::InstanceOf(const Function& constructor) const { bool result; napi_status status = napi_instanceof(_env, _value, constructor, &result); NAPI_THROW_IF_FAILED(_env, status, false); return result; } template
inline void Object::AddFinalizer(Finalizer finalizeCallback, T* data) { details::FinalizeData
* finalizeData = new details::FinalizeData
( {std::move(finalizeCallback), nullptr}); napi_status status = details::AttachData(_env, *this, data, details::FinalizeData
::Wrapper, finalizeData); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED_VOID(_env, status); } } template
inline void Object::AddFinalizer(Finalizer finalizeCallback, T* data, Hint* finalizeHint) { details::FinalizeData
* finalizeData = new details::FinalizeData
( {std::move(finalizeCallback), finalizeHint}); napi_status status = details::AttachData(_env, *this, data, details::FinalizeData
::WrapperWithHint, finalizeData); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED_VOID(_env, status); } } #if NAPI_VERSION >= 8 inline bool Object::Freeze() { napi_status status = napi_object_freeze(_env, _value); NAPI_THROW_IF_FAILED(_env, status, false); return true; } inline bool Object::Seal() { napi_status status = napi_object_seal(_env, _value); NAPI_THROW_IF_FAILED(_env, status, false); return true; } #endif // NAPI_VERSION >= 8 //////////////////////////////////////////////////////////////////////////////// // External class //////////////////////////////////////////////////////////////////////////////// template
inline External
External
::New(napi_env env, T* data) { napi_value value; napi_status status = napi_create_external(env, data, nullptr, nullptr, &value); NAPI_THROW_IF_FAILED(env, status, External()); return External(env, value); } template
template
inline External
External
::New(napi_env env, T* data, Finalizer finalizeCallback) { napi_value value; details::FinalizeData
* finalizeData = new details::FinalizeData
( {std::move(finalizeCallback), nullptr}); napi_status status = napi_create_external( env, data, details::FinalizeData
::Wrapper, finalizeData, &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, External()); } return External(env, value); } template
template
inline External
External
::New(napi_env env, T* data, Finalizer finalizeCallback, Hint* finalizeHint) { napi_value value; details::FinalizeData
* finalizeData = new details::FinalizeData
( {std::move(finalizeCallback), finalizeHint}); napi_status status = napi_create_external( env, data, details::FinalizeData
::WrapperWithHint, finalizeData, &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, External()); } return External(env, value); } template
inline External
::External() : Value() { } template
inline External
::External(napi_env env, napi_value value) : Value(env, value) { } template
inline T* External
::Data() const { void* data; napi_status status = napi_get_value_external(_env, _value, &data); NAPI_THROW_IF_FAILED(_env, status, nullptr); return reinterpret_cast
(data); } //////////////////////////////////////////////////////////////////////////////// // Array class //////////////////////////////////////////////////////////////////////////////// inline Array Array::New(napi_env env) { napi_value value; napi_status status = napi_create_array(env, &value); NAPI_THROW_IF_FAILED(env, status, Array()); return Array(env, value); } inline Array Array::New(napi_env env, size_t length) { napi_value value; napi_status status = napi_create_array_with_length(env, length, &value); NAPI_THROW_IF_FAILED(env, status, Array()); return Array(env, value); } inline Array::Array() : Object() { } inline Array::Array(napi_env env, napi_value value) : Object(env, value) { } inline uint32_t Array::Length() const { uint32_t result; napi_status status = napi_get_array_length(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } //////////////////////////////////////////////////////////////////////////////// // ArrayBuffer class //////////////////////////////////////////////////////////////////////////////// inline ArrayBuffer ArrayBuffer::New(napi_env env, size_t byteLength) { napi_value value; void* data; napi_status status = napi_create_arraybuffer(env, byteLength, &data, &value); NAPI_THROW_IF_FAILED(env, status, ArrayBuffer()); return ArrayBuffer(env, value); } inline ArrayBuffer ArrayBuffer::New(napi_env env, void* externalData, size_t byteLength) { napi_value value; napi_status status = napi_create_external_arraybuffer( env, externalData, byteLength, nullptr, nullptr, &value); NAPI_THROW_IF_FAILED(env, status, ArrayBuffer()); return ArrayBuffer(env, value); } template
inline ArrayBuffer ArrayBuffer::New(napi_env env, void* externalData, size_t byteLength, Finalizer finalizeCallback) { napi_value value; details::FinalizeData
* finalizeData = new details::FinalizeData
( {std::move(finalizeCallback), nullptr}); napi_status status = napi_create_external_arraybuffer( env, externalData, byteLength, details::FinalizeData
::Wrapper, finalizeData, &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, ArrayBuffer()); } return ArrayBuffer(env, value); } template
inline ArrayBuffer ArrayBuffer::New(napi_env env, void* externalData, size_t byteLength, Finalizer finalizeCallback, Hint* finalizeHint) { napi_value value; details::FinalizeData
* finalizeData = new details::FinalizeData
( {std::move(finalizeCallback), finalizeHint}); napi_status status = napi_create_external_arraybuffer( env, externalData, byteLength, details::FinalizeData
::WrapperWithHint, finalizeData, &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, ArrayBuffer()); } return ArrayBuffer(env, value); } inline ArrayBuffer::ArrayBuffer() : Object() { } inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value) : Object(env, value) { } inline void* ArrayBuffer::Data() { void* data; napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr); NAPI_THROW_IF_FAILED(_env, status, nullptr); return data; } inline size_t ArrayBuffer::ByteLength() { size_t length; napi_status status = napi_get_arraybuffer_info(_env, _value, nullptr, &length); NAPI_THROW_IF_FAILED(_env, status, 0); return length; } #if NAPI_VERSION >= 7 inline bool ArrayBuffer::IsDetached() const { bool detached; napi_status status = napi_is_detached_arraybuffer(_env, _value, &detached); NAPI_THROW_IF_FAILED(_env, status, false); return detached; } inline void ArrayBuffer::Detach() { napi_status status = napi_detach_arraybuffer(_env, _value); NAPI_THROW_IF_FAILED_VOID(_env, status); } #endif // NAPI_VERSION >= 7 //////////////////////////////////////////////////////////////////////////////// // DataView class //////////////////////////////////////////////////////////////////////////////// inline DataView DataView::New(napi_env env, Napi::ArrayBuffer arrayBuffer) { return New(env, arrayBuffer, 0, arrayBuffer.ByteLength()); } inline DataView DataView::New(napi_env env, Napi::ArrayBuffer arrayBuffer, size_t byteOffset) { if (byteOffset > arrayBuffer.ByteLength()) { NAPI_THROW(RangeError::New(env, "Start offset is outside the bounds of the buffer"), DataView()); } return New(env, arrayBuffer, byteOffset, arrayBuffer.ByteLength() - byteOffset); } inline DataView DataView::New(napi_env env, Napi::ArrayBuffer arrayBuffer, size_t byteOffset, size_t byteLength) { if (byteOffset + byteLength > arrayBuffer.ByteLength()) { NAPI_THROW(RangeError::New(env, "Invalid DataView length"), DataView()); } napi_value value; napi_status status = napi_create_dataview( env, byteLength, arrayBuffer, byteOffset, &value); NAPI_THROW_IF_FAILED(env, status, DataView()); return DataView(env, value); } inline DataView::DataView() : Object() { } inline DataView::DataView(napi_env env, napi_value value) : Object(env, value) { napi_status status = napi_get_dataview_info( _env, _value /* dataView */, &_length /* byteLength */, &_data /* data */, nullptr /* arrayBuffer */, nullptr /* byteOffset */); NAPI_THROW_IF_FAILED_VOID(_env, status); } inline Napi::ArrayBuffer DataView::ArrayBuffer() const { napi_value arrayBuffer; napi_status status = napi_get_dataview_info( _env, _value /* dataView */, nullptr /* byteLength */, nullptr /* data */, &arrayBuffer /* arrayBuffer */, nullptr /* byteOffset */); NAPI_THROW_IF_FAILED(_env, status, Napi::ArrayBuffer()); return Napi::ArrayBuffer(_env, arrayBuffer); } inline size_t DataView::ByteOffset() const { size_t byteOffset; napi_status status = napi_get_dataview_info( _env, _value /* dataView */, nullptr /* byteLength */, nullptr /* data */, nullptr /* arrayBuffer */, &byteOffset /* byteOffset */); NAPI_THROW_IF_FAILED(_env, status, 0); return byteOffset; } inline size_t DataView::ByteLength() const { return _length; } inline void* DataView::Data() const { return _data; } inline float DataView::GetFloat32(size_t byteOffset) const { return ReadData
(byteOffset); } inline double DataView::GetFloat64(size_t byteOffset) const { return ReadData
(byteOffset); } inline int8_t DataView::GetInt8(size_t byteOffset) const { return ReadData
(byteOffset); } inline int16_t DataView::GetInt16(size_t byteOffset) const { return ReadData
(byteOffset); } inline int32_t DataView::GetInt32(size_t byteOffset) const { return ReadData
(byteOffset); } inline uint8_t DataView::GetUint8(size_t byteOffset) const { return ReadData
(byteOffset); } inline uint16_t DataView::GetUint16(size_t byteOffset) const { return ReadData
(byteOffset); } inline uint32_t DataView::GetUint32(size_t byteOffset) const { return ReadData
(byteOffset); } inline void DataView::SetFloat32(size_t byteOffset, float value) const { WriteData
(byteOffset, value); } inline void DataView::SetFloat64(size_t byteOffset, double value) const { WriteData
(byteOffset, value); } inline void DataView::SetInt8(size_t byteOffset, int8_t value) const { WriteData
(byteOffset, value); } inline void DataView::SetInt16(size_t byteOffset, int16_t value) const { WriteData
(byteOffset, value); } inline void DataView::SetInt32(size_t byteOffset, int32_t value) const { WriteData
(byteOffset, value); } inline void DataView::SetUint8(size_t byteOffset, uint8_t value) const { WriteData
(byteOffset, value); } inline void DataView::SetUint16(size_t byteOffset, uint16_t value) const { WriteData
(byteOffset, value); } inline void DataView::SetUint32(size_t byteOffset, uint32_t value) const { WriteData
(byteOffset, value); } template
inline T DataView::ReadData(size_t byteOffset) const { if (byteOffset + sizeof(T) > _length || byteOffset + sizeof(T) < byteOffset) { // overflow NAPI_THROW(RangeError::New(_env, "Offset is outside the bounds of the DataView"), 0); } return *reinterpret_cast
(static_cast
(_data) + byteOffset); } template
inline void DataView::WriteData(size_t byteOffset, T value) const { if (byteOffset + sizeof(T) > _length || byteOffset + sizeof(T) < byteOffset) { // overflow NAPI_THROW_VOID(RangeError::New(_env, "Offset is outside the bounds of the DataView")); } *reinterpret_cast
(static_cast
(_data) + byteOffset) = value; } //////////////////////////////////////////////////////////////////////////////// // TypedArray class //////////////////////////////////////////////////////////////////////////////// inline TypedArray::TypedArray() : Object(), _type(TypedArray::unknown_array_type), _length(0) { } inline TypedArray::TypedArray(napi_env env, napi_value value) : Object(env, value), _type(TypedArray::unknown_array_type), _length(0) { } inline TypedArray::TypedArray(napi_env env, napi_value value, napi_typedarray_type type, size_t length) : Object(env, value), _type(type), _length(length) { } inline napi_typedarray_type TypedArray::TypedArrayType() const { if (_type == TypedArray::unknown_array_type) { napi_status status = napi_get_typedarray_info(_env, _value, &const_cast
(this)->_type, &const_cast
(this)->_length, nullptr, nullptr, nullptr); NAPI_THROW_IF_FAILED(_env, status, napi_int8_array); } return _type; } inline uint8_t TypedArray::ElementSize() const { switch (TypedArrayType()) { case napi_int8_array: case napi_uint8_array: case napi_uint8_clamped_array: return 1; case napi_int16_array: case napi_uint16_array: return 2; case napi_int32_array: case napi_uint32_array: case napi_float32_array: return 4; case napi_float64_array: #if (NAPI_VERSION > 5) case napi_bigint64_array: case napi_biguint64_array: #endif // (NAPI_VERSION > 5) return 8; default: return 0; } } inline size_t TypedArray::ElementLength() const { if (_type == TypedArray::unknown_array_type) { napi_status status = napi_get_typedarray_info(_env, _value, &const_cast
(this)->_type, &const_cast
(this)->_length, nullptr, nullptr, nullptr); NAPI_THROW_IF_FAILED(_env, status, 0); } return _length; } inline size_t TypedArray::ByteOffset() const { size_t byteOffset; napi_status status = napi_get_typedarray_info( _env, _value, nullptr, nullptr, nullptr, nullptr, &byteOffset); NAPI_THROW_IF_FAILED(_env, status, 0); return byteOffset; } inline size_t TypedArray::ByteLength() const { return ElementSize() * ElementLength(); } inline Napi::ArrayBuffer TypedArray::ArrayBuffer() const { napi_value arrayBuffer; napi_status status = napi_get_typedarray_info( _env, _value, nullptr, nullptr, nullptr, &arrayBuffer, nullptr); NAPI_THROW_IF_FAILED(_env, status, Napi::ArrayBuffer()); return Napi::ArrayBuffer(_env, arrayBuffer); } //////////////////////////////////////////////////////////////////////////////// // TypedArrayOf
class //////////////////////////////////////////////////////////////////////////////// template
inline TypedArrayOf
TypedArrayOf
::New(napi_env env, size_t elementLength, napi_typedarray_type type) { Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New(env, elementLength * sizeof (T)); return New(env, elementLength, arrayBuffer, 0, type); } template
inline TypedArrayOf
TypedArrayOf
::New(napi_env env, size_t elementLength, Napi::ArrayBuffer arrayBuffer, size_t bufferOffset, napi_typedarray_type type) { napi_value value; napi_status status = napi_create_typedarray( env, type, elementLength, arrayBuffer, bufferOffset, &value); NAPI_THROW_IF_FAILED(env, status, TypedArrayOf
()); return TypedArrayOf
( env, value, type, elementLength, reinterpret_cast
(reinterpret_cast
(arrayBuffer.Data()) + bufferOffset)); } template
inline TypedArrayOf
::TypedArrayOf() : TypedArray(), _data(nullptr) { } template
inline TypedArrayOf
::TypedArrayOf(napi_env env, napi_value value) : TypedArray(env, value), _data(nullptr) { napi_status status = napi_ok; if (value != nullptr) { status = napi_get_typedarray_info( _env, _value, &_type, &_length, reinterpret_cast
(&_data), nullptr, nullptr); } else { _type = TypedArrayTypeForPrimitiveType
(); _length = 0; } NAPI_THROW_IF_FAILED_VOID(_env, status); } template
inline TypedArrayOf
::TypedArrayOf(napi_env env, napi_value value, napi_typedarray_type type, size_t length, T* data) : TypedArray(env, value, type, length), _data(data) { if (!(type == TypedArrayTypeForPrimitiveType
() || (type == napi_uint8_clamped_array && std::is_same
::value))) { NAPI_THROW_VOID(TypeError::New(env, "Array type must match the template parameter. " "(Uint8 arrays may optionally have the \"clamped\" array type.)")); } } template
inline T& TypedArrayOf
::operator [](size_t index) { return _data[index]; } template
inline const T& TypedArrayOf
::operator [](size_t index) const { return _data[index]; } template
inline T* TypedArrayOf
::Data() { return _data; } template
inline const T* TypedArrayOf
::Data() const { return _data; } //////////////////////////////////////////////////////////////////////////////// // Function class //////////////////////////////////////////////////////////////////////////////// template
static inline napi_status CreateFunction(napi_env env, const char* utf8name, napi_callback cb, CbData* data, napi_value* result) { napi_status status = napi_create_function(env, utf8name, NAPI_AUTO_LENGTH, cb, data, result); if (status == napi_ok) { status = Napi::details::AttachData(env, *result, data); } return status; } template
inline Function Function::New(napi_env env, const char* utf8name, void* data) { napi_value result = nullptr; napi_status status = napi_create_function(env, utf8name, NAPI_AUTO_LENGTH, details::TemplatedVoidCallback
, data, &result); NAPI_THROW_IF_FAILED(env, status, Function()); return Function(env, result); } template
inline Function Function::New(napi_env env, const char* utf8name, void* data) { napi_value result = nullptr; napi_status status = napi_create_function(env, utf8name, NAPI_AUTO_LENGTH, details::TemplatedCallback
, data, &result); NAPI_THROW_IF_FAILED(env, status, Function()); return Function(env, result); } template
inline Function Function::New(napi_env env, const std::string& utf8name, void* data) { return Function::New
(env, utf8name.c_str(), data); } template
inline Function Function::New(napi_env env, const std::string& utf8name, void* data) { return Function::New
(env, utf8name.c_str(), data); } template
inline Function Function::New(napi_env env, Callable cb, const char* utf8name, void* data) { using ReturnType = decltype(cb(CallbackInfo(nullptr, nullptr))); using CbData = details::CallbackData
; auto callbackData = new CbData({ cb, data }); napi_value value; napi_status status = CreateFunction(env, utf8name, CbData::Wrapper, callbackData, &value); if (status != napi_ok) { delete callbackData; NAPI_THROW_IF_FAILED(env, status, Function()); } return Function(env, value); } template
inline Function Function::New(napi_env env, Callable cb, const std::string& utf8name, void* data) { return New(env, cb, utf8name.c_str(), data); } inline Function::Function() : Object() { } inline Function::Function(napi_env env, napi_value value) : Object(env, value) { } inline Value Function::operator ()(const std::initializer_list
& args) const { return Call(Env().Undefined(), args); } inline Value Function::Call(const std::initializer_list
& args) const { return Call(Env().Undefined(), args); } inline Value Function::Call(const std::vector
& args) const { return Call(Env().Undefined(), args); } inline Value Function::Call(size_t argc, const napi_value* args) const { return Call(Env().Undefined(), argc, args); } inline Value Function::Call(napi_value recv, const std::initializer_list
& args) const { return Call(recv, args.size(), args.begin()); } inline Value Function::Call(napi_value recv, const std::vector
& args) const { return Call(recv, args.size(), args.data()); } inline Value Function::Call(napi_value recv, size_t argc, const napi_value* args) const { napi_value result; napi_status status = napi_call_function( _env, recv, _value, argc, args, &result); NAPI_THROW_IF_FAILED(_env, status, Value()); return Value(_env, result); } inline Value Function::MakeCallback( napi_value recv, const std::initializer_list
& args, napi_async_context context) const { return MakeCallback(recv, args.size(), args.begin(), context); } inline Value Function::MakeCallback( napi_value recv, const std::vector
& args, napi_async_context context) const { return MakeCallback(recv, args.size(), args.data(), context); } inline Value Function::MakeCallback( napi_value recv, size_t argc, const napi_value* args, napi_async_context context) const { napi_value result; napi_status status = napi_make_callback( _env, context, recv, _value, argc, args, &result); NAPI_THROW_IF_FAILED(_env, status, Value()); return Value(_env, result); } inline Object Function::New(const std::initializer_list
& args) const { return New(args.size(), args.begin()); } inline Object Function::New(const std::vector
& args) const { return New(args.size(), args.data()); } inline Object Function::New(size_t argc, const napi_value* args) const { napi_value result; napi_status status = napi_new_instance( _env, _value, argc, args, &result); NAPI_THROW_IF_FAILED(_env, status, Object()); return Object(_env, result); } //////////////////////////////////////////////////////////////////////////////// // Promise class //////////////////////////////////////////////////////////////////////////////// inline Promise::Deferred Promise::Deferred::New(napi_env env) { return Promise::Deferred(env); } inline Promise::Deferred::Deferred(napi_env env) : _env(env) { napi_status status = napi_create_promise(_env, &_deferred, &_promise); NAPI_THROW_IF_FAILED_VOID(_env, status); } inline Promise Promise::Deferred::Promise() const { return Napi::Promise(_env, _promise); } inline Napi::Env Promise::Deferred::Env() const { return Napi::Env(_env); } inline void Promise::Deferred::Resolve(napi_value value) const { napi_status status = napi_resolve_deferred(_env, _deferred, value); NAPI_THROW_IF_FAILED_VOID(_env, status); } inline void Promise::Deferred::Reject(napi_value value) const { napi_status status = napi_reject_deferred(_env, _deferred, value); NAPI_THROW_IF_FAILED_VOID(_env, status); } inline Promise::Promise(napi_env env, napi_value value) : Object(env, value) { } //////////////////////////////////////////////////////////////////////////////// // Buffer
class //////////////////////////////////////////////////////////////////////////////// template
inline Buffer
Buffer
::New(napi_env env, size_t length) { napi_value value; void* data; napi_status status = napi_create_buffer(env, length * sizeof (T), &data, &value); NAPI_THROW_IF_FAILED(env, status, Buffer
()); return Buffer(env, value, length, static_cast
(data)); } template
inline Buffer
Buffer
::New(napi_env env, T* data, size_t length) { napi_value value; napi_status status = napi_create_external_buffer( env, length * sizeof (T), data, nullptr, nullptr, &value); NAPI_THROW_IF_FAILED(env, status, Buffer
()); return Buffer(env, value, length, data); } template
template
inline Buffer
Buffer
::New(napi_env env, T* data, size_t length, Finalizer finalizeCallback) { napi_value value; details::FinalizeData
* finalizeData = new details::FinalizeData
( {std::move(finalizeCallback), nullptr}); napi_status status = napi_create_external_buffer( env, length * sizeof (T), data, details::FinalizeData
::Wrapper, finalizeData, &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, Buffer()); } return Buffer(env, value, length, data); } template
template
inline Buffer
Buffer
::New(napi_env env, T* data, size_t length, Finalizer finalizeCallback, Hint* finalizeHint) { napi_value value; details::FinalizeData
* finalizeData = new details::FinalizeData
( {std::move(finalizeCallback), finalizeHint}); napi_status status = napi_create_external_buffer( env, length * sizeof (T), data, details::FinalizeData
::WrapperWithHint, finalizeData, &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, Buffer()); } return Buffer(env, value, length, data); } template
inline Buffer
Buffer
::Copy(napi_env env, const T* data, size_t length) { napi_value value; napi_status status = napi_create_buffer_copy( env, length * sizeof (T), data, nullptr, &value); NAPI_THROW_IF_FAILED(env, status, Buffer