0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-28 22:46:31 +01:00

n-api: add support for DataView

Basic support for Dataview is added in this commit. This is achieved
by using three functions, napi_create_dataview(), napi_is_dataview()
and napi_get_dataview_info().

PR-URL: https://github.com/nodejs/node/pull/14382
Fixes: https://github.com/nodejs/node/issues/13926
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
Shivanth MP 2017-07-20 01:50:43 +05:30 committed by Tobias Nießen
parent 9926dfebc8
commit 77ca3cb474
6 changed files with 236 additions and 0 deletions

View File

@ -1331,6 +1331,40 @@ JavaScript TypedArray Objects are described in
[Section 22.2](https://tc39.github.io/ecma262/#sec-typedarray-objects)
of the ECMAScript Language Specification.
#### *napi_create_dataview*
<!-- YAML
added: REPLACEME
-->
```C
napi_status napi_create_dataview(napi_env env,
size_t byte_length,
napi_value arraybuffer,
size_t byte_offset,
napi_value* result)
```
- `[in] env`: The environment that the API is invoked under.
- `[in] length`: Number of elements in the DataView.
- `[in] arraybuffer`: ArrayBuffer underlying the DataView.
- `[in] byte_offset`: The byte offset within the ArrayBuffer from which to
start projecting the DataView.
- `[out] result`: A `napi_value` representing a JavaScript DataView.
Returns `napi_ok` if the API succeeded.
This API creates a JavaScript DataView object over an existing ArrayBuffer.
DataView objects provide an array-like view over an underlying data buffer,
but one which allows items of different size and type in the ArrayBuffer.
It is required that `byte_length + byte_offset` is less than or equal to the
size in bytes of the array passed in. If not, a RangeError exception is raised.
JavaScript DataView Objects are described in
[Section 24.3][] of the ECMAScript Language Specification.
### Functions to convert from C types to N-API
#### *napi_create_number*
<!-- YAML
@ -1552,6 +1586,36 @@ This API returns various properties of a typed array.
*Warning*: Use caution while using this API since the underlying data buffer
is managed by the VM
#### *napi_get_dataview_info*
<!-- YAML
added: REPLACEME
-->
```C
napi_status napi_get_dataview_info(napi_env env,
napi_value dataview,
size_t* byte_length,
void** data,
napi_value* arraybuffer,
size_t* byte_offset)
```
- `[in] env`: The environment that the API is invoked under.
- `[in] dataview`: `napi_value` representing the DataView whose
properties to query.
- `[out] byte_length`: Number of bytes in the DataView.
- `[out] data`: The data buffer underlying the DataView.
- `[out] arraybuffer`: ArrayBuffer underlying the DataView.
- `[out] byte_offset`: The byte offset within the data buffer from which
to start projecting the DataView.
Returns `napi_ok` if the API succeeded.
This API returns various properties of a DataView.
#### *napi_get_value_bool*
<!-- YAML
added: v8.0.0
@ -2019,6 +2083,25 @@ Returns `napi_ok` if the API succeeded.
This API checks if the Object passsed in is a typed array.
### *napi_is_dataview*
<!-- YAML
added: REPLACEME
-->
```C
napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
```
- `[in] env`: The environment that the API is invoked under.
- `[in] value`: The JavaScript value to check.
- `[out] result`: Whether the given `napi_value` represents a DataView.
Returns `napi_ok` if the API succeeded.
This API checks if the Object passed in is a DataView.
### *napi_strict_equals*
<!-- YAML
added: v8.0.0
@ -3165,6 +3248,7 @@ support it:
[Object Wrap]: #n_api_object_wrap
[Section 9.1.6]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
[Section 12.5.5]: https://tc39.github.io/ecma262/#sec-typeof-operator
[Section 24.3]: https://tc39.github.io/ecma262/#sec-dataview-objects
[Working with JavaScript Functions]: #n_api_working_with_javascript_functions
[Working with JavaScript Properties]: #n_api_working_with_javascript_properties
[Working with JavaScript Values]: #n_api_working_with_javascript_values

View File

@ -3016,6 +3016,72 @@ napi_status napi_get_typedarray_info(napi_env env,
return napi_clear_last_error(env);
}
napi_status napi_create_dataview(napi_env env,
size_t byte_length,
napi_value arraybuffer,
size_t byte_offset,
napi_value* result) {
NAPI_PREAMBLE(env);
CHECK_ARG(env, arraybuffer);
CHECK_ARG(env, result);
v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(arraybuffer);
RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(), napi_invalid_arg);
v8::Local<v8::ArrayBuffer> buffer = value.As<v8::ArrayBuffer>();
v8::Local<v8::DataView> DataView = v8::DataView::New(buffer, byte_offset,
byte_length);
*result = v8impl::JsValueFromV8LocalValue(DataView);
return GET_RETURN_STATUS(env);
}
napi_status napi_is_dataview(napi_env env, napi_value value, bool* result) {
CHECK_ENV(env);
CHECK_ARG(env, value);
CHECK_ARG(env, result);
v8::Local<v8::Value> val = v8impl::V8LocalValueFromJsValue(value);
*result = val->IsDataView();
return napi_clear_last_error(env);
}
napi_status napi_get_dataview_info(napi_env env,
napi_value dataview,
size_t* byte_length,
void** data,
napi_value* arraybuffer,
size_t* byte_offset) {
CHECK_ENV(env);
CHECK_ARG(env, dataview);
v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(dataview);
RETURN_STATUS_IF_FALSE(env, value->IsDataView(), napi_invalid_arg);
v8::Local<v8::DataView> array = value.As<v8::DataView>();
if (byte_length != nullptr) {
*byte_length = array->ByteLength();
}
v8::Local<v8::ArrayBuffer> buffer = array->Buffer();
if (data != nullptr) {
*data = static_cast<uint8_t*>(buffer->GetContents().Data()) +
array->ByteOffset();
}
if (arraybuffer != nullptr) {
*arraybuffer = v8impl::JsValueFromV8LocalValue(buffer);
}
if (byte_offset != nullptr) {
*byte_offset = array->ByteOffset();
}
return napi_clear_last_error(env);
}
napi_status napi_get_version(napi_env env, uint32_t* result) {
CHECK_ENV(env);
CHECK_ARG(env, result);

View File

@ -494,6 +494,21 @@ NAPI_EXTERN napi_status napi_get_typedarray_info(napi_env env,
napi_value* arraybuffer,
size_t* byte_offset);
NAPI_EXTERN napi_status napi_create_dataview(napi_env env,
size_t length,
napi_value arraybuffer,
size_t byte_offset,
napi_value* result);
NAPI_EXTERN napi_status napi_is_dataview(napi_env env,
napi_value value,
bool* result);
NAPI_EXTERN napi_status napi_get_dataview_info(napi_env env,
napi_value dataview,
size_t* bytelength,
void** data,
napi_value* arraybuffer,
size_t* byte_offset);
// Methods to manage simple async operations
NAPI_EXTERN
napi_status napi_create_async_work(napi_env env,

View File

@ -0,0 +1,8 @@
{
"targets": [
{
"target_name": "test_dataview",
"sources": [ "test_dataview.c" ]
}
]
}

View File

@ -0,0 +1,14 @@
'use strict';
const common = require('../../common');
const assert = require('assert');
// Testing api calls for arrays
const test_dataview = require(`./build/${common.buildType}/test_dataview`);
//create dataview
const buffer = new ArrayBuffer(128);
const template = Reflect.construct(DataView, [buffer]);
const theDataview = test_dataview.CreateDataView(template);
assert.ok(theDataview instanceof DataView,
'The new variable should be of type Dataview');

View File

@ -0,0 +1,49 @@
#include <node_api.h>
#include <string.h>
#include "../common.h"
napi_value CreateDataView(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args [1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
napi_valuetype valuetype;
napi_value input_dataview = args[0];
NAPI_CALL(env, napi_typeof(env, input_dataview, &valuetype));
NAPI_ASSERT(env, valuetype == napi_object,
"Wrong type of arguments. Expects a DataView as the first "
"argument.");
bool is_dataview;
NAPI_CALL(env, napi_is_dataview(env, input_dataview, &is_dataview));
NAPI_ASSERT(env, is_dataview,
"Wrong type of arguments. Expects a DataView as the first "
"argument.");
size_t byte_offset = 0;
size_t length = 0;
napi_value buffer;
NAPI_CALL(env,
napi_get_dataview_info(env, input_dataview, &length, NULL,
&buffer, &byte_offset));
napi_value output_dataview;
NAPI_CALL(env,
napi_create_dataview(env, length, buffer,
byte_offset, &output_dataview));
return output_dataview;
}
void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
napi_property_descriptor descriptors[] = {
DECLARE_NAPI_PROPERTY("CreateDataView", CreateDataView)
};
NAPI_CALL_RETURN_VOID(env, napi_define_properties(
env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
}
NAPI_MODULE(addon, Init)