diff --git a/doc/addon-tools.md b/doc/addon-tools.md
index 525f802..675cdeb 100644
--- a/doc/addon-tools.md
+++ b/doc/addon-tools.md
@@ -58,8 +58,6 @@ have `CallbackInfo info` passed as an argument.
* `JS_NUM(VAL)` - create a `Napi::Number` value.
* `JS_EXT(VAL)` - create a `Napi::External` (from pointer) value.
* `JS_BOOL(VAL)` - create a `Napi::Boolean` value.
-* `JS_FUN(VAL)` - create a `Napi::Function` value.
-* `JS_OBJ(VAL)` - create a `Napi::Object` value.
@@ -70,7 +68,7 @@ have `CallbackInfo info` passed as an argument.
These checks throw JS TypeError if not passed. Here `T` is always used as a typename
in error messages. `C` is a
-[Napi::Value](https://github.com/nodejs/node-addon-api/blob/master/doc/value.md#isboolean)
+[Napi::Value](https://github.com/nodejs/node-addon-api/blob/master/doc/value.md)
check method, like `IsObject()`. `I` is the index of argument as in `info[I]`,
starting from `0`.
@@ -151,7 +149,6 @@ That extrapolates well to all the helpers below:
```
NAN_METHOD(test) {
-
REQ_UINT32_ARG(0, width);
REQ_UINT32_ARG(1, height);
LET_FLOAT_ARG(2, z);
@@ -162,37 +159,6 @@ NAN_METHOD(test) {
-
-
-Set object accessors
-
-Simplified accessor assignment, adds accessors of NAME for OBJ. Read accessor is
-assumed to have the name `NAME+'Getter'` and write accessor is `NAME+'Setter'`.
-
-* `ACCESSOR_RW(CLASS, NAME)` - add read and write accessors NAME of CLASS.
-* `ACCESSOR_R(CLASS, NAME)` - add read accessor NAME of CLASS.
-* `ACCESSOR_M(CLASS, NAME)` - add method NAME of CLASS.
-
-
-```
-void MyClass::init(Napi::Env env, Napi::Object exports) {
- ...
- Napi::Function ctor = DefineClass(env, "MyClass", {
- ACCESSOR_R(MyClass, isDestroyed),
- ACCESSOR_RW(MyClass, x),
- ACCESSOR_M(MyClass, reset),
- });
- ...
-}
-JS_GETTER(MyClass::isDestroyedGetter) { ...
-JS_GETTER(MyClass::xGetter) { ...
-JS_SETTER(MyClass::xSetter) { ...
-JS_METHOD(MyClass::save) { ...
-```
-
-
-
-
Setter argument
@@ -215,24 +181,29 @@ argument, from which a C++ value is extracted.
* `SETTER_ARRV_ARG`
```
-JS_SETTER(MyClass::x) { SETTER_STR_ARG;
+JS_IMPLEMENT_SETTER(MyClass, x) { THIS_CHECK; SETTER_STR_ARG;
// Variable created: std::string v;
...
```
+See also: [Class Wrapping](class-wrapping.md)
+
-Data retrieval
+JS Data to C++ Data
* `T *getArrayData(value, num = NULL)` - extracts TypedArray data of any type from
the given JS value. Does not accept `Array`. Checks with `IsArrayBuffer()`.
Returns `nullptr` for empty JS values. For unacceptable values throws TypeError.
-* `void *getData(value)` - if value is a TypedArray, then the result of
-`getArrayData(value)` is returned. Otherwise if value has `'data'` property, it's
-content is then returned as `node::Buffer`. Returns `nullptr` in other cases.
+* `T *getBufferData(value, num = NULL)` - extracts Buffer data from
+the given JS value. Checks with `IsBuffer()`.
+Returns `nullptr` for empty JS values. For unacceptable values throws TypeError.
+
+* `void *getData(value)` - if `value` or `value.data` is a `TypedArray|Buffer`,
+calls `getArrayData` or `getArrayData` respectively. Returns `nullptr` in other cases.
diff --git a/doc/class-wrapping.md b/doc/class-wrapping.md
index 6733277..259ec93 100644
--- a/doc/class-wrapping.md
+++ b/doc/class-wrapping.md
@@ -1,5 +1,16 @@
# Es5 class wrapping
+For NAPI addons this allows to call `super()` from C++ and makes the class
+constructor callable with `ClassName.call(obj, ...args)`.
+Also multiple C++ objects can be attached to a single JS object
+if it is necessary in an inheritance scenario.
+On JS side `util.inherits`
+[is used](https://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor),
+and on C++ side `inheritEs5`.
+This implementation is using composition rather than inheritance, so
+it is easily pluggable.
+
+
## Class Declaration
```
@@ -40,7 +51,6 @@ the second is the name of the setter to be created.
## Class Implementation
```
-// Some utility stuff
IMPLEMENT_ES5_CLASS(ClassName);
// Fill the properties and export the class
@@ -83,5 +93,16 @@ JS_IMPLEMENT_GETTER(ClassName, isDestroyed) { THIS_CHECK;
RET_BOOL(_isDestroyed);
}
-
```
+
+`IMPLEMENT_ES5_CLASS` - implements some utility functions for class wrapping.
+`JS_ASSIGN_METHOD` - in `init()`, assigns the given method to this class.
+`JS_ASSIGN_GETTER` - in `init()`, assigns the given getter to this class.
+`JS_ASSIGN_SETTER` - in `init()`, assigns both getter and setter to this class.
+It also takes only one argument because both have the same name.
+`JS_IMPLEMENT_METHOD` - implements a method, the first argument is this class,
+the second is the name of the method being implemented.
+`JS_IMPLEMENT_GETTER` - implements a getter, the first argument is this class,
+the second is the name of the getter being implemented.
+`JS_IMPLEMENT_SETTER` - implements a setter, the first argument is this class,
+the second is the name of the setter being implemented.
diff --git a/include/addon-tools.hpp b/include/addon-tools.hpp
index bc29d95..9582216 100644
--- a/include/addon-tools.hpp
+++ b/include/addon-tools.hpp
@@ -310,25 +310,21 @@
} \
} while (0)
-#define NAPI_CALL(the_call, ATE) \
+#define NAPI_CALL(the_call) \
do { \
if ((the_call) != napi_ok) { \
GET_AND_THROW_LAST_ERROR(); \
- ATE; \
+ RET_UNDEFINED; \
} \
} while (0)
-#define JS_RUN_3(code, VAR, ATE) \
+#define JS_RUN(code, VAR) \
napi_value __RESULT_ ## VAR; \
NAPI_CALL( \
- napi_run_script(env, napi_value(JS_STR(code)), &__RESULT_ ## VAR), \
- ATE \
+ napi_run_script(env, napi_value(JS_STR(code)), &__RESULT_ ## VAR) \
); \
Napi::Value VAR(env, __RESULT_ ## VAR);
-#define JS_RUN_2(code, VAR) JS_RUN_3(code, VAR, return)
-#define JS_RUN JS_RUN_3
-
template
inline Type* getArrayData(
@@ -400,6 +396,8 @@ inline void *getData(Napi::Env env, Napi::Object obj) {
if (obj.IsTypedArray() || obj.IsArrayBuffer()) {
pixels = getArrayData(env, obj);
+ } else if (obj.IsBuffer()) {
+ pixels = getBufferData(env, obj);
} else if (obj.Has("data")) {
Napi::Object data = obj.Get("data").As();
if (data.IsTypedArray() || data.IsArrayBuffer()) {
@@ -414,23 +412,25 @@ inline void *getData(Napi::Env env, Napi::Object obj) {
}
-inline void consoleLog(
+inline Napi::Value consoleLog(
Napi::Env env,
int argc,
const Napi::Value *argv
) {
- JS_RUN_2("console.log", log);
+ JS_RUN("console.log", log);
std::vector args;
for (int i = 0; i < argc; i++) {
args.push_back(napi_value(argv[i]));
}
log.As().Call(args);
+ RET_UNDEFINED;
}
-inline void consoleLog(Napi::Env env, const std::string &message) {
+inline Napi::Value consoleLog(Napi::Env env, const std::string &message) {
Napi::Value arg = JS_STR(message);
consoleLog(env, 1, &arg);
+ RET_UNDEFINED;
}
@@ -490,31 +490,26 @@ inline void eventEmitAsync(
inline void inheritEs5(
- napi_env env,
+ Napi::Env env,
Napi::Function ctor,
Napi::Function superCtor
) {
- napi_value global;
- napi_value globalObject;
- napi_value setProto;
- napi_value ctorProtoProp;
- napi_value superCtorProtoProp;
- napi_value argv[2];
+ Napi::Object global = env.Global();
+ Napi::Object globalObject = global.Get("Object").As();
+ Napi::Function setProto = globalObject.Get("setPrototypeOf").As();
+ Napi::Value ctorProtoProp = ctor.Get("prototype");
+ Napi::Value superCtorProtoProp = superCtor.Get("prototype");
- napi_get_global(env, &global);
- napi_get_named_property(env, global, "Object", &globalObject);
- napi_get_named_property(env, globalObject, "setPrototypeOf", &setProto);
- napi_get_named_property(env, ctor, "prototype", &ctorProtoProp);
- napi_get_named_property(env, superCtor, "prototype", &superCtorProtoProp);
+ napi_value argv[2];
argv[0] = ctorProtoProp;
argv[1] = superCtorProtoProp;
- napi_call_function(env, global, setProto, 2, argv, nullptr);
+ setProto.Call(global, 2, argv);
argv[0] = ctor;
argv[1] = superCtor;
- napi_call_function(env, global, setProto, 2, argv, nullptr);
+ setProto.Call(global, 2, argv);
ctor.Set("super_", superCtor);
@@ -640,11 +635,11 @@ private: \
);
#define JS_DECLARE_METHOD(CLASS, NAME) \
- inline static Napi::Value __st_##NAME(const Napi::CallbackInfo &info) { \
+ inline static JS_METHOD(__st_##NAME) { \
JS_GET_THAT(CLASS); \
return that->__i_##NAME(info); \
}; \
- Napi::Value __i_##NAME(const Napi::CallbackInfo &info);
+ JS_METHOD(__i_##NAME);
#define JS_DECLARE_GETTER(CLASS, NAME) JS_DECLARE_METHOD(CLASS, NAME##Getter)
@@ -661,9 +656,10 @@ private: \
);
#define JS_IMPLEMENT_METHOD(CLASS, NAME) \
- Napi::Value CLASS::__i_##NAME(const Napi::CallbackInfo &info)
+ JS_METHOD(CLASS::__i_##NAME)
-#define JS_IMPLEMENT_GETTER(CLASS, NAME) JS_IMPLEMENT_METHOD(CLASS, NAME##Getter)
+#define JS_IMPLEMENT_GETTER(CLASS, NAME) \
+ JS_IMPLEMENT_METHOD(CLASS, NAME##Getter)
#define JS_IMPLEMENT_SETTER(CLASS, NAME) \
Napi::Value CLASS::__i_##NAME##Setter( \