001 package edu.rice.cs.cunit.classFile.constantPool;
002
003 import edu.rice.cs.cunit.classFile.constantPool.visitors.CheckUTFVisitor;
004 import edu.rice.cs.cunit.classFile.constantPool.visitors.IPoolInfoVisitor;
005
006 import java.io.DataInputStream;
007 import java.io.DataOutputStream;
008 import java.io.IOException;
009
010 /**
011 * Represents a class in the constant pool.
012 *
013 * @author Mathias Ricken
014 */
015 public class ClassPoolInfo extends APoolInfo {
016 /**
017 * Class name information.
018 */
019 private AUTFPoolInfo _name;
020
021 /**
022 * Class name index.
023 */
024 private short _nameIndex;
025
026 /**
027 * Constructor.
028 *
029 * @param name class name information
030 * @param cp constant pool
031 */
032 public ClassPoolInfo(AUTFPoolInfo name, ConstantPool cp) {
033 super(CONSTANT_Class, cp);
034 _name = name;
035 reindex();
036 }
037
038 /**
039 * Constructor reading from a stream.
040 *
041 * @param dis input stream
042 * @param cp constant pool
043 *
044 * @throws IOException
045 */
046 public ClassPoolInfo(DataInputStream dis, ConstantPool cp) throws IOException {
047 super(CONSTANT_Class, cp);
048 _nameIndex = dis.readShort();
049 }
050
051 /**
052 * Accessor for the name information.
053 *
054 * @return name information
055 */
056 public AUTFPoolInfo getName() {
057 return _name;
058 }
059
060 /**
061 * Mutator for the name information.
062 *
063 * @param name new name information
064 */
065 public void setName(AUTFPoolInfo name) {
066 _name = name;
067 }
068
069 /**
070 * Write this constant pool object into the stream, including the type byte.
071 *
072 * @param dos stream
073 *
074 * @throws java.io.IOException
075 */
076 public void write(DataOutputStream dos) throws IOException {
077 reindex();
078 dos.writeByte(_type);
079 dos.writeShort(_nameIndex);
080 }
081
082 /**
083 * Resolve constant pool objects. This makes sure that the object links match the index links.
084 */
085 public void resolve() {
086 _name = _constantPool.get(_nameIndex).execute(CheckUTFVisitor.singleton(), null);
087 }
088
089 /**
090 * Reindex constant pool indices. This makes sure the index links match the object links.
091 */
092 public void reindex() {
093 _nameIndex = _constantPool.indexOf(_name);
094 }
095
096 /**
097 * Return a human-readable version of this constant pool object.
098 *
099 * @return string
100 */
101 public String toStringVerbose() {
102 StringBuilder s = new StringBuilder();
103 s.append("CONSTANT_Class: Name = #");
104 s.append(_nameIndex);
105 s.append(' ');
106 s.append(toString());
107 return s.toString();
108 }
109
110 /**
111 * Return a human-readable version of this constant pool object.
112 *
113 * @return string
114 */
115 public String toString() {
116 return _name.toString();
117 }
118
119 /**
120 * Return a hash code.
121 *
122 * @return hash code
123 */
124 public int hashCode() {
125 return _nameIndex;
126 }
127
128 /**
129 * Compare this object and another one.
130 *
131 * @param obj other object
132 *
133 * @return true if the same
134 */
135 public boolean equals(Object obj) {
136 return (obj instanceof ClassPoolInfo) && (
137 (((ClassPoolInfo)obj)._nameIndex == _nameIndex) ||
138 (((ClassPoolInfo)obj)._name == _name)
139 );
140 }
141
142 /**
143 * Execute a visitor.
144 *
145 * @param visitor visitor
146 * @param data visitor-specific parameter
147 *
148 * @return visitor-specific return value
149 */
150 public <R, D> R execute(IPoolInfoVisitor<R, D> visitor, D data) {
151 return visitor.classCase(this, data);
152 }
153 }