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