source: imaps-frontend/node_modules/node-addon-api/napi.h

main
Last change on this file was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 112.7 KB
RevLine 
[0c6b92a]1#ifndef SRC_NAPI_H_
2#define SRC_NAPI_H_
3
4#ifndef NAPI_HAS_THREADS
5#if !defined(__wasm__) || (defined(__EMSCRIPTEN_PTHREADS__) || \
6 (defined(__wasi__) && defined(_REENTRANT)))
7#define NAPI_HAS_THREADS 1
8#else
9#define NAPI_HAS_THREADS 0
10#endif
11#endif
12
13#include <node_api.h>
14#include <functional>
15#include <initializer_list>
16#include <memory>
17#if NAPI_HAS_THREADS
18#include <mutex>
19#endif // NAPI_HAS_THREADS
20#include <string>
21#include <vector>
22
23// VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known
24// good version)
25#if !defined(_MSC_VER) || _MSC_FULL_VER >= 190024210
26#define NAPI_HAS_CONSTEXPR 1
27#endif
28
29// VS2013 does not support char16_t literal strings, so we'll work around it
30// using wchar_t strings and casting them. This is safe as long as the character
31// sizes are the same.
32#if defined(_MSC_VER) && _MSC_VER <= 1800
33static_assert(sizeof(char16_t) == sizeof(wchar_t),
34 "Size mismatch between char16_t and wchar_t");
35#define NAPI_WIDE_TEXT(x) reinterpret_cast<char16_t*>(L##x)
36#else
37#define NAPI_WIDE_TEXT(x) u##x
38#endif
39
40// If C++ exceptions are not explicitly enabled or disabled, enable them
41// if exceptions were enabled in the compiler settings.
42#if !defined(NAPI_CPP_EXCEPTIONS) && !defined(NAPI_DISABLE_CPP_EXCEPTIONS)
43#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
44#define NAPI_CPP_EXCEPTIONS
45#else
46#error Exception support not detected. \
47 Define either NAPI_CPP_EXCEPTIONS or NAPI_DISABLE_CPP_EXCEPTIONS.
48#endif
49#endif
50
51// If C++ NAPI_CPP_EXCEPTIONS are enabled, NODE_ADDON_API_ENABLE_MAYBE should
52// not be set
53#if defined(NAPI_CPP_EXCEPTIONS) && defined(NODE_ADDON_API_ENABLE_MAYBE)
54#error NODE_ADDON_API_ENABLE_MAYBE should not be set when \
55 NAPI_CPP_EXCEPTIONS is defined.
56#endif
57
58#ifdef _NOEXCEPT
59#define NAPI_NOEXCEPT _NOEXCEPT
60#else
61#define NAPI_NOEXCEPT noexcept
62#endif
63
64#ifdef NAPI_CPP_EXCEPTIONS
65
66// When C++ exceptions are enabled, Errors are thrown directly. There is no need
67// to return anything after the throw statements. The variadic parameter is an
68// optional return value that is ignored.
69// We need _VOID versions of the macros to avoid warnings resulting from
70// leaving the NAPI_THROW_* `...` argument empty.
71
72#define NAPI_THROW(e, ...) throw e
73#define NAPI_THROW_VOID(e) throw e
74
75#define NAPI_THROW_IF_FAILED(env, status, ...) \
76 if ((status) != napi_ok) throw Napi::Error::New(env);
77
78#define NAPI_THROW_IF_FAILED_VOID(env, status) \
79 if ((status) != napi_ok) throw Napi::Error::New(env);
80
81#else // NAPI_CPP_EXCEPTIONS
82
83// When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions,
84// which are pending until the callback returns to JS. The variadic parameter
85// is an optional return value; usually it is an empty result.
86// We need _VOID versions of the macros to avoid warnings resulting from
87// leaving the NAPI_THROW_* `...` argument empty.
88
89#define NAPI_THROW(e, ...) \
90 do { \
91 (e).ThrowAsJavaScriptException(); \
92 return __VA_ARGS__; \
93 } while (0)
94
95#define NAPI_THROW_VOID(e) \
96 do { \
97 (e).ThrowAsJavaScriptException(); \
98 return; \
99 } while (0)
100
101#define NAPI_THROW_IF_FAILED(env, status, ...) \
102 if ((status) != napi_ok) { \
103 Napi::Error::New(env).ThrowAsJavaScriptException(); \
104 return __VA_ARGS__; \
105 }
106
107#define NAPI_THROW_IF_FAILED_VOID(env, status) \
108 if ((status) != napi_ok) { \
109 Napi::Error::New(env).ThrowAsJavaScriptException(); \
110 return; \
111 }
112
113#endif // NAPI_CPP_EXCEPTIONS
114
115#ifdef NODE_ADDON_API_ENABLE_MAYBE
116#define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \
117 NAPI_THROW_IF_FAILED(env, status, Napi::Nothing<type>())
118
119#define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \
120 NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \
121 return Napi::Just<type>(result);
122#else
123#define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \
124 NAPI_THROW_IF_FAILED(env, status, type())
125
126#define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \
127 NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \
128 return result;
129#endif
130
131#define NAPI_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete;
132#define NAPI_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete;
133
134#define NAPI_DISALLOW_ASSIGN_COPY(CLASS) \
135 NAPI_DISALLOW_ASSIGN(CLASS) \
136 NAPI_DISALLOW_COPY(CLASS)
137
138#define NAPI_CHECK(condition, location, message) \
139 do { \
140 if (!(condition)) { \
141 Napi::Error::Fatal((location), (message)); \
142 } \
143 } while (0)
144
145#define NAPI_FATAL_IF_FAILED(status, location, message) \
146 NAPI_CHECK((status) == napi_ok, location, message)
147
148////////////////////////////////////////////////////////////////////////////////
149/// Node-API C++ Wrapper Classes
150///
151/// These classes wrap the "Node-API" ABI-stable C APIs for Node.js, providing a
152/// C++ object model and C++ exception-handling semantics with low overhead.
153/// The wrappers are all header-only so that they do not affect the ABI.
154////////////////////////////////////////////////////////////////////////////////
155namespace Napi {
156
157#ifdef NAPI_CPP_CUSTOM_NAMESPACE
158// NAPI_CPP_CUSTOM_NAMESPACE can be #define'd per-addon to avoid symbol
159// conflicts between different instances of node-addon-api
160
161// First dummy definition of the namespace to make sure that Napi::(name) still
162// refers to the right things inside this file.
163namespace NAPI_CPP_CUSTOM_NAMESPACE {}
164using namespace NAPI_CPP_CUSTOM_NAMESPACE;
165
166namespace NAPI_CPP_CUSTOM_NAMESPACE {
167#endif
168
169// Forward declarations
170class Env;
171class Value;
172class Boolean;
173class Number;
174#if NAPI_VERSION > 5
175class BigInt;
176#endif // NAPI_VERSION > 5
177#if (NAPI_VERSION > 4)
178class Date;
179#endif
180class String;
181class Object;
182class Array;
183class ArrayBuffer;
184class Function;
185class Error;
186class PropertyDescriptor;
187class CallbackInfo;
188class TypedArray;
189template <typename T>
190class TypedArrayOf;
191
192using Int8Array =
193 TypedArrayOf<int8_t>; ///< Typed-array of signed 8-bit integers
194using Uint8Array =
195 TypedArrayOf<uint8_t>; ///< Typed-array of unsigned 8-bit integers
196using Int16Array =
197 TypedArrayOf<int16_t>; ///< Typed-array of signed 16-bit integers
198using Uint16Array =
199 TypedArrayOf<uint16_t>; ///< Typed-array of unsigned 16-bit integers
200using Int32Array =
201 TypedArrayOf<int32_t>; ///< Typed-array of signed 32-bit integers
202using Uint32Array =
203 TypedArrayOf<uint32_t>; ///< Typed-array of unsigned 32-bit integers
204using Float32Array =
205 TypedArrayOf<float>; ///< Typed-array of 32-bit floating-point values
206using Float64Array =
207 TypedArrayOf<double>; ///< Typed-array of 64-bit floating-point values
208#if NAPI_VERSION > 5
209using BigInt64Array =
210 TypedArrayOf<int64_t>; ///< Typed array of signed 64-bit integers
211using BigUint64Array =
212 TypedArrayOf<uint64_t>; ///< Typed array of unsigned 64-bit integers
213#endif // NAPI_VERSION > 5
214
215/// Defines the signature of a Node-API C++ module's registration callback
216/// (init) function.
217using ModuleRegisterCallback = Object (*)(Env env, Object exports);
218
219class MemoryManagement;
220
221/// A simple Maybe type, representing an object which may or may not have a
222/// value.
223///
224/// If an API method returns a Maybe<>, the API method can potentially fail
225/// either because an exception is thrown, or because an exception is pending,
226/// e.g. because a previous API call threw an exception that hasn't been
227/// caught yet. In that case, a "Nothing" value is returned.
228template <class T>
229class Maybe {
230 public:
231 bool IsNothing() const;
232 bool IsJust() const;
233
234 /// Short-hand for Unwrap(), which doesn't return a value. Could be used
235 /// where the actual value of the Maybe is not needed like Object::Set.
236 /// If this Maybe is nothing (empty), node-addon-api will crash the
237 /// process.
238 void Check() const;
239
240 /// Return the value of type T contained in the Maybe. If this Maybe is
241 /// nothing (empty), node-addon-api will crash the process.
242 T Unwrap() const;
243
244 /// Return the value of type T contained in the Maybe, or using a default
245 /// value if this Maybe is nothing (empty).
246 T UnwrapOr(const T& default_value) const;
247
248 /// Converts this Maybe to a value of type T in the out. If this Maybe is
249 /// nothing (empty), `false` is returned and `out` is left untouched.
250 bool UnwrapTo(T* out) const;
251
252 bool operator==(const Maybe& other) const;
253 bool operator!=(const Maybe& other) const;
254
255 private:
256 Maybe();
257 explicit Maybe(const T& t);
258
259 bool _has_value;
260 T _value;
261
262 template <class U>
263 friend Maybe<U> Nothing();
264 template <class U>
265 friend Maybe<U> Just(const U& u);
266};
267
268template <class T>
269inline Maybe<T> Nothing();
270
271template <class T>
272inline Maybe<T> Just(const T& t);
273
274#if defined(NODE_ADDON_API_ENABLE_MAYBE)
275template <typename T>
276using MaybeOrValue = Maybe<T>;
277#else
278template <typename T>
279using MaybeOrValue = T;
280#endif
281
282/// Environment for Node-API values and operations.
283///
284/// All Node-API values and operations must be associated with an environment.
285/// An environment instance is always provided to callback functions; that
286/// environment must then be used for any creation of Node-API values or other
287/// Node-API operations within the callback. (Many methods infer the
288/// environment from the `this` instance that the method is called on.)
289///
290/// In the future, multiple environments per process may be supported,
291/// although current implementations only support one environment per process.
292///
293/// In the V8 JavaScript engine, a Node-API environment approximately
294/// corresponds to an Isolate.
295class Env {
296 private:
297 napi_env _env;
298#if NAPI_VERSION > 5
299 template <typename T>
300 static void DefaultFini(Env, T* data);
301 template <typename DataType, typename HintType>
302 static void DefaultFiniWithHint(Env, DataType* data, HintType* hint);
303#endif // NAPI_VERSION > 5
304 public:
305 Env(napi_env env);
306
307 operator napi_env() const;
308
309 Object Global() const;
310 Value Undefined() const;
311 Value Null() const;
312
313 bool IsExceptionPending() const;
314 Error GetAndClearPendingException() const;
315
316 MaybeOrValue<Value> RunScript(const char* utf8script) const;
317 MaybeOrValue<Value> RunScript(const std::string& utf8script) const;
318 MaybeOrValue<Value> RunScript(String script) const;
319
320#if NAPI_VERSION > 2
321 template <typename Hook, typename Arg = void>
322 class CleanupHook;
323
324 template <typename Hook>
325 CleanupHook<Hook> AddCleanupHook(Hook hook);
326
327 template <typename Hook, typename Arg>
328 CleanupHook<Hook, Arg> AddCleanupHook(Hook hook, Arg* arg);
329#endif // NAPI_VERSION > 2
330
331#if NAPI_VERSION > 5
332 template <typename T>
333 T* GetInstanceData() const;
334
335 template <typename T>
336 using Finalizer = void (*)(Env, T*);
337 template <typename T, Finalizer<T> fini = Env::DefaultFini<T>>
338 void SetInstanceData(T* data) const;
339
340 template <typename DataType, typename HintType>
341 using FinalizerWithHint = void (*)(Env, DataType*, HintType*);
342 template <typename DataType,
343 typename HintType,
344 FinalizerWithHint<DataType, HintType> fini =
345 Env::DefaultFiniWithHint<DataType, HintType>>
346 void SetInstanceData(DataType* data, HintType* hint) const;
347#endif // NAPI_VERSION > 5
348
349#if NAPI_VERSION > 2
350 template <typename Hook, typename Arg>
351 class CleanupHook {
352 public:
353 CleanupHook();
354 CleanupHook(Env env, Hook hook, Arg* arg);
355 CleanupHook(Env env, Hook hook);
356 bool Remove(Env env);
357 bool IsEmpty() const;
358
359 private:
360 static inline void Wrapper(void* data) NAPI_NOEXCEPT;
361 static inline void WrapperWithArg(void* data) NAPI_NOEXCEPT;
362
363 void (*wrapper)(void* arg);
364 struct CleanupData {
365 Hook hook;
366 Arg* arg;
367 } * data;
368 };
369#endif // NAPI_VERSION > 2
370
371#if NAPI_VERSION > 8
372 const char* GetModuleFileName() const;
373#endif // NAPI_VERSION > 8
374};
375
376/// A JavaScript value of unknown type.
377///
378/// For type-specific operations, convert to one of the Value subclasses using a
379/// `To*` or `As()` method. The `To*` methods do type coercion; the `As()`
380/// method does not.
381///
382/// Napi::Value value = ...
383/// if (!value.IsString()) throw Napi::TypeError::New(env, "Invalid
384/// arg..."); Napi::String str = value.As<Napi::String>(); // Cast to a
385/// string value
386///
387/// Napi::Value anotherValue = ...
388/// bool isTruthy = anotherValue.ToBoolean(); // Coerce to a boolean value
389class Value {
390 public:
391 Value(); ///< Creates a new _empty_ Value instance.
392 Value(napi_env env,
393 napi_value value); ///< Wraps a Node-API value primitive.
394
395 /// Creates a JS value from a C++ primitive.
396 ///
397 /// `value` may be any of:
398 /// - bool
399 /// - Any integer type
400 /// - Any floating point type
401 /// - const char* (encoded using UTF-8, null-terminated)
402 /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
403 /// - std::string (encoded using UTF-8)
404 /// - std::u16string
405 /// - napi::Value
406 /// - napi_value
407 template <typename T>
408 static Value From(napi_env env, const T& value);
409
410 /// Converts to a Node-API value primitive.
411 ///
412 /// If the instance is _empty_, this returns `nullptr`.
413 operator napi_value() const;
414
415 /// Tests if this value strictly equals another value.
416 bool operator==(const Value& other) const;
417
418 /// Tests if this value does not strictly equal another value.
419 bool operator!=(const Value& other) const;
420
421 /// Tests if this value strictly equals another value.
422 bool StrictEquals(const Value& other) const;
423
424 /// Gets the environment the value is associated with.
425 Napi::Env Env() const;
426
427 /// Checks if the value is empty (uninitialized).
428 ///
429 /// An empty value is invalid, and most attempts to perform an operation on an
430 /// empty value will result in an exception. Note an empty value is distinct
431 /// from JavaScript `null` or `undefined`, which are valid values.
432 ///
433 /// When C++ exceptions are disabled at compile time, a method with a `Value`
434 /// return type may return an empty value to indicate a pending exception. So
435 /// when not using C++ exceptions, callers should check whether the value is
436 /// empty before attempting to use it.
437 bool IsEmpty() const;
438
439 napi_valuetype Type() const; ///< Gets the type of the value.
440
441 bool IsUndefined()
442 const; ///< Tests if a value is an undefined JavaScript value.
443 bool IsNull() const; ///< Tests if a value is a null JavaScript value.
444 bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean.
445 bool IsNumber() const; ///< Tests if a value is a JavaScript number.
446#if NAPI_VERSION > 5
447 bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint.
448#endif // NAPI_VERSION > 5
449#if (NAPI_VERSION > 4)
450 bool IsDate() const; ///< Tests if a value is a JavaScript date.
451#endif
452 bool IsString() const; ///< Tests if a value is a JavaScript string.
453 bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol.
454 bool IsArray() const; ///< Tests if a value is a JavaScript array.
455 bool IsArrayBuffer()
456 const; ///< Tests if a value is a JavaScript array buffer.
457 bool IsTypedArray() const; ///< Tests if a value is a JavaScript typed array.
458 bool IsObject() const; ///< Tests if a value is a JavaScript object.
459 bool IsFunction() const; ///< Tests if a value is a JavaScript function.
460 bool IsPromise() const; ///< Tests if a value is a JavaScript promise.
461 bool IsDataView() const; ///< Tests if a value is a JavaScript data view.
462 bool IsBuffer() const; ///< Tests if a value is a Node buffer.
463 bool IsExternal() const; ///< Tests if a value is a pointer to external data.
464
465 /// Casts to another type of `Napi::Value`, when the actual type is known or
466 /// assumed.
467 ///
468 /// This conversion does NOT coerce the type. Calling any methods
469 /// inappropriate for the actual value type will throw `Napi::Error`.
470 ///
471 /// If `NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS` is defined, this method
472 /// asserts that the actual type is the expected type.
473 template <typename T>
474 T As() const;
475
476 MaybeOrValue<Boolean> ToBoolean()
477 const; ///< Coerces a value to a JavaScript boolean.
478 MaybeOrValue<Number> ToNumber()
479 const; ///< Coerces a value to a JavaScript number.
480 MaybeOrValue<String> ToString()
481 const; ///< Coerces a value to a JavaScript string.
482 MaybeOrValue<Object> ToObject()
483 const; ///< Coerces a value to a JavaScript object.
484
485 protected:
486 /// !cond INTERNAL
487 napi_env _env;
488 napi_value _value;
489 /// !endcond
490};
491
492/// A JavaScript boolean value.
493class Boolean : public Value {
494 public:
495 static Boolean New(napi_env env, ///< Node-API environment
496 bool value ///< Boolean value
497 );
498
499 static void CheckCast(napi_env env, napi_value value);
500
501 Boolean(); ///< Creates a new _empty_ Boolean instance.
502 Boolean(napi_env env,
503 napi_value value); ///< Wraps a Node-API value primitive.
504
505 operator bool() const; ///< Converts a Boolean value to a boolean primitive.
506 bool Value() const; ///< Converts a Boolean value to a boolean primitive.
507};
508
509/// A JavaScript number value.
510class Number : public Value {
511 public:
512 static Number New(napi_env env, ///< Node-API environment
513 double value ///< Number value
514 );
515
516 static void CheckCast(napi_env env, napi_value value);
517
518 Number(); ///< Creates a new _empty_ Number instance.
519 Number(napi_env env,
520 napi_value value); ///< Wraps a Node-API value primitive.
521
522 operator int32_t()
523 const; ///< Converts a Number value to a 32-bit signed integer value.
524 operator uint32_t()
525 const; ///< Converts a Number value to a 32-bit unsigned integer value.
526 operator int64_t()
527 const; ///< Converts a Number value to a 64-bit signed integer value.
528 operator float()
529 const; ///< Converts a Number value to a 32-bit floating-point value.
530 operator double()
531 const; ///< Converts a Number value to a 64-bit floating-point value.
532
533 int32_t Int32Value()
534 const; ///< Converts a Number value to a 32-bit signed integer value.
535 uint32_t Uint32Value()
536 const; ///< Converts a Number value to a 32-bit unsigned integer value.
537 int64_t Int64Value()
538 const; ///< Converts a Number value to a 64-bit signed integer value.
539 float FloatValue()
540 const; ///< Converts a Number value to a 32-bit floating-point value.
541 double DoubleValue()
542 const; ///< Converts a Number value to a 64-bit floating-point value.
543};
544
545#if NAPI_VERSION > 5
546/// A JavaScript bigint value.
547class BigInt : public Value {
548 public:
549 static BigInt New(napi_env env, ///< Node-API environment
550 int64_t value ///< Number value
551 );
552 static BigInt New(napi_env env, ///< Node-API environment
553 uint64_t value ///< Number value
554 );
555
556 /// Creates a new BigInt object using a specified sign bit and a
557 /// specified list of digits/words.
558 /// The resulting number is calculated as:
559 /// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...)
560 static BigInt New(napi_env env, ///< Node-API environment
561 int sign_bit, ///< Sign bit. 1 if negative.
562 size_t word_count, ///< Number of words in array
563 const uint64_t* words ///< Array of words
564 );
565
566 static void CheckCast(napi_env env, napi_value value);
567
568 BigInt(); ///< Creates a new _empty_ BigInt instance.
569 BigInt(napi_env env,
570 napi_value value); ///< Wraps a Node-API value primitive.
571
572 int64_t Int64Value(bool* lossless)
573 const; ///< Converts a BigInt value to a 64-bit signed integer value.
574 uint64_t Uint64Value(bool* lossless)
575 const; ///< Converts a BigInt value to a 64-bit unsigned integer value.
576
577 size_t WordCount() const; ///< The number of 64-bit words needed to store
578 ///< the result of ToWords().
579
580 /// Writes the contents of this BigInt to a specified memory location.
581 /// `sign_bit` must be provided and will be set to 1 if this BigInt is
582 /// negative.
583 /// `*word_count` has to be initialized to the length of the `words` array.
584 /// Upon return, it will be set to the actual number of words that would
585 /// be needed to store this BigInt (i.e. the return value of `WordCount()`).
586 void ToWords(int* sign_bit, size_t* word_count, uint64_t* words);
587};
588#endif // NAPI_VERSION > 5
589
590#if (NAPI_VERSION > 4)
591/// A JavaScript date value.
592class Date : public Value {
593 public:
594 /// Creates a new Date value from a double primitive.
595 static Date New(napi_env env, ///< Node-API environment
596 double value ///< Number value
597 );
598
599 static void CheckCast(napi_env env, napi_value value);
600
601 Date(); ///< Creates a new _empty_ Date instance.
602 Date(napi_env env, napi_value value); ///< Wraps a Node-API value primitive.
603 operator double() const; ///< Converts a Date value to double primitive
604
605 double ValueOf() const; ///< Converts a Date value to a double primitive.
606};
607#endif
608
609/// A JavaScript string or symbol value (that can be used as a property name).
610class Name : public Value {
611 public:
612 static void CheckCast(napi_env env, napi_value value);
613
614 Name(); ///< Creates a new _empty_ Name instance.
615 Name(napi_env env,
616 napi_value value); ///< Wraps a Node-API value primitive.
617};
618
619/// A JavaScript string value.
620class String : public Name {
621 public:
622 /// Creates a new String value from a UTF-8 encoded C++ string.
623 static String New(napi_env env, ///< Node-API environment
624 const std::string& value ///< UTF-8 encoded C++ string
625 );
626
627 /// Creates a new String value from a UTF-16 encoded C++ string.
628 static String New(napi_env env, ///< Node-API environment
629 const std::u16string& value ///< UTF-16 encoded C++ string
630 );
631
632 /// Creates a new String value from a UTF-8 encoded C string.
633 static String New(
634 napi_env env, ///< Node-API environment
635 const char* value ///< UTF-8 encoded null-terminated C string
636 );
637
638 /// Creates a new String value from a UTF-16 encoded C string.
639 static String New(
640 napi_env env, ///< Node-API environment
641 const char16_t* value ///< UTF-16 encoded null-terminated C string
642 );
643
644 /// Creates a new String value from a UTF-8 encoded C string with specified
645 /// length.
646 static String New(napi_env env, ///< Node-API environment
647 const char* value, ///< UTF-8 encoded C string (not
648 ///< necessarily null-terminated)
649 size_t length ///< length of the string in bytes
650 );
651
652 /// Creates a new String value from a UTF-16 encoded C string with specified
653 /// length.
654 static String New(
655 napi_env env, ///< Node-API environment
656 const char16_t* value, ///< UTF-16 encoded C string (not necessarily
657 ///< null-terminated)
658 size_t length ///< Length of the string in 2-byte code units
659 );
660
661 /// Creates a new String based on the original object's type.
662 ///
663 /// `value` may be any of:
664 /// - const char* (encoded using UTF-8, null-terminated)
665 /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
666 /// - std::string (encoded using UTF-8)
667 /// - std::u16string
668 template <typename T>
669 static String From(napi_env env, const T& value);
670
671 static void CheckCast(napi_env env, napi_value value);
672
673 String(); ///< Creates a new _empty_ String instance.
674 String(napi_env env,
675 napi_value value); ///< Wraps a Node-API value primitive.
676
677 operator std::string()
678 const; ///< Converts a String value to a UTF-8 encoded C++ string.
679 operator std::u16string()
680 const; ///< Converts a String value to a UTF-16 encoded C++ string.
681 std::string Utf8Value()
682 const; ///< Converts a String value to a UTF-8 encoded C++ string.
683 std::u16string Utf16Value()
684 const; ///< Converts a String value to a UTF-16 encoded C++ string.
685};
686
687/// A JavaScript symbol value.
688class Symbol : public Name {
689 public:
690 /// Creates a new Symbol value with an optional description.
691 static Symbol New(
692 napi_env env, ///< Node-API environment
693 const char* description =
694 nullptr ///< Optional UTF-8 encoded null-terminated C string
695 /// describing the symbol
696 );
697
698 /// Creates a new Symbol value with a description.
699 static Symbol New(
700 napi_env env, ///< Node-API environment
701 const std::string&
702 description ///< UTF-8 encoded C++ string describing the symbol
703 );
704
705 /// Creates a new Symbol value with a description.
706 static Symbol New(napi_env env, ///< Node-API environment
707 String description ///< String value describing the symbol
708 );
709
710 /// Creates a new Symbol value with a description.
711 static Symbol New(
712 napi_env env, ///< Node-API environment
713 napi_value description ///< String value describing the symbol
714 );
715
716 /// Get a public Symbol (e.g. Symbol.iterator).
717 static MaybeOrValue<Symbol> WellKnown(napi_env, const std::string& name);
718
719 // Create a symbol in the global registry, UTF-8 Encoded cpp string
720 static MaybeOrValue<Symbol> For(napi_env env, const std::string& description);
721
722 // Create a symbol in the global registry, C style string (null terminated)
723 static MaybeOrValue<Symbol> For(napi_env env, const char* description);
724
725 // Create a symbol in the global registry, String value describing the symbol
726 static MaybeOrValue<Symbol> For(napi_env env, String description);
727
728 // Create a symbol in the global registry, napi_value describing the symbol
729 static MaybeOrValue<Symbol> For(napi_env env, napi_value description);
730
731 static void CheckCast(napi_env env, napi_value value);
732
733 Symbol(); ///< Creates a new _empty_ Symbol instance.
734 Symbol(napi_env env,
735 napi_value value); ///< Wraps a Node-API value primitive.
736};
737
738class TypeTaggable : public Value {
739 public:
740#if NAPI_VERSION >= 8
741 void TypeTag(const napi_type_tag* type_tag) const;
742 bool CheckTypeTag(const napi_type_tag* type_tag) const;
743#endif // NAPI_VERSION >= 8
744 protected:
745 TypeTaggable();
746 TypeTaggable(napi_env env, napi_value value);
747};
748
749/// A JavaScript object value.
750class Object : public TypeTaggable {
751 public:
752 /// Enables property and element assignments using indexing syntax.
753 ///
754 /// This is a convenient helper to get and set object properties. As
755 /// getting and setting object properties may throw with JavaScript
756 /// exceptions, it is notable that these operations may fail.
757 /// When NODE_ADDON_API_ENABLE_MAYBE is defined, the process will abort
758 /// on JavaScript exceptions.
759 ///
760 /// Example:
761 ///
762 /// Napi::Value propertyValue = object1['A'];
763 /// object2['A'] = propertyValue;
764 /// Napi::Value elementValue = array[0];
765 /// array[1] = elementValue;
766 template <typename Key>
767 class PropertyLValue {
768 public:
769 /// Converts an L-value to a value.
770 operator Value() const;
771
772 /// Assigns a value to the property. The type of value can be
773 /// anything supported by `Object::Set`.
774 template <typename ValueType>
775 PropertyLValue& operator=(ValueType value);
776
777 private:
778 PropertyLValue() = delete;
779 PropertyLValue(Object object, Key key);
780 napi_env _env;
781 napi_value _object;
782 Key _key;
783
784 friend class Napi::Object;
785 };
786
787 /// Creates a new Object value.
788 static Object New(napi_env env ///< Node-API environment
789 );
790
791 static void CheckCast(napi_env env, napi_value value);
792
793 Object(); ///< Creates a new _empty_ Object instance.
794 Object(napi_env env,
795 napi_value value); ///< Wraps a Node-API value primitive.
796
797 /// Gets or sets a named property.
798 PropertyLValue<std::string> operator[](
799 const char* utf8name ///< UTF-8 encoded null-terminated property name
800 );
801
802 /// Gets or sets a named property.
803 PropertyLValue<std::string> operator[](
804 const std::string& utf8name ///< UTF-8 encoded property name
805 );
806
807 /// Gets or sets an indexed property or array element.
808 PropertyLValue<uint32_t> operator[](
809 uint32_t index /// Property / element index
810 );
811
812 /// Gets or sets an indexed property or array element.
813 PropertyLValue<Value> operator[](Value index /// Property / element index
814 ) const;
815
816 /// Gets a named property.
817 MaybeOrValue<Value> operator[](
818 const char* utf8name ///< UTF-8 encoded null-terminated property name
819 ) const;
820
821 /// Gets a named property.
822 MaybeOrValue<Value> operator[](
823 const std::string& utf8name ///< UTF-8 encoded property name
824 ) const;
825
826 /// Gets an indexed property or array element.
827 MaybeOrValue<Value> operator[](uint32_t index ///< Property / element index
828 ) const;
829
830 /// Checks whether a property is present.
831 MaybeOrValue<bool> Has(napi_value key ///< Property key primitive
832 ) const;
833
834 /// Checks whether a property is present.
835 MaybeOrValue<bool> Has(Value key ///< Property key
836 ) const;
837
838 /// Checks whether a named property is present.
839 MaybeOrValue<bool> Has(
840 const char* utf8name ///< UTF-8 encoded null-terminated property name
841 ) const;
842
843 /// Checks whether a named property is present.
844 MaybeOrValue<bool> Has(
845 const std::string& utf8name ///< UTF-8 encoded property name
846 ) const;
847
848 /// Checks whether a own property is present.
849 MaybeOrValue<bool> HasOwnProperty(napi_value key ///< Property key primitive
850 ) const;
851
852 /// Checks whether a own property is present.
853 MaybeOrValue<bool> HasOwnProperty(Value key ///< Property key
854 ) const;
855
856 /// Checks whether a own property is present.
857 MaybeOrValue<bool> HasOwnProperty(
858 const char* utf8name ///< UTF-8 encoded null-terminated property name
859 ) const;
860
861 /// Checks whether a own property is present.
862 MaybeOrValue<bool> HasOwnProperty(
863 const std::string& utf8name ///< UTF-8 encoded property name
864 ) const;
865
866 /// Gets a property.
867 MaybeOrValue<Value> Get(napi_value key ///< Property key primitive
868 ) const;
869
870 /// Gets a property.
871 MaybeOrValue<Value> Get(Value key ///< Property key
872 ) const;
873
874 /// Gets a named property.
875 MaybeOrValue<Value> Get(
876 const char* utf8name ///< UTF-8 encoded null-terminated property name
877 ) const;
878
879 /// Gets a named property.
880 MaybeOrValue<Value> Get(
881 const std::string& utf8name ///< UTF-8 encoded property name
882 ) const;
883
884 /// Sets a property.
885 template <typename ValueType>
886 MaybeOrValue<bool> Set(napi_value key, ///< Property key primitive
887 const ValueType& value ///< Property value primitive
888 ) const;
889
890 /// Sets a property.
891 template <typename ValueType>
892 MaybeOrValue<bool> Set(Value key, ///< Property key
893 const ValueType& value ///< Property value
894 ) const;
895
896 /// Sets a named property.
897 template <typename ValueType>
898 MaybeOrValue<bool> Set(
899 const char* utf8name, ///< UTF-8 encoded null-terminated property name
900 const ValueType& value) const;
901
902 /// Sets a named property.
903 template <typename ValueType>
904 MaybeOrValue<bool> Set(
905 const std::string& utf8name, ///< UTF-8 encoded property name
906 const ValueType& value ///< Property value primitive
907 ) const;
908
909 /// Delete property.
910 MaybeOrValue<bool> Delete(napi_value key ///< Property key primitive
911 ) const;
912
913 /// Delete property.
914 MaybeOrValue<bool> Delete(Value key ///< Property key
915 ) const;
916
917 /// Delete property.
918 MaybeOrValue<bool> Delete(
919 const char* utf8name ///< UTF-8 encoded null-terminated property name
920 ) const;
921
922 /// Delete property.
923 MaybeOrValue<bool> Delete(
924 const std::string& utf8name ///< UTF-8 encoded property name
925 ) const;
926
927 /// Checks whether an indexed property is present.
928 MaybeOrValue<bool> Has(uint32_t index ///< Property / element index
929 ) const;
930
931 /// Gets an indexed property or array element.
932 MaybeOrValue<Value> Get(uint32_t index ///< Property / element index
933 ) const;
934
935 /// Sets an indexed property or array element.
936 template <typename ValueType>
937 MaybeOrValue<bool> Set(uint32_t index, ///< Property / element index
938 const ValueType& value ///< Property value primitive
939 ) const;
940
941 /// Deletes an indexed property or array element.
942 MaybeOrValue<bool> Delete(uint32_t index ///< Property / element index
943 ) const;
944
945 /// This operation can fail in case of Proxy.[[OwnPropertyKeys]] and
946 /// Proxy.[[GetOwnProperty]] calling into JavaScript. See:
947 /// -
948 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys
949 /// -
950 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p
951 MaybeOrValue<Array> GetPropertyNames() const; ///< Get all property names
952
953 /// Defines a property on the object.
954 ///
955 /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling
956 /// into JavaScript. See
957 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
958 MaybeOrValue<bool> DefineProperty(
959 const PropertyDescriptor&
960 property ///< Descriptor for the property to be defined
961 ) const;
962
963 /// Defines properties on the object.
964 ///
965 /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling
966 /// into JavaScript. See
967 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
968 MaybeOrValue<bool> DefineProperties(
969 const std::initializer_list<PropertyDescriptor>& properties
970 ///< List of descriptors for the properties to be defined
971 ) const;
972
973 /// Defines properties on the object.
974 ///
975 /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling
976 /// into JavaScript. See
977 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
978 MaybeOrValue<bool> DefineProperties(
979 const std::vector<PropertyDescriptor>& properties
980 ///< Vector of descriptors for the properties to be defined
981 ) const;
982
983 /// Checks if an object is an instance created by a constructor function.
984 ///
985 /// This is equivalent to the JavaScript `instanceof` operator.
986 ///
987 /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
988 /// JavaScript.
989 /// See
990 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
991 MaybeOrValue<bool> InstanceOf(
992 const Function& constructor ///< Constructor function
993 ) const;
994
995 template <typename Finalizer, typename T>
996 inline void AddFinalizer(Finalizer finalizeCallback, T* data) const;
997
998 template <typename Finalizer, typename T, typename Hint>
999 inline void AddFinalizer(Finalizer finalizeCallback,
1000 T* data,
1001 Hint* finalizeHint) const;
1002
1003#ifdef NAPI_CPP_EXCEPTIONS
1004 class const_iterator;
1005
1006 inline const_iterator begin() const;
1007
1008 inline const_iterator end() const;
1009
1010 class iterator;
1011
1012 inline iterator begin();
1013
1014 inline iterator end();
1015#endif // NAPI_CPP_EXCEPTIONS
1016
1017#if NAPI_VERSION >= 8
1018 /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
1019 /// JavaScript.
1020 /// See
1021 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
1022 MaybeOrValue<bool> Freeze() const;
1023 /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
1024 /// JavaScript.
1025 /// See
1026 /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
1027 MaybeOrValue<bool> Seal() const;
1028#endif // NAPI_VERSION >= 8
1029};
1030
1031template <typename T>
1032class External : public TypeTaggable {
1033 public:
1034 static External New(napi_env env, T* data);
1035
1036 // Finalizer must implement `void operator()(Env env, T* data)`.
1037 template <typename Finalizer>
1038 static External New(napi_env env, T* data, Finalizer finalizeCallback);
1039 // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1040 template <typename Finalizer, typename Hint>
1041 static External New(napi_env env,
1042 T* data,
1043 Finalizer finalizeCallback,
1044 Hint* finalizeHint);
1045
1046 static void CheckCast(napi_env env, napi_value value);
1047
1048 External();
1049 External(napi_env env, napi_value value);
1050
1051 T* Data() const;
1052};
1053
1054class Array : public Object {
1055 public:
1056 static Array New(napi_env env);
1057 static Array New(napi_env env, size_t length);
1058
1059 static void CheckCast(napi_env env, napi_value value);
1060
1061 Array();
1062 Array(napi_env env, napi_value value);
1063
1064 uint32_t Length() const;
1065};
1066
1067#ifdef NAPI_CPP_EXCEPTIONS
1068class Object::const_iterator {
1069 private:
1070 enum class Type { BEGIN, END };
1071
1072 inline const_iterator(const Object* object, const Type type);
1073
1074 public:
1075 inline const_iterator& operator++();
1076
1077 inline bool operator==(const const_iterator& other) const;
1078
1079 inline bool operator!=(const const_iterator& other) const;
1080
1081 inline const std::pair<Value, Object::PropertyLValue<Value>> operator*()
1082 const;
1083
1084 private:
1085 const Napi::Object* _object;
1086 Array _keys;
1087 uint32_t _index;
1088
1089 friend class Object;
1090};
1091
1092class Object::iterator {
1093 private:
1094 enum class Type { BEGIN, END };
1095
1096 inline iterator(Object* object, const Type type);
1097
1098 public:
1099 inline iterator& operator++();
1100
1101 inline bool operator==(const iterator& other) const;
1102
1103 inline bool operator!=(const iterator& other) const;
1104
1105 inline std::pair<Value, Object::PropertyLValue<Value>> operator*();
1106
1107 private:
1108 Napi::Object* _object;
1109 Array _keys;
1110 uint32_t _index;
1111
1112 friend class Object;
1113};
1114#endif // NAPI_CPP_EXCEPTIONS
1115
1116/// A JavaScript array buffer value.
1117class ArrayBuffer : public Object {
1118 public:
1119 /// Creates a new ArrayBuffer instance over a new automatically-allocated
1120 /// buffer.
1121 static ArrayBuffer New(
1122 napi_env env, ///< Node-API environment
1123 size_t byteLength ///< Length of the buffer to be allocated, in bytes
1124 );
1125
1126#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1127 /// Creates a new ArrayBuffer instance, using an external buffer with
1128 /// specified byte length.
1129 static ArrayBuffer New(
1130 napi_env env, ///< Node-API environment
1131 void* externalData, ///< Pointer to the external buffer to be used by
1132 ///< the array
1133 size_t byteLength ///< Length of the external buffer to be used by the
1134 ///< array, in bytes
1135 );
1136
1137 /// Creates a new ArrayBuffer instance, using an external buffer with
1138 /// specified byte length.
1139 template <typename Finalizer>
1140 static ArrayBuffer New(
1141 napi_env env, ///< Node-API environment
1142 void* externalData, ///< Pointer to the external buffer to be used by
1143 ///< the array
1144 size_t byteLength, ///< Length of the external buffer to be used by the
1145 ///< array,
1146 /// in bytes
1147 Finalizer finalizeCallback ///< Function to be called when the array
1148 ///< buffer is destroyed;
1149 /// must implement `void operator()(Env env,
1150 /// void* externalData)`
1151 );
1152
1153 /// Creates a new ArrayBuffer instance, using an external buffer with
1154 /// specified byte length.
1155 template <typename Finalizer, typename Hint>
1156 static ArrayBuffer New(
1157 napi_env env, ///< Node-API environment
1158 void* externalData, ///< Pointer to the external buffer to be used by
1159 ///< the array
1160 size_t byteLength, ///< Length of the external buffer to be used by the
1161 ///< array,
1162 /// in bytes
1163 Finalizer finalizeCallback, ///< Function to be called when the array
1164 ///< buffer is destroyed;
1165 /// must implement `void operator()(Env
1166 /// env, void* externalData, Hint* hint)`
1167 Hint* finalizeHint ///< Hint (second parameter) to be passed to the
1168 ///< finalize callback
1169 );
1170#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1171
1172 static void CheckCast(napi_env env, napi_value value);
1173
1174 ArrayBuffer(); ///< Creates a new _empty_ ArrayBuffer instance.
1175 ArrayBuffer(napi_env env,
1176 napi_value value); ///< Wraps a Node-API value primitive.
1177
1178 void* Data(); ///< Gets a pointer to the data buffer.
1179 size_t ByteLength(); ///< Gets the length of the array buffer in bytes.
1180
1181#if NAPI_VERSION >= 7
1182 bool IsDetached() const;
1183 void Detach();
1184#endif // NAPI_VERSION >= 7
1185};
1186
1187/// A JavaScript typed-array value with unknown array type.
1188///
1189/// For type-specific operations, cast to a `TypedArrayOf<T>` instance using the
1190/// `As()` method:
1191///
1192/// Napi::TypedArray array = ...
1193/// if (t.TypedArrayType() == napi_int32_array) {
1194/// Napi::Int32Array int32Array = t.As<Napi::Int32Array>();
1195/// }
1196class TypedArray : public Object {
1197 public:
1198 static void CheckCast(napi_env env, napi_value value);
1199
1200 TypedArray(); ///< Creates a new _empty_ TypedArray instance.
1201 TypedArray(napi_env env,
1202 napi_value value); ///< Wraps a Node-API value primitive.
1203
1204 napi_typedarray_type TypedArrayType()
1205 const; ///< Gets the type of this typed-array.
1206 Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
1207
1208 uint8_t ElementSize()
1209 const; ///< Gets the size in bytes of one element in the array.
1210 size_t ElementLength() const; ///< Gets the number of elements in the array.
1211 size_t ByteOffset()
1212 const; ///< Gets the offset into the buffer where the array starts.
1213 size_t ByteLength() const; ///< Gets the length of the array in bytes.
1214
1215 protected:
1216 /// !cond INTERNAL
1217 napi_typedarray_type _type;
1218 size_t _length;
1219
1220 TypedArray(napi_env env,
1221 napi_value value,
1222 napi_typedarray_type type,
1223 size_t length);
1224
1225 template <typename T>
1226 static
1227#if defined(NAPI_HAS_CONSTEXPR)
1228 constexpr
1229#endif
1230 napi_typedarray_type
1231 TypedArrayTypeForPrimitiveType() {
1232 return std::is_same<T, int8_t>::value ? napi_int8_array
1233 : std::is_same<T, uint8_t>::value ? napi_uint8_array
1234 : std::is_same<T, int16_t>::value ? napi_int16_array
1235 : std::is_same<T, uint16_t>::value ? napi_uint16_array
1236 : std::is_same<T, int32_t>::value ? napi_int32_array
1237 : std::is_same<T, uint32_t>::value ? napi_uint32_array
1238 : std::is_same<T, float>::value ? napi_float32_array
1239 : std::is_same<T, double>::value ? napi_float64_array
1240#if NAPI_VERSION > 5
1241 : std::is_same<T, int64_t>::value ? napi_bigint64_array
1242 : std::is_same<T, uint64_t>::value ? napi_biguint64_array
1243#endif // NAPI_VERSION > 5
1244 : napi_int8_array;
1245 }
1246 /// !endcond
1247};
1248
1249/// A JavaScript typed-array value with known array type.
1250///
1251/// Note while it is possible to create and access Uint8 "clamped" arrays using
1252/// this class, the _clamping_ behavior is only applied in JavaScript.
1253template <typename T>
1254class TypedArrayOf : public TypedArray {
1255 public:
1256 /// Creates a new TypedArray instance over a new automatically-allocated array
1257 /// buffer.
1258 ///
1259 /// The array type parameter can normally be omitted (because it is inferred
1260 /// from the template parameter T), except when creating a "clamped" array:
1261 ///
1262 /// Uint8Array::New(env, length, napi_uint8_clamped_array)
1263 static TypedArrayOf New(
1264 napi_env env, ///< Node-API environment
1265 size_t elementLength, ///< Length of the created array, as a number of
1266 ///< elements
1267#if defined(NAPI_HAS_CONSTEXPR)
1268 napi_typedarray_type type =
1269 TypedArray::TypedArrayTypeForPrimitiveType<T>()
1270#else
1271 napi_typedarray_type type
1272#endif
1273 ///< Type of array, if different from the default array type for the
1274 ///< template parameter T.
1275 );
1276
1277 /// Creates a new TypedArray instance over a provided array buffer.
1278 ///
1279 /// The array type parameter can normally be omitted (because it is inferred
1280 /// from the template parameter T), except when creating a "clamped" array:
1281 ///
1282 /// Uint8Array::New(env, length, buffer, 0, napi_uint8_clamped_array)
1283 static TypedArrayOf New(
1284 napi_env env, ///< Node-API environment
1285 size_t elementLength, ///< Length of the created array, as a number of
1286 ///< elements
1287 Napi::ArrayBuffer arrayBuffer, ///< Backing array buffer instance to use
1288 size_t bufferOffset, ///< Offset into the array buffer where the
1289 ///< typed-array starts
1290#if defined(NAPI_HAS_CONSTEXPR)
1291 napi_typedarray_type type =
1292 TypedArray::TypedArrayTypeForPrimitiveType<T>()
1293#else
1294 napi_typedarray_type type
1295#endif
1296 ///< Type of array, if different from the default array type for the
1297 ///< template parameter T.
1298 );
1299
1300 static void CheckCast(napi_env env, napi_value value);
1301
1302 TypedArrayOf(); ///< Creates a new _empty_ TypedArrayOf instance.
1303 TypedArrayOf(napi_env env,
1304 napi_value value); ///< Wraps a Node-API value primitive.
1305
1306 T& operator[](size_t index); ///< Gets or sets an element in the array.
1307 const T& operator[](size_t index) const; ///< Gets an element in the array.
1308
1309 /// Gets a pointer to the array's backing buffer.
1310 ///
1311 /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer,
1312 /// because the typed-array may have a non-zero `ByteOffset()` into the
1313 /// `ArrayBuffer`.
1314 T* Data();
1315
1316 /// Gets a pointer to the array's backing buffer.
1317 ///
1318 /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer,
1319 /// because the typed-array may have a non-zero `ByteOffset()` into the
1320 /// `ArrayBuffer`.
1321 const T* Data() const;
1322
1323 private:
1324 T* _data;
1325
1326 TypedArrayOf(napi_env env,
1327 napi_value value,
1328 napi_typedarray_type type,
1329 size_t length,
1330 T* data);
1331};
1332
1333/// The DataView provides a low-level interface for reading/writing multiple
1334/// number types in an ArrayBuffer irrespective of the platform's endianness.
1335class DataView : public Object {
1336 public:
1337 static DataView New(napi_env env, Napi::ArrayBuffer arrayBuffer);
1338 static DataView New(napi_env env,
1339 Napi::ArrayBuffer arrayBuffer,
1340 size_t byteOffset);
1341 static DataView New(napi_env env,
1342 Napi::ArrayBuffer arrayBuffer,
1343 size_t byteOffset,
1344 size_t byteLength);
1345
1346 static void CheckCast(napi_env env, napi_value value);
1347
1348 DataView(); ///< Creates a new _empty_ DataView instance.
1349 DataView(napi_env env,
1350 napi_value value); ///< Wraps a Node-API value primitive.
1351
1352 Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
1353 size_t ByteOffset()
1354 const; ///< Gets the offset into the buffer where the array starts.
1355 size_t ByteLength() const; ///< Gets the length of the array in bytes.
1356
1357 void* Data() const;
1358
1359 float GetFloat32(size_t byteOffset) const;
1360 double GetFloat64(size_t byteOffset) const;
1361 int8_t GetInt8(size_t byteOffset) const;
1362 int16_t GetInt16(size_t byteOffset) const;
1363 int32_t GetInt32(size_t byteOffset) const;
1364 uint8_t GetUint8(size_t byteOffset) const;
1365 uint16_t GetUint16(size_t byteOffset) const;
1366 uint32_t GetUint32(size_t byteOffset) const;
1367
1368 void SetFloat32(size_t byteOffset, float value) const;
1369 void SetFloat64(size_t byteOffset, double value) const;
1370 void SetInt8(size_t byteOffset, int8_t value) const;
1371 void SetInt16(size_t byteOffset, int16_t value) const;
1372 void SetInt32(size_t byteOffset, int32_t value) const;
1373 void SetUint8(size_t byteOffset, uint8_t value) const;
1374 void SetUint16(size_t byteOffset, uint16_t value) const;
1375 void SetUint32(size_t byteOffset, uint32_t value) const;
1376
1377 private:
1378 template <typename T>
1379 T ReadData(size_t byteOffset) const;
1380
1381 template <typename T>
1382 void WriteData(size_t byteOffset, T value) const;
1383
1384 void* _data;
1385 size_t _length;
1386};
1387
1388class Function : public Object {
1389 public:
1390 using VoidCallback = void (*)(const CallbackInfo& info);
1391 using Callback = Value (*)(const CallbackInfo& info);
1392
1393 template <VoidCallback cb>
1394 static Function New(napi_env env,
1395 const char* utf8name = nullptr,
1396 void* data = nullptr);
1397
1398 template <Callback cb>
1399 static Function New(napi_env env,
1400 const char* utf8name = nullptr,
1401 void* data = nullptr);
1402
1403 template <VoidCallback cb>
1404 static Function New(napi_env env,
1405 const std::string& utf8name,
1406 void* data = nullptr);
1407
1408 template <Callback cb>
1409 static Function New(napi_env env,
1410 const std::string& utf8name,
1411 void* data = nullptr);
1412
1413 /// Callable must implement operator() accepting a const CallbackInfo&
1414 /// and return either void or Value.
1415 template <typename Callable>
1416 static Function New(napi_env env,
1417 Callable cb,
1418 const char* utf8name = nullptr,
1419 void* data = nullptr);
1420 /// Callable must implement operator() accepting a const CallbackInfo&
1421 /// and return either void or Value.
1422 template <typename Callable>
1423 static Function New(napi_env env,
1424 Callable cb,
1425 const std::string& utf8name,
1426 void* data = nullptr);
1427
1428 static void CheckCast(napi_env env, napi_value value);
1429
1430 Function();
1431 Function(napi_env env, napi_value value);
1432
1433 MaybeOrValue<Value> operator()(
1434 const std::initializer_list<napi_value>& args) const;
1435
1436 MaybeOrValue<Value> Call(const std::initializer_list<napi_value>& args) const;
1437 MaybeOrValue<Value> Call(const std::vector<napi_value>& args) const;
1438 MaybeOrValue<Value> Call(const std::vector<Value>& args) const;
1439 MaybeOrValue<Value> Call(size_t argc, const napi_value* args) const;
1440 MaybeOrValue<Value> Call(napi_value recv,
1441 const std::initializer_list<napi_value>& args) const;
1442 MaybeOrValue<Value> Call(napi_value recv,
1443 const std::vector<napi_value>& args) const;
1444 MaybeOrValue<Value> Call(napi_value recv,
1445 const std::vector<Value>& args) const;
1446 MaybeOrValue<Value> Call(napi_value recv,
1447 size_t argc,
1448 const napi_value* args) const;
1449
1450 MaybeOrValue<Value> MakeCallback(
1451 napi_value recv,
1452 const std::initializer_list<napi_value>& args,
1453 napi_async_context context = nullptr) const;
1454 MaybeOrValue<Value> MakeCallback(napi_value recv,
1455 const std::vector<napi_value>& args,
1456 napi_async_context context = nullptr) const;
1457 MaybeOrValue<Value> MakeCallback(napi_value recv,
1458 size_t argc,
1459 const napi_value* args,
1460 napi_async_context context = nullptr) const;
1461
1462 MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const;
1463 MaybeOrValue<Object> New(const std::vector<napi_value>& args) const;
1464 MaybeOrValue<Object> New(size_t argc, const napi_value* args) const;
1465};
1466
1467class Promise : public Object {
1468 public:
1469 class Deferred {
1470 public:
1471 static Deferred New(napi_env env);
1472 Deferred(napi_env env);
1473
1474 Napi::Promise Promise() const;
1475 Napi::Env Env() const;
1476
1477 void Resolve(napi_value value) const;
1478 void Reject(napi_value value) const;
1479
1480 private:
1481 napi_env _env;
1482 napi_deferred _deferred;
1483 napi_value _promise;
1484 };
1485
1486 static void CheckCast(napi_env env, napi_value value);
1487
1488 Promise(napi_env env, napi_value value);
1489};
1490
1491template <typename T>
1492class Buffer : public Uint8Array {
1493 public:
1494 static Buffer<T> New(napi_env env, size_t length);
1495#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1496 static Buffer<T> New(napi_env env, T* data, size_t length);
1497
1498 // Finalizer must implement `void operator()(Env env, T* data)`.
1499 template <typename Finalizer>
1500 static Buffer<T> New(napi_env env,
1501 T* data,
1502 size_t length,
1503 Finalizer finalizeCallback);
1504 // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1505 template <typename Finalizer, typename Hint>
1506 static Buffer<T> New(napi_env env,
1507 T* data,
1508 size_t length,
1509 Finalizer finalizeCallback,
1510 Hint* finalizeHint);
1511#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1512
1513 static Buffer<T> NewOrCopy(napi_env env, T* data, size_t length);
1514 // Finalizer must implement `void operator()(Env env, T* data)`.
1515 template <typename Finalizer>
1516 static Buffer<T> NewOrCopy(napi_env env,
1517 T* data,
1518 size_t length,
1519 Finalizer finalizeCallback);
1520 // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1521 template <typename Finalizer, typename Hint>
1522 static Buffer<T> NewOrCopy(napi_env env,
1523 T* data,
1524 size_t length,
1525 Finalizer finalizeCallback,
1526 Hint* finalizeHint);
1527
1528 static Buffer<T> Copy(napi_env env, const T* data, size_t length);
1529
1530 static void CheckCast(napi_env env, napi_value value);
1531
1532 Buffer();
1533 Buffer(napi_env env, napi_value value);
1534 size_t Length() const;
1535 T* Data() const;
1536
1537 private:
1538};
1539
1540/// Holds a counted reference to a value; initially a weak reference unless
1541/// otherwise specified, may be changed to/from a strong reference by adjusting
1542/// the refcount.
1543///
1544/// The referenced value is not immediately destroyed when the reference count
1545/// is zero; it is merely then eligible for garbage-collection if there are no
1546/// other references to the value.
1547template <typename T>
1548class Reference {
1549 public:
1550 static Reference<T> New(const T& value, uint32_t initialRefcount = 0);
1551
1552 Reference();
1553 Reference(napi_env env, napi_ref ref);
1554 ~Reference();
1555
1556 // A reference can be moved but cannot be copied.
1557 Reference(Reference<T>&& other);
1558 Reference<T>& operator=(Reference<T>&& other);
1559 NAPI_DISALLOW_ASSIGN(Reference<T>)
1560
1561 operator napi_ref() const;
1562 bool operator==(const Reference<T>& other) const;
1563 bool operator!=(const Reference<T>& other) const;
1564
1565 Napi::Env Env() const;
1566 bool IsEmpty() const;
1567
1568 // Note when getting the value of a Reference it is usually correct to do so
1569 // within a HandleScope so that the value handle gets cleaned up efficiently.
1570 T Value() const;
1571
1572 uint32_t Ref() const;
1573 uint32_t Unref() const;
1574 void Reset();
1575 void Reset(const T& value, uint32_t refcount = 0);
1576
1577 // Call this on a reference that is declared as static data, to prevent its
1578 // destructor from running at program shutdown time, which would attempt to
1579 // reset the reference when the environment is no longer valid. Avoid using
1580 // this if at all possible. If you do need to use static data, MAKE SURE to
1581 // warn your users that your addon is NOT threadsafe.
1582 void SuppressDestruct();
1583
1584 protected:
1585 Reference(const Reference<T>&);
1586
1587 /// !cond INTERNAL
1588 napi_env _env;
1589 napi_ref _ref;
1590 /// !endcond
1591
1592 private:
1593 bool _suppressDestruct;
1594};
1595
1596class ObjectReference : public Reference<Object> {
1597 public:
1598 ObjectReference();
1599 ObjectReference(napi_env env, napi_ref ref);
1600
1601 // A reference can be moved but cannot be copied.
1602 ObjectReference(Reference<Object>&& other);
1603 ObjectReference& operator=(Reference<Object>&& other);
1604 ObjectReference(ObjectReference&& other);
1605 ObjectReference& operator=(ObjectReference&& other);
1606 NAPI_DISALLOW_ASSIGN(ObjectReference)
1607
1608 MaybeOrValue<Napi::Value> Get(const char* utf8name) const;
1609 MaybeOrValue<Napi::Value> Get(const std::string& utf8name) const;
1610 MaybeOrValue<bool> Set(const char* utf8name, napi_value value) const;
1611 MaybeOrValue<bool> Set(const char* utf8name, Napi::Value value) const;
1612 MaybeOrValue<bool> Set(const char* utf8name, const char* utf8value) const;
1613 MaybeOrValue<bool> Set(const char* utf8name, bool boolValue) const;
1614 MaybeOrValue<bool> Set(const char* utf8name, double numberValue) const;
1615 MaybeOrValue<bool> Set(const std::string& utf8name, napi_value value) const;
1616 MaybeOrValue<bool> Set(const std::string& utf8name, Napi::Value value) const;
1617 MaybeOrValue<bool> Set(const std::string& utf8name,
1618 std::string& utf8value) const;
1619 MaybeOrValue<bool> Set(const std::string& utf8name, bool boolValue) const;
1620 MaybeOrValue<bool> Set(const std::string& utf8name, double numberValue) const;
1621
1622 MaybeOrValue<Napi::Value> Get(uint32_t index) const;
1623 MaybeOrValue<bool> Set(uint32_t index, const napi_value value) const;
1624 MaybeOrValue<bool> Set(uint32_t index, const Napi::Value value) const;
1625 MaybeOrValue<bool> Set(uint32_t index, const char* utf8value) const;
1626 MaybeOrValue<bool> Set(uint32_t index, const std::string& utf8value) const;
1627 MaybeOrValue<bool> Set(uint32_t index, bool boolValue) const;
1628 MaybeOrValue<bool> Set(uint32_t index, double numberValue) const;
1629
1630 protected:
1631 ObjectReference(const ObjectReference&);
1632};
1633
1634class FunctionReference : public Reference<Function> {
1635 public:
1636 FunctionReference();
1637 FunctionReference(napi_env env, napi_ref ref);
1638
1639 // A reference can be moved but cannot be copied.
1640 FunctionReference(Reference<Function>&& other);
1641 FunctionReference& operator=(Reference<Function>&& other);
1642 FunctionReference(FunctionReference&& other);
1643 FunctionReference& operator=(FunctionReference&& other);
1644 NAPI_DISALLOW_ASSIGN_COPY(FunctionReference)
1645
1646 MaybeOrValue<Napi::Value> operator()(
1647 const std::initializer_list<napi_value>& args) const;
1648
1649 MaybeOrValue<Napi::Value> Call(
1650 const std::initializer_list<napi_value>& args) const;
1651 MaybeOrValue<Napi::Value> Call(const std::vector<napi_value>& args) const;
1652 MaybeOrValue<Napi::Value> Call(
1653 napi_value recv, const std::initializer_list<napi_value>& args) const;
1654 MaybeOrValue<Napi::Value> Call(napi_value recv,
1655 const std::vector<napi_value>& args) const;
1656 MaybeOrValue<Napi::Value> Call(napi_value recv,
1657 size_t argc,
1658 const napi_value* args) const;
1659
1660 MaybeOrValue<Napi::Value> MakeCallback(
1661 napi_value recv,
1662 const std::initializer_list<napi_value>& args,
1663 napi_async_context context = nullptr) const;
1664 MaybeOrValue<Napi::Value> MakeCallback(
1665 napi_value recv,
1666 const std::vector<napi_value>& args,
1667 napi_async_context context = nullptr) const;
1668 MaybeOrValue<Napi::Value> MakeCallback(
1669 napi_value recv,
1670 size_t argc,
1671 const napi_value* args,
1672 napi_async_context context = nullptr) const;
1673
1674 MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const;
1675 MaybeOrValue<Object> New(const std::vector<napi_value>& args) const;
1676};
1677
1678// Shortcuts to creating a new reference with inferred type and refcount = 0.
1679template <typename T>
1680Reference<T> Weak(T value);
1681ObjectReference Weak(Object value);
1682FunctionReference Weak(Function value);
1683
1684// Shortcuts to creating a new reference with inferred type and refcount = 1.
1685template <typename T>
1686Reference<T> Persistent(T value);
1687ObjectReference Persistent(Object value);
1688FunctionReference Persistent(Function value);
1689
1690/// A persistent reference to a JavaScript error object. Use of this class
1691/// depends somewhat on whether C++ exceptions are enabled at compile time.
1692///
1693/// ### Handling Errors With C++ Exceptions
1694///
1695/// If C++ exceptions are enabled, then the `Error` class extends
1696/// `std::exception` and enables integrated error-handling for C++ exceptions
1697/// and JavaScript exceptions.
1698///
1699/// If a Node-API call fails without executing any JavaScript code (for
1700/// example due to an invalid argument), then the Node-API wrapper
1701/// automatically converts and throws the error as a C++ exception of type
1702/// `Napi::Error`. Or if a JavaScript function called by C++ code via Node-API
1703/// throws a JavaScript exception, then the Node-API wrapper automatically
1704/// converts and throws it as a C++ exception of type `Napi::Error`.
1705///
1706/// If a C++ exception of type `Napi::Error` escapes from a Node-API C++
1707/// callback, then the Node-API wrapper automatically converts and throws it
1708/// as a JavaScript exception. Therefore, catching a C++ exception of type
1709/// `Napi::Error` prevents a JavaScript exception from being thrown.
1710///
1711/// #### Example 1A - Throwing a C++ exception:
1712///
1713/// Napi::Env env = ...
1714/// throw Napi::Error::New(env, "Example exception");
1715///
1716/// Following C++ statements will not be executed. The exception will bubble
1717/// up as a C++ exception of type `Napi::Error`, until it is either caught
1718/// while still in C++, or else automatically propataged as a JavaScript
1719/// exception when the callback returns to JavaScript.
1720///
1721/// #### Example 2A - Propagating a Node-API C++ exception:
1722///
1723/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1724/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1725///
1726/// Following C++ statements will not be executed. The exception will bubble
1727/// up as a C++ exception of type `Napi::Error`, until it is either caught
1728/// while still in C++, or else automatically propagated as a JavaScript
1729/// exception when the callback returns to JavaScript.
1730///
1731/// #### Example 3A - Handling a Node-API C++ exception:
1732///
1733/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1734/// Napi::Value result;
1735/// try {
1736/// result = jsFunctionThatThrows({ arg1, arg2 });
1737/// } catch (const Napi::Error& e) {
1738/// cerr << "Caught JavaScript exception: " + e.what();
1739/// }
1740///
1741/// Since the exception was caught here, it will not be propagated as a
1742/// JavaScript exception.
1743///
1744/// ### Handling Errors Without C++ Exceptions
1745///
1746/// If C++ exceptions are disabled (by defining `NAPI_DISABLE_CPP_EXCEPTIONS`)
1747/// then this class does not extend `std::exception`, and APIs in the `Napi`
1748/// namespace do not throw C++ exceptions when they fail. Instead, they raise
1749/// _pending_ JavaScript exceptions and return _empty_ `Value`s. Calling code
1750/// should check `Value::IsEmpty()` before attempting to use a returned value,
1751/// and may use methods on the `Env` class to check for, get, and clear a
1752/// pending JavaScript exception. If the pending exception is not cleared, it
1753/// will be thrown when the native callback returns to JavaScript.
1754///
1755/// #### Example 1B - Throwing a JS exception
1756///
1757/// Napi::Env env = ...
1758/// Napi::Error::New(env, "Example
1759/// exception").ThrowAsJavaScriptException(); return;
1760///
1761/// After throwing a JS exception, the code should generally return
1762/// immediately from the native callback, after performing any necessary
1763/// cleanup.
1764///
1765/// #### Example 2B - Propagating a Node-API JS exception:
1766///
1767/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1768/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1769/// if (result.IsEmpty()) return;
1770///
1771/// An empty value result from a Node-API call indicates an error occurred,
1772/// and a JavaScript exception is pending. To let the exception propagate, the
1773/// code should generally return immediately from the native callback, after
1774/// performing any necessary cleanup.
1775///
1776/// #### Example 3B - Handling a Node-API JS exception:
1777///
1778/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1779/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1780/// if (result.IsEmpty()) {
1781/// Napi::Error e = env.GetAndClearPendingException();
1782/// cerr << "Caught JavaScript exception: " + e.Message();
1783/// }
1784///
1785/// Since the exception was cleared here, it will not be propagated as a
1786/// JavaScript exception after the native callback returns.
1787class Error : public ObjectReference
1788#ifdef NAPI_CPP_EXCEPTIONS
1789 ,
1790 public std::exception
1791#endif // NAPI_CPP_EXCEPTIONS
1792{
1793 public:
1794 static Error New(napi_env env);
1795 static Error New(napi_env env, const char* message);
1796 static Error New(napi_env env, const std::string& message);
1797
1798 static NAPI_NO_RETURN void Fatal(const char* location, const char* message);
1799
1800 Error();
1801 Error(napi_env env, napi_value value);
1802
1803 // An error can be moved or copied.
1804 Error(Error&& other);
1805 Error& operator=(Error&& other);
1806 Error(const Error&);
1807 Error& operator=(const Error&);
1808
1809 const std::string& Message() const NAPI_NOEXCEPT;
1810 void ThrowAsJavaScriptException() const;
1811
1812 Object Value() const;
1813
1814#ifdef NAPI_CPP_EXCEPTIONS
1815 const char* what() const NAPI_NOEXCEPT override;
1816#endif // NAPI_CPP_EXCEPTIONS
1817
1818 protected:
1819 /// !cond INTERNAL
1820 using create_error_fn = napi_status (*)(napi_env envb,
1821 napi_value code,
1822 napi_value msg,
1823 napi_value* result);
1824
1825 template <typename TError>
1826 static TError New(napi_env env,
1827 const char* message,
1828 size_t length,
1829 create_error_fn create_error);
1830 /// !endcond
1831
1832 private:
1833 static inline const char* ERROR_WRAP_VALUE() NAPI_NOEXCEPT;
1834 mutable std::string _message;
1835};
1836
1837class TypeError : public Error {
1838 public:
1839 static TypeError New(napi_env env, const char* message);
1840 static TypeError New(napi_env env, const std::string& message);
1841
1842 TypeError();
1843 TypeError(napi_env env, napi_value value);
1844};
1845
1846class RangeError : public Error {
1847 public:
1848 static RangeError New(napi_env env, const char* message);
1849 static RangeError New(napi_env env, const std::string& message);
1850
1851 RangeError();
1852 RangeError(napi_env env, napi_value value);
1853};
1854
1855#if NAPI_VERSION > 8
1856class SyntaxError : public Error {
1857 public:
1858 static SyntaxError New(napi_env env, const char* message);
1859 static SyntaxError New(napi_env env, const std::string& message);
1860
1861 SyntaxError();
1862 SyntaxError(napi_env env, napi_value value);
1863};
1864#endif // NAPI_VERSION > 8
1865
1866class CallbackInfo {
1867 public:
1868 CallbackInfo(napi_env env, napi_callback_info info);
1869 ~CallbackInfo();
1870
1871 // Disallow copying to prevent multiple free of _dynamicArgs
1872 NAPI_DISALLOW_ASSIGN_COPY(CallbackInfo)
1873
1874 Napi::Env Env() const;
1875 Value NewTarget() const;
1876 bool IsConstructCall() const;
1877 size_t Length() const;
1878 const Value operator[](size_t index) const;
1879 Value This() const;
1880 void* Data() const;
1881 void SetData(void* data);
1882 explicit operator napi_callback_info() const;
1883
1884 private:
1885 const size_t _staticArgCount = 6;
1886 napi_env _env;
1887 napi_callback_info _info;
1888 napi_value _this;
1889 size_t _argc;
1890 napi_value* _argv;
1891 napi_value _staticArgs[6];
1892 napi_value* _dynamicArgs;
1893 void* _data;
1894};
1895
1896class PropertyDescriptor {
1897 public:
1898 using GetterCallback = Napi::Value (*)(const Napi::CallbackInfo& info);
1899 using SetterCallback = void (*)(const Napi::CallbackInfo& info);
1900
1901#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
1902 template <typename Getter>
1903 static PropertyDescriptor Accessor(
1904 const char* utf8name,
1905 Getter getter,
1906 napi_property_attributes attributes = napi_default,
1907 void* data = nullptr);
1908 template <typename Getter>
1909 static PropertyDescriptor Accessor(
1910 const std::string& utf8name,
1911 Getter getter,
1912 napi_property_attributes attributes = napi_default,
1913 void* data = nullptr);
1914 template <typename Getter>
1915 static PropertyDescriptor Accessor(
1916 napi_value name,
1917 Getter getter,
1918 napi_property_attributes attributes = napi_default,
1919 void* data = nullptr);
1920 template <typename Getter>
1921 static PropertyDescriptor Accessor(
1922 Name name,
1923 Getter getter,
1924 napi_property_attributes attributes = napi_default,
1925 void* data = nullptr);
1926 template <typename Getter, typename Setter>
1927 static PropertyDescriptor Accessor(
1928 const char* utf8name,
1929 Getter getter,
1930 Setter setter,
1931 napi_property_attributes attributes = napi_default,
1932 void* data = nullptr);
1933 template <typename Getter, typename Setter>
1934 static PropertyDescriptor Accessor(
1935 const std::string& utf8name,
1936 Getter getter,
1937 Setter setter,
1938 napi_property_attributes attributes = napi_default,
1939 void* data = nullptr);
1940 template <typename Getter, typename Setter>
1941 static PropertyDescriptor Accessor(
1942 napi_value name,
1943 Getter getter,
1944 Setter setter,
1945 napi_property_attributes attributes = napi_default,
1946 void* data = nullptr);
1947 template <typename Getter, typename Setter>
1948 static PropertyDescriptor Accessor(
1949 Name name,
1950 Getter getter,
1951 Setter setter,
1952 napi_property_attributes attributes = napi_default,
1953 void* data = nullptr);
1954 template <typename Callable>
1955 static PropertyDescriptor Function(
1956 const char* utf8name,
1957 Callable cb,
1958 napi_property_attributes attributes = napi_default,
1959 void* data = nullptr);
1960 template <typename Callable>
1961 static PropertyDescriptor Function(
1962 const std::string& utf8name,
1963 Callable cb,
1964 napi_property_attributes attributes = napi_default,
1965 void* data = nullptr);
1966 template <typename Callable>
1967 static PropertyDescriptor Function(
1968 napi_value name,
1969 Callable cb,
1970 napi_property_attributes attributes = napi_default,
1971 void* data = nullptr);
1972 template <typename Callable>
1973 static PropertyDescriptor Function(
1974 Name name,
1975 Callable cb,
1976 napi_property_attributes attributes = napi_default,
1977 void* data = nullptr);
1978#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
1979
1980 template <GetterCallback Getter>
1981 static PropertyDescriptor Accessor(
1982 const char* utf8name,
1983 napi_property_attributes attributes = napi_default,
1984 void* data = nullptr);
1985
1986 template <GetterCallback Getter>
1987 static PropertyDescriptor Accessor(
1988 const std::string& utf8name,
1989 napi_property_attributes attributes = napi_default,
1990 void* data = nullptr);
1991
1992 template <GetterCallback Getter>
1993 static PropertyDescriptor Accessor(
1994 Name name,
1995 napi_property_attributes attributes = napi_default,
1996 void* data = nullptr);
1997
1998 template <GetterCallback Getter, SetterCallback Setter>
1999 static PropertyDescriptor Accessor(
2000 const char* utf8name,
2001 napi_property_attributes attributes = napi_default,
2002 void* data = nullptr);
2003
2004 template <GetterCallback Getter, SetterCallback Setter>
2005 static PropertyDescriptor Accessor(
2006 const std::string& utf8name,
2007 napi_property_attributes attributes = napi_default,
2008 void* data = nullptr);
2009
2010 template <GetterCallback Getter, SetterCallback Setter>
2011 static PropertyDescriptor Accessor(
2012 Name name,
2013 napi_property_attributes attributes = napi_default,
2014 void* data = nullptr);
2015
2016 template <typename Getter>
2017 static PropertyDescriptor Accessor(
2018 Napi::Env env,
2019 Napi::Object object,
2020 const char* utf8name,
2021 Getter getter,
2022 napi_property_attributes attributes = napi_default,
2023 void* data = nullptr);
2024 template <typename Getter>
2025 static PropertyDescriptor Accessor(
2026 Napi::Env env,
2027 Napi::Object object,
2028 const std::string& utf8name,
2029 Getter getter,
2030 napi_property_attributes attributes = napi_default,
2031 void* data = nullptr);
2032 template <typename Getter>
2033 static PropertyDescriptor Accessor(
2034 Napi::Env env,
2035 Napi::Object object,
2036 Name name,
2037 Getter getter,
2038 napi_property_attributes attributes = napi_default,
2039 void* data = nullptr);
2040 template <typename Getter, typename Setter>
2041 static PropertyDescriptor Accessor(
2042 Napi::Env env,
2043 Napi::Object object,
2044 const char* utf8name,
2045 Getter getter,
2046 Setter setter,
2047 napi_property_attributes attributes = napi_default,
2048 void* data = nullptr);
2049 template <typename Getter, typename Setter>
2050 static PropertyDescriptor Accessor(
2051 Napi::Env env,
2052 Napi::Object object,
2053 const std::string& utf8name,
2054 Getter getter,
2055 Setter setter,
2056 napi_property_attributes attributes = napi_default,
2057 void* data = nullptr);
2058 template <typename Getter, typename Setter>
2059 static PropertyDescriptor Accessor(
2060 Napi::Env env,
2061 Napi::Object object,
2062 Name name,
2063 Getter getter,
2064 Setter setter,
2065 napi_property_attributes attributes = napi_default,
2066 void* data = nullptr);
2067 template <typename Callable>
2068 static PropertyDescriptor Function(
2069 Napi::Env env,
2070 Napi::Object object,
2071 const char* utf8name,
2072 Callable cb,
2073 napi_property_attributes attributes = napi_default,
2074 void* data = nullptr);
2075 template <typename Callable>
2076 static PropertyDescriptor Function(
2077 Napi::Env env,
2078 Napi::Object object,
2079 const std::string& utf8name,
2080 Callable cb,
2081 napi_property_attributes attributes = napi_default,
2082 void* data = nullptr);
2083 template <typename Callable>
2084 static PropertyDescriptor Function(
2085 Napi::Env env,
2086 Napi::Object object,
2087 Name name,
2088 Callable cb,
2089 napi_property_attributes attributes = napi_default,
2090 void* data = nullptr);
2091 static PropertyDescriptor Value(
2092 const char* utf8name,
2093 napi_value value,
2094 napi_property_attributes attributes = napi_default);
2095 static PropertyDescriptor Value(
2096 const std::string& utf8name,
2097 napi_value value,
2098 napi_property_attributes attributes = napi_default);
2099 static PropertyDescriptor Value(
2100 napi_value name,
2101 napi_value value,
2102 napi_property_attributes attributes = napi_default);
2103 static PropertyDescriptor Value(
2104 Name name,
2105 Napi::Value value,
2106 napi_property_attributes attributes = napi_default);
2107
2108 PropertyDescriptor(napi_property_descriptor desc);
2109
2110 operator napi_property_descriptor&();
2111 operator const napi_property_descriptor&() const;
2112
2113 private:
2114 napi_property_descriptor _desc;
2115};
2116
2117/// Property descriptor for use with `ObjectWrap::DefineClass()`.
2118///
2119/// This is different from the standalone `PropertyDescriptor` because it is
2120/// specific to each `ObjectWrap<T>` subclass. This prevents using descriptors
2121/// from a different class when defining a new class (preventing the callbacks
2122/// from having incorrect `this` pointers).
2123template <typename T>
2124class ClassPropertyDescriptor {
2125 public:
2126 ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {}
2127
2128 operator napi_property_descriptor&() { return _desc; }
2129 operator const napi_property_descriptor&() const { return _desc; }
2130
2131 private:
2132 napi_property_descriptor _desc;
2133};
2134
2135template <typename T, typename TCallback>
2136struct MethodCallbackData {
2137 TCallback callback;
2138 void* data;
2139};
2140
2141template <typename T, typename TGetterCallback, typename TSetterCallback>
2142struct AccessorCallbackData {
2143 TGetterCallback getterCallback;
2144 TSetterCallback setterCallback;
2145 void* data;
2146};
2147
2148template <typename T>
2149class InstanceWrap {
2150 public:
2151 using InstanceVoidMethodCallback = void (T::*)(const CallbackInfo& info);
2152 using InstanceMethodCallback = Napi::Value (T::*)(const CallbackInfo& info);
2153 using InstanceGetterCallback = Napi::Value (T::*)(const CallbackInfo& info);
2154 using InstanceSetterCallback = void (T::*)(const CallbackInfo& info,
2155 const Napi::Value& value);
2156
2157 using PropertyDescriptor = ClassPropertyDescriptor<T>;
2158
2159 static PropertyDescriptor InstanceMethod(
2160 const char* utf8name,
2161 InstanceVoidMethodCallback method,
2162 napi_property_attributes attributes = napi_default,
2163 void* data = nullptr);
2164 static PropertyDescriptor InstanceMethod(
2165 const char* utf8name,
2166 InstanceMethodCallback method,
2167 napi_property_attributes attributes = napi_default,
2168 void* data = nullptr);
2169 static PropertyDescriptor InstanceMethod(
2170 Symbol name,
2171 InstanceVoidMethodCallback method,
2172 napi_property_attributes attributes = napi_default,
2173 void* data = nullptr);
2174 static PropertyDescriptor InstanceMethod(
2175 Symbol name,
2176 InstanceMethodCallback method,
2177 napi_property_attributes attributes = napi_default,
2178 void* data = nullptr);
2179 template <InstanceVoidMethodCallback method>
2180 static PropertyDescriptor InstanceMethod(
2181 const char* utf8name,
2182 napi_property_attributes attributes = napi_default,
2183 void* data = nullptr);
2184 template <InstanceMethodCallback method>
2185 static PropertyDescriptor InstanceMethod(
2186 const char* utf8name,
2187 napi_property_attributes attributes = napi_default,
2188 void* data = nullptr);
2189 template <InstanceVoidMethodCallback method>
2190 static PropertyDescriptor InstanceMethod(
2191 Symbol name,
2192 napi_property_attributes attributes = napi_default,
2193 void* data = nullptr);
2194 template <InstanceMethodCallback method>
2195 static PropertyDescriptor InstanceMethod(
2196 Symbol name,
2197 napi_property_attributes attributes = napi_default,
2198 void* data = nullptr);
2199 static PropertyDescriptor InstanceAccessor(
2200 const char* utf8name,
2201 InstanceGetterCallback getter,
2202 InstanceSetterCallback setter,
2203 napi_property_attributes attributes = napi_default,
2204 void* data = nullptr);
2205 static PropertyDescriptor InstanceAccessor(
2206 Symbol name,
2207 InstanceGetterCallback getter,
2208 InstanceSetterCallback setter,
2209 napi_property_attributes attributes = napi_default,
2210 void* data = nullptr);
2211 template <InstanceGetterCallback getter,
2212 InstanceSetterCallback setter = nullptr>
2213 static PropertyDescriptor InstanceAccessor(
2214 const char* utf8name,
2215 napi_property_attributes attributes = napi_default,
2216 void* data = nullptr);
2217 template <InstanceGetterCallback getter,
2218 InstanceSetterCallback setter = nullptr>
2219 static PropertyDescriptor InstanceAccessor(
2220 Symbol name,
2221 napi_property_attributes attributes = napi_default,
2222 void* data = nullptr);
2223 static PropertyDescriptor InstanceValue(
2224 const char* utf8name,
2225 Napi::Value value,
2226 napi_property_attributes attributes = napi_default);
2227 static PropertyDescriptor InstanceValue(
2228 Symbol name,
2229 Napi::Value value,
2230 napi_property_attributes attributes = napi_default);
2231
2232 protected:
2233 static void AttachPropData(napi_env env,
2234 napi_value value,
2235 const napi_property_descriptor* prop);
2236
2237 private:
2238 using This = InstanceWrap<T>;
2239
2240 using InstanceVoidMethodCallbackData =
2241 MethodCallbackData<T, InstanceVoidMethodCallback>;
2242 using InstanceMethodCallbackData =
2243 MethodCallbackData<T, InstanceMethodCallback>;
2244 using InstanceAccessorCallbackData =
2245 AccessorCallbackData<T, InstanceGetterCallback, InstanceSetterCallback>;
2246
2247 static napi_value InstanceVoidMethodCallbackWrapper(napi_env env,
2248 napi_callback_info info);
2249 static napi_value InstanceMethodCallbackWrapper(napi_env env,
2250 napi_callback_info info);
2251 static napi_value InstanceGetterCallbackWrapper(napi_env env,
2252 napi_callback_info info);
2253 static napi_value InstanceSetterCallbackWrapper(napi_env env,
2254 napi_callback_info info);
2255
2256 template <InstanceSetterCallback method>
2257 static napi_value WrappedMethod(napi_env env,
2258 napi_callback_info info) NAPI_NOEXCEPT;
2259
2260 template <InstanceSetterCallback setter>
2261 struct SetterTag {};
2262
2263 template <InstanceSetterCallback setter>
2264 static napi_callback WrapSetter(SetterTag<setter>) NAPI_NOEXCEPT {
2265 return &This::WrappedMethod<setter>;
2266 }
2267 static napi_callback WrapSetter(SetterTag<nullptr>) NAPI_NOEXCEPT {
2268 return nullptr;
2269 }
2270};
2271
2272/// Base class to be extended by C++ classes exposed to JavaScript; each C++
2273/// class instance gets "wrapped" by a JavaScript object that is managed by this
2274/// class.
2275///
2276/// At initialization time, the `DefineClass()` method must be used to
2277/// hook up the accessor and method callbacks. It takes a list of
2278/// property descriptors, which can be constructed via the various
2279/// static methods on the base class.
2280///
2281/// #### Example:
2282///
2283/// class Example: public Napi::ObjectWrap<Example> {
2284/// public:
2285/// static void Initialize(Napi::Env& env, Napi::Object& target) {
2286/// Napi::Function constructor = DefineClass(env, "Example", {
2287/// InstanceAccessor<&Example::GetSomething,
2288/// &Example::SetSomething>("value"),
2289/// InstanceMethod<&Example::DoSomething>("doSomething"),
2290/// });
2291/// target.Set("Example", constructor);
2292/// }
2293///
2294/// Example(const Napi::CallbackInfo& info); // Constructor
2295/// Napi::Value GetSomething(const Napi::CallbackInfo& info);
2296/// void SetSomething(const Napi::CallbackInfo& info, const Napi::Value&
2297/// value); Napi::Value DoSomething(const Napi::CallbackInfo& info);
2298/// }
2299template <typename T>
2300class ObjectWrap : public InstanceWrap<T>, public Reference<Object> {
2301 public:
2302 ObjectWrap(const CallbackInfo& callbackInfo);
2303 virtual ~ObjectWrap();
2304
2305 static T* Unwrap(Object wrapper);
2306
2307 // Methods exposed to JavaScript must conform to one of these callback
2308 // signatures.
2309 using StaticVoidMethodCallback = void (*)(const CallbackInfo& info);
2310 using StaticMethodCallback = Napi::Value (*)(const CallbackInfo& info);
2311 using StaticGetterCallback = Napi::Value (*)(const CallbackInfo& info);
2312 using StaticSetterCallback = void (*)(const CallbackInfo& info,
2313 const Napi::Value& value);
2314
2315 using PropertyDescriptor = ClassPropertyDescriptor<T>;
2316
2317 static Function DefineClass(
2318 Napi::Env env,
2319 const char* utf8name,
2320 const std::initializer_list<PropertyDescriptor>& properties,
2321 void* data = nullptr);
2322 static Function DefineClass(Napi::Env env,
2323 const char* utf8name,
2324 const std::vector<PropertyDescriptor>& properties,
2325 void* data = nullptr);
2326 static PropertyDescriptor StaticMethod(
2327 const char* utf8name,
2328 StaticVoidMethodCallback method,
2329 napi_property_attributes attributes = napi_default,
2330 void* data = nullptr);
2331 static PropertyDescriptor StaticMethod(
2332 const char* utf8name,
2333 StaticMethodCallback method,
2334 napi_property_attributes attributes = napi_default,
2335 void* data = nullptr);
2336 static PropertyDescriptor StaticMethod(
2337 Symbol name,
2338 StaticVoidMethodCallback method,
2339 napi_property_attributes attributes = napi_default,
2340 void* data = nullptr);
2341 static PropertyDescriptor StaticMethod(
2342 Symbol name,
2343 StaticMethodCallback method,
2344 napi_property_attributes attributes = napi_default,
2345 void* data = nullptr);
2346 template <StaticVoidMethodCallback method>
2347 static PropertyDescriptor StaticMethod(
2348 const char* utf8name,
2349 napi_property_attributes attributes = napi_default,
2350 void* data = nullptr);
2351 template <StaticVoidMethodCallback method>
2352 static PropertyDescriptor StaticMethod(
2353 Symbol name,
2354 napi_property_attributes attributes = napi_default,
2355 void* data = nullptr);
2356 template <StaticMethodCallback method>
2357 static PropertyDescriptor StaticMethod(
2358 const char* utf8name,
2359 napi_property_attributes attributes = napi_default,
2360 void* data = nullptr);
2361 template <StaticMethodCallback method>
2362 static PropertyDescriptor StaticMethod(
2363 Symbol name,
2364 napi_property_attributes attributes = napi_default,
2365 void* data = nullptr);
2366 static PropertyDescriptor StaticAccessor(
2367 const char* utf8name,
2368 StaticGetterCallback getter,
2369 StaticSetterCallback setter,
2370 napi_property_attributes attributes = napi_default,
2371 void* data = nullptr);
2372 static PropertyDescriptor StaticAccessor(
2373 Symbol name,
2374 StaticGetterCallback getter,
2375 StaticSetterCallback setter,
2376 napi_property_attributes attributes = napi_default,
2377 void* data = nullptr);
2378 template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr>
2379 static PropertyDescriptor StaticAccessor(
2380 const char* utf8name,
2381 napi_property_attributes attributes = napi_default,
2382 void* data = nullptr);
2383 template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr>
2384 static PropertyDescriptor StaticAccessor(
2385 Symbol name,
2386 napi_property_attributes attributes = napi_default,
2387 void* data = nullptr);
2388 static PropertyDescriptor StaticValue(
2389 const char* utf8name,
2390 Napi::Value value,
2391 napi_property_attributes attributes = napi_default);
2392 static PropertyDescriptor StaticValue(
2393 Symbol name,
2394 Napi::Value value,
2395 napi_property_attributes attributes = napi_default);
2396 static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo);
2397 virtual void Finalize(Napi::Env env);
2398
2399 private:
2400 using This = ObjectWrap<T>;
2401
2402 static napi_value ConstructorCallbackWrapper(napi_env env,
2403 napi_callback_info info);
2404 static napi_value StaticVoidMethodCallbackWrapper(napi_env env,
2405 napi_callback_info info);
2406 static napi_value StaticMethodCallbackWrapper(napi_env env,
2407 napi_callback_info info);
2408 static napi_value StaticGetterCallbackWrapper(napi_env env,
2409 napi_callback_info info);
2410 static napi_value StaticSetterCallbackWrapper(napi_env env,
2411 napi_callback_info info);
2412 static void FinalizeCallback(napi_env env, void* data, void* hint);
2413 static Function DefineClass(Napi::Env env,
2414 const char* utf8name,
2415 const size_t props_count,
2416 const napi_property_descriptor* props,
2417 void* data = nullptr);
2418
2419 using StaticVoidMethodCallbackData =
2420 MethodCallbackData<T, StaticVoidMethodCallback>;
2421 using StaticMethodCallbackData = MethodCallbackData<T, StaticMethodCallback>;
2422
2423 using StaticAccessorCallbackData =
2424 AccessorCallbackData<T, StaticGetterCallback, StaticSetterCallback>;
2425
2426 template <StaticSetterCallback method>
2427 static napi_value WrappedMethod(napi_env env,
2428 napi_callback_info info) NAPI_NOEXCEPT;
2429
2430 template <StaticSetterCallback setter>
2431 struct StaticSetterTag {};
2432
2433 template <StaticSetterCallback setter>
2434 static napi_callback WrapStaticSetter(StaticSetterTag<setter>) NAPI_NOEXCEPT {
2435 return &This::WrappedMethod<setter>;
2436 }
2437 static napi_callback WrapStaticSetter(StaticSetterTag<nullptr>)
2438 NAPI_NOEXCEPT {
2439 return nullptr;
2440 }
2441
2442 bool _construction_failed = true;
2443};
2444
2445class HandleScope {
2446 public:
2447 HandleScope(napi_env env, napi_handle_scope scope);
2448 explicit HandleScope(Napi::Env env);
2449 ~HandleScope();
2450
2451 // Disallow copying to prevent double close of napi_handle_scope
2452 NAPI_DISALLOW_ASSIGN_COPY(HandleScope)
2453
2454 operator napi_handle_scope() const;
2455
2456 Napi::Env Env() const;
2457
2458 private:
2459 napi_env _env;
2460 napi_handle_scope _scope;
2461};
2462
2463class EscapableHandleScope {
2464 public:
2465 EscapableHandleScope(napi_env env, napi_escapable_handle_scope scope);
2466 explicit EscapableHandleScope(Napi::Env env);
2467 ~EscapableHandleScope();
2468
2469 // Disallow copying to prevent double close of napi_escapable_handle_scope
2470 NAPI_DISALLOW_ASSIGN_COPY(EscapableHandleScope)
2471
2472 operator napi_escapable_handle_scope() const;
2473
2474 Napi::Env Env() const;
2475 Value Escape(napi_value escapee);
2476
2477 private:
2478 napi_env _env;
2479 napi_escapable_handle_scope _scope;
2480};
2481
2482#if (NAPI_VERSION > 2)
2483class CallbackScope {
2484 public:
2485 CallbackScope(napi_env env, napi_callback_scope scope);
2486 CallbackScope(napi_env env, napi_async_context context);
2487 virtual ~CallbackScope();
2488
2489 // Disallow copying to prevent double close of napi_callback_scope
2490 NAPI_DISALLOW_ASSIGN_COPY(CallbackScope)
2491
2492 operator napi_callback_scope() const;
2493
2494 Napi::Env Env() const;
2495
2496 private:
2497 napi_env _env;
2498 napi_callback_scope _scope;
2499};
2500#endif
2501
2502class AsyncContext {
2503 public:
2504 explicit AsyncContext(napi_env env, const char* resource_name);
2505 explicit AsyncContext(napi_env env,
2506 const char* resource_name,
2507 const Object& resource);
2508 virtual ~AsyncContext();
2509
2510 AsyncContext(AsyncContext&& other);
2511 AsyncContext& operator=(AsyncContext&& other);
2512 NAPI_DISALLOW_ASSIGN_COPY(AsyncContext)
2513
2514 operator napi_async_context() const;
2515
2516 Napi::Env Env() const;
2517
2518 private:
2519 napi_env _env;
2520 napi_async_context _context;
2521};
2522
2523#if NAPI_HAS_THREADS
2524class AsyncWorker {
2525 public:
2526 virtual ~AsyncWorker();
2527
2528 NAPI_DISALLOW_ASSIGN_COPY(AsyncWorker)
2529
2530 operator napi_async_work() const;
2531
2532 Napi::Env Env() const;
2533
2534 void Queue();
2535 void Cancel();
2536 void SuppressDestruct();
2537
2538 ObjectReference& Receiver();
2539 FunctionReference& Callback();
2540
2541 virtual void OnExecute(Napi::Env env);
2542 virtual void OnWorkComplete(Napi::Env env, napi_status status);
2543
2544 protected:
2545 explicit AsyncWorker(const Function& callback);
2546 explicit AsyncWorker(const Function& callback, const char* resource_name);
2547 explicit AsyncWorker(const Function& callback,
2548 const char* resource_name,
2549 const Object& resource);
2550 explicit AsyncWorker(const Object& receiver, const Function& callback);
2551 explicit AsyncWorker(const Object& receiver,
2552 const Function& callback,
2553 const char* resource_name);
2554 explicit AsyncWorker(const Object& receiver,
2555 const Function& callback,
2556 const char* resource_name,
2557 const Object& resource);
2558
2559 explicit AsyncWorker(Napi::Env env);
2560 explicit AsyncWorker(Napi::Env env, const char* resource_name);
2561 explicit AsyncWorker(Napi::Env env,
2562 const char* resource_name,
2563 const Object& resource);
2564
2565 virtual void Execute() = 0;
2566 virtual void OnOK();
2567 virtual void OnError(const Error& e);
2568 virtual void Destroy();
2569 virtual std::vector<napi_value> GetResult(Napi::Env env);
2570
2571 void SetError(const std::string& error);
2572
2573 private:
2574 static inline void OnAsyncWorkExecute(napi_env env, void* asyncworker);
2575 static inline void OnAsyncWorkComplete(napi_env env,
2576 napi_status status,
2577 void* asyncworker);
2578
2579 napi_env _env;
2580 napi_async_work _work;
2581 ObjectReference _receiver;
2582 FunctionReference _callback;
2583 std::string _error;
2584 bool _suppress_destruct;
2585};
2586#endif // NAPI_HAS_THREADS
2587
2588#if (NAPI_VERSION > 3 && NAPI_HAS_THREADS)
2589class ThreadSafeFunction {
2590 public:
2591 // This API may only be called from the main thread.
2592 template <typename ResourceString>
2593 static ThreadSafeFunction New(napi_env env,
2594 const Function& callback,
2595 ResourceString resourceName,
2596 size_t maxQueueSize,
2597 size_t initialThreadCount);
2598
2599 // This API may only be called from the main thread.
2600 template <typename ResourceString, typename ContextType>
2601 static ThreadSafeFunction New(napi_env env,
2602 const Function& callback,
2603 ResourceString resourceName,
2604 size_t maxQueueSize,
2605 size_t initialThreadCount,
2606 ContextType* context);
2607
2608 // This API may only be called from the main thread.
2609 template <typename ResourceString, typename Finalizer>
2610 static ThreadSafeFunction New(napi_env env,
2611 const Function& callback,
2612 ResourceString resourceName,
2613 size_t maxQueueSize,
2614 size_t initialThreadCount,
2615 Finalizer finalizeCallback);
2616
2617 // This API may only be called from the main thread.
2618 template <typename ResourceString,
2619 typename Finalizer,
2620 typename FinalizerDataType>
2621 static ThreadSafeFunction New(napi_env env,
2622 const Function& callback,
2623 ResourceString resourceName,
2624 size_t maxQueueSize,
2625 size_t initialThreadCount,
2626 Finalizer finalizeCallback,
2627 FinalizerDataType* data);
2628
2629 // This API may only be called from the main thread.
2630 template <typename ResourceString, typename ContextType, typename Finalizer>
2631 static ThreadSafeFunction New(napi_env env,
2632 const Function& callback,
2633 ResourceString resourceName,
2634 size_t maxQueueSize,
2635 size_t initialThreadCount,
2636 ContextType* context,
2637 Finalizer finalizeCallback);
2638
2639 // This API may only be called from the main thread.
2640 template <typename ResourceString,
2641 typename ContextType,
2642 typename Finalizer,
2643 typename FinalizerDataType>
2644 static ThreadSafeFunction New(napi_env env,
2645 const Function& callback,
2646 ResourceString resourceName,
2647 size_t maxQueueSize,
2648 size_t initialThreadCount,
2649 ContextType* context,
2650 Finalizer finalizeCallback,
2651 FinalizerDataType* data);
2652
2653 // This API may only be called from the main thread.
2654 template <typename ResourceString>
2655 static ThreadSafeFunction New(napi_env env,
2656 const Function& callback,
2657 const Object& resource,
2658 ResourceString resourceName,
2659 size_t maxQueueSize,
2660 size_t initialThreadCount);
2661
2662 // This API may only be called from the main thread.
2663 template <typename ResourceString, typename ContextType>
2664 static ThreadSafeFunction New(napi_env env,
2665 const Function& callback,
2666 const Object& resource,
2667 ResourceString resourceName,
2668 size_t maxQueueSize,
2669 size_t initialThreadCount,
2670 ContextType* context);
2671
2672 // This API may only be called from the main thread.
2673 template <typename ResourceString, typename Finalizer>
2674 static ThreadSafeFunction New(napi_env env,
2675 const Function& callback,
2676 const Object& resource,
2677 ResourceString resourceName,
2678 size_t maxQueueSize,
2679 size_t initialThreadCount,
2680 Finalizer finalizeCallback);
2681
2682 // This API may only be called from the main thread.
2683 template <typename ResourceString,
2684 typename Finalizer,
2685 typename FinalizerDataType>
2686 static ThreadSafeFunction New(napi_env env,
2687 const Function& callback,
2688 const Object& resource,
2689 ResourceString resourceName,
2690 size_t maxQueueSize,
2691 size_t initialThreadCount,
2692 Finalizer finalizeCallback,
2693 FinalizerDataType* data);
2694
2695 // This API may only be called from the main thread.
2696 template <typename ResourceString, typename ContextType, typename Finalizer>
2697 static ThreadSafeFunction New(napi_env env,
2698 const Function& callback,
2699 const Object& resource,
2700 ResourceString resourceName,
2701 size_t maxQueueSize,
2702 size_t initialThreadCount,
2703 ContextType* context,
2704 Finalizer finalizeCallback);
2705
2706 // This API may only be called from the main thread.
2707 template <typename ResourceString,
2708 typename ContextType,
2709 typename Finalizer,
2710 typename FinalizerDataType>
2711 static ThreadSafeFunction New(napi_env env,
2712 const Function& callback,
2713 const Object& resource,
2714 ResourceString resourceName,
2715 size_t maxQueueSize,
2716 size_t initialThreadCount,
2717 ContextType* context,
2718 Finalizer finalizeCallback,
2719 FinalizerDataType* data);
2720
2721 ThreadSafeFunction();
2722 ThreadSafeFunction(napi_threadsafe_function tsFunctionValue);
2723
2724 operator napi_threadsafe_function() const;
2725
2726 // This API may be called from any thread.
2727 napi_status BlockingCall() const;
2728
2729 // This API may be called from any thread.
2730 template <typename Callback>
2731 napi_status BlockingCall(Callback callback) const;
2732
2733 // This API may be called from any thread.
2734 template <typename DataType, typename Callback>
2735 napi_status BlockingCall(DataType* data, Callback callback) const;
2736
2737 // This API may be called from any thread.
2738 napi_status NonBlockingCall() const;
2739
2740 // This API may be called from any thread.
2741 template <typename Callback>
2742 napi_status NonBlockingCall(Callback callback) const;
2743
2744 // This API may be called from any thread.
2745 template <typename DataType, typename Callback>
2746 napi_status NonBlockingCall(DataType* data, Callback callback) const;
2747
2748 // This API may only be called from the main thread.
2749 void Ref(napi_env env) const;
2750
2751 // This API may only be called from the main thread.
2752 void Unref(napi_env env) const;
2753
2754 // This API may be called from any thread.
2755 napi_status Acquire() const;
2756
2757 // This API may be called from any thread.
2758 napi_status Release() const;
2759
2760 // This API may be called from any thread.
2761 napi_status Abort() const;
2762
2763 struct ConvertibleContext {
2764 template <class T>
2765 operator T*() {
2766 return static_cast<T*>(context);
2767 }
2768 void* context;
2769 };
2770
2771 // This API may be called from any thread.
2772 ConvertibleContext GetContext() const;
2773
2774 private:
2775 using CallbackWrapper = std::function<void(Napi::Env, Napi::Function)>;
2776
2777 template <typename ResourceString,
2778 typename ContextType,
2779 typename Finalizer,
2780 typename FinalizerDataType>
2781 static ThreadSafeFunction New(napi_env env,
2782 const Function& callback,
2783 const Object& resource,
2784 ResourceString resourceName,
2785 size_t maxQueueSize,
2786 size_t initialThreadCount,
2787 ContextType* context,
2788 Finalizer finalizeCallback,
2789 FinalizerDataType* data,
2790 napi_finalize wrapper);
2791
2792 napi_status CallInternal(CallbackWrapper* callbackWrapper,
2793 napi_threadsafe_function_call_mode mode) const;
2794
2795 static void CallJS(napi_env env,
2796 napi_value jsCallback,
2797 void* context,
2798 void* data);
2799
2800 napi_threadsafe_function _tsfn;
2801};
2802
2803// A TypedThreadSafeFunction by default has no context (nullptr) and can
2804// accept any type (void) to its CallJs.
2805template <typename ContextType = std::nullptr_t,
2806 typename DataType = void,
2807 void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*) =
2808 nullptr>
2809class TypedThreadSafeFunction {
2810 public:
2811 // This API may only be called from the main thread.
2812 // Helper function that returns nullptr if running Node-API 5+, otherwise a
2813 // non-empty, no-op Function. This provides the ability to specify at
2814 // compile-time a callback parameter to `New` that safely does no action
2815 // when targeting _any_ Node-API version.
2816#if NAPI_VERSION > 4
2817 static std::nullptr_t EmptyFunctionFactory(Napi::Env env);
2818#else
2819 static Napi::Function EmptyFunctionFactory(Napi::Env env);
2820#endif
2821 static Napi::Function FunctionOrEmpty(Napi::Env env,
2822 Napi::Function& callback);
2823
2824#if NAPI_VERSION > 4
2825 // This API may only be called from the main thread.
2826 // Creates a new threadsafe function with:
2827 // Callback [missing] Resource [missing] Finalizer [missing]
2828 template <typename ResourceString>
2829 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2830 napi_env env,
2831 ResourceString resourceName,
2832 size_t maxQueueSize,
2833 size_t initialThreadCount,
2834 ContextType* context = nullptr);
2835
2836 // This API may only be called from the main thread.
2837 // Creates a new threadsafe function with:
2838 // Callback [missing] Resource [passed] Finalizer [missing]
2839 template <typename ResourceString>
2840 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2841 napi_env env,
2842 const Object& resource,
2843 ResourceString resourceName,
2844 size_t maxQueueSize,
2845 size_t initialThreadCount,
2846 ContextType* context = nullptr);
2847
2848 // This API may only be called from the main thread.
2849 // Creates a new threadsafe function with:
2850 // Callback [missing] Resource [missing] Finalizer [passed]
2851 template <typename ResourceString,
2852 typename Finalizer,
2853 typename FinalizerDataType = void>
2854 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2855 napi_env env,
2856 ResourceString resourceName,
2857 size_t maxQueueSize,
2858 size_t initialThreadCount,
2859 ContextType* context,
2860 Finalizer finalizeCallback,
2861 FinalizerDataType* data = nullptr);
2862
2863 // This API may only be called from the main thread.
2864 // Creates a new threadsafe function with:
2865 // Callback [missing] Resource [passed] Finalizer [passed]
2866 template <typename ResourceString,
2867 typename Finalizer,
2868 typename FinalizerDataType = void>
2869 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2870 napi_env env,
2871 const Object& resource,
2872 ResourceString resourceName,
2873 size_t maxQueueSize,
2874 size_t initialThreadCount,
2875 ContextType* context,
2876 Finalizer finalizeCallback,
2877 FinalizerDataType* data = nullptr);
2878#endif
2879
2880 // This API may only be called from the main thread.
2881 // Creates a new threadsafe function with:
2882 // Callback [passed] Resource [missing] Finalizer [missing]
2883 template <typename ResourceString>
2884 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2885 napi_env env,
2886 const Function& callback,
2887 ResourceString resourceName,
2888 size_t maxQueueSize,
2889 size_t initialThreadCount,
2890 ContextType* context = nullptr);
2891
2892 // This API may only be called from the main thread.
2893 // Creates a new threadsafe function with:
2894 // Callback [passed] Resource [passed] Finalizer [missing]
2895 template <typename ResourceString>
2896 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2897 napi_env env,
2898 const Function& callback,
2899 const Object& resource,
2900 ResourceString resourceName,
2901 size_t maxQueueSize,
2902 size_t initialThreadCount,
2903 ContextType* context = nullptr);
2904
2905 // This API may only be called from the main thread.
2906 // Creates a new threadsafe function with:
2907 // Callback [passed] Resource [missing] Finalizer [passed]
2908 template <typename ResourceString,
2909 typename Finalizer,
2910 typename FinalizerDataType = void>
2911 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2912 napi_env env,
2913 const Function& callback,
2914 ResourceString resourceName,
2915 size_t maxQueueSize,
2916 size_t initialThreadCount,
2917 ContextType* context,
2918 Finalizer finalizeCallback,
2919 FinalizerDataType* data = nullptr);
2920
2921 // This API may only be called from the main thread.
2922 // Creates a new threadsafe function with:
2923 // Callback [passed] Resource [passed] Finalizer [passed]
2924 template <typename CallbackType,
2925 typename ResourceString,
2926 typename Finalizer,
2927 typename FinalizerDataType>
2928 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2929 napi_env env,
2930 CallbackType callback,
2931 const Object& resource,
2932 ResourceString resourceName,
2933 size_t maxQueueSize,
2934 size_t initialThreadCount,
2935 ContextType* context,
2936 Finalizer finalizeCallback,
2937 FinalizerDataType* data = nullptr);
2938
2939 TypedThreadSafeFunction();
2940 TypedThreadSafeFunction(napi_threadsafe_function tsFunctionValue);
2941
2942 operator napi_threadsafe_function() const;
2943
2944 // This API may be called from any thread.
2945 napi_status BlockingCall(DataType* data = nullptr) const;
2946
2947 // This API may be called from any thread.
2948 napi_status NonBlockingCall(DataType* data = nullptr) const;
2949
2950 // This API may only be called from the main thread.
2951 void Ref(napi_env env) const;
2952
2953 // This API may only be called from the main thread.
2954 void Unref(napi_env env) const;
2955
2956 // This API may be called from any thread.
2957 napi_status Acquire() const;
2958
2959 // This API may be called from any thread.
2960 napi_status Release() const;
2961
2962 // This API may be called from any thread.
2963 napi_status Abort() const;
2964
2965 // This API may be called from any thread.
2966 ContextType* GetContext() const;
2967
2968 private:
2969 template <typename ResourceString,
2970 typename Finalizer,
2971 typename FinalizerDataType>
2972 static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2973 napi_env env,
2974 const Function& callback,
2975 const Object& resource,
2976 ResourceString resourceName,
2977 size_t maxQueueSize,
2978 size_t initialThreadCount,
2979 ContextType* context,
2980 Finalizer finalizeCallback,
2981 FinalizerDataType* data,
2982 napi_finalize wrapper);
2983
2984 static void CallJsInternal(napi_env env,
2985 napi_value jsCallback,
2986 void* context,
2987 void* data);
2988
2989 protected:
2990 napi_threadsafe_function _tsfn;
2991};
2992template <typename DataType>
2993class AsyncProgressWorkerBase : public AsyncWorker {
2994 public:
2995 virtual void OnWorkProgress(DataType* data) = 0;
2996 class ThreadSafeData {
2997 public:
2998 ThreadSafeData(AsyncProgressWorkerBase* asyncprogressworker, DataType* data)
2999 : _asyncprogressworker(asyncprogressworker), _data(data) {}
3000
3001 AsyncProgressWorkerBase* asyncprogressworker() {
3002 return _asyncprogressworker;
3003 };
3004 DataType* data() { return _data; };
3005
3006 private:
3007 AsyncProgressWorkerBase* _asyncprogressworker;
3008 DataType* _data;
3009 };
3010 void OnWorkComplete(Napi::Env env, napi_status status) override;
3011
3012 protected:
3013 explicit AsyncProgressWorkerBase(const Object& receiver,
3014 const Function& callback,
3015 const char* resource_name,
3016 const Object& resource,
3017 size_t queue_size = 1);
3018 virtual ~AsyncProgressWorkerBase();
3019
3020// Optional callback of Napi::ThreadSafeFunction only available after
3021// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791
3022#if NAPI_VERSION > 4
3023 explicit AsyncProgressWorkerBase(Napi::Env env,
3024 const char* resource_name,
3025 const Object& resource,
3026 size_t queue_size = 1);
3027#endif
3028
3029 static inline void OnAsyncWorkProgress(Napi::Env env,
3030 Napi::Function jsCallback,
3031 void* data);
3032
3033 napi_status NonBlockingCall(DataType* data);
3034
3035 private:
3036 ThreadSafeFunction _tsfn;
3037 bool _work_completed = false;
3038 napi_status _complete_status;
3039 static inline void OnThreadSafeFunctionFinalize(
3040 Napi::Env env, void* data, AsyncProgressWorkerBase* context);
3041};
3042
3043template <class T>
3044class AsyncProgressWorker : public AsyncProgressWorkerBase<void> {
3045 public:
3046 virtual ~AsyncProgressWorker();
3047
3048 class ExecutionProgress {
3049 friend class AsyncProgressWorker;
3050
3051 public:
3052 void Signal() const;
3053 void Send(const T* data, size_t count) const;
3054
3055 private:
3056 explicit ExecutionProgress(AsyncProgressWorker* worker) : _worker(worker) {}
3057 AsyncProgressWorker* const _worker;
3058 };
3059
3060 void OnWorkProgress(void*) override;
3061
3062 protected:
3063 explicit AsyncProgressWorker(const Function& callback);
3064 explicit AsyncProgressWorker(const Function& callback,
3065 const char* resource_name);
3066 explicit AsyncProgressWorker(const Function& callback,
3067 const char* resource_name,
3068 const Object& resource);
3069 explicit AsyncProgressWorker(const Object& receiver,
3070 const Function& callback);
3071 explicit AsyncProgressWorker(const Object& receiver,
3072 const Function& callback,
3073 const char* resource_name);
3074 explicit AsyncProgressWorker(const Object& receiver,
3075 const Function& callback,
3076 const char* resource_name,
3077 const Object& resource);
3078
3079// Optional callback of Napi::ThreadSafeFunction only available after
3080// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791
3081#if NAPI_VERSION > 4
3082 explicit AsyncProgressWorker(Napi::Env env);
3083 explicit AsyncProgressWorker(Napi::Env env, const char* resource_name);
3084 explicit AsyncProgressWorker(Napi::Env env,
3085 const char* resource_name,
3086 const Object& resource);
3087#endif
3088 virtual void Execute(const ExecutionProgress& progress) = 0;
3089 virtual void OnProgress(const T* data, size_t count) = 0;
3090
3091 private:
3092 void Execute() override;
3093 void Signal();
3094 void SendProgress_(const T* data, size_t count);
3095
3096 std::mutex _mutex;
3097 T* _asyncdata;
3098 size_t _asyncsize;
3099 bool _signaled;
3100};
3101
3102template <class T>
3103class AsyncProgressQueueWorker
3104 : public AsyncProgressWorkerBase<std::pair<T*, size_t>> {
3105 public:
3106 virtual ~AsyncProgressQueueWorker(){};
3107
3108 class ExecutionProgress {
3109 friend class AsyncProgressQueueWorker;
3110
3111 public:
3112 void Signal() const;
3113 void Send(const T* data, size_t count) const;
3114
3115 private:
3116 explicit ExecutionProgress(AsyncProgressQueueWorker* worker)
3117 : _worker(worker) {}
3118 AsyncProgressQueueWorker* const _worker;
3119 };
3120
3121 void OnWorkComplete(Napi::Env env, napi_status status) override;
3122 void OnWorkProgress(std::pair<T*, size_t>*) override;
3123
3124 protected:
3125 explicit AsyncProgressQueueWorker(const Function& callback);
3126 explicit AsyncProgressQueueWorker(const Function& callback,
3127 const char* resource_name);
3128 explicit AsyncProgressQueueWorker(const Function& callback,
3129 const char* resource_name,
3130 const Object& resource);
3131 explicit AsyncProgressQueueWorker(const Object& receiver,
3132 const Function& callback);
3133 explicit AsyncProgressQueueWorker(const Object& receiver,
3134 const Function& callback,
3135 const char* resource_name);
3136 explicit AsyncProgressQueueWorker(const Object& receiver,
3137 const Function& callback,
3138 const char* resource_name,
3139 const Object& resource);
3140
3141// Optional callback of Napi::ThreadSafeFunction only available after
3142// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791
3143#if NAPI_VERSION > 4
3144 explicit AsyncProgressQueueWorker(Napi::Env env);
3145 explicit AsyncProgressQueueWorker(Napi::Env env, const char* resource_name);
3146 explicit AsyncProgressQueueWorker(Napi::Env env,
3147 const char* resource_name,
3148 const Object& resource);
3149#endif
3150 virtual void Execute(const ExecutionProgress& progress) = 0;
3151 virtual void OnProgress(const T* data, size_t count) = 0;
3152
3153 private:
3154 void Execute() override;
3155 void Signal() const;
3156 void SendProgress_(const T* data, size_t count);
3157};
3158#endif // NAPI_VERSION > 3 && NAPI_HAS_THREADS
3159
3160// Memory management.
3161class MemoryManagement {
3162 public:
3163 static int64_t AdjustExternalMemory(Env env, int64_t change_in_bytes);
3164};
3165
3166// Version management
3167class VersionManagement {
3168 public:
3169 static uint32_t GetNapiVersion(Env env);
3170 static const napi_node_version* GetNodeVersion(Env env);
3171};
3172
3173#if NAPI_VERSION > 5
3174template <typename T>
3175class Addon : public InstanceWrap<T> {
3176 public:
3177 static inline Object Init(Env env, Object exports);
3178 static T* Unwrap(Object wrapper);
3179
3180 protected:
3181 using AddonProp = ClassPropertyDescriptor<T>;
3182 void DefineAddon(Object exports,
3183 const std::initializer_list<AddonProp>& props);
3184 Napi::Object DefineProperties(Object object,
3185 const std::initializer_list<AddonProp>& props);
3186
3187 private:
3188 Object entry_point_;
3189};
3190#endif // NAPI_VERSION > 5
3191
3192#ifdef NAPI_CPP_CUSTOM_NAMESPACE
3193} // namespace NAPI_CPP_CUSTOM_NAMESPACE
3194#endif
3195
3196} // namespace Napi
3197
3198// Inline implementations of all the above class methods are included here.
3199#include "napi-inl.h"
3200
3201#endif // SRC_NAPI_H_
Note: See TracBrowser for help on using the repository browser.