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 15U_NAMESPACE_BEGIN 16 17UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator) 18 19UCharCharacterIterator::UCharCharacterIterator() 20 : CharacterIterator(), 21 text(0) 22{ 23 // never default construct! 24} 25 26UCharCharacterIterator::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 33UCharCharacterIterator::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 41UCharCharacterIterator::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 51UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that) 52: CharacterIterator(that), 53 text(that.text) 54{ 55} 56 57UCharCharacterIterator& 58UCharCharacterIterator::operator=(const UCharCharacterIterator& that) { 59 CharacterIterator::operator=(that); 60 text = that.text; 61 return *this; 62} 63 64UCharCharacterIterator::~UCharCharacterIterator() { 65} 66 67UBool 68UCharCharacterIterator::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 85int32_t 86UCharCharacterIterator::hashCode() const { 87 return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end; 88} 89 90CharacterIterator* 91UCharCharacterIterator::clone() const { 92 return new UCharCharacterIterator(*this); 93} 94 95UChar 96UCharCharacterIterator::first() { 97 pos = begin; 98 if(pos < end) { 99 return text[pos]; 100 } else { 101 return DONE; 102 } 103} 104 105UChar 106UCharCharacterIterator::firstPostInc() { 107 pos = begin; 108 if(pos < end) { 109 return text[pos++]; 110 } else { 111 return DONE; 112 } 113} 114 115UChar 116UCharCharacterIterator::last() { 117 pos = end; 118 if(pos > begin) { 119 return text[--pos]; 120 } else { 121 return DONE; 122 } 123} 124 125UChar 126UCharCharacterIterator::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 141UChar 142UCharCharacterIterator::current() const { 143 if (pos >= begin && pos < end) { 144 return text[pos]; 145 } else { 146 return DONE; 147 } 148} 149 150UChar 151UCharCharacterIterator::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 161UChar 162UCharCharacterIterator::nextPostInc() { 163 if (pos < end) { 164 return text[pos++]; 165 } else { 166 return DONE; 167 } 168} 169 170UBool 171UCharCharacterIterator::hasNext() { 172 return (UBool)(pos < end ? TRUE : FALSE); 173} 174 175UChar 176UCharCharacterIterator::previous() { 177 if (pos > begin) { 178 return text[--pos]; 179 } else { 180 return DONE; 181 } 182} 183 184UBool 185UCharCharacterIterator::hasPrevious() { 186 return (UBool)(pos > begin ? TRUE : FALSE); 187} 188 189UChar32 190UCharCharacterIterator::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 202UChar32 203UCharCharacterIterator::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 214UChar32 215UCharCharacterIterator::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 226UChar32 227UCharCharacterIterator::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 245UChar32 246UCharCharacterIterator::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 256UChar32 257UCharCharacterIterator::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 272UChar32 273UCharCharacterIterator::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 283UChar32 284UCharCharacterIterator::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 294int32_t 295UCharCharacterIterator::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 319int32_t 320UCharCharacterIterator::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 350void 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 360void 361UCharCharacterIterator::getText(UnicodeString& result) { 362 result = UnicodeString(text, textLength); 363} 364 365U_NAMESPACE_END 366