libjava/classpath/ChangeLog.gcj:
[official-gcc.git] / libjava / classpath / java / text / AttributedStringIterator.java
blob2f970feba43d36dda287200697d16f5a90d61ed6
1 /* AttributedStringIterator.java -- Class to iterate over AttributedString
2 Copyright (C) 1998, 1999, 2004, 2005, 2006, 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 /**
75 * Creates a new instance.
77 * @param sci an iterator for the string content.
78 * @param attribs the attribute ranges.
79 * @param beginIndex the start index.
80 * @param endIndex the end index.
81 * @param restricts the attributes that the user is interested in.
83 AttributedStringIterator(StringCharacterIterator sci,
84 AttributedString.AttributeRange[] attribs,
85 int beginIndex, int endIndex,
86 AttributedCharacterIterator.Attribute[] restricts)
88 this.ci = new StringCharacterIterator(sci, beginIndex, endIndex);
89 this.attribs = attribs;
90 this.restricts = restricts;
93 /*************************************************************************/
95 // First we have a bunch of stupid redirects. If StringCharacterIterator
96 // weren't final, I just would have extended that for this class. Alas, no.
98 public Object clone()
100 return(ci.clone());
103 public char current()
105 return(ci.current());
108 public char next()
110 return(ci.next());
113 public char previous()
115 return(ci.previous());
118 public char first()
120 return(ci.first());
123 public char last()
125 return(ci.last());
128 public int getIndex()
130 return(ci.getIndex());
133 public char setIndex(int index)
135 return(ci.setIndex(index));
138 public int getBeginIndex()
140 return(ci.getBeginIndex());
143 public int getEndIndex()
145 return(ci.getEndIndex());
149 * Here is where the AttributedCharacterIterator methods start.
152 /*************************************************************************/
155 * Returns a list of all the attribute keys that are defined anywhere
156 * on this string.
158 public Set getAllAttributeKeys()
160 HashSet s = new HashSet();
161 if (attribs == null)
162 return(s);
164 for (int i = 0; i < attribs.length; i++)
166 if (attribs[i].beginIndex > getEndIndex()
167 || attribs[i].endIndex <= getBeginIndex())
168 continue;
170 Set key_set = attribs[i].attribs.keySet();
171 Iterator iter = key_set.iterator();
172 while (iter.hasNext())
174 s.add(iter.next());
178 return(s);
181 /*************************************************************************/
184 * Various methods that determine how far the run extends for various
185 * attribute combinations.
188 public int getRunLimit()
190 return getRunLimit(getAllAttributeKeys());
193 public int getRunLimit(AttributedCharacterIterator.Attribute attrib)
195 HashSet s = new HashSet();
196 s.add(attrib);
197 return(getRunLimit(s));
200 public synchronized int getRunLimit(Set attributeSet)
202 if (attributeSet == null)
203 return ci.getEndIndex();
205 int current = ci.getIndex();
206 int end = ci.getEndIndex();
207 int limit = current;
208 if (current == end)
209 return end;
210 Map runValues = getAttributes();
211 while (limit < end)
213 Iterator iterator = attributeSet.iterator();
214 while (iterator.hasNext())
216 Attribute attributeKey = (Attribute) iterator.next();
217 Object v1 = runValues.get(attributeKey);
218 Object v2 = getAttribute(attributeKey, limit + 1);
219 boolean changed = false;
220 // check for equal or both null, if NO return start
221 if (v1 != null)
223 changed = !v1.equals(v2);
225 else
227 changed = (v2 != null);
229 if (changed)
230 return limit + 1;
232 // no differences, so increment limit and next and loop again
233 limit++;
235 return end;
238 /*************************************************************************/
241 * Various methods that determine where the run begins for various
242 * attribute combinations.
246 * Returns the index of the first character in the run containing the current
247 * character and defined by all the attributes defined for that character
248 * position.
250 * @return The run start index.
252 public int getRunStart()
254 return(getRunStart(getAttributes().keySet()));
258 * Returns the index of the first character in the run, defined by the
259 * specified attribute, that contains the current character.
261 * @param attrib the attribute (<code>null</code> permitted).
263 * return The index of the first character in the run.
265 public int getRunStart(AttributedCharacterIterator.Attribute attrib)
267 if (attrib == null)
268 return ci.getBeginIndex();
269 HashSet s = new HashSet();
270 s.add(attrib);
271 return(getRunStart(s));
275 * Returns the index of the first character in the run, defined by the
276 * specified attribute set, that contains the current character.
278 * @param attributeSet the attribute set (<code>null</code> permitted).
280 * return The index of the first character in the run.
282 public int getRunStart(Set attributeSet)
284 if (attributeSet == null)
285 return ci.getBeginIndex();
287 int current = ci.getIndex();
288 int begin = ci.getBeginIndex();
289 int start = current;
290 if (start == begin)
291 return begin;
292 Map runValues = getAttributes();
293 int prev = start - 1;
294 while (start > begin)
296 Iterator iterator = attributeSet.iterator();
297 while (iterator.hasNext())
299 Attribute attributeKey = (Attribute) iterator.next();
300 Object v1 = runValues.get(attributeKey);
301 Object v2 = getAttribute(attributeKey, prev);
302 boolean changed = false;
303 // check for equal or both null, if NO return start
304 if (v1 != null)
306 changed = !v1.equals(v2);
308 else
310 changed = (v2 != null);
312 if (changed)
313 return start;
315 // no differences, so decrement start and prev and loop again
316 start--;
317 prev--;
319 return start;
322 /*************************************************************************/
325 * Returns the value for an attribute at the specified position. If the
326 * attribute key (<code>key</code>) is <code>null</code>, the method returns
327 * <code>null</code>.
329 * @param key the key (<code>null</code> permitted).
330 * @param pos the character position.
332 * @return The attribute value (possibly <code>null</code>).
334 private Object getAttribute(AttributedCharacterIterator.Attribute key,
335 int pos)
337 if (attribs == null)
338 return null;
339 for (int i = attribs.length - 1; i >= 0; i--)
341 if (pos >= attribs[i].beginIndex && pos < attribs[i].endIndex)
343 Set keys = attribs[i].attribs.keySet();
344 if (keys.contains(key))
346 return attribs[i].attribs.get(key);
350 return null;
354 * Returns the value for an attribute at the current position. If the
355 * attribute key (<code>key</code>) is <code>null</code>, the method returns
356 * <code>null</code>.
358 * @param key the key (<code>null</code> permitted).
360 * @return The attribute value (possibly <code>null</code>).
362 public Object getAttribute(AttributedCharacterIterator.Attribute key)
364 return getAttribute(key, ci.getIndex());
367 /*************************************************************************/
370 * Return a list of all the attributes and values defined for this
371 * character
373 public Map getAttributes()
375 HashMap m = new HashMap();
376 if (attribs == null)
377 return(m);
379 for (int i = 0; i < attribs.length; i++)
381 if ((ci.getIndex() >= attribs[i].beginIndex) &&
382 (ci.getIndex() < attribs[i].endIndex))
383 m.putAll(attribs[i].attribs);
386 return(m);
389 } // class AttributedStringIterator