5 #ifndef V8_INTL_SUPPORT 6 #error Internationalization is expected to be enabled. 7 #endif // V8_INTL_SUPPORT 9 #include "src/objects/js-segment-iterator.h" 15 #include "src/heap/factory.h" 16 #include "src/isolate.h" 17 #include "src/objects-inl.h" 18 #include "src/objects/intl-objects.h" 19 #include "src/objects/js-segment-iterator-inl.h" 20 #include "src/objects/managed.h" 21 #include "unicode/brkiter.h" 26 MaybeHandle<String> JSSegmentIterator::GetSegment(Isolate* isolate,
29 return Intl::ToString(isolate, *(unicode_string()->raw()), start, end);
32 Handle<String> JSSegmentIterator::GranularityAsString()
const {
33 switch (granularity()) {
34 case JSSegmenter::Granularity::GRAPHEME:
35 return GetReadOnlyRoots().grapheme_string_handle();
36 case JSSegmenter::Granularity::WORD:
37 return GetReadOnlyRoots().word_string_handle();
38 case JSSegmenter::Granularity::SENTENCE:
39 return GetReadOnlyRoots().sentence_string_handle();
40 case JSSegmenter::Granularity::LINE:
41 return GetReadOnlyRoots().line_string_handle();
42 case JSSegmenter::Granularity::COUNT:
47 MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
48 Isolate* isolate, icu::BreakIterator* break_iterator,
49 JSSegmenter::Granularity granularity, Handle<String> text) {
50 CHECK_NOT_NULL(break_iterator);
52 Handle<Map> map = Handle<Map>(
53 isolate->native_context()->intl_segment_iterator_map(), isolate);
54 Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
56 Handle<JSSegmentIterator> segment_iterator =
57 Handle<JSSegmentIterator>::cast(result);
59 segment_iterator->set_flags(0);
60 segment_iterator->set_granularity(granularity);
62 Handle<Managed<icu::BreakIterator>> managed_break_iterator =
63 Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);
64 segment_iterator->set_icu_break_iterator(*managed_break_iterator);
67 Managed<icu::UnicodeString>* unicode_string =
68 Intl::SetTextToBreakIterator(isolate, text, break_iterator);
69 segment_iterator->set_unicode_string(unicode_string);
76 return segment_iterator;
80 Handle<Object> JSSegmentIterator::BreakType()
const {
81 icu::BreakIterator* break_iterator = icu_break_iterator()->raw();
82 int32_t rule_status = break_iterator->getRuleStatus();
83 switch (granularity()) {
84 case JSSegmenter::Granularity::GRAPHEME:
85 return GetReadOnlyRoots().undefined_value_handle();
86 case JSSegmenter::Granularity::WORD:
87 if (rule_status >= UBRK_WORD_NONE && rule_status < UBRK_WORD_NONE_LIMIT) {
90 return GetReadOnlyRoots().none_string_handle();
92 if ((rule_status >= UBRK_WORD_NUMBER &&
93 rule_status < UBRK_WORD_NUMBER_LIMIT) ||
94 (rule_status >= UBRK_WORD_LETTER &&
95 rule_status < UBRK_WORD_LETTER_LIMIT) ||
96 (rule_status >= UBRK_WORD_KANA &&
97 rule_status < UBRK_WORD_KANA_LIMIT) ||
98 (rule_status >= UBRK_WORD_IDEO &&
99 rule_status < UBRK_WORD_IDEO_LIMIT)) {
102 return GetReadOnlyRoots().word_string_handle();
104 return GetReadOnlyRoots().undefined_value_handle();
105 case JSSegmenter::Granularity::LINE:
106 if (rule_status >= UBRK_LINE_SOFT && rule_status < UBRK_LINE_SOFT_LIMIT) {
109 return GetReadOnlyRoots().soft_string_handle();
111 if ((rule_status >= UBRK_LINE_HARD &&
112 rule_status < UBRK_LINE_HARD_LIMIT)) {
114 return GetReadOnlyRoots().hard_string_handle();
116 return GetReadOnlyRoots().undefined_value_handle();
117 case JSSegmenter::Granularity::SENTENCE:
118 if (rule_status >= UBRK_SENTENCE_TERM &&
119 rule_status < UBRK_SENTENCE_TERM_LIMIT) {
122 return GetReadOnlyRoots().term_string_handle();
124 if ((rule_status >= UBRK_SENTENCE_SEP &&
125 rule_status < UBRK_SENTENCE_SEP_LIMIT)) {
129 return GetReadOnlyRoots().sep_string_handle();
131 return GetReadOnlyRoots().undefined_value_handle();
132 case JSSegmenter::Granularity::COUNT:
138 Handle<Object> JSSegmentIterator::Position(
139 Isolate* isolate, Handle<JSSegmentIterator> segment_iterator) {
140 icu::BreakIterator* icu_break_iterator =
141 segment_iterator->icu_break_iterator()->raw();
142 CHECK_NOT_NULL(icu_break_iterator);
143 return isolate->factory()->NewNumberFromInt(icu_break_iterator->current());
147 MaybeHandle<JSReceiver> JSSegmentIterator::Next(
148 Isolate* isolate, Handle<JSSegmentIterator> segment_iterator) {
149 Factory* factory = isolate->factory();
150 icu::BreakIterator* icu_break_iterator =
151 segment_iterator->icu_break_iterator()->raw();
153 int32_t prev = icu_break_iterator->current();
155 int32_t position = icu_break_iterator->next();
156 if (position == icu::BreakIterator::DONE) {
158 return factory->NewJSIteratorResult(isolate->factory()->undefined_value(),
162 Handle<Object> new_position = factory->NewNumberFromInt(position);
166 Handle<String> segment;
167 ASSIGN_RETURN_ON_EXCEPTION(
168 isolate, segment, segment_iterator->GetSegment(isolate, prev, position),
172 Handle<Object> break_type = segment_iterator->BreakType();
175 Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
178 CHECK(JSReceiver::CreateDataProperty(
179 isolate, result, factory->segment_string(), segment, kDontThrow)
183 CHECK(JSReceiver::CreateDataProperty(isolate, result,
184 factory->breakType_string(), break_type,
189 CHECK(JSReceiver::CreateDataProperty(isolate, result,
190 factory->position_string(), new_position,
195 return factory->NewJSIteratorResult(result,
false);
199 Maybe<bool> JSSegmentIterator::Following(
200 Isolate* isolate, Handle<JSSegmentIterator> segment_iterator,
201 Handle<Object> from_obj) {
202 Factory* factory = isolate->factory();
203 icu::BreakIterator* icu_break_iterator =
204 segment_iterator->icu_break_iterator()->raw();
206 if (!from_obj->IsUndefined()) {
209 if (!from_obj->ToArrayIndex(&from)) {
210 THROW_NEW_ERROR_RETURN_VALUE(
212 NewRangeError(MessageTemplate::kParameterOfFunctionOutOfRange,
213 factory->NewStringFromStaticChars(
"from"),
214 factory->NewStringFromStaticChars(
"following"),
221 if (icu_break_iterator->following(from) == icu::BreakIterator::DONE) {
222 THROW_NEW_ERROR_RETURN_VALUE(
224 NewRangeError(MessageTemplate::kParameterOfFunctionOutOfRange,
225 factory->NewStringFromStaticChars(
"from"),
226 factory->NewStringFromStaticChars(
"following"),
236 return Just(icu_break_iterator->next() == icu::BreakIterator::DONE);
240 Maybe<bool> JSSegmentIterator::Preceding(
241 Isolate* isolate, Handle<JSSegmentIterator> segment_iterator,
242 Handle<Object> from_obj) {
243 Factory* factory = isolate->factory();
244 icu::BreakIterator* icu_break_iterator =
245 segment_iterator->icu_break_iterator()->raw();
247 if (!from_obj->IsUndefined()) {
250 if (!from_obj->ToArrayIndex(&from)) {
251 THROW_NEW_ERROR_RETURN_VALUE(
253 NewRangeError(MessageTemplate::kParameterOfFunctionOutOfRange,
254 factory->NewStringFromStaticChars(
"from"),
255 factory->NewStringFromStaticChars(
"following"),
263 static_cast<uint32_t>(icu_break_iterator->getText().getLength());
264 if (from > text_len ||
265 icu_break_iterator->preceding(from) == icu::BreakIterator::DONE) {
266 THROW_NEW_ERROR_RETURN_VALUE(
268 NewRangeError(MessageTemplate::kParameterOfFunctionOutOfRange,
269 factory->NewStringFromStaticChars(
"from"),
270 factory->NewStringFromStaticChars(
"preceding"),
278 return Just(icu_break_iterator->previous() == icu::BreakIterator::DONE);