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