sboag       00/02/17 07:44:31

  Added:       src/org/apache/xalan/xpath/xml MutableAttrListImpl.java
  Log:
  Faster attribute list implemenation.
  
  Revision  Changes    Path
  1.1                  
xml-xalan/src/org/apache/xalan/xpath/xml/MutableAttrListImpl.java
  
  Index: MutableAttrListImpl.java
  ===================================================================
  package org.apache.xalan.xpath.xml;
  
  import org.apache.xalan.xpath.xml.StringVector;
  import org.xml.sax.AttributeList;
  import java.io.Serializable;
  
  public class MutableAttrListImpl extends StringVector implements 
AttributeList, Serializable
  {
  static final int OFFSET_NAME = 0;
  static final int OFFSET_TYPE = 1;
  static final int OFFSET_VALUE = 2;
  static final int SLOTS_PER_ATTR = 3;
  
    /**
     * Create an empty attribute list.
     *
     * <p>This constructor is most useful for parser writers, who
     * will use it to create a single, reusable attribute list that
     * can be reset with the clear method between elements.</p>
     *
     * @see #addAttribute
     * @see #clear
     */
    public MutableAttrListImpl ()
    {
    }
    
    
    /**
     * Construct a persistent copy of an existing attribute list.
     *
     * <p>This constructor is most useful for application writers,
     * who will use it to create a persistent copy of an existing
     * attribute list.</p>
     *
     * @param atts The attribute list to copy
     * @see org.xml.sax.DocumentHandler#startElement
     */
    public MutableAttrListImpl (AttributeList atts)
    {
      setAttributeList(atts);
    }
    
    
    
    ////////////////////////////////////////////////////////////////////
    // Methods specific to this class.
    ////////////////////////////////////////////////////////////////////
    
    
    /**
     * Set the attribute list, discarding previous contents.
     *
     * <p>This method allows an application writer to reuse an
     * attribute list easily.</p>
     *
     * @param atts The attribute list to copy.
     */
    public void setAttributeList (AttributeList atts)
    {
      int count = atts.getLength();
      
      clear();
      
      for (int i = 0; i < count; i++) 
      {
        addAttribute(atts.getName(i), atts.getType(i), atts.getValue(i));
      }
    }
    
    
    /**
     * Add an attribute to an attribute list.
     *
     * <p>This method is provided for SAX parser writers, to allow them
     * to build up an attribute list incrementally before delivering
     * it to the application.</p>
     *
     * @param name The attribute name.
     * @param type The attribute type ("NMTOKEN" for an enumeration).
     * @param value The attribute value (must not be null).
     * @see #removeAttribute
     * @see org.xml.sax.DocumentHandler#startElement
     */
    public void addAttribute (String name, String type, String value)
    {
      // removeAttribute (name); // I think this is correct, but I don't think 
I need it
      
    if((m_firstFree+SLOTS_PER_ATTR) >= m_mapSize)
      {
        m_mapSize+=m_blocksize;
        String newMap[] = new String[m_mapSize];
        System.arraycopy(m_map, 0, newMap, 0, m_firstFree+1);
        m_map = newMap;
      }
  
      m_map[m_firstFree+OFFSET_NAME] = name;
      m_map[m_firstFree+OFFSET_TYPE] = type;
      m_map[m_firstFree+OFFSET_VALUE] = value;
      m_firstFree+=SLOTS_PER_ATTR;
    }
    
    
    /**
     * Remove an attribute from the list.
     *
     * <p>SAX application writers can use this method to filter an
     * attribute out of an AttributeList.  Note that invoking this
     * method will change the length of the attribute list and
     * some of the attribute's indices.</p>
     *
     * <p>If the requested attribute is not in the list, this is
     * a no-op.</p>
     *
     * @param name The attribute name.
     * @see #addAttribute
     */
    public void removeAttribute (String name)
    {
      for(int i = 0; i < m_firstFree; i++)
      {
        if(m_map[i+OFFSET_NAME].equals(name))
        {
          if(i > m_firstFree)
            System.arraycopy(m_map, i+SLOTS_PER_ATTR, m_map, i-SLOTS_PER_ATTR, 
m_firstFree-i);
          else
          {
            m_map[i+OFFSET_NAME] = null;
            m_map[i+OFFSET_TYPE] = null;
            m_map[i+OFFSET_VALUE] = null;
          }
          m_firstFree-=SLOTS_PER_ATTR;
          return;
        }
      }
    }
    
    
    /**
     * Clear the attribute list.
     *
     * <p>SAX parser writers can use this method to reset the attribute
     * list between DocumentHandler.startElement events.  Normally,
     * it will make sense to reuse the same MutableAttrListImpl object
     * rather than allocating a new one each time.</p>
     *
     * @see org.xml.sax.DocumentHandler#startElement
     */
    public void clear ()
    {
    for(int i = 0; i < m_firstFree; i++)
    {
        m_map[i] = null;
    }
      m_firstFree = 0; 
    }
    
    ////////////////////////////////////////////////////////////////////
    // Implementation of org.xml.sax.AttributeList
    ////////////////////////////////////////////////////////////////////
    
    
    /**
     * Return the number of attributes in the list.
     *
     * @return The number of attributes in the list.
     * @see org.xml.sax.AttributeList#getLength
     */
    public int getLength ()
    {
      return (m_firstFree > 0) ? (m_firstFree/SLOTS_PER_ATTR) : 0;
    }
    
    
    /**
     * Get the name of an attribute (by position).
     *
     * @param i The position of the attribute in the list.
     * @return The attribute name as a string, or null if there
     *         is no attribute at that position.
     * @see org.xml.sax.AttributeList#getName(int)
     */
    public String getName (int i)
    {
      if (i < 0) 
      {
        return null;
      }
      try 
      {
        return m_map[(i*SLOTS_PER_ATTR)+OFFSET_NAME];
      }
      catch (ArrayIndexOutOfBoundsException e) 
      {
        return null;
      }
    }
    
    
    /**
     * Get the type of an attribute (by position).
     *
     * @param i The position of the attribute in the list.
     * @return The attribute type as a string ("NMTOKEN" for an
     *         enumeration, and "CDATA" if no declaration was
     *         read), or null if there is no attribute at
     *         that position.
     * @see org.xml.sax.AttributeList#getType(int)
     */
    public String getType (int i)
    {
      if (i < 0) 
      {
        return null;
      }
      try 
      {
        return m_map[(i*SLOTS_PER_ATTR)+OFFSET_TYPE];
      }
      catch (ArrayIndexOutOfBoundsException e) 
      {
        return null;
      }
    }
    
    
    /**
     * Get the value of an attribute (by position).
     *
     * @param i The position of the attribute in the list.
     * @return The attribute value as a string, or null if
     *         there is no attribute at that position.
     * @see org.xml.sax.AttributeList#getValue(int)
     */
    public String getValue (int i)
    {
      if (i < 0) 
      {
        return null;
      }
      try 
      {
        return m_map[(i*SLOTS_PER_ATTR)+OFFSET_VALUE];
      }
      catch (ArrayIndexOutOfBoundsException e) 
      {
        return null;
      }
    }
    
    
    /**
     * Get the type of an attribute (by name).
     *
     * @param name The attribute name.
     * @return The attribute type as a string ("NMTOKEN" for an
     *         enumeration, and "CDATA" if no declaration was
     *         read).
     * @see org.xml.sax.AttributeList#getType(java.lang.String)
     */
    public String getType (String name)
    {
      for(int i = 0; i <= m_firstFree; i++)
    {
        if(m_map[i+OFFSET_NAME].equals(name))
        {
          return m_map[i+OFFSET_TYPE];
        }
    }
    return "CDATA";
    }
    
    
    /**
     * Get the value of an attribute (by name).
     *
     * @param name The attribute name.
     * @see org.xml.sax.AttributeList#getValue(java.lang.String)
     */
    public String getValue (String name)
    {
      for(int i = 0; i <= m_firstFree; i++)
    {
        if(m_map[i+OFFSET_NAME].equals(name))
        {
          return m_map[i+OFFSET_NAME];
        }
    }
    return null;
    }
  
}
  
  // end of MutableAttrListImpl.java
  
  
  

Reply via email to