mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Optimize napi_get_value_string_utf8 napi_get_value_string_latin1 napi_get_value_string_utf16 (#20612)
This commit is contained in:
@@ -2059,23 +2059,26 @@ struct BufferElement<NapiStringEncoding::utf16le> {
|
||||
template<NapiStringEncoding EncodeTo>
|
||||
napi_status napi_get_value_string_any_encoding(napi_env env, napi_value napiValue, typename BufferElement<EncodeTo>::Type* buf, size_t bufsize, size_t* writtenPtr)
|
||||
{
|
||||
NAPI_PREAMBLE(env);
|
||||
NAPI_CHECK_ARG(env, napiValue);
|
||||
JSValue jsValue = toJS(napiValue);
|
||||
NAPI_RETURN_EARLY_IF_FALSE(env, jsValue.isString(), napi_string_expected);
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
String view = jsValue.asCell()->getString(globalObject);
|
||||
size_t length = view.length();
|
||||
JSString* jsString = jsValue.toString(globalObject);
|
||||
NAPI_RETURN_IF_EXCEPTION(env);
|
||||
const auto view = jsString->view(globalObject);
|
||||
NAPI_RETURN_IF_EXCEPTION(env);
|
||||
|
||||
if (buf == nullptr) {
|
||||
// they just want to know the length
|
||||
NAPI_CHECK_ARG(env, writtenPtr);
|
||||
switch (EncodeTo) {
|
||||
case NapiStringEncoding::utf8:
|
||||
if (view.is8Bit()) {
|
||||
*writtenPtr = Bun__encoding__byteLengthLatin1AsUTF8(view.span8().data(), length);
|
||||
if (view->is8Bit()) {
|
||||
*writtenPtr = Bun__encoding__byteLengthLatin1AsUTF8(view->span8().data(), view->length());
|
||||
} else {
|
||||
*writtenPtr = Bun__encoding__byteLengthUTF16AsUTF8(view.span16().data(), length);
|
||||
*writtenPtr = Bun__encoding__byteLengthUTF16AsUTF8(view->span16().data(), view->length());
|
||||
}
|
||||
break;
|
||||
case NapiStringEncoding::utf16le:
|
||||
@@ -2084,7 +2087,7 @@ napi_status napi_get_value_string_any_encoding(napi_env env, napi_value napiValu
|
||||
// if the string's encoding is the same as the destination encoding, this is trivially correct
|
||||
// if we are converting UTF-16 to Latin-1, then we do so by truncating each code unit, so the length is the same
|
||||
// if we are converting Latin-1 to UTF-16, then we do so by extending each code unit, so the length is also the same
|
||||
*writtenPtr = length;
|
||||
*writtenPtr = view->length();
|
||||
break;
|
||||
}
|
||||
return napi_set_last_error(env, napi_ok);
|
||||
@@ -2108,19 +2111,22 @@ napi_status napi_get_value_string_any_encoding(napi_env env, napi_value napiValu
|
||||
// since we need to put a null terminator there
|
||||
? 2 * (bufsize - 1)
|
||||
: bufsize - 1);
|
||||
if (view.is8Bit()) {
|
||||
if (view->is8Bit()) {
|
||||
const auto span = view->span8();
|
||||
if constexpr (EncodeTo == NapiStringEncoding::utf16le) {
|
||||
|
||||
// pass subslice to work around Bun__encoding__writeLatin1 asserting that the output has room
|
||||
written = Bun__encoding__writeLatin1(view.span8().data(),
|
||||
std::min(static_cast<size_t>(view.span8().size()), bufsize),
|
||||
written = Bun__encoding__writeLatin1(span.data(),
|
||||
std::min(static_cast<size_t>(span.size()), bufsize),
|
||||
writable_byte_slice.data(),
|
||||
writable_byte_slice.size(),
|
||||
static_cast<uint8_t>(EncodeTo));
|
||||
} else {
|
||||
written = Bun__encoding__writeLatin1(view.span8().data(), view.length(), writable_byte_slice.data(), writable_byte_slice.size(), static_cast<uint8_t>(EncodeTo));
|
||||
written = Bun__encoding__writeLatin1(span.data(), span.size(), writable_byte_slice.data(), writable_byte_slice.size(), static_cast<uint8_t>(EncodeTo));
|
||||
}
|
||||
} else {
|
||||
written = Bun__encoding__writeUTF16(view.span16().data(), view.length(), writable_byte_slice.data(), writable_byte_slice.size(), static_cast<uint8_t>(EncodeTo));
|
||||
const auto span = view->span16();
|
||||
written = Bun__encoding__writeUTF16(span.data(), span.size(), writable_byte_slice.data(), writable_byte_slice.size(), static_cast<uint8_t>(EncodeTo));
|
||||
}
|
||||
|
||||
// convert bytes to code units
|
||||
|
||||
Reference in New Issue
Block a user