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