• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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