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 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