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