Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / java / text / AttributedStringIterator.java
blobf6b9b186831c0b90341a88bf48528ad970985003
1 /* AttributedStringIterator.java -- Class to iterate over AttributedString
2 Copyright (C) 1998, 1999, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.text;
41 import java.util.HashMap;
42 import java.util.HashSet;
43 import java.util.Iterator;
44 import java.util.Map;
45 import java.util.Set;
47 /**
48 * This class implements the AttributedCharacterIterator interface. It
49 * is used by AttributedString.getIterator().
51 * @version 0.0
53 * @author Aaron M. Renn (arenn@urbanophile.com)
55 class AttributedStringIterator implements AttributedCharacterIterator
58 /*************************************************************************/
60 /** The character iterator containing the text */
61 private CharacterIterator ci;
63 /** The list of attributes and ranges */
64 private AttributedString.AttributeRange[] attribs;
66 /**
67 * The list of attributes that the user is interested in. We may,
68 * at our option, not return any other attributes.
70 private AttributedCharacterIterator.Attribute[] restricts;
72 /*************************************************************************/
74 AttributedStringIterator(StringCharacterIterator sci,
75 AttributedString.AttributeRange[] attribs,
76 int begin_index, int end_index,
77 AttributedCharacterIterator.Attribute[] restricts)
79 this.ci = new StringCharacterIterator(sci, begin_index, end_index);
80 this.attribs = attribs;
81 this.restricts = restricts;
84 /*************************************************************************/
86 // First we have a bunch of stupid redirects. If StringCharacterIterator
87 // weren't final, I just would have extended that for this class. Alas, no.
89 public Object clone()
91 return(ci.clone());
94 public char current()
96 return(ci.current());
99 public char next()
101 return(ci.next());
104 public char previous()
106 return(ci.previous());
109 public char first()
111 return(ci.first());
114 public char last()
116 return(ci.last());
119 public int getIndex()
121 return(ci.getIndex());
124 public char setIndex(int index)
126 return(ci.setIndex(index));
129 public int getBeginIndex()
131 return(ci.getBeginIndex());
134 public int getEndIndex()
136 return(ci.getEndIndex());
140 * Here is where the AttributedCharacterIterator methods start.
143 /*************************************************************************/
146 * Returns a list of all the attribute keys that are defined anywhere
147 * on this string.
149 public Set getAllAttributeKeys()
151 HashSet s = new HashSet();
152 if (attribs == null)
153 return(s);
155 for (int i = 0; i < attribs.length; i++)
157 if (attribs[i].begin_index > getEndIndex()
158 || attribs[i].end_index <= getBeginIndex())
159 continue;
161 Set key_set = attribs[i].attribs.keySet();
162 Iterator iter = key_set.iterator();
163 while (iter.hasNext())
165 s.add(iter.next());
169 return(s);
172 /*************************************************************************/
175 * Various methods that determine how far the run extends for various
176 * attribute combinations.
179 public int getRunLimit()
181 return(getRunLimit(getAttributes().keySet()));
184 public int getRunLimit(AttributedCharacterIterator.Attribute attrib)
186 HashSet s = new HashSet();
187 s.add(attrib);
188 return(getRunLimit(s));
191 public synchronized int getRunLimit(Set attributeSet)
193 if (attributeSet == null)
194 return ci.getEndIndex();
196 int current = ci.getIndex();
197 int end = ci.getEndIndex();
198 int limit = current;
199 if (current == end)
200 return end;
201 Map runValues = getAttributes();
202 while (limit < end)
204 Iterator iterator = attributeSet.iterator();
205 while (iterator.hasNext())
207 // Qualified name is a workaround for a gcj 4.0 bug.
208 AttributedCharacterIterator.Attribute attributeKey
209 = (AttributedCharacterIterator.Attribute) iterator.next();
210 Object v1 = runValues.get(attributeKey);
211 Object v2 = getAttribute(attributeKey, limit + 1);
212 boolean changed = false;
213 // check for equal or both null, if NO return start
214 if (v1 != null)
216 changed = !v1.equals(v2);
218 else
220 changed = (v2 != null);
222 if (changed)
223 return limit + 1;
225 // no differences, so increment limit and next and loop again
226 limit++;
228 return end;
231 /*************************************************************************/
234 * Various methods that determine where the run begins for various
235 * attribute combinations.
239 * Returns the index of the first character in the run containing the current
240 * character and defined by all the attributes defined for that character
241 * position.
243 * @return The run start index.
245 public int getRunStart()
247 return(getRunStart(getAttributes().keySet()));
251 * Returns the index of the first character in the run, defined by the
252 * specified attribute, that contains the current character.
254 * @param attrib the attribute (<code>null</code> permitted).
256 * return The index of the first character in the run.
258 public int getRunStart(AttributedCharacterIterator.Attribute attrib)
260 if (attrib == null)
261 return ci.getBeginIndex();
262 HashSet s = new HashSet();
263 s.add(attrib);
264 return(getRunStart(s));
268 * Returns the index of the first character in the run, defined by the
269 * specified attribute set, that contains the current character.
271 * @param attributeSet the attribute set (<code>null</code> permitted).
273 * return The index of the first character in the run.
275 public int getRunStart(Set attributeSet)
277 if (attributeSet == null)
278 return ci.getBeginIndex();
280 int current = ci.getIndex();
281 int begin = ci.getBeginIndex();
282 int start = current;
283 if (start == begin)
284 return begin;
285 Map runValues = getAttributes();
286 int prev = start - 1;
287 while (start > begin)
289 Iterator iterator = attributeSet.iterator();
290 while (iterator.hasNext())
292 // Qualified name is a workaround for a gcj 4.0 bug.
293 AttributedCharacterIterator.Attribute attributeKey
294 = (AttributedCharacterIterator.Attribute) iterator.next();
295 Object v1 = runValues.get(attributeKey);
296 Object v2 = getAttribute(attributeKey, prev);
297 boolean changed = false;
298 // check for equal or both null, if NO return start
299 if (v1 != null)
301 changed = !v1.equals(v2);
303 else
305 changed = (v2 != null);
307 if (changed)
308 return start;
310 // no differences, so decrement start and prev and loop again
311 start--;
312 prev--;
314 return start;
317 /*************************************************************************/
320 * Returns the value for an attribute at the specified position. If the
321 * attribute key (<code>key</code>) is <code>null</code>, the method returns
322 * <code>null</code>.
324 * @param key the key (<code>null</code> permitted).
325 * @param pos the character position.
327 * @return The attribute value (possibly <code>null</code>).
329 private Object getAttribute(AttributedCharacterIterator.Attribute key,
330 int pos)
332 if (attribs == null)
333 return null;
334 for (int i = attribs.length - 1; i >= 0; i--)
336 if (pos >= attribs[i].begin_index && pos < attribs[i].end_index)
338 Set keys = attribs[i].attribs.keySet();
339 if (keys.contains(key))
341 return attribs[i].attribs.get(key);
345 return null;
349 * Returns the value for an attribute at the current position. If the
350 * attribute key (<code>key</code>) is <code>null</code>, the method returns
351 * <code>null</code>.
353 * @param key the key (<code>null</code> permitted).
355 * @return The attribute value (possibly <code>null</code>).
357 public Object getAttribute(AttributedCharacterIterator.Attribute key)
359 return getAttribute(key, ci.getIndex());
362 /*************************************************************************/
365 * Return a list of all the attributes and values defined for this
366 * character
368 public Map getAttributes()
370 HashMap m = new HashMap();
371 if (attribs == null)
372 return(m);
374 for (int i = 0; i < attribs.length; i++)
376 if ((ci.getIndex() >= attribs[i].begin_index) &&
377 (ci.getIndex() < attribs[i].end_index))
378 m.putAll(attribs[i].attribs);
381 return(m);
384 } // class AttributedStringIterator