mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			390 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			390 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* 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
 |