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