001: /* ===========================================================================
002: * $RCSfile: CpInfo.java,v $
003: * ===========================================================================
004: *
005: * RetroGuard -- an obfuscation package for Java classfiles.
006: *
007: * Copyright (c) 1998-2006 Mark Welsh (markw@retrologic.com)
008: *
009: * This program can be redistributed and/or modified under the terms of the
010: * Version 2 of the GNU General Public License as published by the Free
011: * Software Foundation.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: */
019:
020: package COM.rl.obf.classfile;
021:
022: import java.io.*;
023: import java.util.*;
024:
025: /**
026: * Representation of an entry in the ConstantPool. Specific types of entry
027: * have their representations sub-classed from this.
028: *
029: * @author Mark Welsh
030: */
031: abstract public class CpInfo implements ClassConstants {
032: // Constants -------------------------------------------------------------
033:
034: // Fields ----------------------------------------------------------------
035: private int u1tag;
036: private byte info[];
037:
038: protected int refCount = 0; // Used for reference counting in Constant Pool
039:
040: // Class Methods ---------------------------------------------------------
041: /**
042: * Create a new CpInfo from the data passed.
043: *
044: * @throws IOException if class file is corrupt or incomplete
045: */
046: public static CpInfo create(DataInput din) throws Exception {
047: if (din == null)
048: throw new IOException("No input stream was provided.");
049:
050: // Instantiate based on tag byte
051: CpInfo ci = null;
052: switch (din.readUnsignedByte()) {
053: case CONSTANT_Utf8:
054: ci = new Utf8CpInfo();
055: break;
056: case CONSTANT_Integer:
057: ci = new IntegerCpInfo();
058: break;
059: case CONSTANT_Float:
060: ci = new FloatCpInfo();
061: break;
062: case CONSTANT_Long:
063: ci = new LongCpInfo();
064: break;
065: case CONSTANT_Double:
066: ci = new DoubleCpInfo();
067: break;
068: case CONSTANT_Class:
069: ci = new ClassCpInfo();
070: break;
071: case CONSTANT_String:
072: ci = new StringCpInfo();
073: break;
074: case CONSTANT_Fieldref:
075: ci = new FieldrefCpInfo();
076: break;
077: case CONSTANT_Methodref:
078: ci = new MethodrefCpInfo();
079: break;
080: case CONSTANT_InterfaceMethodref:
081: ci = new InterfaceMethodrefCpInfo();
082: break;
083: case CONSTANT_NameAndType:
084: ci = new NameAndTypeCpInfo();
085: break;
086: default:
087: throw new IOException("Unknown tag type in constant pool.");
088: }
089: ci.readInfo(din);
090: return ci;
091: }
092:
093: // Instance Methods ------------------------------------------------------
094: protected CpInfo(int tag) {
095: u1tag = tag;
096: }
097:
098: /** Read the 'info' data following the u1tag byte; over-ride this in sub-classes. */
099: abstract protected void readInfo(DataInput din) throws Exception;
100:
101: /** Check for Utf8 references to constant pool and mark them; over-ride this in sub-classes. */
102: protected void markUtf8Refs(ConstantPool pool) throws Exception {
103: }
104:
105: /** Check for NameAndType references to constant pool and mark them; over-ride this in sub-classes. */
106: protected void markNTRefs(ConstantPool pool) throws Exception {
107: }
108:
109: /** Export the representation to a DataOutput stream. */
110: public void write(DataOutput dout) throws Exception {
111: if (dout == null)
112: throw new IOException("No output stream was provided.");
113: dout.writeByte(u1tag);
114: writeInfo(dout);
115: }
116:
117: /** Write the 'info' data following the u1tag byte; over-ride this in sub-classes. */
118: abstract protected void writeInfo(DataOutput dout) throws Exception;
119:
120: /** Return the reference count. */
121: public int getRefCount() {
122: return refCount;
123: }
124:
125: /** Increment the reference count. */
126: public void incRefCount() {
127: refCount++;
128: }
129:
130: /** Decrement the reference count. */
131: public void decRefCount() throws Exception {
132: if (refCount == 0)
133: throw new Exception(
134: "Illegal to decrement ref count that is already zero.");
135: refCount--;
136: }
137:
138: /** Reset the reference count to zero. */
139: public void resetRefCount() {
140: refCount = 0;
141: }
142:
143: /** Dump the content of the class file to the specified file (used for debugging). */
144: public void dump(PrintWriter pw, ClassFile cf, int index)
145: throws Exception {
146: }
147: }
|