|
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 |
|
17 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator) |
|
18 |
|
19 UCharCharacterIterator::UCharCharacterIterator() |
|
20 : CharacterIterator(), |
|
21 text(0) |
|
22 { |
|
23 // never default construct! |
|
24 } |
|
25 |
|
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 |
|
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 |
|
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 |
|
51 UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that) |
|
52 : CharacterIterator(that), |
|
53 text(that.text) |
|
54 { |
|
55 } |
|
56 |
|
57 UCharCharacterIterator& |
|
58 UCharCharacterIterator::operator=(const UCharCharacterIterator& that) { |
|
59 CharacterIterator::operator=(that); |
|
60 text = that.text; |
|
61 return *this; |
|
62 } |
|
63 |
|
64 UCharCharacterIterator::~UCharCharacterIterator() { |
|
65 } |
|
66 |
|
67 UBool |
|
68 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 |
|
86 UCharCharacterIterator::hashCode() const { |
|
87 return ustr_hashUCharsN(text, textLength) ^ pos ^ begin ^ end; |
|
88 } |
|
89 |
|
90 CharacterIterator* |
|
91 UCharCharacterIterator::clone() const { |
|
92 return new UCharCharacterIterator(*this); |
|
93 } |
|
94 |
|
95 UChar |
|
96 UCharCharacterIterator::first() { |
|
97 pos = begin; |
|
98 if(pos < end) { |
|
99 return text[pos]; |
|
100 } else { |
|
101 return DONE; |
|
102 } |
|
103 } |
|
104 |
|
105 UChar |
|
106 UCharCharacterIterator::firstPostInc() { |
|
107 pos = begin; |
|
108 if(pos < end) { |
|
109 return text[pos++]; |
|
110 } else { |
|
111 return DONE; |
|
112 } |
|
113 } |
|
114 |
|
115 UChar |
|
116 UCharCharacterIterator::last() { |
|
117 pos = end; |
|
118 if(pos > begin) { |
|
119 return text[--pos]; |
|
120 } else { |
|
121 return DONE; |
|
122 } |
|
123 } |
|
124 |
|
125 UChar |
|
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 |
|
142 UCharCharacterIterator::current() const { |
|
143 if (pos >= begin && pos < end) { |
|
144 return text[pos]; |
|
145 } else { |
|
146 return DONE; |
|
147 } |
|
148 } |
|
149 |
|
150 UChar |
|
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 |
|
162 UCharCharacterIterator::nextPostInc() { |
|
163 if (pos < end) { |
|
164 return text[pos++]; |
|
165 } else { |
|
166 return DONE; |
|
167 } |
|
168 } |
|
169 |
|
170 UBool |
|
171 UCharCharacterIterator::hasNext() { |
|
172 return (UBool)(pos < end ? TRUE : FALSE); |
|
173 } |
|
174 |
|
175 UChar |
|
176 UCharCharacterIterator::previous() { |
|
177 if (pos > begin) { |
|
178 return text[--pos]; |
|
179 } else { |
|
180 return DONE; |
|
181 } |
|
182 } |
|
183 |
|
184 UBool |
|
185 UCharCharacterIterator::hasPrevious() { |
|
186 return (UBool)(pos > begin ? TRUE : FALSE); |
|
187 } |
|
188 |
|
189 UChar32 |
|
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 |
|
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 |
|
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 |
|
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 |
|
246 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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
361 UCharCharacterIterator::getText(UnicodeString& result) { |
|
362 result = UnicodeString(text, textLength); |
|
363 } |
|
364 |
|
365 U_NAMESPACE_END |