11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_INTL_SUPPORT
61cb0ef41Sopenharmony_ci#error Internationalization is expected to be enabled.
71cb0ef41Sopenharmony_ci#endif  // V8_INTL_SUPPORT
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#include "src/objects/js-segment-iterator.h"
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include <map>
121cb0ef41Sopenharmony_ci#include <memory>
131cb0ef41Sopenharmony_ci#include <string>
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
161cb0ef41Sopenharmony_ci#include "src/heap/factory.h"
171cb0ef41Sopenharmony_ci#include "src/objects/intl-objects.h"
181cb0ef41Sopenharmony_ci#include "src/objects/js-segment-iterator-inl.h"
191cb0ef41Sopenharmony_ci#include "src/objects/js-segments.h"
201cb0ef41Sopenharmony_ci#include "src/objects/managed-inl.h"
211cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
221cb0ef41Sopenharmony_ci#include "unicode/brkiter.h"
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_cinamespace v8 {
251cb0ef41Sopenharmony_cinamespace internal {
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciHandle<String> JSSegmentIterator::GranularityAsString(Isolate* isolate) const {
281cb0ef41Sopenharmony_ci  return JSSegmenter::GetGranularityString(isolate, granularity());
291cb0ef41Sopenharmony_ci}
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci// ecma402 #sec-createsegmentiterator
321cb0ef41Sopenharmony_ciMaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
331cb0ef41Sopenharmony_ci    Isolate* isolate, icu::BreakIterator* break_iterator,
341cb0ef41Sopenharmony_ci    JSSegmenter::Granularity granularity) {
351cb0ef41Sopenharmony_ci  // Clone a copy for both the ownership and not sharing with containing and
361cb0ef41Sopenharmony_ci  // other calls to the iterator because icu::BreakIterator keep the iteration
371cb0ef41Sopenharmony_ci  // position internally and cannot be shared across multiple calls to
381cb0ef41Sopenharmony_ci  // JSSegmentIterator::Create and JSSegments::Containing.
391cb0ef41Sopenharmony_ci  break_iterator = break_iterator->clone();
401cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(break_iterator);
411cb0ef41Sopenharmony_ci  Handle<Map> map = Handle<Map>(
421cb0ef41Sopenharmony_ci      isolate->native_context()->intl_segment_iterator_map(), isolate);
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  // 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0.
451cb0ef41Sopenharmony_ci  break_iterator->first();
461cb0ef41Sopenharmony_ci  Handle<Managed<icu::BreakIterator>> managed_break_iterator =
471cb0ef41Sopenharmony_ci      Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  icu::UnicodeString* string = new icu::UnicodeString();
501cb0ef41Sopenharmony_ci  break_iterator->getText().getText(*string);
511cb0ef41Sopenharmony_ci  Handle<Managed<icu::UnicodeString>> unicode_string =
521cb0ef41Sopenharmony_ci      Managed<icu::UnicodeString>::FromRawPtr(isolate, 0, string);
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  break_iterator->setText(*string);
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  // Now all properties are ready, so we can allocate the result object.
571cb0ef41Sopenharmony_ci  Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
581cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
591cb0ef41Sopenharmony_ci  Handle<JSSegmentIterator> segment_iterator =
601cb0ef41Sopenharmony_ci      Handle<JSSegmentIterator>::cast(result);
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  segment_iterator->set_flags(0);
631cb0ef41Sopenharmony_ci  segment_iterator->set_granularity(granularity);
641cb0ef41Sopenharmony_ci  segment_iterator->set_icu_break_iterator(*managed_break_iterator);
651cb0ef41Sopenharmony_ci  segment_iterator->set_unicode_string(*unicode_string);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  return segment_iterator;
681cb0ef41Sopenharmony_ci}
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci// ecma402 #sec-%segmentiteratorprototype%.next
711cb0ef41Sopenharmony_ciMaybeHandle<JSReceiver> JSSegmentIterator::Next(
721cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<JSSegmentIterator> segment_iterator) {
731cb0ef41Sopenharmony_ci  Factory* factory = isolate->factory();
741cb0ef41Sopenharmony_ci  icu::BreakIterator* icu_break_iterator =
751cb0ef41Sopenharmony_ci      segment_iterator->icu_break_iterator().raw();
761cb0ef41Sopenharmony_ci  // 5. Let startIndex be iterator.[[IteratedStringNextSegmentCodeUnitIndex]].
771cb0ef41Sopenharmony_ci  int32_t start_index = icu_break_iterator->current();
781cb0ef41Sopenharmony_ci  // 6. Let endIndex be ! FindBoundary(segmenter, string, startIndex, after).
791cb0ef41Sopenharmony_ci  int32_t end_index = icu_break_iterator->next();
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  // 7. If endIndex is not finite, then
821cb0ef41Sopenharmony_ci  if (end_index == icu::BreakIterator::DONE) {
831cb0ef41Sopenharmony_ci    // a. Return ! CreateIterResultObject(undefined, true).
841cb0ef41Sopenharmony_ci    return factory->NewJSIteratorResult(isolate->factory()->undefined_value(),
851cb0ef41Sopenharmony_ci                                        true);
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  // 8. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to endIndex.
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  // 9. Let segmentData be ! CreateSegmentDataObject(segmenter, string,
911cb0ef41Sopenharmony_ci  // startIndex, endIndex).
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  icu::UnicodeString string;
941cb0ef41Sopenharmony_ci  icu_break_iterator->getText().getText(string);
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  Handle<Object> segment_data;
971cb0ef41Sopenharmony_ci  ASSIGN_RETURN_ON_EXCEPTION(
981cb0ef41Sopenharmony_ci      isolate, segment_data,
991cb0ef41Sopenharmony_ci      JSSegments::CreateSegmentDataObject(
1001cb0ef41Sopenharmony_ci          isolate, segment_iterator->granularity(), icu_break_iterator, string,
1011cb0ef41Sopenharmony_ci          start_index, end_index),
1021cb0ef41Sopenharmony_ci      JSReceiver);
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  // 10. Return ! CreateIterResultObject(segmentData, false).
1051cb0ef41Sopenharmony_ci  return factory->NewJSIteratorResult(segment_data, false);
1061cb0ef41Sopenharmony_ci}
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci}  // namespace internal
1091cb0ef41Sopenharmony_ci}  // namespace v8
110