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