11cb0ef41Sopenharmony_ci// © 2016 and later: Unicode, Inc. and others.
21cb0ef41Sopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html
31cb0ef41Sopenharmony_ci/*
41cb0ef41Sopenharmony_ci******************************************************************************
51cb0ef41Sopenharmony_ci* Copyright (C) 1998-2012, International Business Machines Corporation and
61cb0ef41Sopenharmony_ci* others. All Rights Reserved.
71cb0ef41Sopenharmony_ci******************************************************************************
81cb0ef41Sopenharmony_ci*/
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "utypeinfo.h"  // for 'typeid' to work
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include "unicode/uchriter.h"
131cb0ef41Sopenharmony_ci#include "unicode/ustring.h"
141cb0ef41Sopenharmony_ci#include "unicode/utf16.h"
151cb0ef41Sopenharmony_ci#include "ustr_imp.h"
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciU_NAMESPACE_BEGIN
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciUOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator)
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciUCharCharacterIterator::UCharCharacterIterator()
221cb0ef41Sopenharmony_ci  : CharacterIterator(),
231cb0ef41Sopenharmony_ci  text(0)
241cb0ef41Sopenharmony_ci{
251cb0ef41Sopenharmony_ci    // never default construct!
261cb0ef41Sopenharmony_ci}
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciUCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
291cb0ef41Sopenharmony_ci                                               int32_t length)
301cb0ef41Sopenharmony_ci  : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0),
311cb0ef41Sopenharmony_ci  text(textPtr)
321cb0ef41Sopenharmony_ci{
331cb0ef41Sopenharmony_ci}
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ciUCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
361cb0ef41Sopenharmony_ci                                               int32_t length,
371cb0ef41Sopenharmony_ci                                               int32_t position)
381cb0ef41Sopenharmony_ci  : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, position),
391cb0ef41Sopenharmony_ci  text(textPtr)
401cb0ef41Sopenharmony_ci{
411cb0ef41Sopenharmony_ci}
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ciUCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr,
441cb0ef41Sopenharmony_ci                                               int32_t length,
451cb0ef41Sopenharmony_ci                                               int32_t textBegin,
461cb0ef41Sopenharmony_ci                                               int32_t textEnd,
471cb0ef41Sopenharmony_ci                                               int32_t position)
481cb0ef41Sopenharmony_ci  : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, textBegin, textEnd, position),
491cb0ef41Sopenharmony_ci  text(textPtr)
501cb0ef41Sopenharmony_ci{
511cb0ef41Sopenharmony_ci}
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ciUCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that)
541cb0ef41Sopenharmony_ci: CharacterIterator(that),
551cb0ef41Sopenharmony_ci  text(that.text)
561cb0ef41Sopenharmony_ci{
571cb0ef41Sopenharmony_ci}
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ciUCharCharacterIterator&
601cb0ef41Sopenharmony_ciUCharCharacterIterator::operator=(const UCharCharacterIterator& that) {
611cb0ef41Sopenharmony_ci    CharacterIterator::operator=(that);
621cb0ef41Sopenharmony_ci    text = that.text;
631cb0ef41Sopenharmony_ci    return *this;
641cb0ef41Sopenharmony_ci}
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ciUCharCharacterIterator::~UCharCharacterIterator() {
671cb0ef41Sopenharmony_ci}
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_cibool
701cb0ef41Sopenharmony_ciUCharCharacterIterator::operator==(const ForwardCharacterIterator& that) const {
711cb0ef41Sopenharmony_ci    if (this == &that) {
721cb0ef41Sopenharmony_ci        return true;
731cb0ef41Sopenharmony_ci    }
741cb0ef41Sopenharmony_ci    if (typeid(*this) != typeid(that)) {
751cb0ef41Sopenharmony_ci        return false;
761cb0ef41Sopenharmony_ci    }
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci    const UCharCharacterIterator&    realThat = static_cast<const UCharCharacterIterator&>(that);
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci    return text == realThat.text
811cb0ef41Sopenharmony_ci        && textLength == realThat.textLength
821cb0ef41Sopenharmony_ci        && pos == realThat.pos
831cb0ef41Sopenharmony_ci        && begin == realThat.begin
841cb0ef41Sopenharmony_ci        && end == realThat.end;
851cb0ef41Sopenharmony_ci}
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ciint32_t
881cb0ef41Sopenharmony_ciUCharCharacterIterator::hashCode() const {
891cb0ef41Sopenharmony_ci    return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end;
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ciUCharCharacterIterator*
931cb0ef41Sopenharmony_ciUCharCharacterIterator::clone() const {
941cb0ef41Sopenharmony_ci    return new UCharCharacterIterator(*this);
951cb0ef41Sopenharmony_ci}
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_cichar16_t
981cb0ef41Sopenharmony_ciUCharCharacterIterator::first() {
991cb0ef41Sopenharmony_ci    pos = begin;
1001cb0ef41Sopenharmony_ci    if(pos < end) {
1011cb0ef41Sopenharmony_ci        return text[pos];
1021cb0ef41Sopenharmony_ci    } else {
1031cb0ef41Sopenharmony_ci        return DONE;
1041cb0ef41Sopenharmony_ci    }
1051cb0ef41Sopenharmony_ci}
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_cichar16_t
1081cb0ef41Sopenharmony_ciUCharCharacterIterator::firstPostInc() {
1091cb0ef41Sopenharmony_ci    pos = begin;
1101cb0ef41Sopenharmony_ci    if(pos < end) {
1111cb0ef41Sopenharmony_ci        return text[pos++];
1121cb0ef41Sopenharmony_ci    } else {
1131cb0ef41Sopenharmony_ci        return DONE;
1141cb0ef41Sopenharmony_ci    }
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_cichar16_t
1181cb0ef41Sopenharmony_ciUCharCharacterIterator::last() {
1191cb0ef41Sopenharmony_ci    pos = end;
1201cb0ef41Sopenharmony_ci    if(pos > begin) {
1211cb0ef41Sopenharmony_ci        return text[--pos];
1221cb0ef41Sopenharmony_ci    } else {
1231cb0ef41Sopenharmony_ci        return DONE;
1241cb0ef41Sopenharmony_ci    }
1251cb0ef41Sopenharmony_ci}
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_cichar16_t
1281cb0ef41Sopenharmony_ciUCharCharacterIterator::setIndex(int32_t position) {
1291cb0ef41Sopenharmony_ci    if(position < begin) {
1301cb0ef41Sopenharmony_ci        pos = begin;
1311cb0ef41Sopenharmony_ci    } else if(position > end) {
1321cb0ef41Sopenharmony_ci        pos = end;
1331cb0ef41Sopenharmony_ci    } else {
1341cb0ef41Sopenharmony_ci        pos = position;
1351cb0ef41Sopenharmony_ci    }
1361cb0ef41Sopenharmony_ci    if(pos < end) {
1371cb0ef41Sopenharmony_ci        return text[pos];
1381cb0ef41Sopenharmony_ci    } else {
1391cb0ef41Sopenharmony_ci        return DONE;
1401cb0ef41Sopenharmony_ci    }
1411cb0ef41Sopenharmony_ci}
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_cichar16_t
1441cb0ef41Sopenharmony_ciUCharCharacterIterator::current() const {
1451cb0ef41Sopenharmony_ci    if (pos >= begin && pos < end) {
1461cb0ef41Sopenharmony_ci        return text[pos];
1471cb0ef41Sopenharmony_ci    } else {
1481cb0ef41Sopenharmony_ci        return DONE;
1491cb0ef41Sopenharmony_ci    }
1501cb0ef41Sopenharmony_ci}
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_cichar16_t
1531cb0ef41Sopenharmony_ciUCharCharacterIterator::next() {
1541cb0ef41Sopenharmony_ci    if (pos + 1 < end) {
1551cb0ef41Sopenharmony_ci        return text[++pos];
1561cb0ef41Sopenharmony_ci    } else {
1571cb0ef41Sopenharmony_ci        /* make current() return DONE */
1581cb0ef41Sopenharmony_ci        pos = end;
1591cb0ef41Sopenharmony_ci        return DONE;
1601cb0ef41Sopenharmony_ci    }
1611cb0ef41Sopenharmony_ci}
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_cichar16_t
1641cb0ef41Sopenharmony_ciUCharCharacterIterator::nextPostInc() {
1651cb0ef41Sopenharmony_ci    if (pos < end) {
1661cb0ef41Sopenharmony_ci        return text[pos++];
1671cb0ef41Sopenharmony_ci    } else {
1681cb0ef41Sopenharmony_ci        return DONE;
1691cb0ef41Sopenharmony_ci    }
1701cb0ef41Sopenharmony_ci}
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ciUBool
1731cb0ef41Sopenharmony_ciUCharCharacterIterator::hasNext() {
1741cb0ef41Sopenharmony_ci    return (UBool)(pos < end ? true : false);
1751cb0ef41Sopenharmony_ci}
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_cichar16_t
1781cb0ef41Sopenharmony_ciUCharCharacterIterator::previous() {
1791cb0ef41Sopenharmony_ci    if (pos > begin) {
1801cb0ef41Sopenharmony_ci        return text[--pos];
1811cb0ef41Sopenharmony_ci    } else {
1821cb0ef41Sopenharmony_ci        return DONE;
1831cb0ef41Sopenharmony_ci    }
1841cb0ef41Sopenharmony_ci}
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ciUBool
1871cb0ef41Sopenharmony_ciUCharCharacterIterator::hasPrevious() {
1881cb0ef41Sopenharmony_ci    return (UBool)(pos > begin ? true : false);
1891cb0ef41Sopenharmony_ci}
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ciUChar32
1921cb0ef41Sopenharmony_ciUCharCharacterIterator::first32() {
1931cb0ef41Sopenharmony_ci    pos = begin;
1941cb0ef41Sopenharmony_ci    if(pos < end) {
1951cb0ef41Sopenharmony_ci        int32_t i = pos;
1961cb0ef41Sopenharmony_ci        UChar32 c;
1971cb0ef41Sopenharmony_ci        U16_NEXT(text, i, end, c);
1981cb0ef41Sopenharmony_ci        return c;
1991cb0ef41Sopenharmony_ci    } else {
2001cb0ef41Sopenharmony_ci        return DONE;
2011cb0ef41Sopenharmony_ci    }
2021cb0ef41Sopenharmony_ci}
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ciUChar32
2051cb0ef41Sopenharmony_ciUCharCharacterIterator::first32PostInc() {
2061cb0ef41Sopenharmony_ci    pos = begin;
2071cb0ef41Sopenharmony_ci    if(pos < end) {
2081cb0ef41Sopenharmony_ci        UChar32 c;
2091cb0ef41Sopenharmony_ci        U16_NEXT(text, pos, end, c);
2101cb0ef41Sopenharmony_ci        return c;
2111cb0ef41Sopenharmony_ci    } else {
2121cb0ef41Sopenharmony_ci        return DONE;
2131cb0ef41Sopenharmony_ci    }
2141cb0ef41Sopenharmony_ci}
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ciUChar32
2171cb0ef41Sopenharmony_ciUCharCharacterIterator::last32() {
2181cb0ef41Sopenharmony_ci    pos = end;
2191cb0ef41Sopenharmony_ci    if(pos > begin) {
2201cb0ef41Sopenharmony_ci        UChar32 c;
2211cb0ef41Sopenharmony_ci        U16_PREV(text, begin, pos, c);
2221cb0ef41Sopenharmony_ci        return c;
2231cb0ef41Sopenharmony_ci    } else {
2241cb0ef41Sopenharmony_ci        return DONE;
2251cb0ef41Sopenharmony_ci    }
2261cb0ef41Sopenharmony_ci}
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ciUChar32
2291cb0ef41Sopenharmony_ciUCharCharacterIterator::setIndex32(int32_t position) {
2301cb0ef41Sopenharmony_ci    if(position < begin) {
2311cb0ef41Sopenharmony_ci        position = begin;
2321cb0ef41Sopenharmony_ci    } else if(position > end) {
2331cb0ef41Sopenharmony_ci        position = end;
2341cb0ef41Sopenharmony_ci    }
2351cb0ef41Sopenharmony_ci    if(position < end) {
2361cb0ef41Sopenharmony_ci        U16_SET_CP_START(text, begin, position);
2371cb0ef41Sopenharmony_ci        int32_t i = this->pos = position;
2381cb0ef41Sopenharmony_ci        UChar32 c;
2391cb0ef41Sopenharmony_ci        U16_NEXT(text, i, end, c);
2401cb0ef41Sopenharmony_ci        return c;
2411cb0ef41Sopenharmony_ci    } else {
2421cb0ef41Sopenharmony_ci        this->pos = position;
2431cb0ef41Sopenharmony_ci        return DONE;
2441cb0ef41Sopenharmony_ci    }
2451cb0ef41Sopenharmony_ci}
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ciUChar32
2481cb0ef41Sopenharmony_ciUCharCharacterIterator::current32() const {
2491cb0ef41Sopenharmony_ci    if (pos >= begin && pos < end) {
2501cb0ef41Sopenharmony_ci        UChar32 c;
2511cb0ef41Sopenharmony_ci        U16_GET(text, begin, pos, end, c);
2521cb0ef41Sopenharmony_ci        return c;
2531cb0ef41Sopenharmony_ci    } else {
2541cb0ef41Sopenharmony_ci        return DONE;
2551cb0ef41Sopenharmony_ci    }
2561cb0ef41Sopenharmony_ci}
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ciUChar32
2591cb0ef41Sopenharmony_ciUCharCharacterIterator::next32() {
2601cb0ef41Sopenharmony_ci    if (pos < end) {
2611cb0ef41Sopenharmony_ci        U16_FWD_1(text, pos, end);
2621cb0ef41Sopenharmony_ci        if(pos < end) {
2631cb0ef41Sopenharmony_ci            int32_t i = pos;
2641cb0ef41Sopenharmony_ci            UChar32 c;
2651cb0ef41Sopenharmony_ci            U16_NEXT(text, i, end, c);
2661cb0ef41Sopenharmony_ci            return c;
2671cb0ef41Sopenharmony_ci        }
2681cb0ef41Sopenharmony_ci    }
2691cb0ef41Sopenharmony_ci    /* make current() return DONE */
2701cb0ef41Sopenharmony_ci    pos = end;
2711cb0ef41Sopenharmony_ci    return DONE;
2721cb0ef41Sopenharmony_ci}
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ciUChar32
2751cb0ef41Sopenharmony_ciUCharCharacterIterator::next32PostInc() {
2761cb0ef41Sopenharmony_ci    if (pos < end) {
2771cb0ef41Sopenharmony_ci        UChar32 c;
2781cb0ef41Sopenharmony_ci        U16_NEXT(text, pos, end, c);
2791cb0ef41Sopenharmony_ci        return c;
2801cb0ef41Sopenharmony_ci    } else {
2811cb0ef41Sopenharmony_ci        return DONE;
2821cb0ef41Sopenharmony_ci    }
2831cb0ef41Sopenharmony_ci}
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ciUChar32
2861cb0ef41Sopenharmony_ciUCharCharacterIterator::previous32() {
2871cb0ef41Sopenharmony_ci    if (pos > begin) {
2881cb0ef41Sopenharmony_ci        UChar32 c;
2891cb0ef41Sopenharmony_ci        U16_PREV(text, begin, pos, c);
2901cb0ef41Sopenharmony_ci        return c;
2911cb0ef41Sopenharmony_ci    } else {
2921cb0ef41Sopenharmony_ci        return DONE;
2931cb0ef41Sopenharmony_ci    }
2941cb0ef41Sopenharmony_ci}
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ciint32_t
2971cb0ef41Sopenharmony_ciUCharCharacterIterator::move(int32_t delta, CharacterIterator::EOrigin origin) {
2981cb0ef41Sopenharmony_ci    switch(origin) {
2991cb0ef41Sopenharmony_ci    case kStart:
3001cb0ef41Sopenharmony_ci        pos = begin + delta;
3011cb0ef41Sopenharmony_ci        break;
3021cb0ef41Sopenharmony_ci    case kCurrent:
3031cb0ef41Sopenharmony_ci        pos += delta;
3041cb0ef41Sopenharmony_ci        break;
3051cb0ef41Sopenharmony_ci    case kEnd:
3061cb0ef41Sopenharmony_ci        pos = end + delta;
3071cb0ef41Sopenharmony_ci        break;
3081cb0ef41Sopenharmony_ci    default:
3091cb0ef41Sopenharmony_ci        break;
3101cb0ef41Sopenharmony_ci    }
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci    if(pos < begin) {
3131cb0ef41Sopenharmony_ci        pos = begin;
3141cb0ef41Sopenharmony_ci    } else if(pos > end) {
3151cb0ef41Sopenharmony_ci        pos = end;
3161cb0ef41Sopenharmony_ci    }
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci    return pos;
3191cb0ef41Sopenharmony_ci}
3201cb0ef41Sopenharmony_ci
3211cb0ef41Sopenharmony_ciint32_t
3221cb0ef41Sopenharmony_ciUCharCharacterIterator::move32(int32_t delta, CharacterIterator::EOrigin origin) {
3231cb0ef41Sopenharmony_ci    // this implementation relies on the "safe" version of the UTF macros
3241cb0ef41Sopenharmony_ci    // (or the trustworthiness of the caller)
3251cb0ef41Sopenharmony_ci    switch(origin) {
3261cb0ef41Sopenharmony_ci    case kStart:
3271cb0ef41Sopenharmony_ci        pos = begin;
3281cb0ef41Sopenharmony_ci        if(delta > 0) {
3291cb0ef41Sopenharmony_ci            U16_FWD_N(text, pos, end, delta);
3301cb0ef41Sopenharmony_ci        }
3311cb0ef41Sopenharmony_ci        break;
3321cb0ef41Sopenharmony_ci    case kCurrent:
3331cb0ef41Sopenharmony_ci        if(delta > 0) {
3341cb0ef41Sopenharmony_ci            U16_FWD_N(text, pos, end, delta);
3351cb0ef41Sopenharmony_ci        } else {
3361cb0ef41Sopenharmony_ci            U16_BACK_N(text, begin, pos, -delta);
3371cb0ef41Sopenharmony_ci        }
3381cb0ef41Sopenharmony_ci        break;
3391cb0ef41Sopenharmony_ci    case kEnd:
3401cb0ef41Sopenharmony_ci        pos = end;
3411cb0ef41Sopenharmony_ci        if(delta < 0) {
3421cb0ef41Sopenharmony_ci            U16_BACK_N(text, begin, pos, -delta);
3431cb0ef41Sopenharmony_ci        }
3441cb0ef41Sopenharmony_ci        break;
3451cb0ef41Sopenharmony_ci    default:
3461cb0ef41Sopenharmony_ci        break;
3471cb0ef41Sopenharmony_ci    }
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci    return pos;
3501cb0ef41Sopenharmony_ci}
3511cb0ef41Sopenharmony_ci
3521cb0ef41Sopenharmony_civoid UCharCharacterIterator::setText(ConstChar16Ptr newText,
3531cb0ef41Sopenharmony_ci                                     int32_t      newTextLength) {
3541cb0ef41Sopenharmony_ci    text = newText;
3551cb0ef41Sopenharmony_ci    if(newText == 0 || newTextLength < 0) {
3561cb0ef41Sopenharmony_ci        newTextLength = 0;
3571cb0ef41Sopenharmony_ci    }
3581cb0ef41Sopenharmony_ci    end = textLength = newTextLength;
3591cb0ef41Sopenharmony_ci    pos = begin = 0;
3601cb0ef41Sopenharmony_ci}
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_civoid
3631cb0ef41Sopenharmony_ciUCharCharacterIterator::getText(UnicodeString& result) {
3641cb0ef41Sopenharmony_ci    result = UnicodeString(text, textLength);
3651cb0ef41Sopenharmony_ci}
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ciU_NAMESPACE_END
368