diff --git a/Userland/Libraries/LibJS/CMakeLists.txt b/Userland/Libraries/LibJS/CMakeLists.txt index 15319f9828..b55e3a1390 100644 --- a/Userland/Libraries/LibJS/CMakeLists.txt +++ b/Userland/Libraries/LibJS/CMakeLists.txt @@ -157,6 +157,7 @@ set(SOURCES Runtime/TypedArray.cpp Runtime/TypedArrayConstructor.cpp Runtime/TypedArrayPrototype.cpp + Runtime/Utf16String.cpp Runtime/Value.cpp Runtime/VM.cpp Runtime/WeakContainer.cpp diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index b16094535f..7247cefd24 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -169,6 +169,7 @@ class Statement; class StringOrSymbol; class Symbol; class Token; +class Utf16String; class VM; class Value; class WeakContainer; diff --git a/Userland/Libraries/LibJS/Runtime/Utf16String.cpp b/Userland/Libraries/LibJS/Runtime/Utf16String.cpp new file mode 100644 index 0000000000..b2e40c252f --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/Utf16String.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace JS { +namespace Detail { + +static NonnullRefPtr the_empty_utf16_string() +{ + static NonnullRefPtr empty_string = Utf16StringImpl::create(); + return empty_string; +} + +Utf16StringImpl::Utf16StringImpl(Vector string) + : m_string(move(string)) +{ +} + +NonnullRefPtr Utf16StringImpl::create() +{ + return adopt_ref(*new Utf16StringImpl()); +} + +NonnullRefPtr Utf16StringImpl::create(Vector string) +{ + return adopt_ref(*new Utf16StringImpl(move(string))); +} + +NonnullRefPtr Utf16StringImpl::create(StringView const& string) +{ + return create(AK::utf8_to_utf16(string)); +} + +NonnullRefPtr Utf16StringImpl::create(Utf16View const& view) +{ + Vector string; + string.ensure_capacity(view.length_in_code_units()); + string.append(view.data(), view.length_in_code_units()); + return create(move(string)); +} + +Vector const& Utf16StringImpl::string() const +{ + return m_string; +} + +Utf16View Utf16StringImpl::view() const +{ + return Utf16View { m_string }; +} + +} + +Utf16String::Utf16String() + : m_string(Detail::the_empty_utf16_string()) +{ +} + +Utf16String::Utf16String(Vector string) + : m_string(Detail::Utf16StringImpl::create(move(string))) +{ +} + +Utf16String::Utf16String(StringView const& string) + : m_string(Detail::Utf16StringImpl::create(move(string))) +{ +} + +Utf16String::Utf16String(Utf16View const& string) + : m_string(Detail::Utf16StringImpl::create(move(string))) +{ +} + +Vector const& Utf16String::string() const +{ + return m_string->string(); +} + +Utf16View Utf16String::view() const +{ + return m_string->view(); +} + +Utf16View Utf16String::substring_view(size_t code_unit_offset, size_t code_unit_length) const +{ + return view().substring_view(code_unit_offset, code_unit_length); +} + +Utf16View Utf16String::substring_view(size_t code_unit_offset) const +{ + return view().substring_view(code_unit_offset); +} + +String Utf16String::to_utf8() const +{ + return view().to_utf8(Utf16View::AllowInvalidCodeUnits::Yes); +} + +u16 Utf16String::code_unit_at(size_t index) const +{ + return view().code_unit_at(index); +} + +size_t Utf16String::length_in_code_units() const +{ + return view().length_in_code_units(); +} + +bool Utf16String::is_empty() const +{ + return view().is_empty(); +} + +} diff --git a/Userland/Libraries/LibJS/Runtime/Utf16String.h b/Userland/Libraries/LibJS/Runtime/Utf16String.h new file mode 100644 index 0000000000..640de51218 --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/Utf16String.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace JS { +namespace Detail { + +class Utf16StringImpl : public RefCounted { +public: + ~Utf16StringImpl() = default; + + static NonnullRefPtr create(); + static NonnullRefPtr create(Vector); + static NonnullRefPtr create(StringView const&); + static NonnullRefPtr create(Utf16View const&); + + Vector const& string() const; + Utf16View view() const; + +private: + Utf16StringImpl() = default; + explicit Utf16StringImpl(Vector string); + + Vector m_string; +}; + +} + +class Utf16String { +public: + Utf16String(); + explicit Utf16String(Vector); + explicit Utf16String(StringView const&); + explicit Utf16String(Utf16View const&); + + Vector const& string() const; + Utf16View view() const; + Utf16View substring_view(size_t code_unit_offset, size_t code_unit_length) const; + Utf16View substring_view(size_t code_unit_offset) const; + + String to_utf8() const; + u16 code_unit_at(size_t index) const; + + size_t length_in_code_units() const; + bool is_empty() const; + +private: + NonnullRefPtr m_string; +}; + +}