001/**
002 *  Licensed to the Apache Software Foundation (ASF) under one or more
003 *  contributor license agreements.  See the NOTICE file distributed with
004 *  this work for additional information regarding copyright ownership.
005 *  The ASF licenses this file to You under the Apache License, Version 2.0
006 *  (the "License"); you may not use this file except in compliance with
007 *  the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 *  Unless required by applicable law or agreed to in writing, software
012 *  distributed under the License is distributed on an "AS IS" BASIS,
013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 *  See the License for the specific language governing permissions and
015 *  limitations under the License.
016 */
017
018package org.apache.bcel.classfile;
019
020import java.io.DataInput;
021import java.io.DataOutputStream;
022import java.io.IOException;
023
024import org.apache.bcel.Const;
025
026// The new table is used when generic types are about...
027
028//LocalVariableTable_attribute {
029//       u2 attribute_name_index;
030//       u4 attribute_length;
031//       u2 local_variable_table_length;
032//       {  u2 start_pc;
033//          u2 length;
034//          u2 name_index;
035//          u2 descriptor_index;
036//          u2 index;
037//       } local_variable_table[local_variable_table_length];
038//     }
039
040//LocalVariableTypeTable_attribute {
041//    u2 attribute_name_index;
042//    u4 attribute_length;
043//    u2 local_variable_type_table_length;
044//    {
045//      u2 start_pc;
046//      u2 length;
047//      u2 name_index;
048//      u2 signature_index;
049//      u2 index;
050//    } localVariableTypeTable[local_variable_type_table_length];
051//  }
052// J5TODO: Needs some testing !
053
054/**
055 * @since 6.0
056 */
057public class LocalVariableTypeTable extends Attribute {
058
059    private LocalVariable[] localVariableTypeTable;        // variables
060
061    public LocalVariableTypeTable(final LocalVariableTypeTable c) {
062        this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), c.getConstantPool());
063    }
064
065    public LocalVariableTypeTable(final int name_index, final int length, final LocalVariable[] local_variable_table, final ConstantPool constant_pool) {
066        super(Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool);
067        this.localVariableTypeTable = local_variable_table;
068    }
069
070    LocalVariableTypeTable(final int nameIdx, final int len, final DataInput input, final ConstantPool cpool) throws IOException {
071        this(nameIdx, len, (LocalVariable[]) null, cpool);
072
073        final int local_variable_type_table_length = input.readUnsignedShort();
074        localVariableTypeTable = new LocalVariable[local_variable_type_table_length];
075
076        for (int i = 0; i < local_variable_type_table_length; i++) {
077            localVariableTypeTable[i] = new LocalVariable(input, cpool);
078        }
079    }
080
081    @Override
082    public void accept(final Visitor v) {
083        v.visitLocalVariableTypeTable(this);
084    }
085
086    @Override
087    public final void dump(final DataOutputStream file) throws IOException {
088        super.dump(file);
089        file.writeShort(localVariableTypeTable.length);
090        for (final LocalVariable variable : localVariableTypeTable) {
091            variable.dump(file);
092        }
093    }
094
095    public final LocalVariable[] getLocalVariableTypeTable() {
096        return localVariableTypeTable;
097    }
098
099    public final LocalVariable getLocalVariable(final int index) {
100        for (final LocalVariable variable : localVariableTypeTable) {
101            if (variable.getIndex() == index) {
102                return variable;
103            }
104        }
105
106        return null;
107    }
108
109    public final void setLocalVariableTable(final LocalVariable[] local_variable_table) {
110        this.localVariableTypeTable = local_variable_table;
111    }
112
113    /**
114     * @return String representation.
115     */
116    @Override
117    public final String toString() {
118        final StringBuilder buf = new StringBuilder();
119
120        for (int i = 0; i < localVariableTypeTable.length; i++) {
121            buf.append(localVariableTypeTable[i].toStringShared(true));
122
123            if (i < localVariableTypeTable.length - 1) {
124                buf.append('\n');
125            }
126        }
127
128        return buf.toString();
129    }
130
131    /**
132     * @return deep copy of this attribute
133     */
134    @Override
135    public Attribute copy(final ConstantPool constant_pool) {
136        final LocalVariableTypeTable c = (LocalVariableTypeTable) clone();
137
138        c.localVariableTypeTable = new LocalVariable[localVariableTypeTable.length];
139        for (int i = 0; i < localVariableTypeTable.length; i++) {
140            c.localVariableTypeTable[i] = localVariableTypeTable[i].copy();
141        }
142
143        c.setConstantPool(constant_pool);
144        return c;
145    }
146
147    public final int getTableLength() {
148        return localVariableTypeTable == null ? 0 : localVariableTypeTable.length;
149    }
150}