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 17U_NAMESPACE_BEGIN 18 19UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator) 20 21UCharCharacterIterator::UCharCharacterIterator() 22 : CharacterIterator(), 23 text(0) 24{ 25 // never default construct! 26} 27 28UCharCharacterIterator::UCharCharacterIterator(ConstChar16Ptr textPtr, 29 int32_t length) 30 : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0), 31 text(textPtr) 32{ 33} 34 35UCharCharacterIterator::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 43UCharCharacterIterator::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 53UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that) 54: CharacterIterator(that), 55 text(that.text) 56{ 57} 58 59UCharCharacterIterator& 60UCharCharacterIterator::operator=(const UCharCharacterIterator& that) { 61 CharacterIterator::operator=(that); 62 text = that.text; 63 return *this; 64} 65 66UCharCharacterIterator::~UCharCharacterIterator() { 67} 68 69bool 70UCharCharacterIterator::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 const UCharCharacterIterator& realThat = static_cast<const 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 87int32_t 88UCharCharacterIterator::hashCode() const { 89 return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end; 90} 91 92UCharCharacterIterator* 93UCharCharacterIterator::clone() const { 94 return new UCharCharacterIterator(*this); 95} 96 97char16_t 98UCharCharacterIterator::first() { 99 pos = begin; 100 if(pos < end) { 101 return text[pos]; 102 } else { 103 return DONE; 104 } 105} 106 107char16_t 108UCharCharacterIterator::firstPostInc() { 109 pos = begin; 110 if(pos < end) { 111 return text[pos++]; 112 } else { 113 return DONE; 114 } 115} 116 117char16_t 118UCharCharacterIterator::last() { 119 pos = end; 120 if(pos > begin) { 121 return text[--pos]; 122 } else { 123 return DONE; 124 } 125} 126 127char16_t 128UCharCharacterIterator::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 143char16_t 144UCharCharacterIterator::current() const { 145 if (pos >= begin && pos < end) { 146 return text[pos]; 147 } else { 148 return DONE; 149 } 150} 151 152char16_t 153UCharCharacterIterator::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 163char16_t 164UCharCharacterIterator::nextPostInc() { 165 if (pos < end) { 166 return text[pos++]; 167 } else { 168 return DONE; 169 } 170} 171 172UBool 173UCharCharacterIterator::hasNext() { 174 return (UBool)(pos < end ? true : false); 175} 176 177char16_t 178UCharCharacterIterator::previous() { 179 if (pos > begin) { 180 return text[--pos]; 181 } else { 182 return DONE; 183 } 184} 185 186UBool 187UCharCharacterIterator::hasPrevious() { 188 return (UBool)(pos > begin ? true : false); 189} 190 191UChar32 192UCharCharacterIterator::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 204UChar32 205UCharCharacterIterator::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 216UChar32 217UCharCharacterIterator::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 228UChar32 229UCharCharacterIterator::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 247UChar32 248UCharCharacterIterator::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 258UChar32 259UCharCharacterIterator::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 274UChar32 275UCharCharacterIterator::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 285UChar32 286UCharCharacterIterator::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 296int32_t 297UCharCharacterIterator::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 321int32_t 322UCharCharacterIterator::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 352void 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 362void 363UCharCharacterIterator::getText(UnicodeString& result) { 364 result = UnicodeString(text, textLength); 365} 366 367U_NAMESPACE_END 368