Home | History | Annotate | Download | only in common
      1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 ******************************************************************************
      5 * Copyright (C) 1998-2012, International Business Machines Corporation and
      6 * others. All Rights Reserved.
      7 ******************************************************************************
      8 */
      9 
     10 #include "utypeinfo.h"  // for 'typeid' to work
     11 
     12 #include "unicode/uchriter.h"
     13 #include "unicode/ustring.h"
     14 #include "unicode/utf16.h"
     15 #include "ustr_imp.h"
     16 
     17 U_NAMESPACE_BEGIN
     18 
     19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator)
     20 
     21 UCharCharacterIterator::UCharCharacterIterator()
     22   : CharacterIterator(),
     23   text(0)
     24 {
     25     // never default construct!
     26 }
     27 
     28 UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
     29                                                int32_t length)
     30   : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0),
     31   text(textPtr)
     32 {
     33 }
     34 
     35 UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
     36                                                int32_t length,
     37                                                int32_t position)
     38   : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, position),
     39   text(textPtr)
     40 {
     41 }
     42 
     43 UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
     44                                                int32_t length,
     45                                                int32_t textBegin,
     46                                                int32_t textEnd,
     47                                                int32_t position)
     48   : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, textBegin, textEnd, position),
     49   text(textPtr)
     50 {
     51 }
     52 
     53 UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that)
     54 : CharacterIterator(that),
     55   text(that.text)
     56 {
     57 }
     58 
     59 UCharCharacterIterator&
     60 UCharCharacterIterator::operator=(const UCharCharacterIterator& that) {
     61     CharacterIterator::operator=(that);
     62     text = that.text;
     63     return *this;
     64 }
     65 
     66 UCharCharacterIterator::~UCharCharacterIterator() {
     67 }
     68 
     69 UBool
     70 UCharCharacterIterator::operator==(const ForwardCharacterIterator& that) const {
     71     if (this == &that) {
     72         return TRUE;
     73     }
     74     if (typeid(*this) != typeid(that)) {
     75         return FALSE;
     76     }
     77 
     78     UCharCharacterIterator&    realThat = (UCharCharacterIterator&)that;
     79 
     80     return text == realThat.text
     81         && textLength == realThat.textLength
     82         && pos == realThat.pos
     83         && begin == realThat.begin
     84         && end == realThat.end;
     85 }
     86 
     87 int32_t
     88 UCharCharacterIterator::hashCode() const {
     89     return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end;
     90 }
     91 
     92 CharacterIterator*
     93 UCharCharacterIterator::clone() const {
     94     return new UCharCharacterIterator(*this);
     95 }
     96 
     97 UChar
     98 UCharCharacterIterator::first() {
     99     pos = begin;
    100     if(pos < end) {
    101         return text[pos];
    102     } else {
    103         return DONE;
    104     }
    105 }
    106 
    107 UChar
    108 UCharCharacterIterator::firstPostInc() {
    109     pos = begin;
    110     if(pos < end) {
    111         return text[pos++];
    112     } else {
    113         return DONE;
    114     }
    115 }
    116 
    117 UChar
    118 UCharCharacterIterator::last() {
    119     pos = end;
    120     if(pos > begin) {
    121         return text[--pos];
    122     } else {
    123         return DONE;
    124     }
    125 }
    126 
    127 UChar
    128 UCharCharacterIterator::setIndex(int32_t position) {
    129     if(position < begin) {
    130         pos = begin;
    131     } else if(position > end) {
    132         pos = end;
    133     } else {
    134         pos = position;
    135     }
    136     if(pos < end) {
    137         return text[pos];
    138     } else {
    139         return DONE;
    140     }
    141 }
    142 
    143 UChar
    144 UCharCharacterIterator::current() const {
    145     if (pos >= begin && pos < end) {
    146         return text[pos];
    147     } else {
    148         return DONE;
    149     }
    150 }
    151 
    152 UChar
    153 UCharCharacterIterator::next() {
    154     if (pos + 1 < end) {
    155         return text[++pos];
    156     } else {
    157         /* make current() return DONE */
    158         pos = end;
    159         return DONE;
    160     }
    161 }
    162 
    163 UChar
    164 UCharCharacterIterator::nextPostInc() {
    165     if (pos < end) {
    166         return text[pos++];
    167     } else {
    168         return DONE;
    169     }
    170 }
    171 
    172 UBool
    173 UCharCharacterIterator::hasNext() {
    174     return (UBool)(pos < end ? TRUE : FALSE);
    175 }
    176 
    177 UChar
    178 UCharCharacterIterator::previous() {
    179     if (pos > begin) {
    180         return text[--pos];
    181     } else {
    182         return DONE;
    183     }
    184 }
    185 
    186 UBool
    187 UCharCharacterIterator::hasPrevious() {
    188     return (UBool)(pos > begin ? TRUE : FALSE);
    189 }
    190 
    191 UChar32
    192 UCharCharacterIterator::first32() {
    193     pos = begin;
    194     if(pos < end) {
    195         int32_t i = pos;
    196         UChar32 c;
    197         U16_NEXT(text, i, end, c);
    198         return c;
    199     } else {
    200         return DONE;
    201     }
    202 }
    203 
    204 UChar32
    205 UCharCharacterIterator::first32PostInc() {
    206     pos = begin;
    207     if(pos < end) {
    208         UChar32 c;
    209         U16_NEXT(text, pos, end, c);
    210         return c;
    211     } else {
    212         return DONE;
    213     }
    214 }
    215 
    216 UChar32
    217 UCharCharacterIterator::last32() {
    218     pos = end;
    219     if(pos > begin) {
    220         UChar32 c;
    221         U16_PREV(text, begin, pos, c);
    222         return c;
    223     } else {
    224         return DONE;
    225     }
    226 }
    227 
    228 UChar32
    229 UCharCharacterIterator::setIndex32(int32_t position) {
    230     if(position < begin) {
    231         position = begin;
    232     } else if(position > end) {
    233         position = end;
    234     }
    235     if(position < end) {
    236         U16_SET_CP_START(text, begin, position);
    237         int32_t i = this->pos = position;
    238         UChar32 c;
    239         U16_NEXT(text, i, end, c);
    240         return c;
    241     } else {
    242         this->pos = position;
    243         return DONE;
    244     }
    245 }
    246 
    247 UChar32
    248 UCharCharacterIterator::current32() const {
    249     if (pos >= begin && pos < end) {
    250         UChar32 c;
    251         U16_GET(text, begin, pos, end, c);
    252         return c;
    253     } else {
    254         return DONE;
    255     }
    256 }
    257 
    258 UChar32
    259 UCharCharacterIterator::next32() {
    260     if (pos < end) {
    261         U16_FWD_1(text, pos, end);
    262         if(pos < end) {
    263             int32_t i = pos;
    264             UChar32 c;
    265             U16_NEXT(text, i, end, c);
    266             return c;
    267         }
    268     }
    269     /* make current() return DONE */
    270     pos = end;
    271     return DONE;
    272 }
    273 
    274 UChar32
    275 UCharCharacterIterator::next32PostInc() {
    276     if (pos < end) {
    277         UChar32 c;
    278         U16_NEXT(text, pos, end, c);
    279         return c;
    280     } else {
    281         return DONE;
    282     }
    283 }
    284 
    285 UChar32
    286 UCharCharacterIterator::previous32() {
    287     if (pos > begin) {
    288         UChar32 c;
    289         U16_PREV(text, begin, pos, c);
    290         return c;
    291     } else {
    292         return DONE;
    293     }
    294 }
    295 
    296 int32_t
    297 UCharCharacterIterator::move(int32_t delta, CharacterIterator::EOrigin origin) {
    298     switch(origin) {
    299     case kStart:
    300         pos = begin + delta;
    301         break;
    302     case kCurrent:
    303         pos += delta;
    304         break;
    305     case kEnd:
    306         pos = end + delta;
    307         break;
    308     default:
    309         break;
    310     }
    311 
    312     if(pos < begin) {
    313         pos = begin;
    314     } else if(pos > end) {
    315         pos = end;
    316     }
    317 
    318     return pos;
    319 }
    320 
    321 int32_t
    322 UCharCharacterIterator::move32(int32_t delta, CharacterIterator::EOrigin origin) {
    323     // this implementation relies on the "safe" version of the UTF macros
    324     // (or the trustworthiness of the caller)
    325     switch(origin) {
    326     case kStart:
    327         pos = begin;
    328         if(delta > 0) {
    329             U16_FWD_N(text, pos, end, delta);
    330         }
    331         break;
    332     case kCurrent:
    333         if(delta > 0) {
    334             U16_FWD_N(text, pos, end, delta);
    335         } else {
    336             U16_BACK_N(text, begin, pos, -delta);
    337         }
    338         break;
    339     case kEnd:
    340         pos = end;
    341         if(delta < 0) {
    342             U16_BACK_N(text, begin, pos, -delta);
    343         }
    344         break;
    345     default:
    346         break;
    347     }
    348 
    349     return pos;
    350 }
    351 
    352 void UCharCharacterIterator::setText(const UChar* newText,
    353                                      int32_t      newTextLength) {
    354     text = newText;
    355     if(newText == 0 || newTextLength < 0) {
    356         newTextLength = 0;
    357     }
    358     end = textLength = newTextLength;
    359     pos = begin = 0;
    360 }
    361 
    362 void
    363 UCharCharacterIterator::getText(UnicodeString& result) {
    364     result = UnicodeString(text, textLength);
    365 }
    366 
    367 U_NAMESPACE_END
    368