V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
js-break-iterator.cc
1 // Copyright 2018 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_INTL_SUPPORT
6 #error Internationalization is expected to be enabled.
7 #endif // V8_INTL_SUPPORT
8 
9 #include "src/objects/js-break-iterator.h"
10 
11 #include "src/objects/intl-objects.h"
12 #include "src/objects/js-break-iterator-inl.h"
13 #include "unicode/brkiter.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::Initialize(
19  Isolate* isolate, Handle<JSV8BreakIterator> break_iterator_holder,
20  Handle<Object> locales, Handle<Object> options_obj) {
21  Factory* factory = isolate->factory();
22 
23  // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
24  Maybe<std::vector<std::string>> maybe_requested_locales =
25  Intl::CanonicalizeLocaleList(isolate, locales);
26  MAYBE_RETURN(maybe_requested_locales, MaybeHandle<JSV8BreakIterator>());
27  std::vector<std::string> requested_locales =
28  maybe_requested_locales.FromJust();
29 
30  Handle<JSReceiver> options;
31  if (options_obj->IsUndefined(isolate)) {
32  options = factory->NewJSObjectWithNullProto();
33  } else {
34  ASSIGN_RETURN_ON_EXCEPTION(
35  isolate, options,
36  Object::ToObject(isolate, options_obj, "Intl.JSV8BreakIterator"),
37  JSV8BreakIterator);
38  }
39 
40  // Extract locale string
41  Maybe<Intl::MatcherOption> maybe_locale_matcher =
42  Intl::GetLocaleMatcher(isolate, options, "Intl.JSV8BreakIterator");
43  MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSV8BreakIterator>());
44  Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
45 
46  Intl::ResolvedLocale r =
47  Intl::ResolveLocale(isolate, JSV8BreakIterator::GetAvailableLocales(),
48  requested_locales, matcher, {});
49 
50  // Extract type from options
51  Maybe<Type> maybe_type = Intl::GetStringOption<Type>(
52  isolate, options, "type", "Intl.v8BreakIterator",
53  {"word", "character", "sentence", "line"},
54  {Type::WORD, Type::CHARACTER, Type::SENTENCE, Type::LINE}, Type::WORD);
55  MAYBE_RETURN(maybe_type, MaybeHandle<JSV8BreakIterator>());
56  Type type_enum = maybe_type.FromJust();
57 
58  icu::Locale icu_locale = r.icu_locale;
59  DCHECK(!icu_locale.isBogus());
60 
61  // Construct break_iterator using icu_locale and type
62  UErrorCode status = U_ZERO_ERROR;
63  std::unique_ptr<icu::BreakIterator> break_iterator = nullptr;
64  switch (type_enum) {
65  case Type::CHARACTER:
66  break_iterator.reset(
67  icu::BreakIterator::createCharacterInstance(icu_locale, status));
68  break;
69  case Type::SENTENCE:
70  break_iterator.reset(
71  icu::BreakIterator::createSentenceInstance(icu_locale, status));
72  break;
73  case Type::LINE:
74  break_iterator.reset(
75  icu::BreakIterator::createLineInstance(icu_locale, status));
76  break;
77  default:
78  break_iterator.reset(
79  icu::BreakIterator::createWordInstance(icu_locale, status));
80  break;
81  }
82 
83  // Error handling for break_iterator
84  if (U_FAILURE(status)) {
85  FATAL("Failed to create ICU break iterator, are ICU data files missing?");
86  }
87  CHECK_NOT_NULL(break_iterator.get());
88  isolate->CountUsage(v8::Isolate::UseCounterFeature::kBreakIterator);
89 
90  // Construct managed objects from pointers
91  Handle<Managed<icu::BreakIterator>> managed_break_iterator =
92  Managed<icu::BreakIterator>::FromUniquePtr(isolate, 0,
93  std::move(break_iterator));
94  Handle<Managed<icu::UnicodeString>> managed_unicode_string =
95  Managed<icu::UnicodeString>::FromRawPtr(isolate, 0, nullptr);
96 
97  Handle<String> locale_str =
98  isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
99  break_iterator_holder->set_locale(*locale_str);
100 
101  break_iterator_holder->set_type(type_enum);
102  break_iterator_holder->set_break_iterator(*managed_break_iterator);
103  break_iterator_holder->set_unicode_string(*managed_unicode_string);
104 
105  // Return break_iterator_holder
106  return break_iterator_holder;
107 }
108 
109 Handle<JSObject> JSV8BreakIterator::ResolvedOptions(
110  Isolate* isolate, Handle<JSV8BreakIterator> break_iterator) {
111  Factory* factory = isolate->factory();
112 
113  Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
114  Handle<String> locale(break_iterator->locale(), isolate);
115 
116  JSObject::AddProperty(isolate, result, factory->locale_string(), locale,
117  NONE);
118  JSObject::AddProperty(isolate, result, factory->type_string(),
119  break_iterator->TypeAsString(), NONE);
120  return result;
121 }
122 
123 void JSV8BreakIterator::AdoptText(
124  Isolate* isolate, Handle<JSV8BreakIterator> break_iterator_holder,
125  Handle<String> text) {
126  icu::BreakIterator* break_iterator =
127  break_iterator_holder->break_iterator()->raw();
128  CHECK_NOT_NULL(break_iterator);
129  Managed<icu::UnicodeString>* unicode_string =
130  Intl::SetTextToBreakIterator(isolate, text, break_iterator);
131  break_iterator_holder->set_unicode_string(unicode_string);
132 }
133 
134 Handle<String> JSV8BreakIterator::TypeAsString() const {
135  switch (type()) {
136  case Type::CHARACTER:
137  return GetReadOnlyRoots().character_string_handle();
138  case Type::WORD:
139  return GetReadOnlyRoots().word_string_handle();
140  case Type::SENTENCE:
141  return GetReadOnlyRoots().sentence_string_handle();
142  case Type::LINE:
143  return GetReadOnlyRoots().line_string_handle();
144  case Type::COUNT:
145  UNREACHABLE();
146  }
147 }
148 
149 Handle<Object> JSV8BreakIterator::Current(
150  Isolate* isolate, Handle<JSV8BreakIterator> break_iterator) {
151  return isolate->factory()->NewNumberFromInt(
152  break_iterator->break_iterator()->raw()->current());
153 }
154 
155 Handle<Object> JSV8BreakIterator::First(
156  Isolate* isolate, Handle<JSV8BreakIterator> break_iterator) {
157  return isolate->factory()->NewNumberFromInt(
158  break_iterator->break_iterator()->raw()->first());
159 }
160 
161 Handle<Object> JSV8BreakIterator::Next(
162  Isolate* isolate, Handle<JSV8BreakIterator> break_iterator) {
163  return isolate->factory()->NewNumberFromInt(
164  break_iterator->break_iterator()->raw()->next());
165 }
166 
167 String JSV8BreakIterator::BreakType(Isolate* isolate,
168  Handle<JSV8BreakIterator> break_iterator) {
169  int32_t status = break_iterator->break_iterator()->raw()->getRuleStatus();
170  // Keep return values in sync with JavaScript BreakType enum.
171  if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
172  return ReadOnlyRoots(isolate).none_string();
173  }
174  if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
175  return ReadOnlyRoots(isolate).number_string();
176  }
177  if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
178  return ReadOnlyRoots(isolate).letter_string();
179  }
180  if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
181  return ReadOnlyRoots(isolate).kana_string();
182  }
183  if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
184  return ReadOnlyRoots(isolate).ideo_string();
185  }
186  return ReadOnlyRoots(isolate).unknown_string();
187 }
188 
189 std::set<std::string> JSV8BreakIterator::GetAvailableLocales() {
190  int32_t num_locales = 0;
191  const icu::Locale* icu_available_locales =
192  icu::BreakIterator::getAvailableLocales(num_locales);
193  return Intl::BuildLocaleSet(icu_available_locales, num_locales);
194 }
195 
196 } // namespace internal
197 } // namespace v8
Definition: libplatform.h:13