Skip to content

Commit

Permalink
node-api: add support for napi_set_named_property_len function
Browse files Browse the repository at this point in the history
  • Loading branch information
Mert Can Altin committed May 14, 2024
1 parent 9807ede commit 20834e7
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
24 changes: 24 additions & 0 deletions doc/api/n-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3134,6 +3134,30 @@ overhead in creating/storing strings with this method.
The JavaScript `string` type is described in
[Section 6.1.4][] of the ECMAScript Language Specification.

> **Stability**: 1 - Experimental

```c
napi_status NAPI_CDECL napi_set_named_property_len(napi_env env,
napi_value object,
const char* utf8name,
size_t name_length,
napi_value value);
```

* `[in] env`: The environment that the API is invoked under.
* `[in] object`: The JavaScript object on which to set the named property.
* `[in] utf8name`: Character buffer representing a UTF-8-encoded string.
* `[in] name_length`: The length of the string in bytes, or NAPI\_AUTO\_LENGTH if it is null-terminated.
* `[in] value`: The napi\_value representing the value to set as the named property.
Returns napi\_ok if the API succeeded.

This API sets a named property on a JavaScript object, treating '\0'
characters as values rather than terminators. This allows for more
flexible property names, especially when dealing with virtual module
names or other scenarios where '\0' characters are used as part of the name.

Note: This function is experimental and its stability may change in future releases.

### Functions to convert from Node-API to C types

#### `napi_get_array_length`
Expand Down
7 changes: 7 additions & 0 deletions src/js_native_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ NAPI_EXTERN napi_status NAPI_CDECL node_api_create_property_key_utf16(
napi_env env, const char16_t* str, size_t length, napi_value* result);
#endif // NAPI_EXPERIMENTAL

#ifdef NAPI_EXPERIMENTAL
#define NODE_API_EXPERIMENTAL_HAS_PROPERTY_KEYS
NAPI_EXTERN napi_status NAPI_CDECL napi_set_named_property_len(
napi_env env, napi_value object, const char* utf8name,
size_t name_length, napi_value value);
#endif // NAPI_EXPERIMENTAL

NAPI_EXTERN napi_status NAPI_CDECL napi_create_symbol(napi_env env,
napi_value description,
napi_value* result);
Expand Down
26 changes: 26 additions & 0 deletions src/js_native_api_v8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1718,6 +1718,32 @@ napi_status NAPI_CDECL node_api_create_property_key_utf16(napi_env env,
});
}

napi_status NAPI_CDECL napi_set_named_property_len(napi_env env,
napi_value object,
const char* utf8name,
size_t name_length,
napi_value value) {
std::u16string utf16name;
utf16name.reserve(name_length);
for (size_t i = 0; i < name_length; ++i) {
if (utf8name[i] == '\0') {
utf16name.push_back(static_cast<char16_t>('\0'));
} else {
utf16name.push_back(static_cast<char16_t>(utf8name[i]));
}
}

napi_value result;
napi_status status = napi_set_named_property(
env, object, utf16name.data(), utf16name.length(), value);

if (status != napi_ok) {
return status;
}

return napi_ok;
}

napi_status NAPI_CDECL napi_create_double(napi_env env,
double value,
napi_value* result) {
Expand Down
50 changes: 50 additions & 0 deletions test/js-native-api/test_string/test_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,56 @@ static napi_value TestPropertyKeyUtf16AutoLength(napi_env env,
auto_length);
}

static napi_value TestSetNamedPropertyLen(napi_env env, napi_callback_info info) {
size_t argc = 0;
napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);

if (argc < 1) {
napi_throw_error(env, nullptr, "Invalid number of arguments");
return nullptr;
}

napi_value object;
napi_create_object(env, &object);

const char* key = "\0test";
napi_value value;
napi_create_int32(env, 42, &value);

napi_status status = napi_set_named_property_len(env, object, key, strlen(key), value);
if (status != napi_ok) {
napi_throw_error(env, nullptr, "Failed to set named property");
return nullptr;
}

return object;
}

static napi_value TestSetNamedPropertyLenAutoLength(napi_env env, napi_callback_info info) {
size_t argc = 0;
napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);

if (argc < 1) {
napi_throw_error(env, nullptr, "Invalid number of arguments");
return nullptr;
}

napi_value object;
napi_create_object(env, &object);

const char* key = "\0test";
napi_value value;
napi_create_int32(env, 42, &value);

napi_status status = napi_set_named_property_len(env, object, key, strlen(key), value);
if (status != napi_ok) {
napi_throw_error(env, nullptr, "Failed to set named property");
return nullptr;
}

return object;
}

static napi_value Utf16Length(napi_env env, napi_callback_info info) {
napi_value args[1];
NODE_API_CALL(env, validate_and_retrieve_single_string_arg(env, info, args));
Expand Down

0 comments on commit 20834e7

Please sign in to comment.