|
|
@@ -62,12 +62,20 @@ import java.io.*; |
|
|
|
* purposes. This attribute is used by the <em>Code</em> attribute. It |
|
|
|
* contains pairs of PCs and line numbers. |
|
|
|
* |
|
|
|
* @version $Id: LineNumberTable.java,v 1.2 2004/11/19 16:45:18 aclement Exp $ |
|
|
|
* @version $Id: LineNumberTable.java,v 1.3 2006/02/07 15:15:42 aclement Exp $ |
|
|
|
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> |
|
|
|
* @see Code |
|
|
|
* @see LineNumber |
|
|
|
* |
|
|
|
* changes: |
|
|
|
* asc Feb06 Made unpacking lazy |
|
|
|
*/ |
|
|
|
public final class LineNumberTable extends Attribute { |
|
|
|
|
|
|
|
|
|
|
|
// if 'isInPackedState' then this data needs unpacking |
|
|
|
private boolean isInPackedState = false; |
|
|
|
private byte[] data; |
|
|
|
|
|
|
|
private int line_number_table_length; |
|
|
|
private LineNumber[] line_number_table; // Table of line/numbers pairs |
|
|
|
|
|
|
@@ -76,8 +84,7 @@ public final class LineNumberTable extends Attribute { |
|
|
|
* references (shallow copy). Use copy() for a physical copy. |
|
|
|
*/ |
|
|
|
public LineNumberTable(LineNumberTable c) { |
|
|
|
this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), |
|
|
|
c.getConstantPool()); |
|
|
|
this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool()); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
@@ -87,11 +94,10 @@ public final class LineNumberTable extends Attribute { |
|
|
|
* @param constant_pool Array of constants |
|
|
|
*/ |
|
|
|
public LineNumberTable(int name_index, int length, |
|
|
|
LineNumber[] line_number_table, |
|
|
|
ConstantPool constant_pool) |
|
|
|
{ |
|
|
|
LineNumber[] line_number_table, ConstantPool constant_pool) { |
|
|
|
super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool); |
|
|
|
setLineNumberTable(line_number_table); |
|
|
|
isInPackedState=false; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -105,13 +111,32 @@ public final class LineNumberTable extends Attribute { |
|
|
|
LineNumberTable(int name_index, int length, DataInputStream file, |
|
|
|
ConstantPool constant_pool) throws IOException |
|
|
|
{ |
|
|
|
this(name_index, length, (LineNumber[])null, constant_pool); |
|
|
|
line_number_table_length = (file.readUnsignedShort()); |
|
|
|
line_number_table = new LineNumber[line_number_table_length]; |
|
|
|
this(name_index, length, (LineNumber[])null, constant_pool); |
|
|
|
data = new byte[length]; |
|
|
|
int byteReads = file.read(data); |
|
|
|
isInPackedState = true; |
|
|
|
// assert(bytesRead==length) |
|
|
|
} |
|
|
|
|
|
|
|
// Unpacks the byte array into the table |
|
|
|
private void unpack() { |
|
|
|
if (!isInPackedState) return; |
|
|
|
|
|
|
|
for(int i=0; i < line_number_table_length; i++) |
|
|
|
line_number_table[i] = new LineNumber(file); |
|
|
|
} |
|
|
|
try { |
|
|
|
ByteArrayInputStream bs = new ByteArrayInputStream(data); |
|
|
|
DataInputStream dis = new DataInputStream(bs); |
|
|
|
line_number_table_length = (dis.readUnsignedShort()); |
|
|
|
line_number_table = new LineNumber[line_number_table_length]; |
|
|
|
for (int i=0; i < line_number_table_length; i++) |
|
|
|
line_number_table[i] = new LineNumber(dis); |
|
|
|
dis.close(); |
|
|
|
data = null; // throw it away now |
|
|
|
} catch (IOException e) { |
|
|
|
throw new RuntimeException("Unpacking of LineNumberTable attribute failed"); |
|
|
|
} |
|
|
|
isInPackedState=false; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Called by objects that are traversing the nodes of the tree implicitely |
|
|
|
* defined by the contents of a Java class. I.e., the hierarchy of methods, |
|
|
@@ -120,8 +145,10 @@ public final class LineNumberTable extends Attribute { |
|
|
|
* @param v Visitor object |
|
|
|
*/ |
|
|
|
public void accept(Visitor v) { |
|
|
|
unpack(); |
|
|
|
v.visitLineNumberTable(this); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Dump line number table attribute to file stream in binary format. |
|
|
|
* |
|
|
@@ -131,20 +158,26 @@ public final class LineNumberTable extends Attribute { |
|
|
|
public final void dump(DataOutputStream file) throws IOException |
|
|
|
{ |
|
|
|
super.dump(file); |
|
|
|
file.writeShort(line_number_table_length); |
|
|
|
for(int i=0; i < line_number_table_length; i++) |
|
|
|
line_number_table[i].dump(file); |
|
|
|
if (isInPackedState) { |
|
|
|
file.write(data); |
|
|
|
} else { |
|
|
|
file.writeShort(line_number_table_length); |
|
|
|
for(int i=0; i < line_number_table_length; i++) |
|
|
|
line_number_table[i].dump(file); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @return Array of (pc offset, line number) pairs. |
|
|
|
*/ |
|
|
|
public final LineNumber[] getLineNumberTable() { return line_number_table; } |
|
|
|
public final LineNumber[] getLineNumberTable() { unpack();return line_number_table; } |
|
|
|
|
|
|
|
/** |
|
|
|
* @param line_number_table. |
|
|
|
*/ |
|
|
|
public final void setLineNumberTable(LineNumber[] line_number_table) { |
|
|
|
this.data = null; |
|
|
|
this.isInPackedState=false; |
|
|
|
this.line_number_table = line_number_table; |
|
|
|
|
|
|
|
line_number_table_length = (line_number_table == null)? 0 : |
|
|
@@ -155,6 +188,7 @@ public final class LineNumberTable extends Attribute { |
|
|
|
* @return String representation. |
|
|
|
*/ |
|
|
|
public final String toString() { |
|
|
|
unpack(); |
|
|
|
StringBuffer buf = new StringBuffer(); |
|
|
|
StringBuffer line = new StringBuffer(); |
|
|
|
|
|
|
@@ -183,6 +217,7 @@ public final class LineNumberTable extends Attribute { |
|
|
|
* @return corresponding line in source code |
|
|
|
*/ |
|
|
|
public int getSourceLine(int pos) { |
|
|
|
unpack(); |
|
|
|
int l = 0, r = line_number_table_length-1; |
|
|
|
|
|
|
|
if(r < 0) // array is empty |
|
|
@@ -226,6 +261,7 @@ public final class LineNumberTable extends Attribute { |
|
|
|
* @return deep copy of this attribute |
|
|
|
*/ |
|
|
|
public Attribute copy(ConstantPool constant_pool) { |
|
|
|
unpack(); |
|
|
|
LineNumberTable c = (LineNumberTable)clone(); |
|
|
|
|
|
|
|
c.line_number_table = new LineNumber[line_number_table_length]; |
|
|
@@ -236,5 +272,5 @@ public final class LineNumberTable extends Attribute { |
|
|
|
return c; |
|
|
|
} |
|
|
|
|
|
|
|
public final int getTableLength() { return line_number_table_length; } |
|
|
|
public final int getTableLength() { unpack();return line_number_table_length; } |
|
|
|
} |