Serenity Operating System
1/*
2 * Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/StringView.h>
8#include <LibJS/Runtime/Utf16String.h>
9#include <LibJS/Runtime/VM.h>
10
11namespace JS {
12namespace Detail {
13
14static ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> the_empty_utf16_string(VM& vm)
15{
16 static NonnullRefPtr<Utf16StringImpl> empty_string = TRY(Utf16StringImpl::create(vm));
17 return empty_string;
18}
19
20Utf16StringImpl::Utf16StringImpl(Utf16Data string)
21 : m_string(move(string))
22{
23}
24
25ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> Utf16StringImpl::create(VM& vm)
26{
27 return TRY_OR_THROW_OOM(vm, adopt_nonnull_ref_or_enomem(new (nothrow) Utf16StringImpl()));
28}
29
30ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> Utf16StringImpl::create(VM& vm, Utf16Data string)
31{
32 return TRY_OR_THROW_OOM(vm, adopt_nonnull_ref_or_enomem(new (nothrow) Utf16StringImpl(move(string))));
33}
34
35ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> Utf16StringImpl::create(VM& vm, StringView string)
36{
37 return create(vm, TRY_OR_THROW_OOM(vm, utf8_to_utf16(string)));
38}
39
40ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> Utf16StringImpl::create(VM& vm, Utf16View const& view)
41{
42 Utf16Data string;
43 TRY_OR_THROW_OOM(vm, string.try_ensure_capacity(view.length_in_code_units()));
44 string.unchecked_append(view.data(), view.length_in_code_units());
45 return create(vm, move(string));
46}
47
48Utf16Data const& Utf16StringImpl::string() const
49{
50 return m_string;
51}
52
53Utf16View Utf16StringImpl::view() const
54{
55 return Utf16View { m_string };
56}
57
58}
59
60ThrowCompletionOr<Utf16String> Utf16String::create(VM& vm)
61{
62 return Utf16String { TRY(Detail::the_empty_utf16_string(vm)) };
63}
64
65ThrowCompletionOr<Utf16String> Utf16String::create(VM& vm, Utf16Data string)
66{
67 return Utf16String { TRY(Detail::Utf16StringImpl::create(vm, move(string))) };
68}
69
70ThrowCompletionOr<Utf16String> Utf16String::create(VM& vm, StringView string)
71{
72 return Utf16String { TRY(Detail::Utf16StringImpl::create(vm, string)) };
73}
74
75ThrowCompletionOr<Utf16String> Utf16String::create(VM& vm, Utf16View const& string)
76{
77 return Utf16String { TRY(Detail::Utf16StringImpl::create(vm, string)) };
78}
79
80Utf16String::Utf16String(NonnullRefPtr<Detail::Utf16StringImpl> string)
81 : m_string(move(string))
82{
83}
84
85Utf16Data const& Utf16String::string() const
86{
87 return m_string->string();
88}
89
90Utf16View Utf16String::view() const
91{
92 return m_string->view();
93}
94
95Utf16View Utf16String::substring_view(size_t code_unit_offset, size_t code_unit_length) const
96{
97 return view().substring_view(code_unit_offset, code_unit_length);
98}
99
100Utf16View Utf16String::substring_view(size_t code_unit_offset) const
101{
102 return view().substring_view(code_unit_offset);
103}
104
105ThrowCompletionOr<String> Utf16String::to_utf8(VM& vm) const
106{
107 return TRY_OR_THROW_OOM(vm, view().to_utf8(Utf16View::AllowInvalidCodeUnits::Yes));
108}
109
110ThrowCompletionOr<DeprecatedString> Utf16String::to_deprecated_string(VM& vm) const
111{
112 return TRY_OR_THROW_OOM(vm, view().to_deprecated_string(Utf16View::AllowInvalidCodeUnits::Yes));
113}
114
115u16 Utf16String::code_unit_at(size_t index) const
116{
117 return view().code_unit_at(index);
118}
119
120size_t Utf16String::length_in_code_units() const
121{
122 return view().length_in_code_units();
123}
124
125bool Utf16String::is_empty() const
126{
127 return view().is_empty();
128}
129
130}