diff options
Diffstat (limited to 'libjava/classpath/java/text/AttributedStringIterator.java')
-rw-r--r-- | libjava/classpath/java/text/AttributedStringIterator.java | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/libjava/classpath/java/text/AttributedStringIterator.java b/libjava/classpath/java/text/AttributedStringIterator.java new file mode 100644 index 000000000..429bd7063 --- /dev/null +++ b/libjava/classpath/java/text/AttributedStringIterator.java @@ -0,0 +1,389 @@ +/* AttributedStringIterator.java -- Class to iterate over AttributedString + Copyright (C) 1998, 1999, 2004, 2005, 2006, Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.text; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * This class implements the AttributedCharacterIterator interface. It + * is used by AttributedString.getIterator(). + * + * @version 0.0 + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +class AttributedStringIterator implements AttributedCharacterIterator +{ + + /*************************************************************************/ + + /** The character iterator containing the text */ + private CharacterIterator ci; + + /** The list of attributes and ranges */ + private AttributedString.AttributeRange[] attribs; + + /** + * The list of attributes that the user is interested in. We may, + * at our option, not return any other attributes. + */ + private AttributedCharacterIterator.Attribute[] restricts; + + /*************************************************************************/ + + /** + * Creates a new instance. + * + * @param sci an iterator for the string content. + * @param attribs the attribute ranges. + * @param beginIndex the start index. + * @param endIndex the end index. + * @param restricts the attributes that the user is interested in. + */ + AttributedStringIterator(StringCharacterIterator sci, + AttributedString.AttributeRange[] attribs, + int beginIndex, int endIndex, + AttributedCharacterIterator.Attribute[] restricts) + { + this.ci = new StringCharacterIterator(sci, beginIndex, endIndex); + this.attribs = attribs; + this.restricts = restricts; + } + + /*************************************************************************/ + + // First we have a bunch of stupid redirects. If StringCharacterIterator + // weren't final, I just would have extended that for this class. Alas, no. + + public Object clone() + { + return(ci.clone()); + } + + public char current() + { + return(ci.current()); + } + + public char next() + { + return(ci.next()); + } + + public char previous() + { + return(ci.previous()); + } + + public char first() + { + return(ci.first()); + } + + public char last() + { + return(ci.last()); + } + + public int getIndex() + { + return(ci.getIndex()); + } + + public char setIndex(int index) + { + return(ci.setIndex(index)); + } + + public int getBeginIndex() + { + return(ci.getBeginIndex()); + } + + public int getEndIndex() + { + return(ci.getEndIndex()); + } + + /* + * Here is where the AttributedCharacterIterator methods start. + */ + + /*************************************************************************/ + + /** + * Returns a list of all the attribute keys that are defined anywhere + * on this string. + */ + public Set getAllAttributeKeys() + { + HashSet s = new HashSet(); + if (attribs == null) + return(s); + + for (int i = 0; i < attribs.length; i++) + { + if (attribs[i].beginIndex > getEndIndex() + || attribs[i].endIndex <= getBeginIndex()) + continue; + + Set key_set = attribs[i].attribs.keySet(); + Iterator iter = key_set.iterator(); + while (iter.hasNext()) + { + s.add(iter.next()); + } + } + + return(s); + } + + /*************************************************************************/ + + /** + * Various methods that determine how far the run extends for various + * attribute combinations. + */ + + public int getRunLimit() + { + return getRunLimit(getAllAttributeKeys()); + } + + public int getRunLimit(AttributedCharacterIterator.Attribute attrib) + { + HashSet s = new HashSet(); + s.add(attrib); + return(getRunLimit(s)); + } + + public synchronized int getRunLimit(Set attributeSet) + { + if (attributeSet == null) + return ci.getEndIndex(); + + int current = ci.getIndex(); + int end = ci.getEndIndex(); + int limit = current; + if (current == end) + return end; + Map runValues = getAttributes(); + while (limit < end) + { + Iterator iterator = attributeSet.iterator(); + while (iterator.hasNext()) + { + Attribute attributeKey = (Attribute) iterator.next(); + Object v1 = runValues.get(attributeKey); + Object v2 = getAttribute(attributeKey, limit + 1); + boolean changed = false; + // check for equal or both null, if NO return start + if (v1 != null) + { + changed = !v1.equals(v2); + } + else + { + changed = (v2 != null); + } + if (changed) + return limit + 1; + } + // no differences, so increment limit and next and loop again + limit++; + } + return end; + } + + /*************************************************************************/ + + /** + * Various methods that determine where the run begins for various + * attribute combinations. + */ + + /** + * Returns the index of the first character in the run containing the current + * character and defined by all the attributes defined for that character + * position. + * + * @return The run start index. + */ + public int getRunStart() + { + return(getRunStart(getAttributes().keySet())); + } + + /** + * Returns the index of the first character in the run, defined by the + * specified attribute, that contains the current character. + * + * @param attrib the attribute (<code>null</code> permitted). + * + * return The index of the first character in the run. + */ + public int getRunStart(AttributedCharacterIterator.Attribute attrib) + { + if (attrib == null) + return ci.getBeginIndex(); + HashSet s = new HashSet(); + s.add(attrib); + return(getRunStart(s)); + } + + /** + * Returns the index of the first character in the run, defined by the + * specified attribute set, that contains the current character. + * + * @param attributeSet the attribute set (<code>null</code> permitted). + * + * return The index of the first character in the run. + */ + public int getRunStart(Set attributeSet) + { + if (attributeSet == null) + return ci.getBeginIndex(); + + int current = ci.getIndex(); + int begin = ci.getBeginIndex(); + int start = current; + if (start == begin) + return begin; + Map runValues = getAttributes(); + int prev = start - 1; + while (start > begin) + { + Iterator iterator = attributeSet.iterator(); + while (iterator.hasNext()) + { + Attribute attributeKey = (Attribute) iterator.next(); + Object v1 = runValues.get(attributeKey); + Object v2 = getAttribute(attributeKey, prev); + boolean changed = false; + // check for equal or both null, if NO return start + if (v1 != null) + { + changed = !v1.equals(v2); + } + else + { + changed = (v2 != null); + } + if (changed) + return start; + } + // no differences, so decrement start and prev and loop again + start--; + prev--; + } + return start; + } + + /*************************************************************************/ + + /** + * Returns the value for an attribute at the specified position. If the + * attribute key (<code>key</code>) is <code>null</code>, the method returns + * <code>null</code>. + * + * @param key the key (<code>null</code> permitted). + * @param pos the character position. + * + * @return The attribute value (possibly <code>null</code>). + */ + private Object getAttribute(AttributedCharacterIterator.Attribute key, + int pos) + { + if (attribs == null) + return null; + for (int i = attribs.length - 1; i >= 0; i--) + { + if (pos >= attribs[i].beginIndex && pos < attribs[i].endIndex) + { + Set keys = attribs[i].attribs.keySet(); + if (keys.contains(key)) + { + return attribs[i].attribs.get(key); + } + } + } + return null; + } + + /** + * Returns the value for an attribute at the current position. If the + * attribute key (<code>key</code>) is <code>null</code>, the method returns + * <code>null</code>. + * + * @param key the key (<code>null</code> permitted). + * + * @return The attribute value (possibly <code>null</code>). + */ + public Object getAttribute(AttributedCharacterIterator.Attribute key) + { + return getAttribute(key, ci.getIndex()); + } + + /*************************************************************************/ + + /** + * Return a list of all the attributes and values defined for this + * character + */ + public Map getAttributes() + { + HashMap m = new HashMap(); + if (attribs == null) + return(m); + + for (int i = 0; i < attribs.length; i++) + { + if ((ci.getIndex() >= attribs[i].beginIndex) && + (ci.getIndex() < attribs[i].endIndex)) + m.putAll(attribs[i].attribs); + } + + return(m); + } + +} // class AttributedStringIterator |