|  | // © 2016 and later: Unicode, Inc. and others. | 
|  | // License & terms of use: http://www.unicode.org/copyright.html | 
|  | /* | 
|  | ****************************************************************************** | 
|  | * Copyright (C) 1998-2012, International Business Machines Corporation and | 
|  | * others. All Rights Reserved. | 
|  | ****************************************************************************** | 
|  | */ | 
|  |  | 
|  | #include "utypeinfo.h"  // for 'typeid' to work | 
|  |  | 
|  | #include "unicode/uchriter.h" | 
|  | #include "unicode/ustring.h" | 
|  | #include "unicode/utf16.h" | 
|  | #include "ustr_imp.h" | 
|  |  | 
|  | U_NAMESPACE_BEGIN | 
|  |  | 
|  | UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator) | 
|  |  | 
|  | UCharCharacterIterator::UCharCharacterIterator() | 
|  | : CharacterIterator(), | 
|  | text(0) | 
|  | { | 
|  | // never default construct! | 
|  | } | 
|  |  | 
|  | UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr, | 
|  | int32_t length) | 
|  | : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0), | 
|  | text(textPtr) | 
|  | { | 
|  | } | 
|  |  | 
|  | UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr, | 
|  | int32_t length, | 
|  | int32_t position) | 
|  | : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, position), | 
|  | text(textPtr) | 
|  | { | 
|  | } | 
|  |  | 
|  | UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr, | 
|  | int32_t length, | 
|  | int32_t textBegin, | 
|  | int32_t textEnd, | 
|  | int32_t position) | 
|  | : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, textBegin, textEnd, position), | 
|  | text(textPtr) | 
|  | { | 
|  | } | 
|  |  | 
|  | UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that) | 
|  | : CharacterIterator(that), | 
|  | text(that.text) | 
|  | { | 
|  | } | 
|  |  | 
|  | UCharCharacterIterator& | 
|  | UCharCharacterIterator::operator=(const UCharCharacterIterator& that) { | 
|  | CharacterIterator::operator=(that); | 
|  | text = that.text; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | UCharCharacterIterator::~UCharCharacterIterator() { | 
|  | } | 
|  |  | 
|  | UBool | 
|  | UCharCharacterIterator::operator==(const ForwardCharacterIterator& that) const { | 
|  | if (this == &that) { | 
|  | return TRUE; | 
|  | } | 
|  | if (typeid(*this) != typeid(that)) { | 
|  | return FALSE; | 
|  | } | 
|  |  | 
|  | UCharCharacterIterator&    realThat = (UCharCharacterIterator&)that; | 
|  |  | 
|  | return text == realThat.text | 
|  | && textLength == realThat.textLength | 
|  | && pos == realThat.pos | 
|  | && begin == realThat.begin | 
|  | && end == realThat.end; | 
|  | } | 
|  |  | 
|  | int32_t | 
|  | UCharCharacterIterator::hashCode() const { | 
|  | return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end; | 
|  | } | 
|  |  | 
|  | CharacterIterator* | 
|  | UCharCharacterIterator::clone() const { | 
|  | return new UCharCharacterIterator(*this); | 
|  | } | 
|  |  | 
|  | UChar | 
|  | UCharCharacterIterator::first() { | 
|  | pos = begin; | 
|  | if(pos < end) { | 
|  | return text[pos]; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar | 
|  | UCharCharacterIterator::firstPostInc() { | 
|  | pos = begin; | 
|  | if(pos < end) { | 
|  | return text[pos++]; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar | 
|  | UCharCharacterIterator::last() { | 
|  | pos = end; | 
|  | if(pos > begin) { | 
|  | return text[--pos]; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar | 
|  | UCharCharacterIterator::setIndex(int32_t position) { | 
|  | if(position < begin) { | 
|  | pos = begin; | 
|  | } else if(position > end) { | 
|  | pos = end; | 
|  | } else { | 
|  | pos = position; | 
|  | } | 
|  | if(pos < end) { | 
|  | return text[pos]; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar | 
|  | UCharCharacterIterator::current() const { | 
|  | if (pos >= begin && pos < end) { | 
|  | return text[pos]; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar | 
|  | UCharCharacterIterator::next() { | 
|  | if (pos + 1 < end) { | 
|  | return text[++pos]; | 
|  | } else { | 
|  | /* make current() return DONE */ | 
|  | pos = end; | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar | 
|  | UCharCharacterIterator::nextPostInc() { | 
|  | if (pos < end) { | 
|  | return text[pos++]; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UBool | 
|  | UCharCharacterIterator::hasNext() { | 
|  | return (UBool)(pos < end ? TRUE : FALSE); | 
|  | } | 
|  |  | 
|  | UChar | 
|  | UCharCharacterIterator::previous() { | 
|  | if (pos > begin) { | 
|  | return text[--pos]; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UBool | 
|  | UCharCharacterIterator::hasPrevious() { | 
|  | return (UBool)(pos > begin ? TRUE : FALSE); | 
|  | } | 
|  |  | 
|  | UChar32 | 
|  | UCharCharacterIterator::first32() { | 
|  | pos = begin; | 
|  | if(pos < end) { | 
|  | int32_t i = pos; | 
|  | UChar32 c; | 
|  | U16_NEXT(text, i, end, c); | 
|  | return c; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar32 | 
|  | UCharCharacterIterator::first32PostInc() { | 
|  | pos = begin; | 
|  | if(pos < end) { | 
|  | UChar32 c; | 
|  | U16_NEXT(text, pos, end, c); | 
|  | return c; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar32 | 
|  | UCharCharacterIterator::last32() { | 
|  | pos = end; | 
|  | if(pos > begin) { | 
|  | UChar32 c; | 
|  | U16_PREV(text, begin, pos, c); | 
|  | return c; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar32 | 
|  | UCharCharacterIterator::setIndex32(int32_t position) { | 
|  | if(position < begin) { | 
|  | position = begin; | 
|  | } else if(position > end) { | 
|  | position = end; | 
|  | } | 
|  | if(position < end) { | 
|  | U16_SET_CP_START(text, begin, position); | 
|  | int32_t i = this->pos = position; | 
|  | UChar32 c; | 
|  | U16_NEXT(text, i, end, c); | 
|  | return c; | 
|  | } else { | 
|  | this->pos = position; | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar32 | 
|  | UCharCharacterIterator::current32() const { | 
|  | if (pos >= begin && pos < end) { | 
|  | UChar32 c; | 
|  | U16_GET(text, begin, pos, end, c); | 
|  | return c; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar32 | 
|  | UCharCharacterIterator::next32() { | 
|  | if (pos < end) { | 
|  | U16_FWD_1(text, pos, end); | 
|  | if(pos < end) { | 
|  | int32_t i = pos; | 
|  | UChar32 c; | 
|  | U16_NEXT(text, i, end, c); | 
|  | return c; | 
|  | } | 
|  | } | 
|  | /* make current() return DONE */ | 
|  | pos = end; | 
|  | return DONE; | 
|  | } | 
|  |  | 
|  | UChar32 | 
|  | UCharCharacterIterator::next32PostInc() { | 
|  | if (pos < end) { | 
|  | UChar32 c; | 
|  | U16_NEXT(text, pos, end, c); | 
|  | return c; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | UChar32 | 
|  | UCharCharacterIterator::previous32() { | 
|  | if (pos > begin) { | 
|  | UChar32 c; | 
|  | U16_PREV(text, begin, pos, c); | 
|  | return c; | 
|  | } else { | 
|  | return DONE; | 
|  | } | 
|  | } | 
|  |  | 
|  | int32_t | 
|  | UCharCharacterIterator::move(int32_t delta, CharacterIterator::EOrigin origin) { | 
|  | switch(origin) { | 
|  | case kStart: | 
|  | pos = begin + delta; | 
|  | break; | 
|  | case kCurrent: | 
|  | pos += delta; | 
|  | break; | 
|  | case kEnd: | 
|  | pos = end + delta; | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  |  | 
|  | if(pos < begin) { | 
|  | pos = begin; | 
|  | } else if(pos > end) { | 
|  | pos = end; | 
|  | } | 
|  |  | 
|  | return pos; | 
|  | } | 
|  |  | 
|  | int32_t | 
|  | UCharCharacterIterator::move32(int32_t delta, CharacterIterator::EOrigin origin) { | 
|  | // this implementation relies on the "safe" version of the UTF macros | 
|  | // (or the trustworthiness of the caller) | 
|  | switch(origin) { | 
|  | case kStart: | 
|  | pos = begin; | 
|  | if(delta > 0) { | 
|  | U16_FWD_N(text, pos, end, delta); | 
|  | } | 
|  | break; | 
|  | case kCurrent: | 
|  | if(delta > 0) { | 
|  | U16_FWD_N(text, pos, end, delta); | 
|  | } else { | 
|  | U16_BACK_N(text, begin, pos, -delta); | 
|  | } | 
|  | break; | 
|  | case kEnd: | 
|  | pos = end; | 
|  | if(delta < 0) { | 
|  | U16_BACK_N(text, begin, pos, -delta); | 
|  | } | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  |  | 
|  | return pos; | 
|  | } | 
|  |  | 
|  | void UCharCharacterIterator::setText(ConstChar16Ptr newText, | 
|  | int32_t      newTextLength) { | 
|  | text = newText; | 
|  | if(newText == 0 || newTextLength < 0) { | 
|  | newTextLength = 0; | 
|  | } | 
|  | end = textLength = newTextLength; | 
|  | pos = begin = 0; | 
|  | } | 
|  |  | 
|  | void | 
|  | UCharCharacterIterator::getText(UnicodeString& result) { | 
|  | result = UnicodeString(text, textLength); | 
|  | } | 
|  |  | 
|  | U_NAMESPACE_END |