/**
* JavaGuard -- an obfuscation package for Java classfiles.
*
* Copyright (c) 1999 Mark Welsh (markw@retrologic.com)
* Copyright (c) 2002 Thorsten Heit (theit@gmx.de)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author may be contacted at theit@gmx.de.
*
*
* $Id: CpInfo.java,v 1.2 2002/05/08 11:53:42 glurk Exp $
*/
package net.sf.javaguard.classfile;
import java.io.*;
import java.util.*;
/** Representation of an entry in the ConstantPool. Specific types of entry
* have their representations sub-classed from this.
*
* @author <a href="mailto:theit@gmx.de">Thorsten Heit</a>
* @author <a href="mailto:markw@retrologic.com">Mark Welsh</a>
*/
abstract public class CpInfo implements ClassConstants {
/** Holds a tag that describes the type of the entry, stored in a single byte
* in the class file.
*/
private int tag;
/** Used for reference counting in the constant pool. */
private int refCount = 0;
/** Create a new CpInfo from the data passed.
* @param din the input stream to read from
* @return the new CpInfo class created from the input stream
* @throws IOException if class file is corrupt or incomplete
*/
public static CpInfo create(DataInput din)
throws IOException {
if (din == null) throw new IOException("No input stream was provided.");
// Instantiate based on tag byte
CpInfo ci = null;
switch (din.readUnsignedByte()) {
case CONSTANT_Utf8:
ci = new Utf8CpInfo();
break;
case CONSTANT_Integer:
ci = new IntegerCpInfo();
break;
case CONSTANT_Float:
ci = new FloatCpInfo();
break;
case CONSTANT_Long:
ci = new LongCpInfo();
break;
case CONSTANT_Double:
ci = new DoubleCpInfo();
break;
case CONSTANT_Class:
ci = new ClassCpInfo();
break;
case CONSTANT_String:
ci = new StringCpInfo();
break;
case CONSTANT_Fieldref:
ci = new FieldrefCpInfo();
break;
case CONSTANT_Methodref:
ci = new MethodrefCpInfo();
break;
case CONSTANT_InterfaceMethodref:
ci = new InterfaceMethodrefCpInfo();
break;
case CONSTANT_NameAndType:
ci = new NameAndTypeCpInfo();
break;
default:
throw new IOException("Unknown tag type in constant pool.");
}
ci.readInfo(din);
return ci;
}
/** Default constructor for the CpInfo class.
* @param tag an integer tag describes the type of the class
*/
protected CpInfo(int tag) {
setTag(tag);
}
/** Sets the tag that describes the type of the constant pool entry.
* @param tag type of the contant pool entry
* @see #getTag
*/
private void setTag(int tag) {
this.tag = tag;
}
/** Returns the tag that describes the type of the constant pool entry.
* @return type of the constant pool entry
* @see #setTag
*/
private int getTag() {
return tag;
}
/** Read the 'info' data following the u1tag byte; over-ride this in
* sub-classes.
* @param din the input stream
* @throws IOException if an I/O error occurs
*/
abstract protected void readInfo(DataInput din)
throws IOException;
/** Check for Utf8 references to constant pool and mark them; override this
* in sub-classes.
* @param pool the constant pool to check
*/
protected void markUtf8Refs(ConstantPool pool) {
}
/** Check for NameAndType references to constant pool and mark them; override
* this in sub-classes.
* @param pool the constant pool
*/
protected void markNTRefs(ConstantPool pool) {
}
/** Export the representation to a DataOutput stream.
* @param dout the output stream
* @throws IOException of an I/O error occurs
*/
public void write(DataOutput dout)
throws IOException {
if (dout == null) throw new IOException("No output stream was provided.");
dout.writeByte(getTag());
writeInfo(dout);
}
/** Write the 'info' data following the u1tag byte; override this in
* sub-classes.
* @param dout the output stream
* @throws IOException if an I/O error occurs
*/
abstract protected void writeInfo(DataOutput dout)
throws IOException;
/** Return the reference count.
* @return the reference count
*/
public int getRefCount() {
return refCount;
}
/** Increment the reference count.
*/
public void incRefCount() {
refCount++;
}
/** Decrement the reference count.
* @throws IllegalStateException if the reference count is already zero
*/
public void decRefCount()
throws IllegalStateException {
if (refCount == 0) throw new IllegalStateException("Illegal to decrement ref count that is already zero.");
refCount--;
}
/** Reset the reference count to zero.
*/
public void resetRefCount() {
refCount = 0;
}
/** Dump the content of the entry to the specified file (used for debugging).
* @param pw the print writer
* @param cf the class file the element belongs to
* @param index the index in the constant pool
*/
abstract public void dump(PrintWriter pw, ClassFile cf, int index);
}
|