1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.bcel.internal.classfile;
  23 
  24 
  25 import  com.sun.org.apache.bcel.internal.Constants;
  26 import  java.io.*;
  27 
  28 /**
  29  * This class represents colection of local variables in a
  30  * method. This attribute is contained in the <em>Code</em> attribute.
  31  *
  32  * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  33  * @see     Code
  34  * @see LocalVariable
  35  */
  36 public class LocalVariableTable extends Attribute {
  37   private int             local_variable_table_length; // Table of local
  38   private LocalVariable[] local_variable_table;        // variables
  39 
  40   /**
  41    * Initialize from another object. Note that both objects use the same
  42    * references (shallow copy). Use copy() for a physical copy.
  43    */
  44   public LocalVariableTable(LocalVariableTable c) {
  45     this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(),
  46          c.getConstantPool());
  47   }
  48 
  49   /**
  50    * @param name_index Index in constant pool to `LocalVariableTable'
  51    * @param length Content length in bytes
  52    * @param local_variable_table Table of local variables
  53    * @param constant_pool Array of constants
  54    */
  55   public LocalVariableTable(int name_index, int length,
  56                             LocalVariable[] local_variable_table,
  57                             ConstantPool    constant_pool)
  58   {
  59     super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool);
  60     setLocalVariableTable(local_variable_table);
  61   }
  62 
  63   /**
  64    * Construct object from file stream.
  65    * @param name_index Index in constant pool
  66    * @param length Content length in bytes
  67    * @param file Input stream
  68    * @param constant_pool Array of constants
  69    * @throws IOException
  70    */
  71   LocalVariableTable(int name_index, int length, DataInputStream file,
  72                      ConstantPool constant_pool) throws IOException
  73   {
  74     this(name_index, length, (LocalVariable[])null, constant_pool);
  75 
  76     local_variable_table_length = (file.readUnsignedShort());
  77     local_variable_table = new LocalVariable[local_variable_table_length];
  78 
  79     for(int i=0; i < local_variable_table_length; i++)
  80       local_variable_table[i] = new LocalVariable(file, constant_pool);
  81   }
  82 
  83   /**
  84    * Called by objects that are traversing the nodes of the tree implicitely
  85    * defined by the contents of a Java class. I.e., the hierarchy of methods,
  86    * fields, attributes, etc. spawns a tree of objects.
  87    *
  88    * @param v Visitor object
  89    */
  90   public void accept(Visitor v) {
  91     v.visitLocalVariableTable(this);
  92   }
  93 
  94   /**
  95    * Dump local variable table attribute to file stream in binary format.
  96    *
  97    * @param file Output file stream
  98    * @throws IOException
  99    */
 100   public final void dump(DataOutputStream file) throws IOException
 101   {
 102     super.dump(file);
 103     file.writeShort(local_variable_table_length);
 104     for(int i=0; i < local_variable_table_length; i++)
 105       local_variable_table[i].dump(file);
 106   }
 107 
 108   /**
 109    * @return Array of local variables of method.
 110    */
 111   public final LocalVariable[] getLocalVariableTable() {
 112     return local_variable_table;
 113   }
 114 
 115   /** @return first matching variable using index
 116    */
 117   public final LocalVariable getLocalVariable(int index) {
 118     for(int i=0; i < local_variable_table_length; i++)
 119       if(local_variable_table[i].getIndex() == index)
 120         return local_variable_table[i];
 121 
 122     return null;
 123   }
 124 
 125   public final void setLocalVariableTable(LocalVariable[] local_variable_table)
 126   {
 127     this.local_variable_table = local_variable_table;
 128     local_variable_table_length = (local_variable_table == null)? 0 :
 129       local_variable_table.length;
 130   }
 131 
 132   /**
 133    * @return String representation.
 134    */
 135   public final String toString() {
 136     StringBuffer buf = new StringBuffer("");
 137 
 138     for(int i=0; i < local_variable_table_length; i++) {
 139       buf.append(local_variable_table[i].toString());
 140 
 141       if(i < local_variable_table_length - 1)
 142         buf.append('\n');
 143     }
 144 
 145     return buf.toString();
 146   }
 147 
 148   /**
 149    * @return deep copy of this attribute
 150    */
 151   public Attribute copy(ConstantPool constant_pool) {
 152     LocalVariableTable c = (LocalVariableTable)clone();
 153 
 154     c.local_variable_table = new LocalVariable[local_variable_table_length];
 155     for(int i=0; i < local_variable_table_length; i++)
 156       c.local_variable_table[i] = local_variable_table[i].copy();
 157 
 158     c.constant_pool = constant_pool;
 159     return c;
 160   }
 161 
 162   public final int getTableLength() { return local_variable_table_length; }
 163 }