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