From 02cc8135f2e0378a8a1794f2dcf45d1eb3aa86e9 Mon Sep 17 00:00:00 2001 From: Kevin Eady <8634912+KevinEady@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:35:31 +0100 Subject: [PATCH 1/2] feat: add SharedArrayBuffer --- doc/README.md | 1 + doc/array_buffer.md | 20 +------ doc/array_buffer_like.md | 27 ++++++++++ doc/shared_array_buffer.md | 49 +++++++++++++++++ doc/value.md | 13 +++++ napi-inl.h | 86 +++++++++++++++++++++++------ napi.h | 30 +++++++++-- test/binding.cc | 8 +++ test/binding.gyp | 1 + test/shared_array_buffer.cc | 104 ++++++++++++++++++++++++++++++++++++ test/shared_array_buffer.js | 55 +++++++++++++++++++ 11 files changed, 355 insertions(+), 39 deletions(-) create mode 100644 doc/array_buffer_like.md create mode 100644 doc/shared_array_buffer.md create mode 100644 test/shared_array_buffer.cc create mode 100644 test/shared_array_buffer.js diff --git a/doc/README.md b/doc/README.md index bad1a5c5a..e5e24dfbe 100644 --- a/doc/README.md +++ b/doc/README.md @@ -60,6 +60,7 @@ The following is the documentation for node-addon-api. - [ClassPropertyDescriptor](class_property_descriptor.md) - [Buffer](buffer.md) - [ArrayBuffer](array_buffer.md) + - [SharedArrayBuffer](shared_array_buffer.md) - [TypedArray](typed_array.md) - [TypedArrayOf](typed_array_of.md) - [DataView](dataview.md) diff --git a/doc/array_buffer.md b/doc/array_buffer.md index de05e55b3..438effd4b 100644 --- a/doc/array_buffer.md +++ b/doc/array_buffer.md @@ -1,6 +1,6 @@ # ArrayBuffer -Class `Napi::ArrayBuffer` inherits from class [`Napi::Object`][]. +Class `Napi::ArrayBuffer` inherits from class [`Napi::ArrayBufferLike`][]. The `Napi::ArrayBuffer` class corresponds to the [JavaScript `ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) @@ -128,22 +128,6 @@ Napi::ArrayBuffer::ArrayBuffer(napi_env env, napi_value value); - `[in] env`: The environment in which to create the `Napi::ArrayBuffer` instance. - `[in] value`: The `Napi::ArrayBuffer` reference to wrap. -### ByteLength - -```cpp -size_t Napi::ArrayBuffer::ByteLength() const; -``` - -Returns the length of the wrapped data, in bytes. - -### Data - -```cpp -void* Napi::ArrayBuffer::Data() const; -``` - -Returns a pointer the wrapped data. - ### Detach ```cpp @@ -160,6 +144,6 @@ bool Napi::ArrayBuffer::IsDetached() const; Returns `true` if this `ArrayBuffer` has been detached. -[`Napi::Object`]: ./object.md +[`Napi::ArrayBufferLike`]: ./array_buffer_like.md [External Buffer]: ./external_buffer.md [Finalization]: ./finalization.md diff --git a/doc/array_buffer_like.md b/doc/array_buffer_like.md new file mode 100644 index 000000000..fa0f29435 --- /dev/null +++ b/doc/array_buffer_like.md @@ -0,0 +1,27 @@ +# ArrayBufferLike + +Class `Napi::ArrayBufferLike` inherits from class [`Napi::Object`][]. + +The `Napi::ArrayBufferLike` class is the base class for [`Napi::ArrayBuffer`][] +and [`Napi::SharedArrayBuffer`][]. It adds common array buffer capabilities to +both. It is an abstract-only base class. + +### ByteLength + +```cpp +size_t Napi::ArrayBufferLike::ByteLength() const; +``` + +Returns the length of the wrapped data, in bytes. + +### Data + +```cpp +void* Napi::ArrayBufferLike::Data() const; +``` + +Returns a pointer the wrapped data. + +[`Napi::ArrayBuffer`]: ./array_buffer.md +[`Napi::Object`]: ./object.md +[`Napi::SharedArrayBuffer`]: ./shared_array_buffer.md diff --git a/doc/shared_array_buffer.md b/doc/shared_array_buffer.md new file mode 100644 index 000000000..22efb5e3e --- /dev/null +++ b/doc/shared_array_buffer.md @@ -0,0 +1,49 @@ +# SharedArrayBuffer + +Class `Napi::SharedArrayBuffer` inherits from class [`Napi::ArrayBufferLike`][]. + +The `Napi::SharedArrayBuffer` class corresponds to the +[JavaScript `SharedArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer) +class. + +**NOTE**: The support for `Napi::SharedArrayBuffer` is only available when using +`NAPI_EXPERIMENTAL` and building against Node.js headers that support this +feature. + +## Methods + +### New + +Allocates a new `Napi::SharedArrayBuffer` instance with a given length. + +```cpp +static Napi::SharedArrayBuffer Napi::SharedArrayBuffer::New(napi_env env, size_t byteLength); +``` + +- `[in] env`: The environment in which to create the `Napi::SharedArrayBuffer` + instance. +- `[in] byteLength`: The length to be allocated, in bytes. + +Returns a new `Napi::SharedArrayBuffer` instance. + +### Constructor + +Initializes an empty instance of the `Napi::SharedArrayBuffer` class. + +```cpp +Napi::SharedArrayBuffer::SharedArrayBuffer(); +``` + +### Constructor + +Initializes a wrapper instance of an existing `Napi::SharedArrayBuffer` object. + +```cpp +Napi::SharedArrayBuffer::SharedArrayBuffer(napi_env env, napi_value value); +``` + +- `[in] env`: The environment in which to create the `Napi::SharedArrayBuffer` + instance. +- `[in] value`: The `Napi::SharedArrayBuffer` reference to wrap. + +[`Napi::ArrayBufferLike`]: ./array_buffer_like.md diff --git a/doc/value.md b/doc/value.md index f19532fa5..f61a36ecf 100644 --- a/doc/value.md +++ b/doc/value.md @@ -268,6 +268,19 @@ bool Napi::Value::IsPromise() const; Returns `true` if the underlying value is a JavaScript `Napi::Promise` or `false` otherwise. +### IsSharedArrayBuffer + +```cpp +bool Napi::Value::IsSharedArrayBuffer() const; +``` + +Returns `true` if the underlying value is a JavaScript +`Napi::IsSharedArrayBuffer` or `false` otherwise. + +**NOTE**: The support for `Napi::SharedArrayBuffer` is only available when using +`NAPI_EXPERIMENTAL` and building against Node.js headers that support this +feature. + ### IsString ```cpp diff --git a/napi-inl.h b/napi-inl.h index 54651c1b5..e24b2ca3f 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -934,6 +934,19 @@ inline bool Value::IsExternal() const { return Type() == napi_external; } +#ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER +inline bool Value::IsSharedArrayBuffer() const { + if (IsEmpty()) { + return false; + } + + bool result; + napi_status status = node_api_is_sharedarraybuffer(_env, _value, &result); + NAPI_THROW_IF_FAILED(_env, status, false); + return result; +} +#endif + template inline T Value::As() const { #ifdef NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS @@ -2068,6 +2081,60 @@ inline uint32_t Array::Length() const { return result; } +inline ArrayBufferLike::ArrayBufferLike() : Object() {} + +inline ArrayBufferLike::ArrayBufferLike(napi_env env, napi_value value) + : Object(env, value) {} + +inline void* ArrayBufferLike::Data() { + void* data; + napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr); + NAPI_THROW_IF_FAILED(_env, status, nullptr); + return data; +} + +inline size_t ArrayBufferLike::ByteLength() { + size_t length; + napi_status status = + napi_get_arraybuffer_info(_env, _value, nullptr, &length); + NAPI_THROW_IF_FAILED(_env, status, 0); + return length; +} + +#ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER +//////////////////////////////////////////////////////////////////////////////// +// SharedArrayBuffer class +//////////////////////////////////////////////////////////////////////////////// + +inline SharedArrayBuffer::SharedArrayBuffer() : ArrayBufferLike() {} + +inline SharedArrayBuffer::SharedArrayBuffer(napi_env env, napi_value value) + : ArrayBufferLike(env, value) {} + +inline void SharedArrayBuffer::CheckCast(napi_env env, napi_value value) { + NAPI_CHECK(value != nullptr, "SharedArrayBuffer::CheckCast", "empty value"); + + bool result; + napi_status status = node_api_is_sharedarraybuffer(env, value, &result); + NAPI_CHECK(status == napi_ok, + "SharedArrayBuffer::CheckCast", + "node_api_is_sharedarraybuffer failed"); + NAPI_CHECK( + result, "SharedArrayBuffer::CheckCast", "value is not sharedarraybuffer"); +} + +inline SharedArrayBuffer SharedArrayBuffer::New(napi_env env, + size_t byteLength) { + napi_value value; + void* data; + napi_status status = + node_api_create_sharedarraybuffer(env, byteLength, &data, &value); + NAPI_THROW_IF_FAILED(env, status, SharedArrayBuffer()); + + return SharedArrayBuffer(env, value); +} +#endif // NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER + //////////////////////////////////////////////////////////////////////////////// // ArrayBuffer class //////////////////////////////////////////////////////////////////////////////// @@ -2154,25 +2221,10 @@ inline void ArrayBuffer::CheckCast(napi_env env, napi_value value) { NAPI_CHECK(result, "ArrayBuffer::CheckCast", "value is not arraybuffer"); } -inline ArrayBuffer::ArrayBuffer() : Object() {} +inline ArrayBuffer::ArrayBuffer() : ArrayBufferLike() {} inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value) - : Object(env, value) {} - -inline void* ArrayBuffer::Data() { - void* data; - napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr); - NAPI_THROW_IF_FAILED(_env, status, nullptr); - return data; -} - -inline size_t ArrayBuffer::ByteLength() { - size_t length; - napi_status status = - napi_get_arraybuffer_info(_env, _value, nullptr, &length); - NAPI_THROW_IF_FAILED(_env, status, 0); - return length; -} + : ArrayBufferLike(env, value) {} #if NAPI_VERSION >= 7 inline bool ArrayBuffer::IsDetached() const { diff --git a/napi.h b/napi.h index ba0e13416..b0575fe4c 100644 --- a/napi.h +++ b/napi.h @@ -543,6 +543,9 @@ class Value { bool IsDataView() const; ///< Tests if a value is a JavaScript data view. bool IsBuffer() const; ///< Tests if a value is a Node buffer. bool IsExternal() const; ///< Tests if a value is a pointer to external data. +#ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER + bool IsSharedArrayBuffer() const; +#endif /// Casts to another type of `Napi::Value`, when the actual type is known or /// assumed. @@ -1202,8 +1205,30 @@ class Object::iterator { }; #endif // NODE_ADDON_API_CPP_EXCEPTIONS +class ArrayBufferLike : public Object { + public: + void* Data(); + size_t ByteLength(); + + protected: + ArrayBufferLike(); + ArrayBufferLike(napi_env env, napi_value value); +}; + +#ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER +class SharedArrayBuffer : public ArrayBufferLike { + public: + SharedArrayBuffer(); + SharedArrayBuffer(napi_env env, napi_value value); + + static SharedArrayBuffer New(napi_env env, size_t byteLength); + + static void CheckCast(napi_env env, napi_value value); +}; +#endif + /// A JavaScript array buffer value. -class ArrayBuffer : public Object { +class ArrayBuffer : public ArrayBufferLike { public: /// Creates a new ArrayBuffer instance over a new automatically-allocated /// buffer. @@ -1264,9 +1289,6 @@ class ArrayBuffer : public Object { ArrayBuffer(napi_env env, napi_value value); ///< Wraps a Node-API value primitive. - void* Data(); ///< Gets a pointer to the data buffer. - size_t ByteLength(); ///< Gets the length of the array buffer in bytes. - #if NAPI_VERSION >= 7 bool IsDetached() const; void Detach(); diff --git a/test/binding.cc b/test/binding.cc index 9e5aaaaa6..fa651cc13 100644 --- a/test/binding.cc +++ b/test/binding.cc @@ -64,6 +64,7 @@ Object InitTypedThreadSafeFunctionSum(Env env); Object InitTypedThreadSafeFunctionUnref(Env env); Object InitTypedThreadSafeFunction(Env env); #endif +Object InitSharedArrayBuffer(Env env); Object InitSymbol(Env env); Object InitTypedArray(Env env); Object InitGlobalObject(Env env); @@ -140,6 +141,7 @@ Object Init(Env env, Object exports) { exports.Set("promise", InitPromise(env)); exports.Set("run_script", InitRunScript(env)); exports.Set("symbol", InitSymbol(env)); + exports.Set("sharedarraybuffer", InitSharedArrayBuffer(env)); #if (NAPI_VERSION > 3) exports.Set("threadsafe_function_ctx", InitThreadSafeFunctionCtx(env)); exports.Set("threadsafe_function_exception", @@ -194,6 +196,12 @@ Object Init(Env env, Object exports) { "isExperimental", Napi::Boolean::New(env, NAPI_VERSION == NAPI_VERSION_EXPERIMENTAL)); +#ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER + exports.Set("hasSharedArrayBuffer", Napi::Boolean::New(env, true)); +#else + exports.Set("hasSharedArrayBuffer", Napi::Boolean::New(env, false)); +#endif + return exports; } diff --git a/test/binding.gyp b/test/binding.gyp index 8ee391fb9..9ff334b64 100644 --- a/test/binding.gyp +++ b/test/binding.gyp @@ -54,6 +54,7 @@ 'object/subscript_operator.cc', 'promise.cc', 'run_script.cc', + 'shared_array_buffer.cc', 'symbol.cc', 'threadsafe_function/threadsafe_function_ctx.cc', 'threadsafe_function/threadsafe_function_exception.cc', diff --git a/test/shared_array_buffer.cc b/test/shared_array_buffer.cc new file mode 100644 index 000000000..57f66495a --- /dev/null +++ b/test/shared_array_buffer.cc @@ -0,0 +1,104 @@ +#include "napi.h" + +using namespace Napi; + +namespace { + +#ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER +Value TestIsSharedArrayBuffer(const CallbackInfo& info) { + if (info.Length() < 1) { + Error::New(info.Env(), "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return Value(); + } + + return Boolean::New(info.Env(), info[0].IsSharedArrayBuffer()); +} + +Value TestCreateSharedArrayBuffer(const CallbackInfo& info) { + if (info.Length() < 1) { + Error::New(info.Env(), "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return Value(); + } else if (!info[0].IsNumber()) { + Error::New(info.Env(), + "Wrong type of arguments. Expects a number as first argument.") + .ThrowAsJavaScriptException(); + return Value(); + } + + auto byte_length = info[0].As().Uint32Value(); + if (byte_length == 0) { + Error::New(info.Env(), + "Invalid byte length. Expects a non-negative integer.") + .ThrowAsJavaScriptException(); + return Value(); + } + + return SharedArrayBuffer::New(info.Env(), byte_length); +} + +Value TestGetSharedArrayBufferInfo(const CallbackInfo& info) { + if (info.Length() < 1) { + Error::New(info.Env(), "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return Value(); + } else if (!info[0].IsSharedArrayBuffer()) { + Error::New(info.Env(), + "Wrong type of arguments. Expects a SharedArrayBuffer as first " + "argument.") + .ThrowAsJavaScriptException(); + return Value(); + } + + auto byte_length = info[0].As().ByteLength(); + + return Number::New(info.Env(), byte_length); +} + +Value TestSharedArrayBufferData(const CallbackInfo& info) { + if (info.Length() < 1) { + Error::New(info.Env(), "Wrong number of arguments") + .ThrowAsJavaScriptException(); + return Value(); + } else if (!info[0].IsSharedArrayBuffer()) { + Error::New(info.Env(), + "Wrong type of arguments. Expects a SharedArrayBuffer as first " + "argument.") + .ThrowAsJavaScriptException(); + return Value(); + } + + auto byte_length = info[0].As().ByteLength(); + void* data = info[0].As().Data(); + + if (byte_length > 0 && data != nullptr) { + uint8_t* bytes = static_cast(data); + for (size_t i = 0; i < byte_length; i++) { + bytes[i] = i % 256; + } + + return Boolean::New(info.Env(), true); + } + + return Boolean::New(info.Env(), false); +} +#endif +} // end anonymous namespace + +Object InitSharedArrayBuffer(Env env) { + Object exports = Object::New(env); + +#ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER + exports["testIsSharedArrayBuffer"] = + Function::New(env, TestIsSharedArrayBuffer); + exports["testCreateSharedArrayBuffer"] = + Function::New(env, TestCreateSharedArrayBuffer); + exports["testGetSharedArrayBufferInfo"] = + Function::New(env, TestGetSharedArrayBufferInfo); + exports["testSharedArrayBufferData"] = + Function::New(env, TestSharedArrayBufferData); +#endif + + return exports; +} diff --git a/test/shared_array_buffer.js b/test/shared_array_buffer.js new file mode 100644 index 000000000..018021ace --- /dev/null +++ b/test/shared_array_buffer.js @@ -0,0 +1,55 @@ +'use strict'; + +const assert = require('assert'); + +module.exports = require('./common').runTest(test); + +let skippedMessageShown = false; + +function test ({ hasSharedArrayBuffer, sharedarraybuffer }) { + if (!hasSharedArrayBuffer) { + if (!skippedMessageShown) { + console.log(' >Skipped (no SharedArrayBuffer support)'); + skippedMessageShown = true; + } + return; + } + + { + const sab = new SharedArrayBuffer(16); + const ab = new ArrayBuffer(16); + const obj = {}; + const arr = []; + + assert.strictEqual(sharedarraybuffer.testIsSharedArrayBuffer(sab), true); + assert.strictEqual(sharedarraybuffer.testIsSharedArrayBuffer(ab), false); + assert.strictEqual(sharedarraybuffer.testIsSharedArrayBuffer(obj), false); + assert.strictEqual(sharedarraybuffer.testIsSharedArrayBuffer(arr), false); + assert.strictEqual(sharedarraybuffer.testIsSharedArrayBuffer(null), false); + assert.strictEqual(sharedarraybuffer.testIsSharedArrayBuffer(undefined), false); + } + + { + const sab = sharedarraybuffer.testCreateSharedArrayBuffer(16); + assert(sab instanceof SharedArrayBuffer); + assert.strictEqual(sab.byteLength, 16); + } + + { + const sab = new SharedArrayBuffer(32); + const byteLength = sharedarraybuffer.testGetSharedArrayBufferInfo(sab); + assert.strictEqual(byteLength, 32); + } + + { + const sab = new SharedArrayBuffer(8); + const result = sharedarraybuffer.testSharedArrayBufferData(sab); + assert.strictEqual(result, true); + + // Check if data was written correctly + const view = new Uint8Array(sab); + for (let i = 0; i < 8; i++) { + assert.strictEqual(view[i], i % 256); + } + } +} From f861d36e5aba8b3d84f78f08a3399fea1c84128e Mon Sep 17 00:00:00 2001 From: Kevin Eady <8634912+KevinEady@users.noreply.github.com> Date: Fri, 31 Oct 2025 09:35:35 +0100 Subject: [PATCH 2/2] fixup! remove ArrayBufferLike common ancestor --- doc/array_buffer.md | 20 +++++++++++-- doc/array_buffer_like.md | 27 ------------------ doc/shared_array_buffer.md | 20 +++++++++++-- napi-inl.h | 58 ++++++++++++++++++++++---------------- napi.h | 20 ++++++------- 5 files changed, 78 insertions(+), 67 deletions(-) delete mode 100644 doc/array_buffer_like.md diff --git a/doc/array_buffer.md b/doc/array_buffer.md index 438effd4b..de05e55b3 100644 --- a/doc/array_buffer.md +++ b/doc/array_buffer.md @@ -1,6 +1,6 @@ # ArrayBuffer -Class `Napi::ArrayBuffer` inherits from class [`Napi::ArrayBufferLike`][]. +Class `Napi::ArrayBuffer` inherits from class [`Napi::Object`][]. The `Napi::ArrayBuffer` class corresponds to the [JavaScript `ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) @@ -128,6 +128,22 @@ Napi::ArrayBuffer::ArrayBuffer(napi_env env, napi_value value); - `[in] env`: The environment in which to create the `Napi::ArrayBuffer` instance. - `[in] value`: The `Napi::ArrayBuffer` reference to wrap. +### ByteLength + +```cpp +size_t Napi::ArrayBuffer::ByteLength() const; +``` + +Returns the length of the wrapped data, in bytes. + +### Data + +```cpp +void* Napi::ArrayBuffer::Data() const; +``` + +Returns a pointer the wrapped data. + ### Detach ```cpp @@ -144,6 +160,6 @@ bool Napi::ArrayBuffer::IsDetached() const; Returns `true` if this `ArrayBuffer` has been detached. -[`Napi::ArrayBufferLike`]: ./array_buffer_like.md +[`Napi::Object`]: ./object.md [External Buffer]: ./external_buffer.md [Finalization]: ./finalization.md diff --git a/doc/array_buffer_like.md b/doc/array_buffer_like.md deleted file mode 100644 index fa0f29435..000000000 --- a/doc/array_buffer_like.md +++ /dev/null @@ -1,27 +0,0 @@ -# ArrayBufferLike - -Class `Napi::ArrayBufferLike` inherits from class [`Napi::Object`][]. - -The `Napi::ArrayBufferLike` class is the base class for [`Napi::ArrayBuffer`][] -and [`Napi::SharedArrayBuffer`][]. It adds common array buffer capabilities to -both. It is an abstract-only base class. - -### ByteLength - -```cpp -size_t Napi::ArrayBufferLike::ByteLength() const; -``` - -Returns the length of the wrapped data, in bytes. - -### Data - -```cpp -void* Napi::ArrayBufferLike::Data() const; -``` - -Returns a pointer the wrapped data. - -[`Napi::ArrayBuffer`]: ./array_buffer.md -[`Napi::Object`]: ./object.md -[`Napi::SharedArrayBuffer`]: ./shared_array_buffer.md diff --git a/doc/shared_array_buffer.md b/doc/shared_array_buffer.md index 22efb5e3e..872dbb408 100644 --- a/doc/shared_array_buffer.md +++ b/doc/shared_array_buffer.md @@ -1,6 +1,6 @@ # SharedArrayBuffer -Class `Napi::SharedArrayBuffer` inherits from class [`Napi::ArrayBufferLike`][]. +Class `Napi::SharedArrayBuffer` inherits from class [`Napi::Object`][]. The `Napi::SharedArrayBuffer` class corresponds to the [JavaScript `SharedArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer) @@ -46,4 +46,20 @@ Napi::SharedArrayBuffer::SharedArrayBuffer(napi_env env, napi_value value); instance. - `[in] value`: The `Napi::SharedArrayBuffer` reference to wrap. -[`Napi::ArrayBufferLike`]: ./array_buffer_like.md +### ByteLength + +```cpp +size_t Napi::SharedArrayBuffer::ByteLength() const; +``` + +Returns the length of the wrapped data, in bytes. + +### Data + +```cpp +void* Napi::SharedArrayBuffer::Data() const; +``` + +Returns a pointer the wrapped data. + +[`Napi::Object`]: ./object.md diff --git a/napi-inl.h b/napi-inl.h index e24b2ca3f..94574fcc1 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2081,35 +2081,15 @@ inline uint32_t Array::Length() const { return result; } -inline ArrayBufferLike::ArrayBufferLike() : Object() {} - -inline ArrayBufferLike::ArrayBufferLike(napi_env env, napi_value value) - : Object(env, value) {} - -inline void* ArrayBufferLike::Data() { - void* data; - napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr); - NAPI_THROW_IF_FAILED(_env, status, nullptr); - return data; -} - -inline size_t ArrayBufferLike::ByteLength() { - size_t length; - napi_status status = - napi_get_arraybuffer_info(_env, _value, nullptr, &length); - NAPI_THROW_IF_FAILED(_env, status, 0); - return length; -} - #ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER //////////////////////////////////////////////////////////////////////////////// // SharedArrayBuffer class //////////////////////////////////////////////////////////////////////////////// -inline SharedArrayBuffer::SharedArrayBuffer() : ArrayBufferLike() {} +inline SharedArrayBuffer::SharedArrayBuffer() : Object() {} inline SharedArrayBuffer::SharedArrayBuffer(napi_env env, napi_value value) - : ArrayBufferLike(env, value) {} + : Object(env, value) {} inline void SharedArrayBuffer::CheckCast(napi_env env, napi_value value) { NAPI_CHECK(value != nullptr, "SharedArrayBuffer::CheckCast", "empty value"); @@ -2133,6 +2113,21 @@ inline SharedArrayBuffer SharedArrayBuffer::New(napi_env env, return SharedArrayBuffer(env, value); } + +inline void* SharedArrayBuffer::Data() { + void* data; + napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr); + NAPI_THROW_IF_FAILED(_env, status, nullptr); + return data; +} + +inline size_t SharedArrayBuffer::ByteLength() { + size_t length; + napi_status status = + napi_get_arraybuffer_info(_env, _value, nullptr, &length); + NAPI_THROW_IF_FAILED(_env, status, 0); + return length; +} #endif // NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER //////////////////////////////////////////////////////////////////////////////// @@ -2221,10 +2216,25 @@ inline void ArrayBuffer::CheckCast(napi_env env, napi_value value) { NAPI_CHECK(result, "ArrayBuffer::CheckCast", "value is not arraybuffer"); } -inline ArrayBuffer::ArrayBuffer() : ArrayBufferLike() {} +inline ArrayBuffer::ArrayBuffer() : Object() {} inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value) - : ArrayBufferLike(env, value) {} + : Object(env, value) {} + +inline void* ArrayBuffer::Data() { + void* data; + napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr); + NAPI_THROW_IF_FAILED(_env, status, nullptr); + return data; +} + +inline size_t ArrayBuffer::ByteLength() { + size_t length; + napi_status status = + napi_get_arraybuffer_info(_env, _value, nullptr, &length); + NAPI_THROW_IF_FAILED(_env, status, 0); + return length; +} #if NAPI_VERSION >= 7 inline bool ArrayBuffer::IsDetached() const { diff --git a/napi.h b/napi.h index b0575fe4c..013a9114d 100644 --- a/napi.h +++ b/napi.h @@ -1205,18 +1205,8 @@ class Object::iterator { }; #endif // NODE_ADDON_API_CPP_EXCEPTIONS -class ArrayBufferLike : public Object { - public: - void* Data(); - size_t ByteLength(); - - protected: - ArrayBufferLike(); - ArrayBufferLike(napi_env env, napi_value value); -}; - #ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER -class SharedArrayBuffer : public ArrayBufferLike { +class SharedArrayBuffer : public Object { public: SharedArrayBuffer(); SharedArrayBuffer(napi_env env, napi_value value); @@ -1224,11 +1214,14 @@ class SharedArrayBuffer : public ArrayBufferLike { static SharedArrayBuffer New(napi_env env, size_t byteLength); static void CheckCast(napi_env env, napi_value value); + + void* Data(); + size_t ByteLength(); }; #endif /// A JavaScript array buffer value. -class ArrayBuffer : public ArrayBufferLike { +class ArrayBuffer : public Object { public: /// Creates a new ArrayBuffer instance over a new automatically-allocated /// buffer. @@ -1289,6 +1282,9 @@ class ArrayBuffer : public ArrayBufferLike { ArrayBuffer(napi_env env, napi_value value); ///< Wraps a Node-API value primitive. + void* Data(); ///< Gets a pointer to the data buffer. + size_t ByteLength(); ///< Gets the length of the array buffer in bytes. + #if NAPI_VERSION >= 7 bool IsDetached() const; void Detach();