diff options
author | Timothy Flynn <trflynn89@pm.me> | 2021-08-01 19:02:19 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-04 11:18:24 +0200 |
commit | b6ff7f4fcc90fbd378cc3886ae686fd54b8e6190 (patch) | |
tree | 9cdea237057a5580bf5f52ee8beb9ec2f06badaa /Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp | |
parent | 4c2cc419f964009e44330b7d1404763209f97575 (diff) | |
download | serenity-b6ff7f4fcc90fbd378cc3886ae686fd54b8e6190.zip |
LibJS: Allow PrimitiveString to be created with a UTF-16 string
PrimitiveString may currently only be created with a UTF-8 string, and
it transcodes on the fly when a UTF-16 string is needed. Allow creating
a PrimitiveString from a UTF-16 string to avoid unnecessary transcoding
when the caller only wants UTF-16.
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp | 59 |
1 files changed, 49 insertions, 10 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp index bc40b4df19..1d7e74cee2 100644 --- a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp +++ b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp @@ -12,7 +12,14 @@ namespace JS { PrimitiveString::PrimitiveString(String string) - : m_string(move(string)) + : m_utf8_string(move(string)) + , m_has_utf8_string(true) +{ +} + +PrimitiveString::PrimitiveString(Vector<u16> string) + : m_utf16_string(move(string)) + , m_has_utf16_string(true) { } @@ -20,10 +27,21 @@ PrimitiveString::~PrimitiveString() { } +String const& PrimitiveString::string() const +{ + if (!m_has_utf8_string) { + m_utf8_string = utf16_string_view().to_utf8(Utf16View::AllowInvalidCodeUnits::Yes); + m_has_utf8_string = true; + } + return m_utf8_string; +} + Vector<u16> const& PrimitiveString::utf16_string() const { - if (m_utf16_string.is_empty() && !m_string.is_empty()) - m_utf16_string = AK::utf8_to_utf16(m_string); + if (!m_has_utf16_string) { + m_utf16_string = AK::utf8_to_utf16(m_utf8_string); + m_has_utf16_string = true; + } return m_utf16_string; } @@ -32,24 +50,45 @@ Utf16View PrimitiveString::utf16_string_view() const return Utf16View { utf16_string() }; } -PrimitiveString* js_string(Heap& heap, Utf16View const& string) +PrimitiveString* js_string(Heap& heap, Utf16View const& view) +{ + if (view.is_empty()) + return &heap.vm().empty_string(); + + if (view.length_in_code_units() == 1) { + u16 code_unit = view.code_unit_at(0); + if (is_ascii(code_unit)) + return &heap.vm().single_ascii_character_string(static_cast<u8>(code_unit)); + } + + Vector<u16> string; + string.ensure_capacity(view.length_in_code_units()); + string.append(view.data(), view.length_in_code_units()); + return js_string(heap, move(string)); +} + +PrimitiveString* js_string(VM& vm, Utf16View const& view) +{ + return js_string(vm.heap(), view); +} + +PrimitiveString* js_string(Heap& heap, Vector<u16> string) { if (string.is_empty()) return &heap.vm().empty_string(); - if (string.length_in_code_units() == 1) { - u16 code_unit = string.code_unit_at(0); + if (string.size() == 1) { + u16 code_unit = string.at(0); if (is_ascii(code_unit)) return &heap.vm().single_ascii_character_string(static_cast<u8>(code_unit)); } - auto utf8_string = string.to_utf8(Utf16View::AllowInvalidCodeUnits::Yes); - return heap.allocate_without_global_object<PrimitiveString>(move(utf8_string)); + return heap.allocate_without_global_object<PrimitiveString>(move(string)); } -PrimitiveString* js_string(VM& vm, Utf16View const& string) +PrimitiveString* js_string(VM& vm, Vector<u16> string) { - return js_string(vm.heap(), string); + return js_string(vm.heap(), move(string)); } PrimitiveString* js_string(Heap& heap, String string) |