Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: ArrayBuffer and Buffer documentation #256

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 126 additions & 4 deletions doc/array_buffer.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,127 @@
# Array buffer
# ArrayBuffer

You are reading a draft of the next documentation and it's in continuous update so
if you don't find what you need please refer to:
[C++ wrapper classes for the ABI-stable C APIs for Node.js](https://nodejs.github.io/node-addon-api/)
The `ArrayBuffer` class corresponds to the JavaScript `ArrayBuffer` class.

## Methods

### New

Allocates a new `ArrayBuffer` object with a given length.

```cpp
static ArrayBuffer New(napi_env env, size_t byteLength);
```

- `[in] env`: The environment in which to create the ArrayBuffer object.
- `[in] byteLength`: The length to be allocated, in bytes.

Returns a new `ArrayBuffer` object.

### New

Wraps the provided external data into a new `ArrayBuffer` object.

The `ArrayBuffer` object does not assume ownership for the data and expects it
to be valid for the lifetime of the object. Since the `ArrayBuffer` is subject
to garbage collection this overload is only suitable for data which is static
and never needs to be freed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like your description here.

I know we discussed doing a free, but thinking about it I don't like us trying to free an object that we don't know was allocated with malloc or new.

What would be good to figure out though is how to avoid conversion errors from NaN which result in leaks. I'd be tempted to remove or deprecate this one and force callers to indicate they don't need finalization by passing a null to one of the other methods. Since the wrapper is not part of the abi contract I think we could delete the method and provide instructions on what to use instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just deprecate as opposed to remove with the doc saying "don't use"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern about "doc deprecated" is that it requires people to see the doc when converting their code.


```cpp
static ArrayBuffer New(napi_env env, void* externalData, size_t byteLength);
```

- `[in] env`: The environment in which to create the `ArrayBuffer` object.
- `[in] externalData`: The pointer to the external data to wrap.
- `[in] byteLength`: The length of the `externalData`, in bytes.

Returns a new `ArrayBuffer` object.

### New

Wraps the provided external data into a new `ArrayBuffer` object.

The `ArrayBuffer` object does not assume ownership for the data and expects it
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not more accurate that it effectively does take ownership, taking responsibility to run the finalizer to provided to delete the data when the class is deleted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I toyed with the wording here a bit, but since the module code is still responsible for cleanup I feel like it's more accurate to say that ownership is never transferred. The caller is merely lending the data to the ArrayBuffer. Doing a bit more reading, it seems to align pretty well with the way V8 describes these "externalized" ArrayBuffer objects.

https://v8.paulfryzel.com/docs/master/classv8_1_1_array_buffer.html#a166848a34653afd4502e4cc33443815d

After ArrayBuffer had been externalized, it does no longer own the memory block. The caller should take steps to free memory when it is no longer needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kfarnung did we close on what we wanted to do? It would be good to get this landed.

to be valid for the lifetime of the object. The data can only be freed once the
`finalizeCallback` is invoked to indicate that the `ArrayBuffer` has been
released.

```cpp
template <typename Finalizer>
static ArrayBuffer New(napi_env env,
void* externalData,
size_t byteLength,
Finalizer finalizeCallback);
```

- `[in] env`: The environment in which to create the `ArrayBuffer` object.
- `[in] externalData`: The pointer to the external data to wrap.
- `[in] byteLength`: The length of the `externalData`, in bytes.
- `[in] finalizeCallback`: A function to be called when the `ArrayBuffer` is
destroyed. It must implement `operator()`, accept a `void*` (which is the
`externalData` pointer), and return `void`.

Returns a new `ArrayBuffer` object.

### New

Wraps the provided external data into a new `ArrayBuffer` object.

The `ArrayBuffer` object does not assume ownership for the data and expects it
to be valid for the lifetime of the object. The data can only be freed once the
`finalizeCallback` is invoked to indicate that the `ArrayBuffer` has been
released.

```cpp
template <typename Finalizer, typename Hint>
static ArrayBuffer New(napi_env env,
void* externalData,
size_t byteLength,
Finalizer finalizeCallback,
Hint* finalizeHint);
```

- `[in] env`: The environment in which to create the `ArrayBuffer` object.
- `[in] externalData`: The pointer to the external data to wrap.
- `[in] byteLength`: The length of the `externalData`, in bytes.
- `[in] finalizeCallback`: The function to be called when the `ArrayBuffer` is
destroyed. It must implement `operator()`, accept a `void*` (which is the
`externalData` pointer) and `Hint*`, and return `void`.
- `[in] finalizeHint`: The hint to be passed as the second parameter of the
finalize callback.

Returns a new `ArrayBuffer` object.

### Constructor

Initializes an empty instance of the `ArrayBuffer` class.

```cpp
ArrayBuffer();
```

### Constructor

Initializes a wrapper instance of an existing `ArrayBuffer` object.

```cpp
ArrayBuffer(napi_env env, napi_value value);
```

- `[in] env`: The environment in which to create the `ArrayBuffer` object.
- `[in] value`: The `ArrayBuffer` reference to wrap.

### ByteLength

```cpp
size_t ByteLength() const;
```

Returns the length of the wrapped data, in bytes.

### Data

```cpp
T* Data() const;
```

Returns a pointer the wrapped data.
141 changes: 138 additions & 3 deletions doc/buffer.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,140 @@
# Buffer

You are reading a draft of the next documentation and it's in continuous update so
if you don't find what you need please refer to:
[C++ wrapper classes for the ABI-stable C APIs for Node.js](https://nodejs.github.io/node-addon-api/)
The `Buffer` class creates a projection of raw data that can be consumed by
script.

## Methods

### New

Allocates a new `Buffer` object with a given length.

```cpp
static Buffer<T> New(napi_env env, size_t length);
```

- `[in] env`: The environment in which to create the `Buffer` object.
- `[in] length`: The number of `T` elements to allocate.

Returns a new `Buffer` object.

### New

Wraps the provided external data into a new `Buffer` object.

The `Buffer` object does not assume ownership for the data and expects it to be
valid for the lifetime of the object. Since the `Buffer` is subject to garbage
collection this overload is only suitable for data which is static and never
needs to be freed.

```cpp
static Buffer<T> New(napi_env env, T* data, size_t length);
```

- `[in] env`: The environment in which to create the `Buffer` object.
- `[in] data`: The pointer to the external data to expose.
- `[in] length`: The number of `T` elements in the external data.

Returns a new `Buffer` object.

### New

Wraps the provided external data into a new `Buffer` object.

The `Buffer` object does not assume ownership for the data and expects it
to be valid for the lifetime of the object. The data can only be freed once the
`finalizeCallback` is invoked to indicate that the `Buffer` has been released.

```cpp
template <typename Finalizer>
static Buffer<T> New(napi_env env,
T* data,
size_t length,
Finalizer finalizeCallback);
```

- `[in] env`: The environment in which to create the `Buffer` object.
- `[in] data`: The pointer to the external data to expose.
- `[in] length`: The number of `T` elements in the external data.
- `[in] finalizeCallback`: The function to be called when the `Buffer` is
destroyed. It must implement `operator()`, accept a `T*` (which is the
external data pointer), and return `void`.

Returns a new `Buffer` object.

### New

Wraps the provided external data into a new `Buffer` object.

The `Buffer` object does not assume ownership for the data and expects it to be
valid for the lifetime of the object. The data can only be freed once the
`finalizeCallback` is invoked to indicate that the `Buffer` has been released.

```cpp
template <typename Finalizer, typename Hint>
static Buffer<T> New(napi_env env,
T* data,
size_t length,
Finalizer finalizeCallback,
Hint* finalizeHint);
```

- `[in] env`: The environment in which to create the `Buffer` object.
- `[in] data`: The pointer to the external data to expose.
- `[in] length`: The number of `T` elements in the external data.
- `[in] finalizeCallback`: The function to be called when the `Buffer` is
destroyed. It must implement `operator()`, accept a `T*` (which is the
external data pointer) and `Hint*`, and return `void`.
- `[in] finalizeHint`: The hint to be passed as the second parameter of the
finalize callback.

Returns a new `Buffer` object.

### Copy

Allocates a new `Buffer` object and copies the provided external data into it.

```cpp
static Buffer<T> Copy(napi_env env, const T* data, size_t length);
```

- `[in] env`: The environment in which to create the `Buffer` object.
- `[in] data`: The pointer to the external data to copy.
- `[in] length`: The number of `T` elements in the external data.

Returns a new `Buffer` object containing a copy of the data.

### Constructor

Initializes an empty instance of the `Buffer` class.

```cpp
Buffer();
```

### Constructor

Initializes the `Buffer` object using an existing Uint8Array.

```cpp
Buffer(napi_env env, napi_value value);
```

- `[in] env`: The environment in which to create the `Buffer` object.
- `[in] value`: The Uint8Array reference to wrap.

### Data

```cpp
T* Data() const;
```

Returns a pointer the external data.

### Length

```cpp
size_t Length() const;
```

Returns the number of `T` elements in the external data.