Home | History | Annotate | Download | only in attribute
      1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
      2  *
      3  * This program and the accompanying materials are made available under
      4  * the terms of the Common Public License v1.0 which accompanies this distribution,
      5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
      6  *
      7  * $Id: InnerClassesAttribute_info.java,v 1.1.1.1 2004/05/09 16:57:48 vlad_r Exp $
      8  */
      9 package com.vladium.jcd.cls.attribute;
     10 
     11 import java.io.IOException;
     12 import java.util.ArrayList;
     13 import java.util.List;
     14 
     15 import com.vladium.jcd.lib.UDataInputStream;
     16 import com.vladium.jcd.lib.UDataOutputStream;
     17 
     18 // ----------------------------------------------------------------------------
     19 /**
     20  * @author Vlad Roubtsov, (C) 2003
     21  */
     22 public
     23 final class InnerClassesAttribute_info extends Attribute_info
     24 {
     25     // public: ................................................................
     26 
     27     // ACCESSORS:
     28 
     29     public boolean makesClassNested (final int class_index, final int [] nestedAccessFlags)
     30     {
     31         if (class_index > 0)
     32         {
     33             // TODO: avoid linear loop by keeping all class indices in a bitset
     34 
     35             for (int i = 0, iLimit = size (); i < iLimit; ++ i)
     36             {
     37                 final InnerClass_info info = get (i);
     38 
     39                 if (info.m_inner_class_index == class_index)
     40                 {
     41                     nestedAccessFlags [0] = info.m_inner_access_flags;
     42                     return true;
     43                 }
     44             }
     45         }
     46 
     47         return false;
     48     }
     49 
     50     /**
     51      * Returns {@link InnerClass_info} descriptor at a given offset.
     52      *
     53      * @param offset inner class entry offset [must be in [0, size()) range;
     54      * input not checked]
     55      * @return InnerClass_info descriptor [never null]
     56      *
     57      * @throws IndexOutOfBoundsException if 'offset' is outside of valid range
     58      */
     59     public final InnerClass_info get (final int offset)
     60     {
     61         return (InnerClass_info) m_classes.get (offset);
     62     }
     63 
     64     /**
     65      * Returns the number of descriptors in this collection [can be 0].
     66      */
     67     public final int size ()
     68     {
     69         return m_classes.size ();
     70     }
     71 
     72     public final long length ()
     73     {
     74         return 8 + (m_classes.size () << 3); // use size() if class becomes non-final
     75     }
     76 
     77     // Visitor:
     78 
     79     public void accept (final IAttributeVisitor visitor, final Object ctx)
     80     {
     81         visitor.visit (this, ctx);
     82     }
     83 
     84     public String toString ()
     85     {
     86         final StringBuffer s = new StringBuffer ("InnerClassesAttribute_info: [attribute_name_index = " + m_name_index + ", attribute_length = " + length () + "]\n");
     87 
     88         for (int l = 0; l < size (); ++ l)
     89         {
     90             s.append ("            " + get (l));
     91             s.append ("\n"); // TODO: proper EOL const
     92         }
     93 
     94         return s.toString ();
     95     }
     96 
     97     // Cloneable:
     98 
     99     /**
    100      * Performs a deep copy.
    101      */
    102     public Object clone ()
    103     {
    104         final InnerClassesAttribute_info _clone = (InnerClassesAttribute_info) super.clone ();
    105 
    106         final List/* InnerClass_info */ classes = m_classes;
    107 
    108         // do deep copy:
    109         final int class_count = classes.size (); // use size() if class becomes non-final
    110         _clone.m_classes = new ArrayList (class_count);
    111         for (int e = 0; e < class_count; ++ e)
    112         {
    113             _clone.m_classes.add (((InnerClass_info) classes.get (e)).clone ());
    114         }
    115 
    116         return _clone;
    117     }
    118 
    119     // IClassFormatOutput:
    120 
    121     public void writeInClassFormat (final UDataOutputStream out) throws IOException
    122     {
    123         super.writeInClassFormat (out);
    124 
    125         final List/* InnerClass_info */ classes = m_classes;
    126 
    127         final int class_count = classes.size (); // use size() if class becomes non-final
    128         out.writeU2 (class_count);
    129 
    130         for (int l = 0; l < class_count; ++ l)
    131         {
    132             ((InnerClass_info) classes.get (l)).writeInClassFormat (out);
    133         }
    134     }
    135 
    136     // protected: .............................................................
    137 
    138     // package: ...............................................................
    139 
    140 
    141     InnerClassesAttribute_info (final int attribute_name_index, final long attribute_length,
    142                                 final UDataInputStream bytes)
    143         throws IOException
    144     {
    145         super (attribute_name_index, attribute_length);
    146 
    147         final int class_count = bytes.readU2 ();
    148         final List/* InnerClass_info */ classes = new ArrayList (class_count);
    149 
    150         for (int i = 0; i < class_count; ++ i)
    151         {
    152             classes.add (new InnerClass_info (bytes));
    153         }
    154 
    155         m_classes = classes;
    156     }
    157 
    158     // private: ...............................................................
    159 
    160 
    161     private List/* InnerClass_info */ m_classes; // never null
    162 
    163 } // end of class
    164 // ----------------------------------------------------------------------------