1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.classfile;
18
19 import java.io.DataInput;
20 import java.io.DataOutputStream;
21 import java.io.IOException;
22 import java.util.Arrays;
23 import java.util.Iterator;
24 import java.util.stream.Stream;
25
26 import org.apache.bcel.Const;
27 import org.apache.bcel.util.Args;
28
29
30
31
32
33
34
35
36 public class LocalVariableTable extends Attribute implements Iterable<LocalVariable> {
37
38 private static final LocalVariable[] EMPTY_ARRAY = {};
39
40 private LocalVariable[] localVariableTable;
41
42
43
44
45
46
47
48
49
50
51 LocalVariableTable(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException {
52 this(nameIndex, length, (LocalVariable[]) null, constantPool);
53 final int localVariableTableLength = input.readUnsignedShort();
54 localVariableTable = new LocalVariable[localVariableTableLength];
55 for (int i = 0; i < localVariableTableLength; i++) {
56 localVariableTable[i] = new LocalVariable(input, constantPool);
57 }
58 }
59
60
61
62
63
64
65
66 public LocalVariableTable(final int nameIndex, final int length, final LocalVariable[] localVariableTable, final ConstantPool constantPool) {
67 super(Const.ATTR_LOCAL_VARIABLE_TABLE, nameIndex, length, constantPool);
68 this.localVariableTable = localVariableTable != null ? localVariableTable : EMPTY_ARRAY;
69 Args.requireU2(this.localVariableTable.length, "localVariableTable.length");
70 }
71
72
73
74
75
76
77
78 public LocalVariableTable(final LocalVariableTable c) {
79 this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool());
80 }
81
82
83
84
85
86
87
88 @Override
89 public void accept(final Visitor v) {
90 v.visitLocalVariableTable(this);
91 }
92
93
94
95
96 @Override
97 public Attribute copy(final ConstantPool constantPool) {
98 final LocalVariableTable c = (LocalVariableTable) clone();
99 c.localVariableTable = new LocalVariable[localVariableTable.length];
100 Arrays.setAll(c.localVariableTable, i -> localVariableTable[i].copy());
101 c.setConstantPool(constantPool);
102 return c;
103 }
104
105
106
107
108
109
110
111 @Override
112 public final void dump(final DataOutputStream file) throws IOException {
113 super.dump(file);
114 file.writeShort(localVariableTable.length);
115 for (final LocalVariable variable : localVariableTable) {
116 variable.dump(file);
117 }
118 }
119
120
121
122
123
124
125
126
127
128
129 @java.lang.Deprecated
130 public final LocalVariable getLocalVariable(final int index) {
131 for (final LocalVariable variable : localVariableTable) {
132 if (variable.getIndex() == index) {
133 return variable;
134 }
135 }
136 return null;
137 }
138
139
140
141
142
143
144
145
146 public final LocalVariable getLocalVariable(final int index, final int pc) {
147 for (final LocalVariable variable : localVariableTable) {
148 if (variable.getIndex() == index) {
149 final int startPc = variable.getStartPC();
150 final int endPc = startPc + variable.getLength();
151 if (pc >= startPc && pc <= endPc) {
152 return variable;
153 }
154 }
155 }
156 return null;
157 }
158
159
160
161
162 public final LocalVariable[] getLocalVariableTable() {
163 return localVariableTable;
164 }
165
166 public final int getTableLength() {
167 return localVariableTable.length;
168 }
169
170 @Override
171 public Iterator<LocalVariable> iterator() {
172 return Stream.of(localVariableTable).iterator();
173 }
174
175 public final void setLocalVariableTable(final LocalVariable[] localVariableTable) {
176 this.localVariableTable = localVariableTable != null ? localVariableTable : EMPTY_ARRAY;
177 }
178
179
180
181
182 @Override
183 public final String toString() {
184 final StringBuilder buf = new StringBuilder();
185 for (int i = 0; i < localVariableTable.length; i++) {
186 buf.append(localVariableTable[i]);
187 if (i < localVariableTable.length - 1) {
188 buf.append('\n');
189 }
190 }
191 return buf.toString();
192 }
193 }