1 /*
2 ******************************************************************************
3 * Copyright (C) 1998-2012, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ******************************************************************************
6 */
7
8 #include "utypeinfo.h" // for 'typeid' to work
9
10 #include "unicode/uchriter.h"
11 #include "unicode/ustring.h"
12 #include "unicode/utf16.h"
13 #include "ustr_imp.h"
14
15 U_NAMESPACE_BEGIN
16
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator)17 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator)
18
19 UCharCharacterIterator::UCharCharacterIterator()
20 : CharacterIterator(),
21 text(0)
22 {
23 // never default construct!
24 }
25
UCharCharacterIterator(const UChar * textPtr,int32_t length)26 UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
27 int32_t length)
28 : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0),
29 text(textPtr)
30 {
31 }
32
UCharCharacterIterator(const UChar * textPtr,int32_t length,int32_t position)33 UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
34 int32_t length,
35 int32_t position)
36 : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, position),
37 text(textPtr)
38 {
39 }
40
UCharCharacterIterator(const UChar * textPtr,int32_t length,int32_t textBegin,int32_t textEnd,int32_t position)41 UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
42 int32_t length,
43 int32_t textBegin,
44 int32_t textEnd,
45 int32_t position)
46 : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, textBegin, textEnd, position),
47 text(textPtr)
48 {
49 }
50
UCharCharacterIterator(const UCharCharacterIterator & that)51 UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that)
52 : CharacterIterator(that),
53 text(that.text)
54 {
55 }
56
57 UCharCharacterIterator&
operator =(const UCharCharacterIterator & that)58 UCharCharacterIterator::operator=(const UCharCharacterIterator& that) {
59 CharacterIterator::operator=(that);
60 text = that.text;
61 return *this;
62 }
63
~UCharCharacterIterator()64 UCharCharacterIterator::~UCharCharacterIterator() {
65 }
66
67 UBool
operator ==(const ForwardCharacterIterator & that) const68 UCharCharacterIterator::operator==(const ForwardCharacterIterator& that) const {
69 if (this == &that) {
70 return TRUE;
71 }
72 if (typeid(*this) != typeid(that)) {
73 return FALSE;
74 }
75
76 UCharCharacterIterator& realThat = (UCharCharacterIterator&)that;
77
78 return text == realThat.text
79 && textLength == realThat.textLength
80 && pos == realThat.pos
81 && begin == realThat.begin
82 && end == realThat.end;
83 }
84
85 int32_t
hashCode() const86 UCharCharacterIterator::hashCode() const {
87 return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end;
88 }
89
90 CharacterIterator*
clone() const91 UCharCharacterIterator::clone() const {
92 return new UCharCharacterIterator(*this);
93 }
94
95 UChar
first()96 UCharCharacterIterator::first() {
97 pos = begin;
98 if(pos < end) {
99 return text[pos];
100 } else {
101 return DONE;
102 }
103 }
104
105 UChar
firstPostInc()106 UCharCharacterIterator::firstPostInc() {
107 pos = begin;
108 if(pos < end) {
109 return text[pos++];
110 } else {
111 return DONE;
112 }
113 }
114
115 UChar
last()116 UCharCharacterIterator::last() {
117 pos = end;
118 if(pos > begin) {
119 return text[--pos];
120 } else {
121 return DONE;
122 }
123 }
124
125 UChar
setIndex(int32_t position)126 UCharCharacterIterator::setIndex(int32_t position) {
127 if(position < begin) {
128 pos = begin;
129 } else if(position > end) {
130 pos = end;
131 } else {
132 pos = position;
133 }
134 if(pos < end) {
135 return text[pos];
136 } else {
137 return DONE;
138 }
139 }
140
141 UChar
current() const142 UCharCharacterIterator::current() const {
143 if (pos >= begin && pos < end) {
144 return text[pos];
145 } else {
146 return DONE;
147 }
148 }
149
150 UChar
next()151 UCharCharacterIterator::next() {
152 if (pos + 1 < end) {
153 return text[++pos];
154 } else {
155 /* make current() return DONE */
156 pos = end;
157 return DONE;
158 }
159 }
160
161 UChar
nextPostInc()162 UCharCharacterIterator::nextPostInc() {
163 if (pos < end) {
164 return text[pos++];
165 } else {
166 return DONE;
167 }
168 }
169
170 UBool
hasNext()171 UCharCharacterIterator::hasNext() {
172 return (UBool)(pos < end ? TRUE : FALSE);
173 }
174
175 UChar
previous()176 UCharCharacterIterator::previous() {
177 if (pos > begin) {
178 return text[--pos];
179 } else {
180 return DONE;
181 }
182 }
183
184 UBool
hasPrevious()185 UCharCharacterIterator::hasPrevious() {
186 return (UBool)(pos > begin ? TRUE : FALSE);
187 }
188
189 UChar32
first32()190 UCharCharacterIterator::first32() {
191 pos = begin;
192 if(pos < end) {
193 int32_t i = pos;
194 UChar32 c;
195 U16_NEXT(text, i, end, c);
196 return c;
197 } else {
198 return DONE;
199 }
200 }
201
202 UChar32
first32PostInc()203 UCharCharacterIterator::first32PostInc() {
204 pos = begin;
205 if(pos < end) {
206 UChar32 c;
207 U16_NEXT(text, pos, end, c);
208 return c;
209 } else {
210 return DONE;
211 }
212 }
213
214 UChar32
last32()215 UCharCharacterIterator::last32() {
216 pos = end;
217 if(pos > begin) {
218 UChar32 c;
219 U16_PREV(text, begin, pos, c);
220 return c;
221 } else {
222 return DONE;
223 }
224 }
225
226 UChar32
setIndex32(int32_t position)227 UCharCharacterIterator::setIndex32(int32_t position) {
228 if(position < begin) {
229 position = begin;
230 } else if(position > end) {
231 position = end;
232 }
233 if(position < end) {
234 U16_SET_CP_START(text, begin, position);
235 int32_t i = this->pos = position;
236 UChar32 c;
237 U16_NEXT(text, i, end, c);
238 return c;
239 } else {
240 this->pos = position;
241 return DONE;
242 }
243 }
244
245 UChar32
current32() const246 UCharCharacterIterator::current32() const {
247 if (pos >= begin && pos < end) {
248 UChar32 c;
249 U16_GET(text, begin, pos, end, c);
250 return c;
251 } else {
252 return DONE;
253 }
254 }
255
256 UChar32
next32()257 UCharCharacterIterator::next32() {
258 if (pos < end) {
259 U16_FWD_1(text, pos, end);
260 if(pos < end) {
261 int32_t i = pos;
262 UChar32 c;
263 U16_NEXT(text, i, end, c);
264 return c;
265 }
266 }
267 /* make current() return DONE */
268 pos = end;
269 return DONE;
270 }
271
272 UChar32
next32PostInc()273 UCharCharacterIterator::next32PostInc() {
274 if (pos < end) {
275 UChar32 c;
276 U16_NEXT(text, pos, end, c);
277 return c;
278 } else {
279 return DONE;
280 }
281 }
282
283 UChar32
previous32()284 UCharCharacterIterator::previous32() {
285 if (pos > begin) {
286 UChar32 c;
287 U16_PREV(text, begin, pos, c);
288 return c;
289 } else {
290 return DONE;
291 }
292 }
293
294 int32_t
move(int32_t delta,CharacterIterator::EOrigin origin)295 UCharCharacterIterator::move(int32_t delta, CharacterIterator::EOrigin origin) {
296 switch(origin) {
297 case kStart:
298 pos = begin + delta;
299 break;
300 case kCurrent:
301 pos += delta;
302 break;
303 case kEnd:
304 pos = end + delta;
305 break;
306 default:
307 break;
308 }
309
310 if(pos < begin) {
311 pos = begin;
312 } else if(pos > end) {
313 pos = end;
314 }
315
316 return pos;
317 }
318
319 int32_t
move32(int32_t delta,CharacterIterator::EOrigin origin)320 UCharCharacterIterator::move32(int32_t delta, CharacterIterator::EOrigin origin) {
321 // this implementation relies on the "safe" version of the UTF macros
322 // (or the trustworthiness of the caller)
323 switch(origin) {
324 case kStart:
325 pos = begin;
326 if(delta > 0) {
327 U16_FWD_N(text, pos, end, delta);
328 }
329 break;
330 case kCurrent:
331 if(delta > 0) {
332 U16_FWD_N(text, pos, end, delta);
333 } else {
334 U16_BACK_N(text, begin, pos, -delta);
335 }
336 break;
337 case kEnd:
338 pos = end;
339 if(delta < 0) {
340 U16_BACK_N(text, begin, pos, -delta);
341 }
342 break;
343 default:
344 break;
345 }
346
347 return pos;
348 }
349
setText(const UChar * newText,int32_t newTextLength)350 void UCharCharacterIterator::setText(const UChar* newText,
351 int32_t newTextLength) {
352 text = newText;
353 if(newText == 0 || newTextLength < 0) {
354 newTextLength = 0;
355 }
356 end = textLength = newTextLength;
357 pos = begin = 0;
358 }
359
360 void
getText(UnicodeString & result)361 UCharCharacterIterator::getText(UnicodeString& result) {
362 result = UnicodeString(text, textLength);
363 }
364
365 U_NAMESPACE_END
366