1/* 2****************************************************************************** 3* Copyright (C) 1998-2010, International Business Machines Corporation and 4* others. All Rights Reserved. 5****************************************************************************** 6*/ 7 8#include "unicode/utypeinfo.h" // for 'typeid' to work 9 10#include "unicode/uchriter.h" 11#include "unicode/ustring.h" 12#include "uhash.h" 13 14U_NAMESPACE_BEGIN 15 16UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator) 17 18UCharCharacterIterator::UCharCharacterIterator() 19 : CharacterIterator(), 20 text(0) 21{ 22 // never default construct! 23} 24 25UCharCharacterIterator::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 32UCharCharacterIterator::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 40UCharCharacterIterator::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 50UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that) 51: CharacterIterator(that), 52 text(that.text) 53{ 54} 55 56UCharCharacterIterator& 57UCharCharacterIterator::operator=(const UCharCharacterIterator& that) { 58 CharacterIterator::operator=(that); 59 text = that.text; 60 return *this; 61} 62 63UCharCharacterIterator::~UCharCharacterIterator() { 64} 65 66UBool 67UCharCharacterIterator::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 84int32_t 85UCharCharacterIterator::hashCode() const { 86 return uhash_hashUCharsN(text, textLength) ^ pos ^ begin ^ end; 87} 88 89CharacterIterator* 90UCharCharacterIterator::clone() const { 91 return new UCharCharacterIterator(*this); 92} 93 94UChar 95UCharCharacterIterator::first() { 96 pos = begin; 97 if(pos < end) { 98 return text[pos]; 99 } else { 100 return DONE; 101 } 102} 103 104UChar 105UCharCharacterIterator::firstPostInc() { 106 pos = begin; 107 if(pos < end) { 108 return text[pos++]; 109 } else { 110 return DONE; 111 } 112} 113 114UChar 115UCharCharacterIterator::last() { 116 pos = end; 117 if(pos > begin) { 118 return text[--pos]; 119 } else { 120 return DONE; 121 } 122} 123 124UChar 125UCharCharacterIterator::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 140UChar 141UCharCharacterIterator::current() const { 142 if (pos >= begin && pos < end) { 143 return text[pos]; 144 } else { 145 return DONE; 146 } 147} 148 149UChar 150UCharCharacterIterator::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 160UChar 161UCharCharacterIterator::nextPostInc() { 162 if (pos < end) { 163 return text[pos++]; 164 } else { 165 return DONE; 166 } 167} 168 169UBool 170UCharCharacterIterator::hasNext() { 171 return (UBool)(pos < end ? TRUE : FALSE); 172} 173 174UChar 175UCharCharacterIterator::previous() { 176 if (pos > begin) { 177 return text[--pos]; 178 } else { 179 return DONE; 180 } 181} 182 183UBool 184UCharCharacterIterator::hasPrevious() { 185 return (UBool)(pos > begin ? TRUE : FALSE); 186} 187 188UChar32 189UCharCharacterIterator::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 201UChar32 202UCharCharacterIterator::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 213UChar32 214UCharCharacterIterator::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 225UChar32 226UCharCharacterIterator::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 244UChar32 245UCharCharacterIterator::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 255UChar32 256UCharCharacterIterator::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 271UChar32 272UCharCharacterIterator::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 282UChar32 283UCharCharacterIterator::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 293int32_t 294UCharCharacterIterator::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 318int32_t 319UCharCharacterIterator::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 349void 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 359void 360UCharCharacterIterator::getText(UnicodeString& result) { 361 result = UnicodeString(text, textLength); 362} 363 364U_NAMESPACE_END 365