1 package org.apache.bcel.classfile;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache BCEL" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache BCEL", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import org.apache.bcel.Constants;
58 import java.io.*;
59
60 /***
61 * This class represents a table of line numbers for debugging
62 * purposes. This attribute is used by the <em>Code</em> attribute. It
63 * contains pairs of PCs and line numbers.
64 *
65 * @version $Id: LineNumberTable.java,v 1.3 2002/12/08 16:04:37 mdahm Exp $
66 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
67 * @see Code
68 * @see LineNumber
69 */
70 public final class LineNumberTable extends Attribute {
71 private int line_number_table_length;
72 private LineNumber[] line_number_table; // Table of line/numbers pairs
73
74 /*
75 * Initialize from another object. Note that both objects use the same
76 * references (shallow copy). Use copy() for a physical copy.
77 */
78 public LineNumberTable(LineNumberTable c) {
79 this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(),
80 c.getConstantPool());
81 }
82
83 /*
84 * @param name_index Index of name
85 * @param length Content length in bytes
86 * @param line_number_table Table of line/numbers pairs
87 * @param constant_pool Array of constants
88 */
89 public LineNumberTable(int name_index, int length,
90 LineNumber[] line_number_table,
91 ConstantPool constant_pool)
92 {
93 super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool);
94 setLineNumberTable(line_number_table);
95 }
96
97 /***
98 * Construct object from file stream.
99 * @param name_index Index of name
100 * @param length Content length in bytes
101 * @param file Input stream
102 * @throws IOException
103 * @param constant_pool Array of constants
104 */
105 LineNumberTable(int name_index, int length, DataInputStream file,
106 ConstantPool constant_pool) throws IOException
107 {
108 this(name_index, length, (LineNumber[])null, constant_pool);
109 line_number_table_length = (file.readUnsignedShort());
110 line_number_table = new LineNumber[line_number_table_length];
111
112 for(int i=0; i < line_number_table_length; i++)
113 line_number_table[i] = new LineNumber(file);
114 }
115 /***
116 * Called by objects that are traversing the nodes of the tree implicitely
117 * defined by the contents of a Java class. I.e., the hierarchy of methods,
118 * fields, attributes, etc. spawns a tree of objects.
119 *
120 * @param v Visitor object
121 */
122 public void accept(Visitor v) {
123 v.visitLineNumberTable(this);
124 }
125 /***
126 * Dump line number table attribute to file stream in binary format.
127 *
128 * @param file Output file stream
129 * @throws IOException
130 */
131 public final void dump(DataOutputStream file) throws IOException
132 {
133 super.dump(file);
134 file.writeShort(line_number_table_length);
135 for(int i=0; i < line_number_table_length; i++)
136 line_number_table[i].dump(file);
137 }
138
139 /***
140 * @return Array of (pc offset, line number) pairs.
141 */
142 public final LineNumber[] getLineNumberTable() { return line_number_table; }
143
144 /***
145 * @param line_number_table.
146 */
147 public final void setLineNumberTable(LineNumber[] line_number_table) {
148 this.line_number_table = line_number_table;
149
150 line_number_table_length = (line_number_table == null)? 0 :
151 line_number_table.length;
152 }
153
154 /***
155 * @return String representation.
156 */
157 public final String toString() {
158 StringBuffer buf = new StringBuffer();
159 StringBuffer line = new StringBuffer();
160
161 for(int i=0; i < line_number_table_length; i++) {
162 line.append(line_number_table[i].toString());
163
164 if(i < line_number_table_length - 1)
165 line.append(", ");
166
167 if(line.length() > 72) {
168 line.append('\n');
169 buf.append(line);
170 line.setLength(0);
171 }
172 }
173
174 buf.append(line);
175
176 return buf.toString();
177 }
178
179 /***
180 * Map byte code positions to source code lines.
181 *
182 * @param pos byte code offset
183 * @return corresponding line in source code
184 */
185 public int getSourceLine(int pos) {
186 int l = 0, r = line_number_table_length-1;
187
188 if(r < 0) // array is empty
189 return -1;
190
191 int min_index = -1, min=-1;
192
193 /* Do a binary search since the array is ordered.
194 */
195 do {
196 int i = (l + r) / 2;
197 int j = line_number_table[i].getStartPC();
198
199 if(j == pos)
200 return line_number_table[i].getLineNumber();
201 else if(pos < j) // else constrain search area
202 r = i - 1;
203 else // pos > j
204 l = i + 1;
205
206 /* If exact match can't be found (which is the most common case)
207 * return the line number that corresponds to the greatest index less
208 * than pos.
209 */
210 if(j < pos && j > min) {
211 min = j;
212 min_index = i;
213 }
214 } while(l <= r);
215
216 /* It's possible that we did not find any valid entry for the bytecode
217 * offset we were looking for.
218 */
219 if (min_index < 0)
220 return -1;
221
222 return line_number_table[min_index].getLineNumber();
223 }
224
225 /***
226 * @return deep copy of this attribute
227 */
228 public Attribute copy(ConstantPool constant_pool) {
229 LineNumberTable c = (LineNumberTable)clone();
230
231 c.line_number_table = new LineNumber[line_number_table_length];
232 for(int i=0; i < line_number_table_length; i++)
233 c.line_number_table[i] = line_number_table[i].copy();
234
235 c.constant_pool = constant_pool;
236 return c;
237 }
238
239 public final int getTableLength() { return line_number_table_length; }
240 }
This page was automatically generated by Maven