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