1 /*
2 **********************************************************************
3 * Copyright (c) 2002-2006, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 */
7 #include "unicode/usetiter.h"
8 #include "unicode/uniset.h"
9 #include "unicode/unistr.h"
10 #include "uvector.h"
11
12 U_NAMESPACE_BEGIN
13
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeSetIterator)14 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeSetIterator)
15
16 /**
17 * Create an iterator
18 * @param set set to iterate over
19 */
20 UnicodeSetIterator::UnicodeSetIterator(const UnicodeSet& uSet) {
21 cpString = NULL;
22 reset(uSet);
23 }
24
25 /**
26 * Create an iterator. Convenience for when the contents are to be set later.
27 */
UnicodeSetIterator()28 UnicodeSetIterator::UnicodeSetIterator() {
29 this->set = NULL;
30 cpString = NULL;
31 reset();
32 }
33
~UnicodeSetIterator()34 UnicodeSetIterator::~UnicodeSetIterator() {
35 delete cpString;
36 }
37
38 /**
39 * Returns the next element in the set.
40 * @return true if there was another element in the set.
41 * if so, if codepoint == IS_STRING, the value is a string in the string field
42 * else the value is a single code point in the codepoint field.
43 * <br>You are guaranteed that the codepoints are in sorted order, and the strings are in sorted order,
44 * and that all code points are returned before any strings are returned.
45 * <br>Note also that the codepointEnd is undefined after calling this method.
46 */
next()47 UBool UnicodeSetIterator::next() {
48 if (nextElement <= endElement) {
49 codepoint = codepointEnd = nextElement++;
50 string = NULL;
51 return TRUE;
52 }
53 if (range < endRange) {
54 loadRange(++range);
55 codepoint = codepointEnd = nextElement++;
56 string = NULL;
57 return TRUE;
58 }
59
60 if (nextString >= stringCount) return FALSE;
61 codepoint = (UChar32)IS_STRING; // signal that value is actually a string
62 string = (const UnicodeString*) set->strings->elementAt(nextString++);
63 return TRUE;
64 }
65
66 /**
67 * @return true if there was another element in the set.
68 * if so, if codepoint == IS_STRING, the value is a string in the string field
69 * else the value is a range of codepoints in the <codepoint, codepointEnd> fields.
70 * <br>Note that the codepoints are in sorted order, and the strings are in sorted order,
71 * and that all code points are returned before any strings are returned.
72 * <br>You are guaranteed that the ranges are in sorted order, and the strings are in sorted order,
73 * and that all ranges are returned before any strings are returned.
74 * <br>You are also guaranteed that ranges are disjoint and non-contiguous.
75 * <br>Note also that the codepointEnd is undefined after calling this method.
76 */
nextRange()77 UBool UnicodeSetIterator::nextRange() {
78 string = NULL;
79 if (nextElement <= endElement) {
80 codepointEnd = endElement;
81 codepoint = nextElement;
82 nextElement = endElement+1;
83 return TRUE;
84 }
85 if (range < endRange) {
86 loadRange(++range);
87 codepointEnd = endElement;
88 codepoint = nextElement;
89 nextElement = endElement+1;
90 return TRUE;
91 }
92
93 if (nextString >= stringCount) return FALSE;
94 codepoint = (UChar32)IS_STRING; // signal that value is actually a string
95 string = (const UnicodeString*) set->strings->elementAt(nextString++);
96 return TRUE;
97 }
98
99 /**
100 *@param set the set to iterate over. This allows reuse of the iterator.
101 */
reset(const UnicodeSet & uSet)102 void UnicodeSetIterator::reset(const UnicodeSet& uSet) {
103 this->set = &uSet;
104 reset();
105 }
106
107 /**
108 * Resets to the start, to allow the iteration to start over again.
109 */
reset()110 void UnicodeSetIterator::reset() {
111 if (set == NULL) {
112 // Set up indices to empty iteration
113 endRange = -1;
114 stringCount = 0;
115 } else {
116 endRange = set->getRangeCount() - 1;
117 stringCount = set->strings->size();
118 }
119 range = 0;
120 endElement = -1;
121 nextElement = 0;
122 if (endRange >= 0) {
123 loadRange(range);
124 }
125 nextString = 0;
126 string = NULL;
127 }
128
loadRange(int32_t iRange)129 void UnicodeSetIterator::loadRange(int32_t iRange) {
130 nextElement = set->getRangeStart(iRange);
131 endElement = set->getRangeEnd(iRange);
132 }
133
134
getString()135 const UnicodeString& UnicodeSetIterator::getString() {
136 if (string==NULL && codepoint!=(UChar32)IS_STRING) {
137 if (cpString == NULL) {
138 cpString = new UnicodeString();
139 }
140 if (cpString != NULL) {
141 cpString->setTo((UChar32)codepoint);
142 }
143 string = cpString;
144 }
145 return *string;
146 }
147
148 U_NAMESPACE_END
149
150 //eof
151