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