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