001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 *  Unless required by applicable law or agreed to in writing, software
012 *  distributed under the License is distributed on an "AS IS" BASIS,
013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 *  See the License for the specific language governing permissions and
015 *  limitations under the License.
016 *
017 */
018package org.apache.bcel.classfile;
019
020import java.io.DataInput;
021import java.io.DataOutputStream;
022import java.io.IOException;
023
024/**
025 * This class represents a (PC offset, line number) pair, i.e., a line number in
026 * the source that corresponds to a relative address in the byte code. This
027 * is used for debugging purposes.
028 *
029 * @version $Id: LineNumber.java 1749603 2016-06-21 20:50:19Z ggregory $
030 * @see     LineNumberTable
031 */
032public final class LineNumber implements Cloneable, Node {
033
034    /** Program Counter (PC) corresponds to line */
035    private short start_pc;
036    
037    /** number in source file */
038    private short line_number;
039
040    /**
041     * Initialize from another object.
042     * 
043     * @param c the object to copy
044     */
045    public LineNumber(final LineNumber c) {
046        this(c.getStartPC(), c.getLineNumber());
047    }
048
049
050    /**
051     * Construct object from file stream.
052     * 
053     * @param file Input stream
054     * @throws IOEXception if an I/O Exception occurs in readUnsignedShort
055     */
056    LineNumber(final DataInput file) throws IOException {
057        this(file.readUnsignedShort(), file.readUnsignedShort());
058    }
059
060
061    /**
062     * @param start_pc Program Counter (PC) corresponds to
063     * @param line_number line number in source file
064     */
065    public LineNumber(final int start_pc, final int line_number) {
066        this.start_pc = (short) start_pc;
067        this.line_number = (short)line_number;
068    }
069
070
071    /**
072     * Called by objects that are traversing the nodes of the tree implicitely
073     * defined by the contents of a Java class. I.e., the hierarchy of methods,
074     * fields, attributes, etc. spawns a tree of objects.
075     *
076     * @param v Visitor object
077     */
078    @Override
079    public void accept( final Visitor v ) {
080        v.visitLineNumber(this);
081    }
082
083
084    /**
085     * Dump line number/pc pair to file stream in binary format.
086     *
087     * @param file Output file stream
088     * @throws IOEXception if an I/O Exception occurs in writeShort
089     */
090    public final void dump( final DataOutputStream file ) throws IOException {
091        file.writeShort(start_pc);
092        file.writeShort(line_number);
093    }
094
095
096    /**
097     * @return Corresponding source line
098     */
099    public final int getLineNumber() {
100        return 0xffff & line_number;
101    }
102
103
104    /**
105     * @return PC in code
106     */
107    public final int getStartPC() {
108        return  0xffff & start_pc;
109    }
110
111
112    /**
113     * @param line_number the source line number
114     */
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     */
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
132    public final String toString() {
133        return "LineNumber(" + start_pc + ", " + line_number + ")";
134    }
135
136
137    /**
138     * @return deep copy of this object
139     */
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}