Closed
Description
Give how the API looks today is there an efficient way to convert a napi_value into a std::string without doing an extra copy? Currently in order to convert a nap string into a std::string we need to perform 2 copies. Would be nice to be able to at least reduce it to 1 copy. Would be even nicer if one could move/reference ownership i.e. 0 copy.
std::string toString(napi_env& env, const napi_value& from) {
size_t size = 0;
if (IsString(env, from)) {
// TODO (perf): Can we somehow copy directly into an
// allocated but uninitialized std::string?
LD_STRING_OR_BUFFER_TO_COPY(env, from, to);
auto result = std::string(toCh_, toSz_);
delete [] toCh_; // FIX: This will leak if std::string throws...
return result;
} else if (IsBuffer(env, from)) {
char* data = nullptr;
napi_get_buffer_info(env, from, reinterpret_cast<void**>(&data), &size);
return std::string(data, size);
}
return "";
}
#define LD_STRING_OR_BUFFER_TO_COPY(env, from, to) \
char* to##Ch_ = 0; \
size_t to##Sz_ = 0; \
if (IsString(env, from)) { \
napi_get_value_string_utf8(env, from, NULL, 0, &to##Sz_); \
to##Ch_ = new char[to##Sz_ + 1]; \
napi_get_value_string_utf8(env, from, to##Ch_, to##Sz_ + 1, &to##Sz_); \
to##Ch_[to##Sz_] = '\0'; \
} else if (IsBuffer(env, from)) { \
char* buf = 0; \
napi_get_buffer_info(env, from, (void **)&buf, &to##Sz_); \
to##Ch_ = new char[to##Sz_]; \
memcpy(to##Ch_, buf, to##Sz_); \
}
Refs: Level/classic-level#21
Metadata
Metadata
Assignees
Labels
No labels