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
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator)19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator)
20
21 UCharCharacterIterator::UCharCharacterIterator()
22 : CharacterIterator(),
23 text(nullptr)
24 {
25 // never default construct!
26 }
27
UCharCharacterIterator(ConstChar16Ptr textPtr,int32_t length)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
UCharCharacterIterator(ConstChar16Ptr textPtr,int32_t length,int32_t position)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
UCharCharacterIterator(ConstChar16Ptr textPtr,int32_t length,int32_t textBegin,int32_t textEnd,int32_t position)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
UCharCharacterIterator(const UCharCharacterIterator & that)54 UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that)
55 : CharacterIterator(that),
56 text(that.text)
57 {
58 }
59
60 UCharCharacterIterator&
operator =(const UCharCharacterIterator & that)61 UCharCharacterIterator::operator=(const UCharCharacterIterator& that) {
62 CharacterIterator::operator=(that);
63 text = that.text;
64 return *this;
65 }
66
~UCharCharacterIterator()67 UCharCharacterIterator::~UCharCharacterIterator() {
68 }
69
70 bool
operator ==(const ForwardCharacterIterator & that) const71 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
hashCode() const89 UCharCharacterIterator::hashCode() const {
90 return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end;
91 }
92
93 UCharCharacterIterator*
clone() const94 UCharCharacterIterator::clone() const {
95 return new UCharCharacterIterator(*this);
96 }
97
98 char16_t
first()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
firstPostInc()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
last()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
setIndex(int32_t position)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
current() const145 UCharCharacterIterator::current() const {
146 if (pos >= begin && pos < end) {
147 return text[pos];
148 } else {
149 return DONE;
150 }
151 }
152
153 char16_t
next()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
nextPostInc()165 UCharCharacterIterator::nextPostInc() {
166 if (pos < end) {
167 return text[pos++];
168 } else {
169 return DONE;
170 }
171 }
172
173 UBool
hasNext()174 UCharCharacterIterator::hasNext() {
175 return (UBool)(pos < end ? true : false);
176 }
177
178 char16_t
previous()179 UCharCharacterIterator::previous() {
180 if (pos > begin) {
181 return text[--pos];
182 } else {
183 return DONE;
184 }
185 }
186
187 UBool
hasPrevious()188 UCharCharacterIterator::hasPrevious() {
189 return (UBool)(pos > begin ? true : false);
190 }
191
192 UChar32
first32()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
first32PostInc()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
last32()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
setIndex32(int32_t position)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
current32() const249 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
next32()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
next32PostInc()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
previous32()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
move(int32_t delta,CharacterIterator::EOrigin origin)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
move32(int32_t delta,CharacterIterator::EOrigin origin)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
setText(ConstChar16Ptr newText,int32_t newTextLength)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
getText(UnicodeString & result)364 UCharCharacterIterator::getText(UnicodeString& result) {
365 result = UnicodeString(text, textLength);
366 }
367
368 U_NAMESPACE_END
369