| #ifndef SRC_NAPI_H_ |
| #define SRC_NAPI_H_ |
| |
| #ifndef NAPI_HAS_THREADS |
| #if !defined(__wasm__) || (defined(__EMSCRIPTEN_PTHREADS__) || \ |
| (defined(__wasi__) && defined(_REENTRANT))) |
| #define NAPI_HAS_THREADS 1 |
| #else |
| #define NAPI_HAS_THREADS 0 |
| #endif |
| #endif |
| |
| #include <node_api.h> |
| #include <functional> |
| #include <initializer_list> |
| #include <memory> |
| #if NAPI_HAS_THREADS |
| #include <mutex> |
| #endif // NAPI_HAS_THREADS |
| #include <string> |
| #include <vector> |
| |
| // VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known |
| // good version) |
| #if !defined(_MSC_VER) || _MSC_FULL_VER >= 190024210 |
| #define NAPI_HAS_CONSTEXPR 1 |
| #endif |
| |
| // VS2013 does not support char16_t literal strings, so we'll work around it |
| // using wchar_t strings and casting them. This is safe as long as the character |
| // sizes are the same. |
| #if defined(_MSC_VER) && _MSC_VER <= 1800 |
| static_assert(sizeof(char16_t) == sizeof(wchar_t), |
| "Size mismatch between char16_t and wchar_t"); |
| #define NAPI_WIDE_TEXT(x) reinterpret_cast<char16_t*>(L##x) |
| #else |
| #define NAPI_WIDE_TEXT(x) u##x |
| #endif |
| |
| // Backwards-compatibility to handle the rename of this macro definition, in |
| // case they are used within userland code. |
| #ifdef NAPI_CPP_EXCEPTIONS |
| #define NODE_ADDON_API_CPP_EXCEPTIONS |
| #endif |
| #if defined(NODE_ADDON_API_CPP_EXCEPTIONS) && !defined(NAPI_CPP_EXCEPTIONS) |
| #define NAPI_CPP_EXCEPTIONS |
| #endif |
| #ifdef NAPI_DISABLE_CPP_EXCEPTIONS |
| #define NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS |
| #endif |
| #if defined(NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS) && \ |
| !defined(NAPI_DISABLE_CPP_EXCEPTIONS) |
| #define NAPI_DISABLE_CPP_EXCEPTIONS |
| #endif |
| |
| // If C++ exceptions are not explicitly enabled or disabled, enable them |
| // if exceptions were enabled in the compiler settings. |
| #if !defined(NODE_ADDON_API_CPP_EXCEPTIONS) && \ |
| !defined(NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS) |
| #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) |
| #define NODE_ADDON_API_CPP_EXCEPTIONS |
| #else |
| #error Exception support not detected. \ |
| Define either NODE_ADDON_API_CPP_EXCEPTIONS or NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS. |
| #endif |
| #endif |
| |
| // If C++ NODE_ADDON_API_CPP_EXCEPTIONS are enabled, NODE_ADDON_API_ENABLE_MAYBE |
| // should not be set |
| #if defined(NODE_ADDON_API_CPP_EXCEPTIONS) && \ |
| defined(NODE_ADDON_API_ENABLE_MAYBE) |
| #error NODE_ADDON_API_ENABLE_MAYBE should not be set when \ |
| NODE_ADDON_API_CPP_EXCEPTIONS is defined. |
| #endif |
| |
| #ifdef _NOEXCEPT |
| #define NAPI_NOEXCEPT _NOEXCEPT |
| #else |
| #define NAPI_NOEXCEPT noexcept |
| #endif |
| |
| #ifdef NODE_ADDON_API_CPP_EXCEPTIONS |
| |
| // When C++ exceptions are enabled, Errors are thrown directly. There is no need |
| // to return anything after the throw statements. The variadic parameter is an |
| // optional return value that is ignored. |
| // We need _VOID versions of the macros to avoid warnings resulting from |
| // leaving the NAPI_THROW_* `...` argument empty. |
| |
| #define NAPI_THROW(e, ...) throw e |
| #define NAPI_THROW_VOID(e) throw e |
| |
| #define NAPI_THROW_IF_FAILED(env, status, ...) \ |
| if ((status) != napi_ok) throw Napi::Error::New(env); |
| |
| #define NAPI_THROW_IF_FAILED_VOID(env, status) \ |
| if ((status) != napi_ok) throw Napi::Error::New(env); |
| |
| #else // NODE_ADDON_API_CPP_EXCEPTIONS |
| |
| // When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions, |
| // which are pending until the callback returns to JS. The variadic parameter |
| // is an optional return value; usually it is an empty result. |
| // We need _VOID versions of the macros to avoid warnings resulting from |
| // leaving the NAPI_THROW_* `...` argument empty. |
| |
| #define NAPI_THROW(e, ...) \ |
| do { \ |
| (e).ThrowAsJavaScriptException(); \ |
| return __VA_ARGS__; \ |
| } while (0) |
| |
| #define NAPI_THROW_VOID(e) \ |
| do { \ |
| (e).ThrowAsJavaScriptException(); \ |
| return; \ |
| } while (0) |
| |
| #define NAPI_THROW_IF_FAILED(env, status, ...) \ |
| if ((status) != napi_ok) { \ |
| Napi::Error::New(env).ThrowAsJavaScriptException(); \ |
| return __VA_ARGS__; \ |
| } |
| |
| #define NAPI_THROW_IF_FAILED_VOID(env, status) \ |
| if ((status) != napi_ok) { \ |
| Napi::Error::New(env).ThrowAsJavaScriptException(); \ |
| return; \ |
| } |
| |
| #endif // NODE_ADDON_API_CPP_EXCEPTIONS |
| |
| #ifdef NODE_ADDON_API_ENABLE_MAYBE |
| #define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \ |
| NAPI_THROW_IF_FAILED(env, status, Napi::Nothing<type>()) |
| |
| #define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \ |
| NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \ |
| return Napi::Just<type>(result); |
| #else |
| #define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \ |
| NAPI_THROW_IF_FAILED(env, status, type()) |
| |
| #define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \ |
| NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \ |
| return result; |
| #endif |
| |
| #define NAPI_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete; |
| #define NAPI_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete; |
| |
| #define NAPI_DISALLOW_ASSIGN_COPY(CLASS) \ |
| NAPI_DISALLOW_ASSIGN(CLASS) \ |
| NAPI_DISALLOW_COPY(CLASS) |
| |
| #define NAPI_CHECK(condition, location, message) \ |
| do { \ |
| if (!(condition)) { \ |
| Napi::Error::Fatal((location), (message)); \ |
| } \ |
| } while (0) |
| |
| // Internal check helper. Be careful that the formatted message length should be |
| // max 255 size and null terminated. |
| #define NAPI_INTERNAL_CHECK(expr, location, ...) \ |
| do { \ |
| if (!(expr)) { \ |
| std::string msg = Napi::details::StringFormat(__VA_ARGS__); \ |
| Napi::Error::Fatal(location, msg.c_str()); \ |
| } \ |
| } while (0) |
| |
| #define NAPI_INTERNAL_CHECK_EQ(actual, expected, value_format, location) \ |
| do { \ |
| auto actual_value = (actual); \ |
| NAPI_INTERNAL_CHECK(actual_value == (expected), \ |
| location, \ |
| "Expected " #actual " to be equal to " #expected \ |
| ", but got " value_format ".", \ |
| actual_value); \ |
| } while (0) |
| |
| #define NAPI_FATAL_IF_FAILED(status, location, message) \ |
| NAPI_CHECK((status) == napi_ok, location, message) |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// Node-API C++ Wrapper Classes |
| /// |
| /// These classes wrap the "Node-API" ABI-stable C APIs for Node.js, providing a |
| /// C++ object model and C++ exception-handling semantics with low overhead. |
| /// The wrappers are all header-only so that they do not affect the ABI. |
| //////////////////////////////////////////////////////////////////////////////// |
| namespace Napi { |
| |
| #ifdef NAPI_CPP_CUSTOM_NAMESPACE |
| // NAPI_CPP_CUSTOM_NAMESPACE can be #define'd per-addon to avoid symbol |
| // conflicts between different instances of node-addon-api |
| |
| // First dummy definition of the namespace to make sure that Napi::(name) still |
| // refers to the right things inside this file. |
| namespace NAPI_CPP_CUSTOM_NAMESPACE {} |
| using namespace NAPI_CPP_CUSTOM_NAMESPACE; |
| |
| namespace NAPI_CPP_CUSTOM_NAMESPACE { |
| #endif |
| |
| // Forward declarations |
| class Env; |
| class Value; |
| class Boolean; |
| class Number; |
| #if NAPI_VERSION > 5 |
| class BigInt; |
| #endif // NAPI_VERSION > 5 |
| #if (NAPI_VERSION > 4) |
| class Date; |
| #endif |
| class String; |
| class Object; |
| class Array; |
| class ArrayBuffer; |
| class Function; |
| class Error; |
| class PropertyDescriptor; |
| class CallbackInfo; |
| class TypedArray; |
| template <typename T> |
| class TypedArrayOf; |
| |
| using Int8Array = |
| TypedArrayOf<int8_t>; ///< Typed-array of signed 8-bit integers |
| using Uint8Array = |
| TypedArrayOf<uint8_t>; ///< Typed-array of unsigned 8-bit integers |
| using Int16Array = |
| TypedArrayOf<int16_t>; ///< Typed-array of signed 16-bit integers |
| using Uint16Array = |
| TypedArrayOf<uint16_t>; ///< Typed-array of unsigned 16-bit integers |
| using Int32Array = |
| TypedArrayOf<int32_t>; ///< Typed-array of signed 32-bit integers |
| using Uint32Array = |
| TypedArrayOf<uint32_t>; ///< Typed-array of unsigned 32-bit integers |
| using Float32Array = |
| TypedArrayOf<float>; ///< Typed-array of 32-bit floating-point values |
| using Float64Array = |
| TypedArrayOf<double>; ///< Typed-array of 64-bit floating-point values |
| #if NAPI_VERSION > 5 |
| using BigInt64Array = |
| TypedArrayOf<int64_t>; ///< Typed array of signed 64-bit integers |
| using BigUint64Array = |
| TypedArrayOf<uint64_t>; ///< Typed array of unsigned 64-bit integers |
| #endif // NAPI_VERSION > 5 |
| |
| /// Defines the signature of a Node-API C++ module's registration callback |
| /// (init) function. |
| using ModuleRegisterCallback = Object (*)(Env env, Object exports); |
| |
| class MemoryManagement; |
| |
| /// A simple Maybe type, representing an object which may or may not have a |
| /// value. |
| /// |
| /// If an API method returns a Maybe<>, the API method can potentially fail |
| /// either because an exception is thrown, or because an exception is pending, |
| /// e.g. because a previous API call threw an exception that hasn't been |
| /// caught yet. In that case, a "Nothing" value is returned. |
| template <class T> |
| class Maybe { |
| public: |
| bool IsNothing() const; |
| bool IsJust() const; |
| |
| /// Short-hand for Unwrap(), which doesn't return a value. Could be used |
| /// where the actual value of the Maybe is not needed like Object::Set. |
| /// If this Maybe is nothing (empty), node-addon-api will crash the |
| /// process. |
| void Check() const; |
| |
| /// Return the value of type T contained in the Maybe. If this Maybe is |
| /// nothing (empty), node-addon-api will crash the process. |
| T Unwrap() const; |
| |
| /// Return the value of type T contained in the Maybe, or using a default |
| /// value if this Maybe is nothing (empty). |
| T UnwrapOr(const T& default_value) const; |
| |
| /// Converts this Maybe to a value of type T in the out. If this Maybe is |
| /// nothing (empty), `false` is returned and `out` is left untouched. |
| bool UnwrapTo(T* out) const; |
| |
| bool operator==(const Maybe& other) const; |
| bool operator!=(const Maybe& other) const; |
| |
| private: |
| Maybe(); |
| explicit Maybe(const T& t); |
| |
| bool _has_value; |
| T _value; |
| |
| template <class U> |
| friend Maybe<U> Nothing(); |
| template <class U> |
| friend Maybe<U> Just(const U& u); |
| }; |
| |
| template <class T> |
| inline Maybe<T> Nothing(); |
| |
| template <class T> |
| inline Maybe<T> Just(const T& t); |
| |
| #if defined(NODE_ADDON_API_ENABLE_MAYBE) |
| template <typename T> |
| using MaybeOrValue = Maybe<T>; |
| #else |
| template <typename T> |
| using MaybeOrValue = T; |
| #endif |
| |
| #ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER |
| using node_addon_api_basic_env = node_api_nogc_env; |
| using node_addon_api_basic_finalize = node_api_nogc_finalize; |
| #else |
| using node_addon_api_basic_env = napi_env; |
| using node_addon_api_basic_finalize = napi_finalize; |
| #endif |
| |
| /// Environment for Node-API values and operations. |
| /// |
| /// All Node-API values and operations must be associated with an environment. |
| /// An environment instance is always provided to callback functions; that |
| /// environment must then be used for any creation of Node-API values or other |
| /// Node-API operations within the callback. (Many methods infer the |
| /// environment from the `this` instance that the method is called on.) |
| /// |
| /// Multiple environments may co-exist in a single process or a thread. |
| /// |
| /// In the V8 JavaScript engine, a Node-API environment approximately |
| /// corresponds to an Isolate. |
| class BasicEnv { |
| private: |
| node_addon_api_basic_env _env; |
| #if NAPI_VERSION > 5 |
| template <typename T> |
| static void DefaultFini(Env, T* data); |
| template <typename DataType, typename HintType> |
| static void DefaultFiniWithHint(Env, DataType* data, HintType* hint); |
| #endif // NAPI_VERSION > 5 |
| public: |
| BasicEnv(node_addon_api_basic_env env); |
| |
| operator node_addon_api_basic_env() const; |
| |
| // Without these operator overloads, the error: |
| // |
| // Use of overloaded operator '==' is ambiguous (with operand types |
| // 'Napi::Env' and 'Napi::Env') |
| // |
| // ... occurs when comparing foo.Env() == bar.Env() or foo.Env() == nullptr |
| bool operator==(const BasicEnv& other) const { |
| return _env == other._env; |
| }; |
| bool operator==(std::nullptr_t /*other*/) const { |
| return _env == nullptr; |
| }; |
| |
| #if NAPI_VERSION > 2 |
| template <typename Hook, typename Arg = void> |
| class CleanupHook; |
| |
| template <typename Hook> |
| CleanupHook<Hook> AddCleanupHook(Hook hook); |
| |
| template <typename Hook, typename Arg> |
| CleanupHook<Hook, Arg> AddCleanupHook(Hook hook, Arg* arg); |
| #endif // NAPI_VERSION > 2 |
| |
| #if NAPI_VERSION > 5 |
| template <typename T> |
| T* GetInstanceData() const; |
| |
| template <typename T> |
| using Finalizer = void (*)(Env, T*); |
| template <typename T, Finalizer<T> fini = BasicEnv::DefaultFini<T>> |
| void SetInstanceData(T* data) const; |
| |
| template <typename DataType, typename HintType> |
| using FinalizerWithHint = void (*)(Env, DataType*, HintType*); |
| template <typename DataType, |
| typename HintType, |
| FinalizerWithHint<DataType, HintType> fini = |
| BasicEnv::DefaultFiniWithHint<DataType, HintType>> |
| void SetInstanceData(DataType* data, HintType* hint) const; |
| #endif // NAPI_VERSION > 5 |
| |
| #if NAPI_VERSION > 2 |
| template <typename Hook, typename Arg> |
| class CleanupHook { |
| public: |
| CleanupHook(); |
| CleanupHook(BasicEnv env, Hook hook, Arg* arg); |
| CleanupHook(BasicEnv env, Hook hook); |
| bool Remove(BasicEnv env); |
| bool IsEmpty() const; |
| |
| private: |
| static inline void Wrapper(void* data) NAPI_NOEXCEPT; |
| static inline void WrapperWithArg(void* data) NAPI_NOEXCEPT; |
| |
| void (*wrapper)(void* arg); |
| struct CleanupData { |
| Hook hook; |
| Arg* arg; |
| } * data; |
| }; |
| #endif // NAPI_VERSION > 2 |
| |
| #if NAPI_VERSION > 8 |
| const char* GetModuleFileName() const; |
| #endif // NAPI_VERSION > 8 |
| |
| #ifdef NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER |
| template <typename FinalizerType> |
| inline void PostFinalizer(FinalizerType finalizeCallback) const; |
| |
| template <typename FinalizerType, typename T> |
| inline void PostFinalizer(FinalizerType finalizeCallback, T* data) const; |
| |
| template <typename FinalizerType, typename T, typename Hint> |
| inline void PostFinalizer(FinalizerType finalizeCallback, |
| T* data, |
| Hint* finalizeHint) const; |
| #endif // NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER |
| |
| friend class Env; |
| }; |
| |
| class Env : public BasicEnv { |
| public: |
| Env(napi_env env); |
| |
| operator napi_env() const; |
| |
| Object Global() const; |
| Value Undefined() const; |
| Value Null() const; |
| |
| bool IsExceptionPending() const; |
| Error GetAndClearPendingException() const; |
| |
| MaybeOrValue<Value> RunScript(const char* utf8script) const; |
| MaybeOrValue<Value> RunScript(const std::string& utf8script) const; |
| MaybeOrValue<Value> RunScript(String script) const; |
| }; |
| |
| /// A JavaScript value of unknown type. |
| /// |
| /// For type-specific operations, convert to one of the Value subclasses using a |
| /// `To*` or `As()` method. The `To*` methods do type coercion; the `As()` |
| /// method does not. |
| /// |
| /// Napi::Value value = ... |
| /// if (!value.IsString()) throw Napi::TypeError::New(env, "Invalid |
| /// arg..."); Napi::String str = value.As<Napi::String>(); // Cast to a |
| /// string value |
| /// |
| /// Napi::Value anotherValue = ... |
| /// bool isTruthy = anotherValue.ToBoolean(); // Coerce to a boolean value |
| class Value { |
| public: |
| Value(); ///< Creates a new _empty_ Value instance. |
| Value(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| /// Creates a JS value from a C++ primitive. |
| /// |
| /// `value` may be any of: |
| /// - bool |
| /// - Any integer type |
| /// - Any floating point type |
| /// - const char* (encoded using UTF-8, null-terminated) |
| /// - const char16_t* (encoded using UTF-16-LE, null-terminated) |
| /// - std::string (encoded using UTF-8) |
| /// - std::u16string |
| /// - napi::Value |
| /// - napi_value |
| template <typename T> |
| static Value From(napi_env env, const T& value); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| /// Converts to a Node-API value primitive. |
| /// |
| /// If the instance is _empty_, this returns `nullptr`. |
| operator napi_value() const; |
| |
| /// Tests if this value strictly equals another value. |
| bool operator==(const Value& other) const; |
| |
| /// Tests if this value does not strictly equal another value. |
| bool operator!=(const Value& other) const; |
| |
| /// Tests if this value strictly equals another value. |
| bool StrictEquals(const Value& other) const; |
| |
| /// Gets the environment the value is associated with. |
| Napi::Env Env() const; |
| |
| /// Checks if the value is empty (uninitialized). |
| /// |
| /// An empty value is invalid, and most attempts to perform an operation on an |
| /// empty value will result in an exception. Note an empty value is distinct |
| /// from JavaScript `null` or `undefined`, which are valid values. |
| /// |
| /// When C++ exceptions are disabled at compile time, a method with a `Value` |
| /// return type may return an empty value to indicate a pending exception. So |
| /// when not using C++ exceptions, callers should check whether the value is |
| /// empty before attempting to use it. |
| bool IsEmpty() const; |
| |
| napi_valuetype Type() const; ///< Gets the type of the value. |
| |
| bool IsUndefined() |
| const; ///< Tests if a value is an undefined JavaScript value. |
| bool IsNull() const; ///< Tests if a value is a null JavaScript value. |
| bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean. |
| bool IsNumber() const; ///< Tests if a value is a JavaScript number. |
| #if NAPI_VERSION > 5 |
| bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint. |
| #endif // NAPI_VERSION > 5 |
| #if (NAPI_VERSION > 4) |
| bool IsDate() const; ///< Tests if a value is a JavaScript date. |
| #endif |
| bool IsString() const; ///< Tests if a value is a JavaScript string. |
| bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol. |
| bool IsArray() const; ///< Tests if a value is a JavaScript array. |
| bool IsArrayBuffer() |
| const; ///< Tests if a value is a JavaScript array buffer. |
| bool IsTypedArray() const; ///< Tests if a value is a JavaScript typed array. |
| bool IsObject() const; ///< Tests if a value is a JavaScript object. |
| bool IsFunction() const; ///< Tests if a value is a JavaScript function. |
| bool IsPromise() const; ///< Tests if a value is a JavaScript promise. |
| bool IsDataView() const; ///< Tests if a value is a JavaScript data view. |
| bool IsBuffer() const; ///< Tests if a value is a Node buffer. |
| bool IsExternal() const; ///< Tests if a value is a pointer to external data. |
| |
| /// Casts to another type of `Napi::Value`, when the actual type is known or |
| /// assumed. |
| /// |
| /// This conversion does NOT coerce the type. Calling any methods |
| /// inappropriate for the actual value type will throw `Napi::Error`. |
| /// |
| /// If `NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS` is defined, this method |
| /// asserts that the actual type is the expected type. |
| template <typename T> |
| T As() const; |
| |
| // Unsafe Value::As(), should be avoided. |
| template <typename T> |
| T UnsafeAs() const; |
| |
| MaybeOrValue<Boolean> ToBoolean() |
| const; ///< Coerces a value to a JavaScript boolean. |
| MaybeOrValue<Number> ToNumber() |
| const; ///< Coerces a value to a JavaScript number. |
| MaybeOrValue<String> ToString() |
| const; ///< Coerces a value to a JavaScript string. |
| MaybeOrValue<Object> ToObject() |
| const; ///< Coerces a value to a JavaScript object. |
| |
| protected: |
| /// !cond INTERNAL |
| napi_env _env; |
| napi_value _value; |
| /// !endcond |
| }; |
| |
| /// A JavaScript boolean value. |
| class Boolean : public Value { |
| public: |
| static Boolean New(napi_env env, ///< Node-API environment |
| bool value ///< Boolean value |
| ); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Boolean(); ///< Creates a new _empty_ Boolean instance. |
| Boolean(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| operator bool() const; ///< Converts a Boolean value to a boolean primitive. |
| bool Value() const; ///< Converts a Boolean value to a boolean primitive. |
| }; |
| |
| /// A JavaScript number value. |
| class Number : public Value { |
| public: |
| static Number New(napi_env env, ///< Node-API environment |
| double value ///< Number value |
| ); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Number(); ///< Creates a new _empty_ Number instance. |
| Number(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| operator int32_t() |
| const; ///< Converts a Number value to a 32-bit signed integer value. |
| operator uint32_t() |
| const; ///< Converts a Number value to a 32-bit unsigned integer value. |
| operator int64_t() |
| const; ///< Converts a Number value to a 64-bit signed integer value. |
| operator float() |
| const; ///< Converts a Number value to a 32-bit floating-point value. |
| operator double() |
| const; ///< Converts a Number value to a 64-bit floating-point value. |
| |
| int32_t Int32Value() |
| const; ///< Converts a Number value to a 32-bit signed integer value. |
| uint32_t Uint32Value() |
| const; ///< Converts a Number value to a 32-bit unsigned integer value. |
| int64_t Int64Value() |
| const; ///< Converts a Number value to a 64-bit signed integer value. |
| float FloatValue() |
| const; ///< Converts a Number value to a 32-bit floating-point value. |
| double DoubleValue() |
| const; ///< Converts a Number value to a 64-bit floating-point value. |
| }; |
| |
| #if NAPI_VERSION > 5 |
| /// A JavaScript bigint value. |
| class BigInt : public Value { |
| public: |
| static BigInt New(napi_env env, ///< Node-API environment |
| int64_t value ///< Number value |
| ); |
| static BigInt New(napi_env env, ///< Node-API environment |
| uint64_t value ///< Number value |
| ); |
| |
| /// Creates a new BigInt object using a specified sign bit and a |
| /// specified list of digits/words. |
| /// The resulting number is calculated as: |
| /// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...) |
| static BigInt New(napi_env env, ///< Node-API environment |
| int sign_bit, ///< Sign bit. 1 if negative. |
| size_t word_count, ///< Number of words in array |
| const uint64_t* words ///< Array of words |
| ); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| BigInt(); ///< Creates a new _empty_ BigInt instance. |
| BigInt(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| int64_t Int64Value(bool* lossless) |
| const; ///< Converts a BigInt value to a 64-bit signed integer value. |
| uint64_t Uint64Value(bool* lossless) |
| const; ///< Converts a BigInt value to a 64-bit unsigned integer value. |
| |
| size_t WordCount() const; ///< The number of 64-bit words needed to store |
| ///< the result of ToWords(). |
| |
| /// Writes the contents of this BigInt to a specified memory location. |
| /// `sign_bit` must be provided and will be set to 1 if this BigInt is |
| /// negative. |
| /// `*word_count` has to be initialized to the length of the `words` array. |
| /// Upon return, it will be set to the actual number of words that would |
| /// be needed to store this BigInt (i.e. the return value of `WordCount()`). |
| void ToWords(int* sign_bit, size_t* word_count, uint64_t* words); |
| }; |
| #endif // NAPI_VERSION > 5 |
| |
| #if (NAPI_VERSION > 4) |
| /// A JavaScript date value. |
| class Date : public Value { |
| public: |
| /// Creates a new Date value from a double primitive. |
| static Date New(napi_env env, ///< Node-API environment |
| double value ///< Number value |
| ); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Date(); ///< Creates a new _empty_ Date instance. |
| Date(napi_env env, napi_value value); ///< Wraps a Node-API value primitive. |
| operator double() const; ///< Converts a Date value to double primitive |
| |
| double ValueOf() const; ///< Converts a Date value to a double primitive. |
| }; |
| #endif |
| |
| /// A JavaScript string or symbol value (that can be used as a property name). |
| class Name : public Value { |
| public: |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Name(); ///< Creates a new _empty_ Name instance. |
| Name(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| }; |
| |
| /// A JavaScript string value. |
| class String : public Name { |
| public: |
| /// Creates a new String value from a UTF-8 encoded C++ string. |
| static String New(napi_env env, ///< Node-API environment |
| const std::string& value ///< UTF-8 encoded C++ string |
| ); |
| |
| /// Creates a new String value from a UTF-16 encoded C++ string. |
| static String New(napi_env env, ///< Node-API environment |
| const std::u16string& value ///< UTF-16 encoded C++ string |
| ); |
| |
| /// Creates a new String value from a UTF-8 encoded C string. |
| static String New( |
| napi_env env, ///< Node-API environment |
| const char* value ///< UTF-8 encoded null-terminated C string |
| ); |
| |
| /// Creates a new String value from a UTF-16 encoded C string. |
| static String New( |
| napi_env env, ///< Node-API environment |
| const char16_t* value ///< UTF-16 encoded null-terminated C string |
| ); |
| |
| /// Creates a new String value from a UTF-8 encoded C string with specified |
| /// length. |
| static String New(napi_env env, ///< Node-API environment |
| const char* value, ///< UTF-8 encoded C string (not |
| ///< necessarily null-terminated) |
| size_t length ///< length of the string in bytes |
| ); |
| |
| /// Creates a new String value from a UTF-16 encoded C string with specified |
| /// length. |
| static String New( |
| napi_env env, ///< Node-API environment |
| const char16_t* value, ///< UTF-16 encoded C string (not necessarily |
| ///< null-terminated) |
| size_t length ///< Length of the string in 2-byte code units |
| ); |
| |
| /// Creates a new String based on the original object's type. |
| /// |
| /// `value` may be any of: |
| /// - const char* (encoded using UTF-8, null-terminated) |
| /// - const char16_t* (encoded using UTF-16-LE, null-terminated) |
| /// - std::string (encoded using UTF-8) |
| /// - std::u16string |
| template <typename T> |
| static String From(napi_env env, const T& value); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| String(); ///< Creates a new _empty_ String instance. |
| String(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| operator std::string() |
| const; ///< Converts a String value to a UTF-8 encoded C++ string. |
| operator std::u16string() |
| const; ///< Converts a String value to a UTF-16 encoded C++ string. |
| std::string Utf8Value() |
| const; ///< Converts a String value to a UTF-8 encoded C++ string. |
| std::u16string Utf16Value() |
| const; ///< Converts a String value to a UTF-16 encoded C++ string. |
| }; |
| |
| /// A JavaScript symbol value. |
| class Symbol : public Name { |
| public: |
| /// Creates a new Symbol value with an optional description. |
| static Symbol New( |
| napi_env env, ///< Node-API environment |
| const char* description = |
| nullptr ///< Optional UTF-8 encoded null-terminated C string |
| /// describing the symbol |
| ); |
| |
| /// Creates a new Symbol value with a description. |
| static Symbol New( |
| napi_env env, ///< Node-API environment |
| const std::string& |
| description ///< UTF-8 encoded C++ string describing the symbol |
| ); |
| |
| /// Creates a new Symbol value with a description. |
| static Symbol New(napi_env env, ///< Node-API environment |
| String description ///< String value describing the symbol |
| ); |
| |
| /// Creates a new Symbol value with a description. |
| static Symbol New( |
| napi_env env, ///< Node-API environment |
| napi_value description ///< String value describing the symbol |
| ); |
| |
| /// Get a public Symbol (e.g. Symbol.iterator). |
| static MaybeOrValue<Symbol> WellKnown(napi_env, const std::string& name); |
| |
| // Create a symbol in the global registry, UTF-8 Encoded cpp string |
| static MaybeOrValue<Symbol> For(napi_env env, const std::string& description); |
| |
| // Create a symbol in the global registry, C style string (null terminated) |
| static MaybeOrValue<Symbol> For(napi_env env, const char* description); |
| |
| // Create a symbol in the global registry, String value describing the symbol |
| static MaybeOrValue<Symbol> For(napi_env env, String description); |
| |
| // Create a symbol in the global registry, napi_value describing the symbol |
| static MaybeOrValue<Symbol> For(napi_env env, napi_value description); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Symbol(); ///< Creates a new _empty_ Symbol instance. |
| Symbol(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| }; |
| |
| class TypeTaggable : public Value { |
| public: |
| #if NAPI_VERSION >= 8 |
| void TypeTag(const napi_type_tag* type_tag) const; |
| bool CheckTypeTag(const napi_type_tag* type_tag) const; |
| #endif // NAPI_VERSION >= 8 |
| protected: |
| TypeTaggable(); |
| TypeTaggable(napi_env env, napi_value value); |
| }; |
| |
| /// A JavaScript object value. |
| class Object : public TypeTaggable { |
| public: |
| /// Enables property and element assignments using indexing syntax. |
| /// |
| /// This is a convenient helper to get and set object properties. As |
| /// getting and setting object properties may throw with JavaScript |
| /// exceptions, it is notable that these operations may fail. |
| /// When NODE_ADDON_API_ENABLE_MAYBE is defined, the process will abort |
| /// on JavaScript exceptions. |
| /// |
| /// Example: |
| /// |
| /// Napi::Value propertyValue = object1['A']; |
| /// object2['A'] = propertyValue; |
| /// Napi::Value elementValue = array[0]; |
| /// array[1] = elementValue; |
| template <typename Key> |
| class PropertyLValue { |
| public: |
| /// Converts an L-value to a value. |
| operator Value() const; |
| |
| /// Assigns a value to the property. The type of value can be |
| /// anything supported by `Object::Set`. |
| template <typename ValueType> |
| PropertyLValue& operator=(ValueType value); |
| |
| /// Converts an L-value to a value. For convenience. |
| Value AsValue() const; |
| |
| private: |
| PropertyLValue() = delete; |
| PropertyLValue(Object object, Key key); |
| napi_env _env; |
| napi_value _object; |
| Key _key; |
| |
| friend class Napi::Object; |
| }; |
| |
| /// Creates a new Object value. |
| static Object New(napi_env env ///< Node-API environment |
| ); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Object(); ///< Creates a new _empty_ Object instance. |
| Object(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| /// Gets or sets a named property. |
| PropertyLValue<std::string> operator[]( |
| const char* utf8name ///< UTF-8 encoded null-terminated property name |
| ); |
| |
| /// Gets or sets a named property. |
| PropertyLValue<std::string> operator[]( |
| const std::string& utf8name ///< UTF-8 encoded property name |
| ); |
| |
| /// Gets or sets an indexed property or array element. |
| PropertyLValue<uint32_t> operator[]( |
| uint32_t index /// Property / element index |
| ); |
| |
| /// Gets or sets an indexed property or array element. |
| PropertyLValue<Value> operator[](Value index /// Property / element index |
| ) const; |
| |
| /// Gets a named property. |
| MaybeOrValue<Value> operator[]( |
| const char* utf8name ///< UTF-8 encoded null-terminated property name |
| ) const; |
| |
| /// Gets a named property. |
| MaybeOrValue<Value> operator[]( |
| const std::string& utf8name ///< UTF-8 encoded property name |
| ) const; |
| |
| /// Gets an indexed property or array element. |
| MaybeOrValue<Value> operator[](uint32_t index ///< Property / element index |
| ) const; |
| |
| /// Checks whether a property is present. |
| MaybeOrValue<bool> Has(napi_value key ///< Property key primitive |
| ) const; |
| |
| /// Checks whether a property is present. |
| MaybeOrValue<bool> Has(Value key ///< Property key |
| ) const; |
| |
| /// Checks whether a named property is present. |
| MaybeOrValue<bool> Has( |
| const char* utf8name ///< UTF-8 encoded null-terminated property name |
| ) const; |
| |
| /// Checks whether a named property is present. |
| MaybeOrValue<bool> Has( |
| const std::string& utf8name ///< UTF-8 encoded property name |
| ) const; |
| |
| /// Checks whether a own property is present. |
| MaybeOrValue<bool> HasOwnProperty(napi_value key ///< Property key primitive |
| ) const; |
| |
| /// Checks whether a own property is present. |
| MaybeOrValue<bool> HasOwnProperty(Value key ///< Property key |
| ) const; |
| |
| /// Checks whether a own property is present. |
| MaybeOrValue<bool> HasOwnProperty( |
| const char* utf8name ///< UTF-8 encoded null-terminated property name |
| ) const; |
| |
| /// Checks whether a own property is present. |
| MaybeOrValue<bool> HasOwnProperty( |
| const std::string& utf8name ///< UTF-8 encoded property name |
| ) const; |
| |
| /// Gets a property. |
| MaybeOrValue<Value> Get(napi_value key ///< Property key primitive |
| ) const; |
| |
| /// Gets a property. |
| MaybeOrValue<Value> Get(Value key ///< Property key |
| ) const; |
| |
| /// Gets a named property. |
| MaybeOrValue<Value> Get( |
| const char* utf8name ///< UTF-8 encoded null-terminated property name |
| ) const; |
| |
| /// Gets a named property. |
| MaybeOrValue<Value> Get( |
| const std::string& utf8name ///< UTF-8 encoded property name |
| ) const; |
| |
| /// Sets a property. |
| template <typename ValueType> |
| MaybeOrValue<bool> Set(napi_value key, ///< Property key primitive |
| const ValueType& value ///< Property value primitive |
| ) const; |
| |
| /// Sets a property. |
| template <typename ValueType> |
| MaybeOrValue<bool> Set(Value key, ///< Property key |
| const ValueType& value ///< Property value |
| ) const; |
| |
| /// Sets a named property. |
| template <typename ValueType> |
| MaybeOrValue<bool> Set( |
| const char* utf8name, ///< UTF-8 encoded null-terminated property name |
| const ValueType& value) const; |
| |
| /// Sets a named property. |
| template <typename ValueType> |
| MaybeOrValue<bool> Set( |
| const std::string& utf8name, ///< UTF-8 encoded property name |
| const ValueType& value ///< Property value primitive |
| ) const; |
| |
| /// Delete property. |
| MaybeOrValue<bool> Delete(napi_value key ///< Property key primitive |
| ) const; |
| |
| /// Delete property. |
| MaybeOrValue<bool> Delete(Value key ///< Property key |
| ) const; |
| |
| /// Delete property. |
| MaybeOrValue<bool> Delete( |
| const char* utf8name ///< UTF-8 encoded null-terminated property name |
| ) const; |
| |
| /// Delete property. |
| MaybeOrValue<bool> Delete( |
| const std::string& utf8name ///< UTF-8 encoded property name |
| ) const; |
| |
| /// Checks whether an indexed property is present. |
| MaybeOrValue<bool> Has(uint32_t index ///< Property / element index |
| ) const; |
| |
| /// Gets an indexed property or array element. |
| MaybeOrValue<Value> Get(uint32_t index ///< Property / element index |
| ) const; |
| |
| /// Sets an indexed property or array element. |
| template <typename ValueType> |
| MaybeOrValue<bool> Set(uint32_t index, ///< Property / element index |
| const ValueType& value ///< Property value primitive |
| ) const; |
| |
| /// Deletes an indexed property or array element. |
| MaybeOrValue<bool> Delete(uint32_t index ///< Property / element index |
| ) const; |
| |
| /// This operation can fail in case of Proxy.[[OwnPropertyKeys]] and |
| /// Proxy.[[GetOwnProperty]] calling into JavaScript. See: |
| /// - |
| /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys |
| /// - |
| /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p |
| MaybeOrValue<Array> GetPropertyNames() const; ///< Get all property names |
| |
| /// Defines a property on the object. |
| /// |
| /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling |
| /// into JavaScript. See |
| /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc |
| MaybeOrValue<bool> DefineProperty( |
| const PropertyDescriptor& |
| property ///< Descriptor for the property to be defined |
| ) const; |
| |
| /// Defines properties on the object. |
| /// |
| /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling |
| /// into JavaScript. See |
| /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc |
| MaybeOrValue<bool> DefineProperties( |
| const std::initializer_list<PropertyDescriptor>& properties |
| ///< List of descriptors for the properties to be defined |
| ) const; |
| |
| /// Defines properties on the object. |
| /// |
| /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling |
| /// into JavaScript. See |
| /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc |
| MaybeOrValue<bool> DefineProperties( |
| const std::vector<PropertyDescriptor>& properties |
| ///< Vector of descriptors for the properties to be defined |
| ) const; |
| |
| /// Checks if an object is an instance created by a constructor function. |
| /// |
| /// This is equivalent to the JavaScript `instanceof` operator. |
| /// |
| /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into |
| /// JavaScript. |
| /// See |
| /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof |
| MaybeOrValue<bool> InstanceOf( |
| const Function& constructor ///< Constructor function |
| ) const; |
| |
| template <typename Finalizer, typename T> |
| inline void AddFinalizer(Finalizer finalizeCallback, T* data) const; |
| |
| template <typename Finalizer, typename T, typename Hint> |
| inline void AddFinalizer(Finalizer finalizeCallback, |
| T* data, |
| Hint* finalizeHint) const; |
| |
| #ifdef NODE_ADDON_API_CPP_EXCEPTIONS |
| class const_iterator; |
| |
| inline const_iterator begin() const; |
| |
| inline const_iterator end() const; |
| |
| class iterator; |
| |
| inline iterator begin(); |
| |
| inline iterator end(); |
| #endif // NODE_ADDON_API_CPP_EXCEPTIONS |
| |
| #if NAPI_VERSION >= 8 |
| /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into |
| /// JavaScript. |
| /// See |
| /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof |
| MaybeOrValue<bool> Freeze() const; |
| /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into |
| /// JavaScript. |
| /// See |
| /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof |
| MaybeOrValue<bool> Seal() const; |
| #endif // NAPI_VERSION >= 8 |
| }; |
| |
| template <typename T> |
| class External : public TypeTaggable { |
| public: |
| static External New(napi_env env, T* data); |
| |
| // Finalizer must implement `void operator()(Env env, T* data)`. |
| template <typename Finalizer> |
| static External New(napi_env env, T* data, Finalizer finalizeCallback); |
| // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. |
| template <typename Finalizer, typename Hint> |
| static External New(napi_env env, |
| T* data, |
| Finalizer finalizeCallback, |
| Hint* finalizeHint); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| External(); |
| External(napi_env env, napi_value value); |
| |
| T* Data() const; |
| }; |
| |
| class Array : public Object { |
| public: |
| static Array New(napi_env env); |
| static Array New(napi_env env, size_t length); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Array(); |
| Array(napi_env env, napi_value value); |
| |
| uint32_t Length() const; |
| }; |
| |
| #ifdef NODE_ADDON_API_CPP_EXCEPTIONS |
| class Object::const_iterator { |
| private: |
| enum class Type { BEGIN, END }; |
| |
| inline const_iterator(const Object* object, const Type type); |
| |
| public: |
| inline const_iterator& operator++(); |
| |
| inline bool operator==(const const_iterator& other) const; |
| |
| inline bool operator!=(const const_iterator& other) const; |
| |
| inline const std::pair<Value, Object::PropertyLValue<Value>> operator*() |
| const; |
| |
| private: |
| const Napi::Object* _object; |
| Array _keys; |
| uint32_t _index; |
| |
| friend class Object; |
| }; |
| |
| class Object::iterator { |
| private: |
| enum class Type { BEGIN, END }; |
| |
| inline iterator(Object* object, const Type type); |
| |
| public: |
| inline iterator& operator++(); |
| |
| inline bool operator==(const iterator& other) const; |
| |
| inline bool operator!=(const iterator& other) const; |
| |
| inline std::pair<Value, Object::PropertyLValue<Value>> operator*(); |
| |
| private: |
| Napi::Object* _object; |
| Array _keys; |
| uint32_t _index; |
| |
| friend class Object; |
| }; |
| #endif // NODE_ADDON_API_CPP_EXCEPTIONS |
| |
| /// A JavaScript array buffer value. |
| class ArrayBuffer : public Object { |
| public: |
| /// Creates a new ArrayBuffer instance over a new automatically-allocated |
| /// buffer. |
| static ArrayBuffer New( |
| napi_env env, ///< Node-API environment |
| size_t byteLength ///< Length of the buffer to be allocated, in bytes |
| ); |
| |
| #ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED |
| /// Creates a new ArrayBuffer instance, using an external buffer with |
| /// specified byte length. |
| static ArrayBuffer New( |
| napi_env env, ///< Node-API environment |
| void* externalData, ///< Pointer to the external buffer to be used by |
| ///< the array |
| size_t byteLength ///< Length of the external buffer to be used by the |
| ///< array, in bytes |
| ); |
| |
| /// Creates a new ArrayBuffer instance, using an external buffer with |
| /// specified byte length. |
| template <typename Finalizer> |
| static ArrayBuffer New( |
| napi_env env, ///< Node-API environment |
| void* externalData, ///< Pointer to the external buffer to be used by |
| ///< the array |
| size_t byteLength, ///< Length of the external buffer to be used by the |
| ///< array, |
| /// in bytes |
| Finalizer finalizeCallback ///< Function to be called when the array |
| ///< buffer is destroyed; |
| /// must implement `void operator()(Env env, |
| /// void* externalData)` |
| ); |
| |
| /// Creates a new ArrayBuffer instance, using an external buffer with |
| /// specified byte length. |
| template <typename Finalizer, typename Hint> |
| static ArrayBuffer New( |
| napi_env env, ///< Node-API environment |
| void* externalData, ///< Pointer to the external buffer to be used by |
| ///< the array |
| size_t byteLength, ///< Length of the external buffer to be used by the |
| ///< array, |
| /// in bytes |
| Finalizer finalizeCallback, ///< Function to be called when the array |
| ///< buffer is destroyed; |
| /// must implement `void operator()(Env |
| /// env, void* externalData, Hint* hint)` |
| Hint* finalizeHint ///< Hint (second parameter) to be passed to the |
| ///< finalize callback |
| ); |
| #endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| ArrayBuffer(); ///< Creates a new _empty_ ArrayBuffer instance. |
| ArrayBuffer(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| void* Data(); ///< Gets a pointer to the data buffer. |
| size_t ByteLength(); ///< Gets the length of the array buffer in bytes. |
| |
| #if NAPI_VERSION >= 7 |
| bool IsDetached() const; |
| void Detach(); |
| #endif // NAPI_VERSION >= 7 |
| }; |
| |
| /// A JavaScript typed-array value with unknown array type. |
| /// |
| /// For type-specific operations, cast to a `TypedArrayOf<T>` instance using the |
| /// `As()` method: |
| /// |
| /// Napi::TypedArray array = ... |
| /// if (t.TypedArrayType() == napi_int32_array) { |
| /// Napi::Int32Array int32Array = t.As<Napi::Int32Array>(); |
| /// } |
| class TypedArray : public Object { |
| public: |
| static void CheckCast(napi_env env, napi_value value); |
| |
| TypedArray(); ///< Creates a new _empty_ TypedArray instance. |
| TypedArray(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| napi_typedarray_type TypedArrayType() |
| const; ///< Gets the type of this typed-array. |
| Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer. |
| |
| uint8_t ElementSize() |
| const; ///< Gets the size in bytes of one element in the array. |
| size_t ElementLength() const; ///< Gets the number of elements in the array. |
| size_t ByteOffset() |
| const; ///< Gets the offset into the buffer where the array starts. |
| size_t ByteLength() const; ///< Gets the length of the array in bytes. |
| |
| protected: |
| /// !cond INTERNAL |
| napi_typedarray_type _type; |
| size_t _length; |
| |
| TypedArray(napi_env env, |
| napi_value value, |
| napi_typedarray_type type, |
| size_t length); |
| |
| template <typename T> |
| static |
| #if defined(NAPI_HAS_CONSTEXPR) |
| constexpr |
| #endif |
| napi_typedarray_type |
| TypedArrayTypeForPrimitiveType() { |
| return std::is_same<T, int8_t>::value ? napi_int8_array |
| : std::is_same<T, uint8_t>::value ? napi_uint8_array |
| : std::is_same<T, int16_t>::value ? napi_int16_array |
| : std::is_same<T, uint16_t>::value ? napi_uint16_array |
| : std::is_same<T, int32_t>::value ? napi_int32_array |
| : std::is_same<T, uint32_t>::value ? napi_uint32_array |
| : std::is_same<T, float>::value ? napi_float32_array |
| : std::is_same<T, double>::value ? napi_float64_array |
| #if NAPI_VERSION > 5 |
| : std::is_same<T, int64_t>::value ? napi_bigint64_array |
| : std::is_same<T, uint64_t>::value ? napi_biguint64_array |
| #endif // NAPI_VERSION > 5 |
| : napi_int8_array; |
| } |
| /// !endcond |
| }; |
| |
| /// A JavaScript typed-array value with known array type. |
| /// |
| /// Note while it is possible to create and access Uint8 "clamped" arrays using |
| /// this class, the _clamping_ behavior is only applied in JavaScript. |
| template <typename T> |
| class TypedArrayOf : public TypedArray { |
| public: |
| /// Creates a new TypedArray instance over a new automatically-allocated array |
| /// buffer. |
| /// |
| /// The array type parameter can normally be omitted (because it is inferred |
| /// from the template parameter T), except when creating a "clamped" array: |
| /// |
| /// Uint8Array::New(env, length, napi_uint8_clamped_array) |
| static TypedArrayOf New( |
| napi_env env, ///< Node-API environment |
| size_t elementLength, ///< Length of the created array, as a number of |
| ///< elements |
| #if defined(NAPI_HAS_CONSTEXPR) |
| napi_typedarray_type type = |
| TypedArray::TypedArrayTypeForPrimitiveType<T>() |
| #else |
| napi_typedarray_type type |
| #endif |
| ///< Type of array, if different from the default array type for the |
| ///< template parameter T. |
| ); |
| |
| /// Creates a new TypedArray instance over a provided array buffer. |
| /// |
| /// The array type parameter can normally be omitted (because it is inferred |
| /// from the template parameter T), except when creating a "clamped" array: |
| /// |
| /// Uint8Array::New(env, length, buffer, 0, napi_uint8_clamped_array) |
| static TypedArrayOf New( |
| napi_env env, ///< Node-API environment |
| size_t elementLength, ///< Length of the created array, as a number of |
| ///< elements |
| Napi::ArrayBuffer arrayBuffer, ///< Backing array buffer instance to use |
| size_t bufferOffset, ///< Offset into the array buffer where the |
| ///< typed-array starts |
| #if defined(NAPI_HAS_CONSTEXPR) |
| napi_typedarray_type type = |
| TypedArray::TypedArrayTypeForPrimitiveType<T>() |
| #else |
| napi_typedarray_type type |
| #endif |
| ///< Type of array, if different from the default array type for the |
| ///< template parameter T. |
| ); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| TypedArrayOf(); ///< Creates a new _empty_ TypedArrayOf instance. |
| TypedArrayOf(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| T& operator[](size_t index); ///< Gets or sets an element in the array. |
| const T& operator[](size_t index) const; ///< Gets an element in the array. |
| |
| /// Gets a pointer to the array's backing buffer. |
| /// |
| /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, |
| /// because the typed-array may have a non-zero `ByteOffset()` into the |
| /// `ArrayBuffer`. |
| T* Data(); |
| |
| /// Gets a pointer to the array's backing buffer. |
| /// |
| /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, |
| /// because the typed-array may have a non-zero `ByteOffset()` into the |
| /// `ArrayBuffer`. |
| const T* Data() const; |
| |
| private: |
| T* _data; |
| |
| TypedArrayOf(napi_env env, |
| napi_value value, |
| napi_typedarray_type type, |
| size_t length, |
| T* data); |
| }; |
| |
| /// The DataView provides a low-level interface for reading/writing multiple |
| /// number types in an ArrayBuffer irrespective of the platform's endianness. |
| class DataView : public Object { |
| public: |
| static DataView New(napi_env env, Napi::ArrayBuffer arrayBuffer); |
| static DataView New(napi_env env, |
| Napi::ArrayBuffer arrayBuffer, |
| size_t byteOffset); |
| static DataView New(napi_env env, |
| Napi::ArrayBuffer arrayBuffer, |
| size_t byteOffset, |
| size_t byteLength); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| DataView(); ///< Creates a new _empty_ DataView instance. |
| DataView(napi_env env, |
| napi_value value); ///< Wraps a Node-API value primitive. |
| |
| Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer. |
| size_t ByteOffset() |
| const; ///< Gets the offset into the buffer where the array starts. |
| size_t ByteLength() const; ///< Gets the length of the array in bytes. |
| |
| void* Data() const; |
| |
| float GetFloat32(size_t byteOffset) const; |
| double GetFloat64(size_t byteOffset) const; |
| int8_t GetInt8(size_t byteOffset) const; |
| int16_t GetInt16(size_t byteOffset) const; |
| int32_t GetInt32(size_t byteOffset) const; |
| uint8_t GetUint8(size_t byteOffset) const; |
| uint16_t GetUint16(size_t byteOffset) const; |
| uint32_t GetUint32(size_t byteOffset) const; |
| |
| void SetFloat32(size_t byteOffset, float value) const; |
| void SetFloat64(size_t byteOffset, double value) const; |
| void SetInt8(size_t byteOffset, int8_t value) const; |
| void SetInt16(size_t byteOffset, int16_t value) const; |
| void SetInt32(size_t byteOffset, int32_t value) const; |
| void SetUint8(size_t byteOffset, uint8_t value) const; |
| void SetUint16(size_t byteOffset, uint16_t value) const; |
| void SetUint32(size_t byteOffset, uint32_t value) const; |
| |
| private: |
| template <typename T> |
| T ReadData(size_t byteOffset) const; |
| |
| template <typename T> |
| void WriteData(size_t byteOffset, T value) const; |
| |
| void* _data{}; |
| size_t _length{}; |
| }; |
| |
| class Function : public Object { |
| public: |
| using VoidCallback = void (*)(const CallbackInfo& info); |
| using Callback = Value (*)(const CallbackInfo& info); |
| |
| template <VoidCallback cb> |
| static Function New(napi_env env, |
| const char* utf8name = nullptr, |
| void* data = nullptr); |
| |
| template <Callback cb> |
| static Function New(napi_env env, |
| const char* utf8name = nullptr, |
| void* data = nullptr); |
| |
| template <VoidCallback cb> |
| static Function New(napi_env env, |
| const std::string& utf8name, |
| void* data = nullptr); |
| |
| template <Callback cb> |
| static Function New(napi_env env, |
| const std::string& utf8name, |
| void* data = nullptr); |
| |
| /// Callable must implement operator() accepting a const CallbackInfo& |
| /// and return either void or Value. |
| template <typename Callable> |
| static Function New(napi_env env, |
| Callable cb, |
| const char* utf8name = nullptr, |
| void* data = nullptr); |
| /// Callable must implement operator() accepting a const CallbackInfo& |
| /// and return either void or Value. |
| template <typename Callable> |
| static Function New(napi_env env, |
| Callable cb, |
| const std::string& utf8name, |
| void* data = nullptr); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Function(); |
| Function(napi_env env, napi_value value); |
| |
| MaybeOrValue<Value> operator()( |
| const std::initializer_list<napi_value>& args) const; |
| |
| MaybeOrValue<Value> Call(const std::initializer_list<napi_value>& args) const; |
| MaybeOrValue<Value> Call(const std::vector<napi_value>& args) const; |
| MaybeOrValue<Value> Call(const std::vector<Value>& args) const; |
| MaybeOrValue<Value> Call(size_t argc, const napi_value* args) const; |
| MaybeOrValue<Value> Call(napi_value recv, |
| const std::initializer_list<napi_value>& args) const; |
| MaybeOrValue<Value> Call(napi_value recv, |
| const std::vector<napi_value>& args) const; |
| MaybeOrValue<Value> Call(napi_value recv, |
| const std::vector<Value>& args) const; |
| MaybeOrValue<Value> Call(napi_value recv, |
| size_t argc, |
| const napi_value* args) const; |
| |
| MaybeOrValue<Value> MakeCallback( |
| napi_value recv, |
| const std::initializer_list<napi_value>& args, |
| napi_async_context context = nullptr) const; |
| MaybeOrValue<Value> MakeCallback(napi_value recv, |
| const std::vector<napi_value>& args, |
| napi_async_context context = nullptr) const; |
| MaybeOrValue<Value> MakeCallback(napi_value recv, |
| size_t argc, |
| const napi_value* args, |
| napi_async_context context = nullptr) const; |
| |
| MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const; |
| MaybeOrValue<Object> New(const std::vector<napi_value>& args) const; |
| MaybeOrValue<Object> New(size_t argc, const napi_value* args) const; |
| }; |
| |
| class Promise : public Object { |
| public: |
| class Deferred { |
| public: |
| static Deferred New(napi_env env); |
| Deferred(napi_env env); |
| |
| Napi::Promise Promise() const; |
| Napi::Env Env() const; |
| |
| void Resolve(napi_value value) const; |
| void Reject(napi_value value) const; |
| |
| private: |
| napi_env _env; |
| napi_deferred _deferred; |
| napi_value _promise; |
| }; |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Promise(); |
| Promise(napi_env env, napi_value value); |
| |
| MaybeOrValue<Promise> Then(napi_value onFulfilled) const; |
| MaybeOrValue<Promise> Then(napi_value onFulfilled, |
| napi_value onRejected) const; |
| MaybeOrValue<Promise> Catch(napi_value onRejected) const; |
| |
| MaybeOrValue<Promise> Then(const Function& onFulfilled) const; |
| MaybeOrValue<Promise> Then(const Function& onFulfilled, |
| const Function& onRejected) const; |
| MaybeOrValue<Promise> Catch(const Function& onRejected) const; |
| }; |
| |
| template <typename T> |
| class Buffer : public Uint8Array { |
| public: |
| static Buffer<T> New(napi_env env, size_t length); |
| #ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED |
| static Buffer<T> New(napi_env env, T* data, size_t length); |
| |
| // Finalizer must implement `void operator()(Env env, T* data)`. |
| template <typename Finalizer> |
| static Buffer<T> New(napi_env env, |
| T* data, |
| size_t length, |
| Finalizer finalizeCallback); |
| // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. |
| template <typename Finalizer, typename Hint> |
| static Buffer<T> New(napi_env env, |
| T* data, |
| size_t length, |
| Finalizer finalizeCallback, |
| Hint* finalizeHint); |
| #endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED |
| |
| static Buffer<T> NewOrCopy(napi_env env, T* data, size_t length); |
| // Finalizer must implement `void operator()(Env env, T* data)`. |
| template <typename Finalizer> |
| static Buffer<T> NewOrCopy(napi_env env, |
| T* data, |
| size_t length, |
| Finalizer finalizeCallback); |
| // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. |
| template <typename Finalizer, typename Hint> |
| static Buffer<T> NewOrCopy(napi_env env, |
| T* data, |
| size_t length, |
| Finalizer finalizeCallback, |
| Hint* finalizeHint); |
| |
| static Buffer<T> Copy(napi_env env, const T* data, size_t length); |
| |
| static void CheckCast(napi_env env, napi_value value); |
| |
| Buffer(); |
| Buffer(napi_env env, napi_value value); |
| size_t Length() const; |
| T* Data() const; |
| |
| private: |
| }; |
| |
| /// Holds a counted reference to a value; initially a weak reference unless |
| /// otherwise specified, may be changed to/from a strong reference by adjusting |
| /// the refcount. |
| /// |
| /// The referenced value is not immediately destroyed when the reference count |
| /// is zero; it is merely then eligible for garbage-collection if there are no |
| /// other references to the value. |
| template <typename T> |
| class Reference { |
| public: |
| static Reference<T> New(const T& value, uint32_t initialRefcount = 0); |
| |
| Reference(); |
| Reference(napi_env env, napi_ref ref); |
| ~Reference(); |
| |
| // A reference can be moved but cannot be copied. |
| Reference(Reference<T>&& other); |
| Reference<T>& operator=(Reference<T>&& other); |
| NAPI_DISALLOW_ASSIGN(Reference<T>) |
| |
| operator napi_ref() const; |
| bool operator==(const Reference<T>& other) const; |
| bool operator!=(const Reference<T>& other) const; |
| |
| Napi::Env Env() const; |
| bool IsEmpty() const; |
| |
| // Note when getting the value of a Reference it is usually correct to do so |
| // within a HandleScope so that the value handle gets cleaned up efficiently. |
| T Value() const; |
| |
| uint32_t Ref() const; |
| uint32_t Unref() const; |
| void Reset(); |
| void Reset(const T& value, uint32_t refcount = 0); |
| |
| // Call this on a reference that is declared as static data, to prevent its |
| // destructor from running at program shutdown time, which would attempt to |
| // reset the reference when the environment is no longer valid. Avoid using |
| // this if at all possible. If you do need to use static data, MAKE SURE to |
| // warn your users that your addon is NOT threadsafe. |
| void SuppressDestruct(); |
| |
| protected: |
| Reference(const Reference<T>&); |
| |
| /// !cond INTERNAL |
| napi_env _env; |
| napi_ref _ref; |
| /// !endcond |
| |
| private: |
| bool _suppressDestruct; |
| }; |
| |
| class ObjectReference : public Reference<Object> { |
| public: |
| ObjectReference(); |
| ObjectReference(napi_env env, napi_ref ref); |
| |
| // A reference can be moved but cannot be copied. |
| ObjectReference(Reference<Object>&& other); |
| ObjectReference& operator=(Reference<Object>&& other); |
| ObjectReference(ObjectReference&& other); |
| ObjectReference& operator=(ObjectReference&& other); |
| NAPI_DISALLOW_ASSIGN(ObjectReference) |
| |
| MaybeOrValue<Napi::Value> Get(const char* utf8name) const; |
| MaybeOrValue<Napi::Value> Get(const std::string& utf8name) const; |
| MaybeOrValue<bool> Set(const char* utf8name, napi_value value) const; |
| MaybeOrValue<bool> Set(const char* utf8name, Napi::Value value) const; |
| MaybeOrValue<bool> Set(const char* utf8name, const char* utf8value) const; |
| MaybeOrValue<bool> Set(const char* utf8name, bool boolValue) const; |
| MaybeOrValue<bool> Set(const char* utf8name, double numberValue) const; |
| MaybeOrValue<bool> Set(const std::string& utf8name, napi_value value) const; |
| MaybeOrValue<bool> Set(const std::string& utf8name, Napi::Value value) const; |
| MaybeOrValue<bool> Set(const std::string& utf8name, |
| std::string& utf8value) const; |
| MaybeOrValue<bool> Set(const std::string& utf8name, bool boolValue) const; |
| MaybeOrValue<bool> Set(const std::string& utf8name, double numberValue) const; |
| |
| MaybeOrValue<Napi::Value> Get(uint32_t index) const; |
| MaybeOrValue<bool> Set(uint32_t index, const napi_value value) const; |
| MaybeOrValue<bool> Set(uint32_t index, const Napi::Value value) const; |
| MaybeOrValue<bool> Set(uint32_t index, const char* utf8value) const; |
| MaybeOrValue<bool> Set(uint32_t index, const std::string& utf8value) const; |
| MaybeOrValue<bool> Set(uint32_t index, bool boolValue) const; |
| MaybeOrValue<bool> Set(uint32_t index, double numberValue) const; |
| |
| protected: |
| ObjectReference(const ObjectReference&); |
| }; |
| |
| class FunctionReference : public Reference<Function> { |
| public: |
| FunctionReference(); |
| FunctionReference(napi_env env, napi_ref ref); |
| |
| // A reference can be moved but cannot be copied. |
| FunctionReference(Reference<Function>&& other); |
| FunctionReference& operator=(Reference<Function>&& other); |
| FunctionReference(FunctionReference&& other); |
| FunctionReference& operator=(FunctionReference&& other); |
| NAPI_DISALLOW_ASSIGN_COPY(FunctionReference) |
| |
| MaybeOrValue<Napi::Value> operator()( |
| const std::initializer_list<napi_value>& args) const; |
| |
| MaybeOrValue<Napi::Value> Call( |
| const std::initializer_list<napi_value>& args) const; |
| MaybeOrValue<Napi::Value> Call(const std::vector<napi_value>& args) const; |
| MaybeOrValue<Napi::Value> Call( |
| napi_value recv, const std::initializer_list<napi_value>& args) const; |
| MaybeOrValue<Napi::Value> Call(napi_value recv, |
| const std::vector<napi_value>& args) const; |
| MaybeOrValue<Napi::Value> Call(napi_value recv, |
| size_t argc, |
| const napi_value* args) const; |
| |
| MaybeOrValue<Napi::Value> MakeCallback( |
| napi_value recv, |
| const std::initializer_list<napi_value>& args, |
| napi_async_context context = nullptr) const; |
| MaybeOrValue<Napi::Value> MakeCallback( |
| napi_value recv, |
| const std::vector<napi_value>& args, |
| napi_async_context context = nullptr) const; |
| MaybeOrValue<Napi::Value> MakeCallback( |
| napi_value recv, |
| size_t argc, |
| const napi_value* args, |
| napi_async_context context = nullptr) const; |
| |
| MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const; |
| MaybeOrValue<Object> New(const std::vector<napi_value>& args) const; |
| }; |
| |
| // Shortcuts to creating a new reference with inferred type and refcount = 0. |
| template <typename T> |
| Reference<T> Weak(T value); |
| ObjectReference Weak(Object value); |
| FunctionReference Weak(Function value); |
| |
| // Shortcuts to creating a new reference with inferred type and refcount = 1. |
| template <typename T> |
| Reference<T> Persistent(T value); |
| ObjectReference Persistent(Object value); |
| FunctionReference Persistent(Function value); |
| |
| /// A persistent reference to a JavaScript error object. Use of this class |
| /// depends somewhat on whether C++ exceptions are enabled at compile time. |
| /// |
| /// ### Handling Errors With C++ Exceptions |
| /// |
| /// If C++ exceptions are enabled, then the `Error` class extends |
| /// `std::exception` and enables integrated error-handling for C++ exceptions |
| /// and JavaScript exceptions. |
| /// |
| /// If a Node-API call fails without executing any JavaScript code (for |
| /// example due to an invalid argument), then the Node-API wrapper |
| /// automatically converts and throws the error as a C++ exception of type |
| /// `Napi::Error`. Or if a JavaScript function called by C++ code via Node-API |
| /// throws a JavaScript exception, then the Node-API wrapper automatically |
| /// converts and throws it as a C++ exception of type `Napi::Error`. |
| /// |
| /// If a C++ exception of type `Napi::Error` escapes from a Node-API C++ |
| /// callback, then the Node-API wrapper automatically converts and throws it |
| /// as a JavaScript exception. Therefore, catching a C++ exception of type |
| /// `Napi::Error` prevents a JavaScript exception from being thrown. |
| /// |
| /// #### Example 1A - Throwing a C++ exception: |
| /// |
| /// Napi::Env env = ... |
| /// throw Napi::Error::New(env, "Example exception"); |
| /// |
| /// Following C++ statements will not be executed. The exception will bubble |
| /// up as a C++ exception of type `Napi::Error`, until it is either caught |
| /// while still in C++, or else automatically propagated as a JavaScript |
| /// exception when the callback returns to JavaScript. |
| /// |
| /// #### Example 2A - Propagating a Node-API C++ exception: |
| /// |
| /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>(); |
| /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); |
| /// |
| /// Following C++ statements will not be executed. The exception will bubble |
| /// up as a C++ exception of type `Napi::Error`, until it is either caught |
| /// while still in C++, or else automatically propagated as a JavaScript |
| /// exception when the callback returns to JavaScript. |
| /// |
| /// #### Example 3A - Handling a Node-API C++ exception: |
| /// |
| /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>(); |
| /// Napi::Value result; |
| /// try { |
| /// result = jsFunctionThatThrows({ arg1, arg2 }); |
| /// } catch (const Napi::Error& e) { |
| /// cerr << "Caught JavaScript exception: " + e.what(); |
| /// } |
| /// |
| /// Since the exception was caught here, it will not be propagated as a |
| /// JavaScript exception. |
| /// |
| /// ### Handling Errors Without C++ Exceptions |
| /// |
| /// If C++ exceptions are disabled (by defining |
| /// `NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS`) then this class does not extend |
| /// `std::exception`, and APIs in the `Napi` namespace do not throw C++ |
| /// exceptions when they fail. Instead, they raise _pending_ JavaScript |
| /// exceptions and return _empty_ `Value`s. Calling code should check |
| /// `Value::IsEmpty()` before attempting to use a returned value, and may use |
| /// methods on the `Env` class to check for, get, and clear a pending JavaScript |
| /// exception. If the pending exception is not cleared, it will be thrown when |
| /// the native callback returns to JavaScript. |
| /// |
| /// #### Example 1B - Throwing a JS exception |
| /// |
| /// Napi::Env env = ... |
| /// Napi::Error::New(env, "Example |
| /// exception").ThrowAsJavaScriptException(); return; |
| /// |
| /// After throwing a JS exception, the code should generally return |
| /// immediately from the native callback, after performing any necessary |
| /// cleanup. |
| /// |
| /// #### Example 2B - Propagating a Node-API JS exception: |
| /// |
| /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>(); |
| /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); |
| /// if (result.IsEmpty()) return; |
| /// |
| /// An empty value result from a Node-API call indicates an error occurred, |
| /// and a JavaScript exception is pending. To let the exception propagate, the |
| /// code should generally return immediately from the native callback, after |
| /// performing any necessary cleanup. |
| /// |
| /// #### Example 3B - Handling a Node-API JS exception: |
| /// |
| /// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>(); |
| /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); |
| /// if (result.IsEmpty()) { |
| /// Napi::Error e = env.GetAndClearPendingException(); |
| /// cerr << "Caught JavaScript exception: " + e.Message(); |
| /// } |
| /// |
| /// Since the exception was cleared here, it will not be propagated as a |
| /// JavaScript exception after the native callback returns. |
| class Error : public ObjectReference |
| #ifdef NODE_ADDON_API_CPP_EXCEPTIONS |
| , |
| public std::exception |
| #endif // NODE_ADDON_API_CPP_EXCEPTIONS |
| { |
| public: |
| static Error New(napi_env env); |
| static Error New(napi_env env, const char* message); |
| static Error New(napi_env env, const std::string& message); |
| |
| static NAPI_NO_RETURN void Fatal(const char* location, const char* message); |
| |
| Error(); |
| Error(napi_env env, napi_value value); |
| |
| // An error can be moved or copied. |
| Error(Error&& other); |
| Error& operator=(Error&& other); |
| Error(const Error&); |
| Error& operator=(const Error&); |
| |
| const std::string& Message() const NAPI_NOEXCEPT; |
| void ThrowAsJavaScriptException() const; |
| |
| Object Value() const; |
| |
| #ifdef NODE_ADDON_API_CPP_EXCEPTIONS |
| const char* what() const NAPI_NOEXCEPT override; |
| #endif // NODE_ADDON_API_CPP_EXCEPTIONS |
| |
| protected: |
| /// !cond INTERNAL |
| using create_error_fn = napi_status (*)(napi_env envb, |
| napi_value code, |
| napi_value msg, |
| napi_value* result); |
| |
| template <typename TError> |
| static TError New(napi_env env, |
| const char* message, |
| size_t length, |
| create_error_fn create_error); |
| /// !endcond |
| |
| private: |
| static inline const char* ERROR_WRAP_VALUE() NAPI_NOEXCEPT; |
| mutable std::string _message; |
| }; |
| |
| class TypeError : public Error { |
| public: |
| static TypeError New(napi_env env, const char* message); |
| static TypeError New(napi_env env, const std::string& message); |
| |
| TypeError(); |
| TypeError(napi_env env, napi_value value); |
| }; |
| |
| class RangeError : public Error { |
| public: |
| static RangeError New(napi_env env, const char* message); |
| static RangeError New(napi_env env, const std::string& message); |
| |
| RangeError(); |
| RangeError(napi_env env, napi_value value); |
| }; |
| |
| #if NAPI_VERSION > 8 |
| class SyntaxError : public Error { |
| public: |
| static SyntaxError New(napi_env env, const char* message); |
| static SyntaxError New(napi_env env, const std::string& message); |
| |
| SyntaxError(); |
| SyntaxError(napi_env env, napi_value value); |
| }; |
| #endif // NAPI_VERSION > 8 |
| |
| class CallbackInfo { |
| public: |
| CallbackInfo(napi_env env, napi_callback_info info); |
| ~CallbackInfo(); |
| |
| // Disallow copying to prevent multiple free of _dynamicArgs |
| NAPI_DISALLOW_ASSIGN_COPY(CallbackInfo) |
| |
| Napi::Env Env() const; |
| Value NewTarget() const; |
| bool IsConstructCall() const; |
| size_t Length() const; |
| const Value operator[](size_t index) const; |
| Value This() const; |
| void* Data() const; |
| void SetData(void* data); |
| explicit operator napi_callback_info() const; |
| |
| private: |
| const size_t _staticArgCount = 6; |
| napi_env _env; |
| napi_callback_info _info; |
| napi_value _this; |
| size_t _argc; |
| napi_value* _argv; |
| napi_value _staticArgs[6]{}; |
| napi_value* _dynamicArgs; |
| void* _data; |
| }; |
| |
| class PropertyDescriptor { |
| public: |
| using GetterCallback = Napi::Value (*)(const Napi::CallbackInfo& info); |
| using SetterCallback = void (*)(const Napi::CallbackInfo& info); |
| |
| #ifndef NODE_ADDON_API_DISABLE_DEPRECATED |
| template <typename Getter> |
| static PropertyDescriptor Accessor( |
| const char* utf8name, |
| Getter getter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter> |
| static PropertyDescriptor Accessor( |
| const std::string& utf8name, |
| Getter getter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter> |
| static PropertyDescriptor Accessor( |
| napi_value name, |
| Getter getter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter> |
| static PropertyDescriptor Accessor( |
| Name name, |
| Getter getter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter, typename Setter> |
| static PropertyDescriptor Accessor( |
| const char* utf8name, |
| Getter getter, |
| Setter setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter, typename Setter> |
| static PropertyDescriptor Accessor( |
| const std::string& utf8name, |
| Getter getter, |
| Setter setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter, typename Setter> |
| static PropertyDescriptor Accessor( |
| napi_value name, |
| Getter getter, |
| Setter setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter, typename Setter> |
| static PropertyDescriptor Accessor( |
| Name name, |
| Getter getter, |
| Setter setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Callable> |
| static PropertyDescriptor Function( |
| const char* utf8name, |
| Callable cb, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Callable> |
| static PropertyDescriptor Function( |
| const std::string& utf8name, |
| Callable cb, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Callable> |
| static PropertyDescriptor Function( |
| napi_value name, |
| Callable cb, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Callable> |
| static PropertyDescriptor Function( |
| Name name, |
| Callable cb, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| #endif // !NODE_ADDON_API_DISABLE_DEPRECATED |
| |
| template <GetterCallback Getter> |
| static PropertyDescriptor Accessor( |
| const char* utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| |
| template <GetterCallback Getter> |
| static PropertyDescriptor Accessor( |
| const std::string& utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| |
| template <GetterCallback Getter> |
| static PropertyDescriptor Accessor( |
| Name name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| |
| template <GetterCallback Getter, SetterCallback Setter> |
| static PropertyDescriptor Accessor( |
| const char* utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| |
| template <GetterCallback Getter, SetterCallback Setter> |
| static PropertyDescriptor Accessor( |
| const std::string& utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| |
| template <GetterCallback Getter, SetterCallback Setter> |
| static PropertyDescriptor Accessor( |
| Name name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| |
| template <typename Getter> |
| static PropertyDescriptor Accessor( |
| Napi::Env env, |
| Napi::Object object, |
| const char* utf8name, |
| Getter getter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter> |
| static PropertyDescriptor Accessor( |
| Napi::Env env, |
| Napi::Object object, |
| const std::string& utf8name, |
| Getter getter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter> |
| static PropertyDescriptor Accessor( |
| Napi::Env env, |
| Napi::Object object, |
| Name name, |
| Getter getter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter, typename Setter> |
| static PropertyDescriptor Accessor( |
| Napi::Env env, |
| Napi::Object object, |
| const char* utf8name, |
| Getter getter, |
| Setter setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter, typename Setter> |
| static PropertyDescriptor Accessor( |
| Napi::Env env, |
| Napi::Object object, |
| const std::string& utf8name, |
| Getter getter, |
| Setter setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Getter, typename Setter> |
| static PropertyDescriptor Accessor( |
| Napi::Env env, |
| Napi::Object object, |
| Name name, |
| Getter getter, |
| Setter setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Callable> |
| static PropertyDescriptor Function( |
| Napi::Env env, |
| Napi::Object object, |
| const char* utf8name, |
| Callable cb, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Callable> |
| static PropertyDescriptor Function( |
| Napi::Env env, |
| Napi::Object object, |
| const std::string& utf8name, |
| Callable cb, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <typename Callable> |
| static PropertyDescriptor Function( |
| Napi::Env env, |
| Napi::Object object, |
| Name name, |
| Callable cb, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor Value( |
| const char* utf8name, |
| napi_value value, |
| napi_property_attributes attributes = napi_default); |
| static PropertyDescriptor Value( |
| const std::string& utf8name, |
| napi_value value, |
| napi_property_attributes attributes = napi_default); |
| static PropertyDescriptor Value( |
| napi_value name, |
| napi_value value, |
| napi_property_attributes attributes = napi_default); |
| static PropertyDescriptor Value( |
| Name name, |
| Napi::Value value, |
| napi_property_attributes attributes = napi_default); |
| |
| PropertyDescriptor(napi_property_descriptor desc); |
| |
| operator napi_property_descriptor&(); |
| operator const napi_property_descriptor&() const; |
| |
| private: |
| napi_property_descriptor _desc; |
| }; |
| |
| /// Property descriptor for use with `ObjectWrap::DefineClass()`. |
| /// |
| /// This is different from the standalone `PropertyDescriptor` because it is |
| /// specific to each `ObjectWrap<T>` subclass. This prevents using descriptors |
| /// from a different class when defining a new class (preventing the callbacks |
| /// from having incorrect `this` pointers). |
| template <typename T> |
| class ClassPropertyDescriptor { |
| public: |
| ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {} |
| |
| operator napi_property_descriptor&() { return _desc; } |
| operator const napi_property_descriptor&() const { return _desc; } |
| |
| private: |
| napi_property_descriptor _desc; |
| }; |
| |
| template <typename T, typename TCallback> |
| struct MethodCallbackData { |
| TCallback callback; |
| void* data; |
| }; |
| |
| template <typename T, typename TGetterCallback, typename TSetterCallback> |
| struct AccessorCallbackData { |
| TGetterCallback getterCallback; |
| TSetterCallback setterCallback; |
| void* data; |
| }; |
| |
| template <typename T> |
| class InstanceWrap { |
| public: |
| using InstanceVoidMethodCallback = void (T::*)(const CallbackInfo& info); |
| using InstanceMethodCallback = Napi::Value (T::*)(const CallbackInfo& info); |
| using InstanceGetterCallback = Napi::Value (T::*)(const CallbackInfo& info); |
| using InstanceSetterCallback = void (T::*)(const CallbackInfo& info, |
| const Napi::Value& value); |
| |
| using PropertyDescriptor = ClassPropertyDescriptor<T>; |
| |
| static PropertyDescriptor InstanceMethod( |
| const char* utf8name, |
| InstanceVoidMethodCallback method, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor InstanceMethod( |
| const char* utf8name, |
| InstanceMethodCallback method, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor InstanceMethod( |
| Symbol name, |
| InstanceVoidMethodCallback method, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor InstanceMethod( |
| Symbol name, |
| InstanceMethodCallback method, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <InstanceVoidMethodCallback method> |
| static PropertyDescriptor InstanceMethod( |
| const char* utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <InstanceMethodCallback method> |
| static PropertyDescriptor InstanceMethod( |
| const char* utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <InstanceVoidMethodCallback method> |
| static PropertyDescriptor InstanceMethod( |
| Symbol name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <InstanceMethodCallback method> |
| static PropertyDescriptor InstanceMethod( |
| Symbol name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor InstanceAccessor( |
| const char* utf8name, |
| InstanceGetterCallback getter, |
| InstanceSetterCallback setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor InstanceAccessor( |
| Symbol name, |
| InstanceGetterCallback getter, |
| InstanceSetterCallback setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <InstanceGetterCallback getter, |
| InstanceSetterCallback setter = nullptr> |
| static PropertyDescriptor InstanceAccessor( |
| const char* utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <InstanceGetterCallback getter, |
| InstanceSetterCallback setter = nullptr> |
| static PropertyDescriptor InstanceAccessor( |
| Symbol name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor InstanceValue( |
| const char* utf8name, |
| Napi::Value value, |
| napi_property_attributes attributes = napi_default); |
| static PropertyDescriptor InstanceValue( |
| Symbol name, |
| Napi::Value value, |
| napi_property_attributes attributes = napi_default); |
| |
| protected: |
| static void AttachPropData(napi_env env, |
| napi_value value, |
| const napi_property_descriptor* prop); |
| |
| private: |
| using This = InstanceWrap<T>; |
| |
| using InstanceVoidMethodCallbackData = |
| MethodCallbackData<T, InstanceVoidMethodCallback>; |
| using InstanceMethodCallbackData = |
| MethodCallbackData<T, InstanceMethodCallback>; |
| using InstanceAccessorCallbackData = |
| AccessorCallbackData<T, InstanceGetterCallback, InstanceSetterCallback>; |
| |
| static napi_value InstanceVoidMethodCallbackWrapper(napi_env env, |
| napi_callback_info info); |
| static napi_value InstanceMethodCallbackWrapper(napi_env env, |
| napi_callback_info info); |
| static napi_value InstanceGetterCallbackWrapper(napi_env env, |
| napi_callback_info info); |
| static napi_value InstanceSetterCallbackWrapper(napi_env env, |
| napi_callback_info info); |
| |
| template <InstanceSetterCallback method> |
| static napi_value WrappedMethod(napi_env env, |
| napi_callback_info info) NAPI_NOEXCEPT; |
| |
| template <InstanceSetterCallback setter> |
| struct SetterTag {}; |
| |
| template <InstanceSetterCallback setter> |
| static napi_callback WrapSetter(SetterTag<setter>) NAPI_NOEXCEPT { |
| return &This::WrappedMethod<setter>; |
| } |
| static napi_callback WrapSetter(SetterTag<nullptr>) NAPI_NOEXCEPT { |
| return nullptr; |
| } |
| }; |
| |
| /// Base class to be extended by C++ classes exposed to JavaScript; each C++ |
| /// class instance gets "wrapped" by a JavaScript object that is managed by this |
| /// class. |
| /// |
| /// At initialization time, the `DefineClass()` method must be used to |
| /// hook up the accessor and method callbacks. It takes a list of |
| /// property descriptors, which can be constructed via the various |
| /// static methods on the base class. |
| /// |
| /// #### Example: |
| /// |
| /// class Example: public Napi::ObjectWrap<Example> { |
| /// public: |
| /// static void Initialize(Napi::Env& env, Napi::Object& target) { |
| /// Napi::Function constructor = DefineClass(env, "Example", { |
| /// InstanceAccessor<&Example::GetSomething, |
| /// &Example::SetSomething>("value"), |
| /// InstanceMethod<&Example::DoSomething>("doSomething"), |
| /// }); |
| /// target.Set("Example", constructor); |
| /// } |
| /// |
| /// Example(const Napi::CallbackInfo& info); // Constructor |
| /// Napi::Value GetSomething(const Napi::CallbackInfo& info); |
| /// void SetSomething(const Napi::CallbackInfo& info, const Napi::Value& |
| /// value); Napi::Value DoSomething(const Napi::CallbackInfo& info); |
| /// } |
| template <typename T> |
| class ObjectWrap : public InstanceWrap<T>, public Reference<Object> { |
| public: |
| ObjectWrap(const CallbackInfo& callbackInfo); |
| virtual ~ObjectWrap(); |
| |
| static T* Unwrap(Object wrapper); |
| |
| // Methods exposed to JavaScript must conform to one of these callback |
| // signatures. |
| using StaticVoidMethodCallback = void (*)(const CallbackInfo& info); |
| using StaticMethodCallback = Napi::Value (*)(const CallbackInfo& info); |
| using StaticGetterCallback = Napi::Value (*)(const CallbackInfo& info); |
| using StaticSetterCallback = void (*)(const CallbackInfo& info, |
| const Napi::Value& value); |
| |
| using PropertyDescriptor = ClassPropertyDescriptor<T>; |
| |
| static Function DefineClass( |
| Napi::Env env, |
| const char* utf8name, |
| const std::initializer_list<PropertyDescriptor>& properties, |
| void* data = nullptr); |
| static Function DefineClass(Napi::Env env, |
| const char* utf8name, |
| const std::vector<PropertyDescriptor>& properties, |
| void* data = nullptr); |
| static PropertyDescriptor StaticMethod( |
| const char* utf8name, |
| StaticVoidMethodCallback method, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor StaticMethod( |
| const char* utf8name, |
| StaticMethodCallback method, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor StaticMethod( |
| Symbol name, |
| StaticVoidMethodCallback method, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor StaticMethod( |
| Symbol name, |
| StaticMethodCallback method, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <StaticVoidMethodCallback method> |
| static PropertyDescriptor StaticMethod( |
| const char* utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <StaticVoidMethodCallback method> |
| static PropertyDescriptor StaticMethod( |
| Symbol name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <StaticMethodCallback method> |
| static PropertyDescriptor StaticMethod( |
| const char* utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <StaticMethodCallback method> |
| static PropertyDescriptor StaticMethod( |
| Symbol name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor StaticAccessor( |
| const char* utf8name, |
| StaticGetterCallback getter, |
| StaticSetterCallback setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor StaticAccessor( |
| Symbol name, |
| StaticGetterCallback getter, |
| StaticSetterCallback setter, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr> |
| static PropertyDescriptor StaticAccessor( |
| const char* utf8name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr> |
| static PropertyDescriptor StaticAccessor( |
| Symbol name, |
| napi_property_attributes attributes = napi_default, |
| void* data = nullptr); |
| static PropertyDescriptor StaticValue( |
| const char* utf8name, |
| Napi::Value value, |
| napi_property_attributes attributes = napi_default); |
| static PropertyDescriptor StaticValue( |
| Symbol name, |
| Napi::Value value, |
| napi_property_attributes attributes = napi_default); |
| static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo); |
| virtual void Finalize(Napi::Env env); |
| virtual void Finalize(BasicEnv env); |
| |
| private: |
| using This = ObjectWrap<T>; |
| |
| static napi_value ConstructorCallbackWrapper(napi_env env, |
| napi_callback_info info); |
| static napi_value StaticVoidMethodCallbackWrapper(napi_env env, |
| napi_callback_info info); |
| static napi_value StaticMethodCallbackWrapper(napi_env env, |
| napi_callback_info info); |
| static napi_value StaticGetterCallbackWrapper(napi_env env, |
| napi_callback_info info); |
| static napi_value StaticSetterCallbackWrapper(napi_env env, |
| napi_callback_info info); |
| static void FinalizeCallback(node_addon_api_basic_env env, |
| void* data, |
| void* hint); |
| |
| static void PostFinalizeCallback(napi_env env, void* data, void* hint); |
| |
| static Function DefineClass(Napi::Env env, |
| const char* utf8name, |
| const size_t props_count, |
| const napi_property_descriptor* props, |
| void* data = nullptr); |
| |
| using StaticVoidMethodCallbackData = |
| MethodCallbackData<T, StaticVoidMethodCallback>; |
| using StaticMethodCallbackData = MethodCallbackData<T, StaticMethodCallback>; |
| |
| using StaticAccessorCallbackData = |
| AccessorCallbackData<T, StaticGetterCallback, StaticSetterCallback>; |
| |
| template <StaticSetterCallback method> |
| static napi_value WrappedMethod(napi_env env, |
| napi_callback_info info) NAPI_NOEXCEPT; |
| |
| template <StaticSetterCallback setter> |
| struct StaticSetterTag {}; |
| |
| template <StaticSetterCallback setter> |
| static napi_callback WrapStaticSetter(StaticSetterTag<setter>) NAPI_NOEXCEPT { |
| return &This::WrappedMethod<setter>; |
| } |
| static napi_callback WrapStaticSetter(StaticSetterTag<nullptr>) |
| NAPI_NOEXCEPT { |
| return nullptr; |
| } |
| |
| bool _construction_failed = true; |
| bool _finalized = false; |
| }; |
| |
| class HandleScope { |
| public: |
| HandleScope(napi_env env, napi_handle_scope scope); |
| explicit HandleScope(Napi::Env env); |
| ~HandleScope(); |
| |
| // Disallow copying to prevent double close of napi_handle_scope |
| NAPI_DISALLOW_ASSIGN_COPY(HandleScope) |
| |
| operator napi_handle_scope() const; |
| |
| Napi::Env Env() const; |
| |
| private: |
| napi_env _env; |
| napi_handle_scope _scope; |
| }; |
| |
| class EscapableHandleScope { |
| public: |
| EscapableHandleScope(napi_env env, napi_escapable_handle_scope scope); |
| explicit EscapableHandleScope(Napi::Env env); |
| ~EscapableHandleScope(); |
| |
| // Disallow copying to prevent double close of napi_escapable_handle_scope |
| NAPI_DISALLOW_ASSIGN_COPY(EscapableHandleScope) |
| |
| operator napi_escapable_handle_scope() const; |
| |
| Napi::Env Env() const; |
| Value Escape(napi_value escapee); |
| |
| private: |
| napi_env _env; |
| napi_escapable_handle_scope _scope; |
| }; |
| |
| #if (NAPI_VERSION > 2) |
| class CallbackScope { |
| public: |
| CallbackScope(napi_env env, napi_callback_scope scope); |
| CallbackScope(napi_env env, napi_async_context context); |
| virtual ~CallbackScope(); |
| |
| // Disallow copying to prevent double close of napi_callback_scope |
| NAPI_DISALLOW_ASSIGN_COPY(CallbackScope) |
| |
| operator napi_callback_scope() const; |
| |
| Napi::Env Env() const; |
| |
| private: |
| napi_env _env; |
| napi_callback_scope _scope; |
| }; |
| #endif |
| |
| class AsyncContext { |
| public: |
| explicit AsyncContext(napi_env env, const char* resource_name); |
| explicit AsyncContext(napi_env env, |
| const char* resource_name, |
| const Object& resource); |
| virtual ~AsyncContext(); |
| |
| AsyncContext(AsyncContext&& other); |
| AsyncContext& operator=(AsyncContext&& other); |
| NAPI_DISALLOW_ASSIGN_COPY(AsyncContext) |
| |
| operator napi_async_context() const; |
| |
| Napi::Env Env() const; |
| |
| private: |
| napi_env _env; |
| napi_async_context _context; |
| }; |
| |
| #if NAPI_HAS_THREADS |
| class AsyncWorker { |
| public: |
| virtual ~AsyncWorker(); |
| |
| NAPI_DISALLOW_ASSIGN_COPY(AsyncWorker) |
| |
| operator napi_async_work() const; |
| |
| Napi::Env Env() const; |
| |
| void Queue(); |
| void Cancel(); |
| void SuppressDestruct(); |
| |
| ObjectReference& Receiver(); |
| FunctionReference& Callback(); |
| |
| virtual void OnExecute(Napi::Env env); |
| virtual void OnWorkComplete(Napi::Env env, napi_status status); |
| |
| protected: |
| explicit AsyncWorker(const Function& callback); |
| explicit AsyncWorker(const Function& callback, const char* resource_name); |
| explicit AsyncWorker(const Function& callback, |
| const char* resource_name, |
| const Object& resource); |
| explicit AsyncWorker(const Object& receiver, const Function& callback); |
| explicit AsyncWorker(const Object& receiver, |
| const Function& callback, |
| const char* resource_name); |
| explicit AsyncWorker(const Object& receiver, |
| const Function& callback, |
| const char* resource_name, |
| const Object& resource); |
| |
| explicit AsyncWorker(Napi::Env env); |
| explicit AsyncWorker(Napi::Env env, const char* resource_name); |
| explicit AsyncWorker(Napi::Env env, |
| const char* resource_name, |
| const Object& resource); |
| |
| virtual void Execute() = 0; |
| virtual void OnOK(); |
| virtual void OnError(const Error& e); |
| virtual void Destroy(); |
| virtual std::vector<napi_value> GetResult(Napi::Env env); |
| |
| void SetError(const std::string& error); |
| |
| private: |
| static inline void OnAsyncWorkExecute(napi_env env, void* asyncworker); |
| static inline void OnAsyncWorkComplete(napi_env env, |
| napi_status status, |
| void* asyncworker); |
| |
| napi_env _env; |
| napi_async_work _work; |
| ObjectReference _receiver; |
| FunctionReference _callback; |
| std::string _error; |
| bool _suppress_destruct; |
| }; |
| #endif // NAPI_HAS_THREADS |
| |
| #if (NAPI_VERSION > 3 && NAPI_HAS_THREADS) |
| class ThreadSafeFunction { |
| public: |
| // This API may only be called from the main thread. |
| template <typename ResourceString> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, typename ContextType> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, typename Finalizer> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| Finalizer finalizeCallback); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, |
| typename Finalizer, |
| typename FinalizerDataType> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, typename ContextType, typename Finalizer> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, |
| typename ContextType, |
| typename Finalizer, |
| typename FinalizerDataType> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, typename ContextType> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, typename Finalizer> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| Finalizer finalizeCallback); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, |
| typename Finalizer, |
| typename FinalizerDataType> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, typename ContextType, typename Finalizer> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback); |
| |
| // This API may only be called from the main thread. |
| template <typename ResourceString, |
| typename ContextType, |
| typename Finalizer, |
| typename FinalizerDataType> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data); |
| |
| ThreadSafeFunction(); |
| ThreadSafeFunction(napi_threadsafe_function tsFunctionValue); |
| |
| operator napi_threadsafe_function() const; |
| |
| // This API may be called from any thread. |
| napi_status BlockingCall() const; |
| |
| // This API may be called from any thread. |
| template <typename Callback> |
| napi_status BlockingCall(Callback callback) const; |
| |
| // This API may be called from any thread. |
| template <typename DataType, typename Callback> |
| napi_status BlockingCall(DataType* data, Callback callback) const; |
| |
| // This API may be called from any thread. |
| napi_status NonBlockingCall() const; |
| |
| // This API may be called from any thread. |
| template <typename Callback> |
| napi_status NonBlockingCall(Callback callback) const; |
| |
| // This API may be called from any thread. |
| template <typename DataType, typename Callback> |
| napi_status NonBlockingCall(DataType* data, Callback callback) const; |
| |
| // This API may only be called from the main thread. |
| void Ref(napi_env env) const; |
| |
| // This API may only be called from the main thread. |
| void Unref(napi_env env) const; |
| |
| // This API may be called from any thread. |
| napi_status Acquire() const; |
| |
| // This API may be called from any thread. |
| napi_status Release() const; |
| |
| // This API may be called from any thread. |
| napi_status Abort() const; |
| |
| struct ConvertibleContext { |
| template <class T> |
| operator T*() { |
| return static_cast<T*>(context); |
| } |
| void* context; |
| }; |
| |
| // This API may be called from any thread. |
| ConvertibleContext GetContext() const; |
| |
| private: |
| using CallbackWrapper = std::function<void(Napi::Env, Napi::Function)>; |
| |
| template <typename ResourceString, |
| typename ContextType, |
| typename Finalizer, |
| typename FinalizerDataType> |
| static ThreadSafeFunction New(napi_env env, |
| const Function& callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data, |
| napi_finalize wrapper); |
| |
| napi_status CallInternal(CallbackWrapper* callbackWrapper, |
| napi_threadsafe_function_call_mode mode) const; |
| |
| static void CallJS(napi_env env, |
| napi_value jsCallback, |
| void* context, |
| void* data); |
| |
| napi_threadsafe_function _tsfn; |
| }; |
| |
| // A TypedThreadSafeFunction by default has no context (nullptr) and can |
| // accept any type (void) to its CallJs. |
| template <typename ContextType = std::nullptr_t, |
| typename DataType = void, |
| void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*) = |
| nullptr> |
| class TypedThreadSafeFunction { |
| public: |
| // This API may only be called from the main thread. |
| // Helper function that returns nullptr if running Node-API 5+, otherwise a |
| // non-empty, no-op Function. This provides the ability to specify at |
| // compile-time a callback parameter to `New` that safely does no action |
| // when targeting _any_ Node-API version. |
| #if NAPI_VERSION > 4 |
| static std::nullptr_t EmptyFunctionFactory(Napi::Env env); |
| #else |
| static Napi::Function EmptyFunctionFactory(Napi::Env env); |
| #endif |
| static Napi::Function FunctionOrEmpty(Napi::Env env, |
| Napi::Function& callback); |
| |
| #if NAPI_VERSION > 4 |
| // This API may only be called from the main thread. |
| // Creates a new threadsafe function with: |
| // Callback [missing] Resource [missing] Finalizer [missing] |
| template <typename ResourceString> |
| static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( |
| napi_env env, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context = nullptr); |
| |
| // This API may only be called from the main thread. |
| // Creates a new threadsafe function with: |
| // Callback [missing] Resource [passed] Finalizer [missing] |
| template <typename ResourceString> |
| static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( |
| napi_env env, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context = nullptr); |
| |
| // This API may only be called from the main thread. |
| // Creates a new threadsafe function with: |
| // Callback [missing] Resource [missing] Finalizer [passed] |
| template <typename ResourceString, |
| typename Finalizer, |
| typename FinalizerDataType = void> |
| static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( |
| napi_env env, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data = nullptr); |
| |
| // This API may only be called from the main thread. |
| // Creates a new threadsafe function with: |
| // Callback [missing] Resource [passed] Finalizer [passed] |
| template <typename ResourceString, |
| typename Finalizer, |
| typename FinalizerDataType = void> |
| static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( |
| napi_env env, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data = nullptr); |
| #endif |
| |
| // This API may only be called from the main thread. |
| // Creates a new threadsafe function with: |
| // Callback [passed] Resource [missing] Finalizer [missing] |
| template <typename ResourceString> |
| static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( |
| napi_env env, |
| const Function& callback, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context = nullptr); |
| |
| // This API may only be called from the main thread. |
| // Creates a new threadsafe function with: |
| // Callback [passed] Resource [passed] Finalizer [missing] |
| template <typename ResourceString> |
| static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( |
| napi_env env, |
| const Function& callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context = nullptr); |
| |
| // This API may only be called from the main thread. |
| // Creates a new threadsafe function with: |
| // Callback [passed] Resource [missing] Finalizer [passed] |
| template <typename ResourceString, |
| typename Finalizer, |
| typename FinalizerDataType = void> |
| static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( |
| napi_env env, |
| const Function& callback, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data = nullptr); |
| |
| // This API may only be called from the main thread. |
| // Creates a new threadsafe function with: |
| // Callback [passed] Resource [passed] Finalizer [passed] |
| template <typename CallbackType, |
| typename ResourceString, |
| typename Finalizer, |
| typename FinalizerDataType> |
| static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( |
| napi_env env, |
| CallbackType callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data = nullptr); |
| |
| TypedThreadSafeFunction(); |
| TypedThreadSafeFunction(napi_threadsafe_function tsFunctionValue); |
| |
| operator napi_threadsafe_function() const; |
| |
| // This API may be called from any thread. |
| napi_status BlockingCall(DataType* data = nullptr) const; |
| |
| // This API may be called from any thread. |
| napi_status NonBlockingCall(DataType* data = nullptr) const; |
| |
| // This API may only be called from the main thread. |
| void Ref(napi_env env) const; |
| |
| // This API may only be called from the main thread. |
| void Unref(napi_env env) const; |
| |
| // This API may be called from any thread. |
| napi_status Acquire() const; |
| |
| // This API may be called from any thread. |
| napi_status Release() const; |
| |
| // This API may be called from any thread. |
| napi_status Abort() const; |
| |
| // This API may be called from any thread. |
| ContextType* GetContext() const; |
| |
| private: |
| template <typename ResourceString, |
| typename Finalizer, |
| typename FinalizerDataType> |
| static TypedThreadSafeFunction<ContextType, DataType, CallJs> New( |
| napi_env env, |
| const Function& callback, |
| const Object& resource, |
| ResourceString resourceName, |
| size_t maxQueueSize, |
| size_t initialThreadCount, |
| ContextType* context, |
| Finalizer finalizeCallback, |
| FinalizerDataType* data, |
| napi_finalize wrapper); |
| |
| static void CallJsInternal(napi_env env, |
| napi_value jsCallback, |
| void* context, |
| void* data); |
| |
| protected: |
| napi_threadsafe_function _tsfn; |
| }; |
| template <typename DataType> |
| class AsyncProgressWorkerBase : public AsyncWorker { |
| public: |
| virtual void OnWorkProgress(DataType* data) = 0; |
| class ThreadSafeData { |
| public: |
| ThreadSafeData(AsyncProgressWorkerBase* asyncprogressworker, DataType* data) |
| : _asyncprogressworker(asyncprogressworker), _data(data) {} |
| |
| AsyncProgressWorkerBase* asyncprogressworker() { |
| return _asyncprogressworker; |
| }; |
| DataType* data() { return _data; }; |
| |
| private: |
| AsyncProgressWorkerBase* _asyncprogressworker; |
| DataType* _data; |
| }; |
| void OnWorkComplete(Napi::Env env, napi_status status) override; |
| |
| protected: |
| explicit AsyncProgressWorkerBase(const Object& receiver, |
| const Function& callback, |
| const char* resource_name, |
| const Object& resource, |
| size_t queue_size = 1); |
| virtual ~AsyncProgressWorkerBase(); |
| |
| // Optional callback of Napi::ThreadSafeFunction only available after |
| // NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791 |
| #if NAPI_VERSION > 4 |
| explicit AsyncProgressWorkerBase(Napi::Env env, |
| const char* resource_name, |
| const Object& resource, |
| size_t queue_size = 1); |
| #endif |
| |
| static inline void OnAsyncWorkProgress(Napi::Env env, |
| Napi::Function jsCallback, |
| void* data); |
| |
| napi_status NonBlockingCall(DataType* data); |
| |
| private: |
| ThreadSafeFunction _tsfn; |
| bool _work_completed = false; |
| napi_status _complete_status; |
| static inline void OnThreadSafeFunctionFinalize( |
| Napi::Env env, void* data, AsyncProgressWorkerBase* context); |
| }; |
| |
| template <class T> |
| class AsyncProgressWorker : public AsyncProgressWorkerBase<void> { |
| public: |
| virtual ~AsyncProgressWorker(); |
| |
| class ExecutionProgress { |
| friend class AsyncProgressWorker; |
| |
| public: |
| void Signal() const; |
| void Send(const T* data, size_t count) const; |
| |
| private: |
| explicit ExecutionProgress(AsyncProgressWorker* worker) : _worker(worker) {} |
| AsyncProgressWorker* const _worker; |
| }; |
| |
| void OnWorkProgress(void*) override; |
| |
| protected: |
| explicit AsyncProgressWorker(const Function& callback); |
| explicit AsyncProgressWorker(const Function& callback, |
| const char* resource_name); |
| explicit AsyncProgressWorker(const Function& callback, |
| const char* resource_name, |
| const Object& resource); |
| explicit AsyncProgressWorker(const Object& receiver, |
| const Function& callback); |
| explicit AsyncProgressWorker(const Object& receiver, |
| const Function& callback, |
| const char* resource_name); |
| explicit AsyncProgressWorker(const Object& receiver, |
| const Function& callback, |
| const char* resource_name, |
| const Object& resource); |
| |
| // Optional callback of Napi::ThreadSafeFunction only available after |
| // NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791 |
| #if NAPI_VERSION > 4 |
| explicit AsyncProgressWorker(Napi::Env env); |
| explicit AsyncProgressWorker(Napi::Env env, const char* resource_name); |
| explicit AsyncProgressWorker(Napi::Env env, |
| const char* resource_name, |
| const Object& resource); |
| #endif |
| virtual void Execute(const ExecutionProgress& progress) = 0; |
| virtual void OnProgress(const T* data, size_t count) = 0; |
| |
| private: |
| void Execute() override; |
| void Signal(); |
| void SendProgress_(const T* data, size_t count); |
| |
| std::mutex _mutex; |
| T* _asyncdata; |
| size_t _asyncsize; |
| bool _signaled; |
| }; |
| |
| template <class T> |
| class AsyncProgressQueueWorker |
| : public AsyncProgressWorkerBase<std::pair<T*, size_t>> { |
| public: |
| virtual ~AsyncProgressQueueWorker(){}; |
| |
| class ExecutionProgress { |
| friend class AsyncProgressQueueWorker; |
| |
| public: |
| void Signal() const; |
| void Send(const T* data, size_t count) const; |
| |
| private: |
| explicit ExecutionProgress(AsyncProgressQueueWorker* worker) |
| : _worker(worker) {} |
| AsyncProgressQueueWorker* const _worker; |
| }; |
| |
| void OnWorkComplete(Napi::Env env, napi_status status) override; |
| void OnWorkProgress(std::pair<T*, size_t>*) override; |
| |
| protected: |
| explicit AsyncProgressQueueWorker(const Function& callback); |
| explicit AsyncProgressQueueWorker(const Function& callback, |
| const char* resource_name); |
| explicit AsyncProgressQueueWorker(const Function& callback, |
| const char* resource_name, |
| const Object& resource); |
| explicit AsyncProgressQueueWorker(const Object& receiver, |
| const Function& callback); |
| explicit AsyncProgressQueueWorker(const Object& receiver, |
| const Function& callback, |
| const char* resource_name); |
| explicit AsyncProgressQueueWorker(const Object& receiver, |
| const Function& callback, |
| const char* resource_name, |
| const Object& resource); |
| |
| // Optional callback of Napi::ThreadSafeFunction only available after |
| // NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791 |
| #if NAPI_VERSION > 4 |
| explicit AsyncProgressQueueWorker(Napi::Env env); |
| explicit AsyncProgressQueueWorker(Napi::Env env, const char* resource_name); |
| explicit AsyncProgressQueueWorker(Napi::Env env, |
| const char* resource_name, |
| const Object& resource); |
| #endif |
| virtual void Execute(const ExecutionProgress& progress) = 0; |
| virtual void OnProgress(const T* data, size_t count) = 0; |
| |
| private: |
| void Execute() override; |
| void Signal() const; |
| void SendProgress_(const T* data, size_t count); |
| }; |
| #endif // NAPI_VERSION > 3 && NAPI_HAS_THREADS |
| |
| // Memory management. |
| class MemoryManagement { |
| public: |
| static int64_t AdjustExternalMemory(BasicEnv env, int64_t change_in_bytes); |
| }; |
| |
| // Version management |
| class VersionManagement { |
| public: |
| static uint32_t GetNapiVersion(BasicEnv env); |
| static const napi_node_version* GetNodeVersion(BasicEnv env); |
| }; |
| |
| #if NAPI_VERSION > 5 |
| template <typename T> |
| class Addon : public InstanceWrap<T> { |
| public: |
| static inline Object Init(Env env, Object exports); |
| static T* Unwrap(Object wrapper); |
| |
| protected: |
| using AddonProp = ClassPropertyDescriptor<T>; |
| void DefineAddon(Object exports, |
| const std::initializer_list<AddonProp>& props); |
| Napi::Object DefineProperties(Object object, |
| const std::initializer_list<AddonProp>& props); |
| |
| private: |
| Object entry_point_; |
| }; |
| #endif // NAPI_VERSION > 5 |
| |
| #ifdef NAPI_CPP_CUSTOM_NAMESPACE |
| } // namespace NAPI_CPP_CUSTOM_NAMESPACE |
| #endif |
| |
| } // namespace Napi |
| |
| // Inline implementations of all the above class methods are included here. |
| #include "napi-inl.h" |
| |
| #endif // SRC_NAPI_H_ |