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