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(0)
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 != 0 ? (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 != 0 ? (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 != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, textBegin, textEnd, position),
49 text(textPtr)
50 {
51 }
52
UCharCharacterIterator(const UCharCharacterIterator & that)53 UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that)
54 : CharacterIterator(that),
55 text(that.text)
56 {
57 }
58
59 UCharCharacterIterator&
operator =(const UCharCharacterIterator & that)60 UCharCharacterIterator::operator=(const UCharCharacterIterator& that) {
61 CharacterIterator::operator=(that);
62 text = that.text;
63 return *this;
64 }
65
~UCharCharacterIterator()66 UCharCharacterIterator::~UCharCharacterIterator() {
67 }
68
69 UBool
operator ==(const ForwardCharacterIterator & that) const70 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
hashCode() const88 UCharCharacterIterator::hashCode() const {
89 return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end;
90 }
91
92 CharacterIterator*
clone() const93 UCharCharacterIterator::clone() const {
94 return new UCharCharacterIterator(*this);
95 }
96
97 UChar
first()98 UCharCharacterIterator::first() {
99 pos = begin;
100 if(pos < end) {
101 return text[pos];
102 } else {
103 return DONE;
104 }
105 }
106
107 UChar
firstPostInc()108 UCharCharacterIterator::firstPostInc() {
109 pos = begin;
110 if(pos < end) {
111 return text[pos++];
112 } else {
113 return DONE;
114 }
115 }
116
117 UChar
last()118 UCharCharacterIterator::last() {
119 pos = end;
120 if(pos > begin) {
121 return text[--pos];
122 } else {
123 return DONE;
124 }
125 }
126
127 UChar
setIndex(int32_t position)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
current() const144 UCharCharacterIterator::current() const {
145 if (pos >= begin && pos < end) {
146 return text[pos];
147 } else {
148 return DONE;
149 }
150 }
151
152 UChar
next()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
nextPostInc()164 UCharCharacterIterator::nextPostInc() {
165 if (pos < end) {
166 return text[pos++];
167 } else {
168 return DONE;
169 }
170 }
171
172 UBool
hasNext()173 UCharCharacterIterator::hasNext() {
174 return (UBool)(pos < end ? TRUE : FALSE);
175 }
176
177 UChar
previous()178 UCharCharacterIterator::previous() {
179 if (pos > begin) {
180 return text[--pos];
181 } else {
182 return DONE;
183 }
184 }
185
186 UBool
hasPrevious()187 UCharCharacterIterator::hasPrevious() {
188 return (UBool)(pos > begin ? TRUE : FALSE);
189 }
190
191 UChar32
first32()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
first32PostInc()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
last32()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
setIndex32(int32_t position)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
current32() const248 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
next32()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
next32PostInc()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
previous32()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
move(int32_t delta,CharacterIterator::EOrigin origin)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
move32(int32_t delta,CharacterIterator::EOrigin origin)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
setText(ConstChar16Ptr newText,int32_t newTextLength)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
getText(UnicodeString & result)363 UCharCharacterIterator::getText(UnicodeString& result) {
364 result = UnicodeString(text, textLength);
365 }
366
367 U_NAMESPACE_END
368