FileDocCategorySizeDatePackage
ConstantCollection.javaAPI DocAndroid 1.5 API10100Wed May 06 22:41:16 BST 2009com.vladium.jcd.cls

ConstantCollection

public final class ConstantCollection extends Object implements IConstantCollection
author
(C) 2001, Vladimir Roubtsov

Fields Summary
private List
m_constants
private int
m_size
private transient com.vladium.util.ObjectIntMap
m_CONSTANT_Utf8_index
Constructors Summary
ConstantCollection(int capacity)

        m_constants = capacity < 0 ? new ArrayList () : new ArrayList (capacity);
    
Methods Summary
public voidaccept(IClassDefVisitor visitor, java.lang.Object ctx)

        visitor.visit (this, ctx);
    
public intadd(CONSTANT_info constant)

        m_constants.add (constant);
        ++ m_size; 
        final int result = m_constants.size ();
        
        for (int width = 1; width < constant.width (); ++ width)
        {
            ++ m_size;
            m_constants.add (null); // insert padding empty slots            
        }
        
        // update the string index if it is in use:
        if ((m_CONSTANT_Utf8_index != null) && (constant instanceof CONSTANT_Utf8_info))
            m_CONSTANT_Utf8_index.put (((CONSTANT_Utf8_info) constant).m_value, result /* !!! */ - 1);
        
        return result;
    
public java.lang.Objectclone()
Performs a deep copy.

        try
        {
            final ConstantCollection _clone = (ConstantCollection) super.clone ();
            
            // deep copy:
            final int constants_count = m_constants.size ();
            _clone.m_constants = new ArrayList (constants_count);
            for (int c = 0; c < constants_count; ++ c)
            {
                final CONSTANT_info constant = (CONSTANT_info) m_constants.get (c);
                _clone.m_constants.add (constant == null ? null : constant.clone ());
            }
            
            // note: m_CONSTANT_Utf8_index is not cloned intentionally
            
            return _clone;
        }
        catch (CloneNotSupportedException e)
        {
            throw new InternalError (e.toString ());
        }        
    
public intfind(int type, IConstantComparator comparator)

        if (comparator == null)
            throw new IllegalArgumentException ("null input: comparator");
        
        for (int i = 0; i < m_constants.size (); ++ i)
        {
            final CONSTANT_info constant = (CONSTANT_info) m_constants.get (i);
            
            if ((constant != null) && (constant.tag () == type) && comparator.equals (constant))
                return i /* !!! */ + 1; 
        }
        
        return -1;
    
public intfindCONSTANT_Utf8(java.lang.String value)

        if (value == null)
            throw new IllegalArgumentException ("null input: value");
        
        // create index lazily:
        final ObjectIntMap index = getCONSTANT_Utf8_index ();
        final int [] result = new int [1];
        
        if (index.get (value, result))
            return result [0] /* !!! */ + 1;
        else
            return -1;
    
public CONSTANT_infoget(int index)

        final Object result = m_constants.get (index - 1);
        
        if (result == null)
            throw new IllegalStateException ("assertion failure: dereferencing an invalid constant pool slot " + index);
        
        return (CONSTANT_info) result;
    
private com.vladium.util.ObjectIntMapgetCONSTANT_Utf8_index()

        if (m_CONSTANT_Utf8_index == null)
        {
            final ObjectIntMap index = new ObjectIntMap (m_size);
            
            for (int i = 0; i < m_constants.size (); ++ i)
            {
                final CONSTANT_info constant = (CONSTANT_info) m_constants.get (i);
                
                if ((constant != null) && (constant.tag () == CONSTANT_Utf8_info.TAG))
                {
                    // it's ok to always put: the later indices will simply override the earlier ones
                    index.put (((CONSTANT_Utf8_info) constant).m_value, i); // note: unadjusted index saved here
                }
            }
            
            m_CONSTANT_Utf8_index = index;
        }
        
        return m_CONSTANT_Utf8_index;
    
public IConstantCollection.IConstantIteratoriterator()

        return new ConstantIterator (m_constants);
    
public CONSTANT_infoset(int index, CONSTANT_info constant)

        final int zindex = index - 1;
        final CONSTANT_info result = (CONSTANT_info) m_constants.get (zindex);
        
        if (result == null)
            throw new IllegalStateException ("assertion failure: dereferencing an invalid constant pool slot " + index);
            
        if (result.width () != constant.width ())
            throw new IllegalArgumentException ("assertion failure: can't set entry of type [" + result.getClass ().getName () + "] to an entry of type [" + result.getClass ().getName () + "] at pool slot " + index);
        
        m_constants.set (zindex, constant);
        
        // update the string index if it is in use:
        if (m_CONSTANT_Utf8_index != null)
        {
            // remove the old index value if it exists and is equal to 'index':
            if (result instanceof CONSTANT_Utf8_info)
            {
                final String mapKey = ((CONSTANT_Utf8_info) result).m_value;
                final int [] out = new int [1];
        
                if (m_CONSTANT_Utf8_index.get (mapKey, out) && (out [0] == zindex))
                    m_CONSTANT_Utf8_index.remove (mapKey);
            }
            
            // add new index value if necessary:
            if (constant instanceof CONSTANT_Utf8_info)
                m_CONSTANT_Utf8_index.put (((CONSTANT_Utf8_info) constant).m_value, zindex);
        }
        
        return result;
    
public intsize()

        return m_size;
    
public voidwriteInClassFormat(com.vladium.jcd.lib.UDataOutputStream out)

        final int constant_pool_count = m_constants.size (); // note: this is not the same as size()
        out.writeU2 (constant_pool_count + /* !!! */1);
        
        final ConstantIterator i = new ConstantIterator (m_constants);
        for (CONSTANT_info entry; (entry = i.nextConstant ()) != null; )
        {
            entry.writeInClassFormat (out);
        }