1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html 4 /* 5 ******************************************************************************* 6 * Copyright (C) 1996-2014, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10 package android.icu.text; 11 12 import java.util.Iterator; 13 14 // Android patch: Make UnicodeSetIterator non-final. 15 /** 16 * UnicodeSetIterator iterates over the contents of a UnicodeSet. It 17 * iterates over either code points or code point ranges. After all 18 * code points or ranges have been returned, it returns the 19 * multicharacter strings of the UnicodeSet, if any. 20 * 21 * <p>This class is not intended for public subclassing. 22 * 23 * <p>To iterate over code points and multicharacter strings, 24 * use a loop like this: 25 * <pre> 26 * for (UnicodeSetIterator it = new UnicodeSetIterator(set); it.next();) { 27 * processString(it.getString()); 28 * } 29 * </pre> 30 * 31 * <p>To iterate over code point ranges, use a loop like this: 32 * <pre> 33 * for (UnicodeSetIterator it = new UnicodeSetIterator(set); it.nextRange();) { 34 * if (it.codepoint != UnicodeSetIterator.IS_STRING) { 35 * processCodepointRange(it.codepoint, it.codepointEnd); 36 * } else { 37 * processString(it.getString()); 38 * } 39 * } 40 * </pre> 41 * 42 * <p>To iterate over only the strings, start with <code>new UnicodeSetIterator(set).skipToStrings()</code>. 43 * 44 * <p><b>Warning: </b>For speed, UnicodeSet iteration does not check for concurrent modification. 45 * Do not alter the UnicodeSet while iterating. 46 * @author M. Davis 47 * @see UnicodeSet#ranges() 48 * @see UnicodeSet#strings() 49 * @see UnicodeSet#iterator() 50 */ 51 public class UnicodeSetIterator { 52 53 // Android patch: Make UnicodeSetIterator.IS_STRING non-final. 54 /** 55 * Value of <tt>codepoint</tt> if the iterator points to a string. 56 * If <tt>codepoint == IS_STRING</tt>, then examine 57 * <tt>string</tt> for the current iteration result. 58 */ 59 public static int IS_STRING = -1; 60 61 /** 62 * Current code point, or the special value <tt>IS_STRING</tt>, if 63 * the iterator points to a string. 64 */ 65 public int codepoint; 66 67 /** 68 * When iterating over ranges using <tt>nextRange()</tt>, 69 * <tt>codepointEnd</tt> contains the inclusive end of the 70 * iteration range, if <tt>codepoint != IS_STRING</tt>. If 71 * iterating over code points using <tt>next()</tt>, or if 72 * <tt>codepoint == IS_STRING</tt>, then the value of 73 * <tt>codepointEnd</tt> is undefined. 74 */ 75 public int codepointEnd; 76 77 /** 78 * If <tt>codepoint == IS_STRING</tt>, then <tt>string</tt> points 79 * to the current string. If <tt>codepoint != IS_STRING</tt>, the 80 * value of <tt>string</tt> is undefined. 81 */ 82 public String string; 83 84 /** 85 * Create an iterator over the given set. 86 * @param set set to iterate over 87 */ UnicodeSetIterator(UnicodeSet set)88 public UnicodeSetIterator(UnicodeSet set) { 89 reset(set); 90 } 91 92 /** 93 * Create an iterator over nothing. <tt>next()</tt> and 94 * <tt>nextRange()</tt> return false. This is a convenience 95 * constructor allowing the target to be set later. 96 */ UnicodeSetIterator()97 public UnicodeSetIterator() { 98 reset(new UnicodeSet()); 99 } 100 101 /** 102 * Skips over the remaining code points/ranges, if any. 103 * A following call to next() or nextRange() will yield a string, if there is one. 104 * No-op if next() would return false, or if it would yield a string anyway. 105 * 106 * @return this 107 * @see UnicodeSet#strings() 108 */ skipToStrings()109 public UnicodeSetIterator skipToStrings() { 110 // Finish code point/range iteration. 111 range = endRange; 112 endElement = -1; 113 nextElement = 0; 114 return this; 115 } 116 117 /** 118 * Returns the next element in the set, either a single code point 119 * or a string. If there are no more elements in the set, return 120 * false. If <tt>codepoint == IS_STRING</tt>, the value is a 121 * string in the <tt>string</tt> field. Otherwise the value is a 122 * single code point in the <tt>codepoint</tt> field. 123 * 124 * <p>The order of iteration is all code points in sorted order, 125 * followed by all strings sorted order. <tt>codepointEnd</tt> is 126 * undefined after calling this method. <tt>string</tt> is 127 * undefined unless <tt>codepoint == IS_STRING</tt>. Do not mix 128 * calls to <tt>next()</tt> and <tt>nextRange()</tt> without 129 * calling <tt>reset()</tt> between them. The results of doing so 130 * are undefined. 131 * <p><b>Warning: </b>For speed, UnicodeSet iteration does not check for concurrent modification. 132 * Do not alter the UnicodeSet while iterating. 133 * @return true if there was another element in the set and this 134 * object contains the element. 135 */ next()136 public boolean next() { 137 if (nextElement <= endElement) { 138 codepoint = codepointEnd = nextElement++; 139 return true; 140 } 141 if (range < endRange) { 142 loadRange(++range); 143 codepoint = codepointEnd = nextElement++; 144 return true; 145 } 146 147 // stringIterator == null iff there are no string elements remaining 148 149 if (stringIterator == null) { 150 return false; 151 } 152 codepoint = IS_STRING; // signal that value is actually a string 153 string = stringIterator.next(); 154 if (!stringIterator.hasNext()) { 155 stringIterator = null; 156 } 157 return true; 158 } 159 160 /** 161 * Returns the next element in the set, either a code point range 162 * or a string. If there are no more elements in the set, return 163 * false. If <tt>codepoint == IS_STRING</tt>, the value is a 164 * string in the <tt>string</tt> field. Otherwise the value is a 165 * range of one or more code points from <tt>codepoint</tt> to 166 * <tt>codepointeEnd</tt> inclusive. 167 * 168 * <p>The order of iteration is all code points ranges in sorted 169 * order, followed by all strings sorted order. Ranges are 170 * disjoint and non-contiguous. <tt>string</tt> is undefined 171 * unless <tt>codepoint == IS_STRING</tt>. Do not mix calls to 172 * <tt>next()</tt> and <tt>nextRange()</tt> without calling 173 * <tt>reset()</tt> between them. The results of doing so are 174 * undefined. 175 * 176 * @return true if there was another element in the set and this 177 * object contains the element. 178 */ nextRange()179 public boolean nextRange() { 180 if (nextElement <= endElement) { 181 codepointEnd = endElement; 182 codepoint = nextElement; 183 nextElement = endElement+1; 184 return true; 185 } 186 if (range < endRange) { 187 loadRange(++range); 188 codepointEnd = endElement; 189 codepoint = nextElement; 190 nextElement = endElement+1; 191 return true; 192 } 193 194 // stringIterator == null iff there are no string elements remaining 195 196 if (stringIterator == null) { 197 return false; 198 } 199 codepoint = IS_STRING; // signal that value is actually a string 200 string = stringIterator.next(); 201 if (!stringIterator.hasNext()) { 202 stringIterator = null; 203 } 204 return true; 205 } 206 207 /** 208 * Sets this iterator to visit the elements of the given set and 209 * resets it to the start of that set. The iterator is valid only 210 * so long as <tt>set</tt> is valid. 211 * @param uset the set to iterate over. 212 */ reset(UnicodeSet uset)213 public void reset(UnicodeSet uset) { 214 set = uset; 215 reset(); 216 } 217 218 /** 219 * Resets this iterator to the start of the set. 220 */ reset()221 public void reset() { 222 endRange = set.getRangeCount() - 1; 223 range = 0; 224 endElement = -1; 225 nextElement = 0; 226 if (endRange >= 0) { 227 loadRange(range); 228 } 229 if (set.hasStrings()) { 230 stringIterator = set.strings.iterator(); 231 } else { 232 stringIterator = null; 233 } 234 } 235 236 /** 237 * Gets the current string from the iterator. Only use after calling next(), not nextRange(). 238 */ getString()239 public String getString() { 240 if (codepoint != IS_STRING) { 241 return UTF16.valueOf(codepoint); 242 } 243 return string; 244 } 245 246 // ======================= PRIVATES =========================== 247 248 private UnicodeSet set; 249 private int endRange = 0; 250 private int range = 0; 251 252 /** 253 * @hide original deprecated declaration 254 */ 255 private int endElement; 256 /** 257 * @hide original deprecated declaration 258 */ 259 private int nextElement; 260 261 /** 262 * Invariant: stringIterator is null when there are no (more) strings remaining 263 */ 264 private Iterator<String> stringIterator = null; 265 266 /** 267 * @hide original deprecated declaration 268 */ loadRange(int aRange)269 private void loadRange(int aRange) { 270 nextElement = set.getRangeStart(aRange); 271 endElement = set.getRangeEnd(aRange); 272 } 273 } 274