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 final class LineNumberTable extends Attribute implements Iterable<LineNumber> {
37
38 private static final int MAX_LINE_LENGTH = 72;
39 private LineNumber[] lineNumberTable;
40
41
42
43
44
45
46
47
48
49
50 LineNumberTable(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException {
51 this(nameIndex, length, (LineNumber[]) null, constantPool);
52 final int lineNumberTableLength = input.readUnsignedShort();
53 lineNumberTable = new LineNumber[lineNumberTableLength];
54 for (int i = 0; i < lineNumberTableLength; i++) {
55 lineNumberTable[i] = new LineNumber(input);
56 }
57 }
58
59
60
61
62
63
64
65
66
67 public LineNumberTable(final int nameIndex, final int length, final LineNumber[] lineNumberTable, final ConstantPool constantPool) {
68 super(Const.ATTR_LINE_NUMBER_TABLE, nameIndex, length, constantPool);
69 this.lineNumberTable = lineNumberTable != null ? lineNumberTable : LineNumber.EMPTY_ARRAY;
70 Args.requireU2(this.lineNumberTable.length, "lineNumberTable.length");
71 }
72
73
74
75
76
77
78
79 public LineNumberTable(final LineNumberTable c) {
80 this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool());
81 }
82
83
84
85
86
87
88
89 @Override
90 public void accept(final Visitor v) {
91 v.visitLineNumberTable(this);
92 }
93
94
95
96
97 @Override
98 public Attribute copy(final ConstantPool constantPool) {
99
100
101 final LineNumberTable c = (LineNumberTable) clone();
102 c.lineNumberTable = new LineNumber[lineNumberTable.length];
103 Arrays.setAll(c.lineNumberTable, i -> lineNumberTable[i].copy());
104 c.setConstantPool(constantPool);
105 return c;
106 }
107
108
109
110
111
112
113
114 @Override
115 public void dump(final DataOutputStream file) throws IOException {
116 super.dump(file);
117 file.writeShort(lineNumberTable.length);
118 for (final LineNumber lineNumber : lineNumberTable) {
119 lineNumber.dump(file);
120 }
121 }
122
123
124
125
126 public LineNumber[] getLineNumberTable() {
127 return lineNumberTable;
128 }
129
130
131
132
133
134
135
136 public int getSourceLine(final int pos) {
137 int l = 0;
138 int r = lineNumberTable.length - 1;
139 if (r < 0) {
140 return -1;
141 }
142 int minIndex = -1;
143 int min = -1;
144
145
146
147 do {
148 final int i = l + r >>> 1;
149 final int j = lineNumberTable[i].getStartPC();
150 if (j == pos) {
151 return lineNumberTable[i].getLineNumber();
152 }
153 if (pos < j) {
154 r = i - 1;
155 } else {
156 l = i + 1;
157 }
158
159
160
161
162 if (j < pos && j > min) {
163 min = j;
164 minIndex = i;
165 }
166 } while (l <= r);
167
168
169
170 if (minIndex < 0) {
171 return -1;
172 }
173 return lineNumberTable[minIndex].getLineNumber();
174 }
175
176 public int getTableLength() {
177 return lineNumberTable.length;
178 }
179
180 @Override
181 public Iterator<LineNumber> iterator() {
182 return Stream.of(lineNumberTable).iterator();
183 }
184
185
186
187
188 public void setLineNumberTable(final LineNumber[] lineNumberTable) {
189 this.lineNumberTable = lineNumberTable != null ? lineNumberTable : LineNumber.EMPTY_ARRAY;
190 }
191
192
193
194
195 @Override
196 public String toString() {
197 final StringBuilder buf = new StringBuilder();
198 final StringBuilder line = new StringBuilder();
199 final String newLine = System.getProperty("line.separator", "\n");
200 for (int i = 0; i < lineNumberTable.length; i++) {
201 line.append(lineNumberTable[i].toString());
202 if (i < lineNumberTable.length - 1) {
203 line.append(", ");
204 }
205 if (line.length() > MAX_LINE_LENGTH && i < lineNumberTable.length - 1) {
206 line.append(newLine);
207 buf.append(line);
208 line.setLength(0);
209 }
210 }
211 buf.append(line);
212 return buf.toString();
213 }
214 }