blob: 854416753a6944df5e72c1a49ae44f74294466bd [file] [log] [blame]
/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Common Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/cpl-v10.html
*
* $Id: LineNumberTableAttribute_info.java,v 1.1.1.1 2004/05/09 16:57:48 vlad_r Exp $
*/
package com.vladium.jcd.cls.attribute;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.vladium.jcd.lib.UDataInputStream;
import com.vladium.jcd.lib.UDataOutputStream;
// ----------------------------------------------------------------------------
/**
* The LineNumberTable attribute is an optional variable-length attribute in
* the attributes table of a {@link CodeAttribute_info} attribute. It may be
* used by debuggers to determine which part of the JVM code array corresponds
* to a given line number in the original source file. If LineNumberTable
* attributes are present in the attributes table of a given Code attribute,
* then they may appear in any order. Furthermore, multiple LineNumberTable
* attributes may together represent a given line of a source file; that is,
* LineNumberTable attributes need not be one-to-one with source lines.<P>
*
* The LineNumberTable attribute has the following format:
* <PRE>
* LineNumberTable_attribute {
* u2 attribute_name_index;
* u4 attribute_length;
* u2 line_number_table_length;
* { u2 start_pc;
* u2 line_number;
* } line_number_table[line_number_table_length];
* }
* <PRE>
*
* LineNumberTable_attribute structure contains the following items:
* <PRE>
* line_number_table_length
* </PRE>
* The value of the line_number_table_length item indicates the number of
* entries in the line_number_table array.
* <PRE>
* line_number_table[]
* </PRE>
* Each entry in the line_number_table array indicates that the line number
* in the original source file changes at a given point in the code array.<P>
*
* Each line_number_table entry must contain the following two items:
* <PRE>
* start_pc
* </PRE>
* The value of the start_pc item must indicate the index into the code array
* at which the code for a new line in the original source file begins. The
* value of start_pc must be less than the value of the code_length item of
* the {@link CodeAttribute_info} attribute of which this LineNumberTable
* is an attribute.<P>
* <PRE>
* line_number
* </PRE>
* The value of the line_number item must give the corresponding line number
* in the original source file.
*
* @author Vlad Roubtsov, (C) 2003
*/
public
final class LineNumberTableAttribute_info extends Attribute_info
{
// public: ................................................................
// ACCESSORS:
/**
* Returns {@link LineNumber_info} descriptor at a given offset.
*
* @param offset line number entry offset [must be in [0, size()) range;
* input not checked]
* @return LineNumber_info descriptor [never null]
*
* @throws IndexOutOfBoundsException if 'offset' is outside of valid range
*/
public LineNumber_info get (final int offset)
{
return (LineNumber_info) m_lines.get (offset);
}
/**
* Returns the number of descriptors in this collection [can be 0].
*/
public int size ()
{
return m_lines.size ();
}
public long length ()
{
return 8 + (m_lines.size () << 2); // use size() if class becomes non-final
}
// Visitor:
public void accept (final IAttributeVisitor visitor, final Object ctx)
{
visitor.visit (this, ctx);
}
public String toString ()
{
final StringBuffer s = new StringBuffer ("LineNumberTableAttribute_info: [attribute_name_index = " + m_name_index + ", attribute_length = " + length () + "]\n");
for (int l = 0; l < size (); ++ l)
{
s.append (" " + get (l));
s.append ("\n"); // TODO: proper EOL const
}
return s.toString ();
}
// Cloneable:
/**
* Performs a deep copy.
*/
public Object clone ()
{
final LineNumberTableAttribute_info _clone = (LineNumberTableAttribute_info) super.clone ();
// do deep copy:
final int lines_count = m_lines.size (); // use size() if class becomes non-final
_clone.m_lines = new ArrayList (lines_count);
for (int e = 0; e < lines_count; ++ e)
{
_clone.m_lines.add (((LineNumber_info) m_lines.get (e)).clone ());
}
return _clone;
}
// IClassFormatOutput:
public void writeInClassFormat (final UDataOutputStream out) throws IOException
{
super.writeInClassFormat (out);
final int lines_count = m_lines.size (); // use size() if class becomes non-final
out.writeU2 (lines_count);
for (int l = 0; l < lines_count; ++ l)
{
((LineNumber_info) m_lines.get (l)).writeInClassFormat (out);
}
}
// protected: .............................................................
// package: ...............................................................
LineNumberTableAttribute_info (final int attribute_name_index, final long attribute_length,
final UDataInputStream bytes)
throws IOException
{
super (attribute_name_index, attribute_length);
final int lines_count = bytes.readU2 ();
m_lines = new ArrayList (lines_count);
for (int i = 0; i < lines_count; i++)
{
m_lines.add (new LineNumber_info (bytes));
}
}
// private: ...............................................................
private List/* LineNumber_info */ m_lines; // never null
} // end of class
// ----------------------------------------------------------------------------