001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package EDU.purdue.cs.bloat.file;
022:
023: import java.io.*;
024:
025: import EDU.purdue.cs.bloat.reflect.*;
026:
027: /**
028: * LineNumberTable is an attribute of a code attribute. A LineNumberTable stores
029: * information that relates indices into the code array (instructions) to the
030: * lines of code in the source file from which they were compiled. This optional
031: * attribute is used with debuggers (<i>duh</i>) and consists of an array of
032: * <tt>reflect.LineNumberDebugInfo</tt>.
033: *
034: * @see Code
035: * @see EDU.purdue.cs.bloat.reflect.LineNumberDebugInfo
036: *
037: * @author Nate Nystrom (<a
038: * href="mailto:nystrom@cs.purdue.edu">nystrom@cs.purdue.edu</a>)
039: */
040: public class LineNumberTable extends Attribute {
041: private LineNumberDebugInfo[] lineNumbers;
042:
043: /**
044: * Constructor. Create an attribute from a data stream.
045: *
046: * @param in
047: * The data stream of the class file.
048: * @param nameIndex
049: * The index into the constant pool of the name of the attribute.
050: * @param length
051: * The length of the attribute, excluding the header.
052: * @exception IOException
053: * If an error occurs while reading.
054: */
055: public LineNumberTable(final DataInputStream in,
056: final int nameIndex, final int length) throws IOException {
057: super (nameIndex, length);
058:
059: final int numLines = in.readUnsignedShort();
060:
061: lineNumbers = new LineNumberDebugInfo[numLines];
062:
063: for (int i = 0; i < lineNumbers.length; i++) {
064: final int startPC = in.readUnsignedShort();
065: final int lineNumber = in.readUnsignedShort();
066: lineNumbers[i] = new LineNumberDebugInfo(startPC,
067: lineNumber);
068: }
069: }
070:
071: /**
072: * Get the line number debug info for the code.
073: *
074: * @return The line number debug info for the code.
075: */
076: public LineNumberDebugInfo[] lineNumbers() {
077: return lineNumbers;
078: }
079:
080: /**
081: * Set the line number debug info for the code.
082: *
083: * @param lineNumbers
084: * The line number debug info for the code.
085: */
086: public void setLineNumbers(final LineNumberDebugInfo[] lineNumbers) {
087: this .lineNumbers = lineNumbers;
088: }
089:
090: /**
091: * Get the length of the attribute.
092: *
093: * @return The length of the attribute.
094: */
095: public int length() {
096: return 2 + lineNumbers.length * 4;
097: }
098:
099: public String toString() {
100: String x = "(lines";
101:
102: for (int i = 0; i < lineNumbers.length; i++) {
103: x += "\n (line #" + lineNumbers[i].lineNumber()
104: + " pc=" + lineNumbers[i].startPC() + ")";
105: }
106:
107: return x + ")";
108: }
109:
110: /**
111: * Write the attribute to a data stream.
112: *
113: * @param out
114: * The data stream of the class file.
115: * @exception IOException
116: * If an error occurs while writing.
117: */
118: public void writeData(final DataOutputStream out)
119: throws IOException {
120: out.writeShort(lineNumbers.length);
121:
122: for (int i = 0; i < lineNumbers.length; i++) {
123: out.writeShort(lineNumbers[i].startPC());
124: out.writeShort(lineNumbers[i].lineNumber());
125: }
126: }
127:
128: /**
129: * Private constructor used in cloning.
130: */
131: private LineNumberTable(final LineNumberTable other) {
132: super (other.nameIndex, other.length);
133:
134: this .lineNumbers = new LineNumberDebugInfo[other.lineNumbers.length];
135: for (int i = 0; i < other.lineNumbers.length; i++) {
136: this .lineNumbers[i] = (LineNumberDebugInfo) other.lineNumbers[i]
137: .clone();
138: }
139: }
140:
141: public Object clone() {
142: return (new LineNumberTable(this));
143: }
144: }
|