1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  */
18 package org.apache.bcel.classfile;
19 
20 import java.io.DataInput;
21 import java.io.DataOutputStream;
22 import java.io.IOException;
23 
24 /**
25  * This class represents a (PC offset, line number) pair, i.e., a line number in
26  * the source that corresponds to a relative address in the byte code. This
27  * is used for debugging purposes.
28  *
29  * @version $Id$
30  * @see     LineNumberTable
31  */
32 public final class LineNumber implements Cloneable, Node {
33 
34     /** Program Counter (PC) corresponds to line */
35     private short start_pc;
36 
37     /** number in source file */
38     private short line_number;
39 
40     /**
41      * Initialize from another object.
42      *
43      * @param c the object to copy
44      */
LineNumber(final LineNumber c)45     public LineNumber(final LineNumber c) {
46         this(c.getStartPC(), c.getLineNumber());
47     }
48 
49 
50     /**
51      * Construct object from file stream.
52      *
53      * @param file Input stream
54      * @throws IOEXception if an I/O Exception occurs in readUnsignedShort
55      */
LineNumber(final DataInput file)56     LineNumber(final DataInput file) throws IOException {
57         this(file.readUnsignedShort(), file.readUnsignedShort());
58     }
59 
60 
61     /**
62      * @param start_pc Program Counter (PC) corresponds to
63      * @param line_number line number in source file
64      */
LineNumber(final int start_pc, final int line_number)65     public LineNumber(final int start_pc, final int line_number) {
66         this.start_pc = (short) start_pc;
67         this.line_number = (short)line_number;
68     }
69 
70 
71     /**
72      * Called by objects that are traversing the nodes of the tree implicitely
73      * defined by the contents of a Java class. I.e., the hierarchy of methods,
74      * fields, attributes, etc. spawns a tree of objects.
75      *
76      * @param v Visitor object
77      */
78     @Override
accept( final Visitor v )79     public void accept( final Visitor v ) {
80         v.visitLineNumber(this);
81     }
82 
83 
84     /**
85      * Dump line number/pc pair to file stream in binary format.
86      *
87      * @param file Output file stream
88      * @throws IOEXception if an I/O Exception occurs in writeShort
89      */
dump( final DataOutputStream file )90     public final void dump( final DataOutputStream file ) throws IOException {
91         file.writeShort(start_pc);
92         file.writeShort(line_number);
93     }
94 
95 
96     /**
97      * @return Corresponding source line
98      */
getLineNumber()99     public final int getLineNumber() {
100         return 0xffff & line_number;
101     }
102 
103 
104     /**
105      * @return PC in code
106      */
getStartPC()107     public final int getStartPC() {
108         return  0xffff & start_pc;
109     }
110 
111 
112     /**
113      * @param line_number the source line number
114      */
setLineNumber( final int line_number )115     public final void setLineNumber( final int line_number ) {
116         this.line_number = (short) line_number;
117     }
118 
119 
120     /**
121      * @param start_pc the pc for this line number
122      */
setStartPC( final int start_pc )123     public final void setStartPC( final int start_pc ) {
124         this.start_pc = (short) start_pc;
125     }
126 
127 
128     /**
129      * @return String representation
130      */
131     @Override
toString()132     public final String toString() {
133         return "LineNumber(" + start_pc + ", " + line_number + ")";
134     }
135 
136 
137     /**
138      * @return deep copy of this object
139      */
copy()140     public LineNumber copy() {
141         try {
142             return (LineNumber) clone();
143         } catch (final CloneNotSupportedException e) {
144             // TODO should this throw?
145         }
146         return null;
147     }
148 }
149