Imported Upstream version 58.1
[platform/upstream/icu.git] / source / common / uchriter.cpp
1 // Copyright (C) 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(const UChar* 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(const UChar* 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(const UChar* 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(const UChar* 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