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 name-and-type object in the constant pool.
012 *
013 * @author Mathias Ricken
014 */
015 public class NameAndTypePoolInfo extends APoolInfo {
016 /**
017 * Name information.
018 */
019 protected AUTFPoolInfo _name;
020
021 /**
022 * Type descriptor information.
023 */
024 protected AUTFPoolInfo _descriptor;
025
026 /**
027 * Name index.
028 */
029 protected short _nameIndex;
030
031 /**
032 * Type descriptor index.
033 */
034 protected short _descriptorIndex;
035
036 /**
037 * Constructor.
038 *
039 * @param name name information
040 * @param descriptor type descriptor information
041 */
042 public NameAndTypePoolInfo(AUTFPoolInfo name, AUTFPoolInfo descriptor, ConstantPool cp) {
043 super(CONSTANT_NameAndType, cp);
044 _name = name;
045 _descriptor = descriptor;
046 reindex();
047 }
048
049 /**
050 * Constructor reading from a stream.
051 *
052 * @param dis input stream
053 * @param cp constant pool
054 *
055 * @throws IOException
056 */
057 public NameAndTypePoolInfo(DataInputStream dis, ConstantPool cp) throws IOException {
058 super(CONSTANT_NameAndType, cp);
059 _nameIndex = dis.readShort();
060 _descriptorIndex = dis.readShort();
061 }
062
063 /**
064 * Accessor for the name information.
065 *
066 * @return name information
067 */
068 public AUTFPoolInfo getName() {
069 return _name;
070 }
071
072 /**
073 * Mutator for the name information.
074 *
075 * @param name new name information
076 */
077 public void setName(AUTFPoolInfo name) {
078 _name = name;
079 }
080
081 /**
082 * Accessor for the type descriptor information.
083 *
084 * @return type descriptor information
085 */
086 public AUTFPoolInfo getDescriptor() {
087 return _descriptor;
088 }
089
090 /**
091 * Mutator for the type descriptor information.
092 *
093 * @param descriptor type descriptor information
094 */
095 public void setDescriptor(AUTFPoolInfo descriptor) {
096 _descriptor = descriptor;
097 }
098
099 /**
100 * Write this constant pool object into the stream, including the type byte.
101 *
102 * @param dos stream
103 *
104 * @throws java.io.IOException
105 */
106 public void write(DataOutputStream dos) throws IOException {
107 reindex();
108 dos.writeByte(_type);
109 dos.writeShort(_nameIndex);
110 dos.writeShort(_descriptorIndex);
111 }
112
113 /**
114 * Resolve constant pool objects. This makes sure that the object links match the index links.
115 */
116 public void resolve() {
117 _name = _constantPool.get(_nameIndex).execute(CheckUTFVisitor.singleton(), null);
118 _descriptor = _constantPool.get(_descriptorIndex).execute(CheckUTFVisitor.singleton(), null);
119 }
120
121 /**
122 * Reindex constant pool indices. This makes sure the index links match the object links.
123 */
124 public void reindex() {
125 _nameIndex = _constantPool.indexOf(_name);
126 _descriptorIndex = _constantPool.indexOf(_descriptor);
127 }
128
129 /**
130 * Return a human-readable version of this constant pool object.
131 *
132 * @return string
133 */
134 public String toStringVerbose() {
135 StringBuilder s = new StringBuilder();
136 s.append("NAME-AND-TYPE: Name = #");
137 s.append(_nameIndex);
138 s.append(", Descriptor = #");
139 s.append(_descriptorIndex);
140 s.append(' ');
141 s.append(toString());
142
143 return s.toString();
144 }
145
146 /**
147 * Return a human-readable version of this constant pool object.
148 *
149 * @return string
150 */
151 public String toString() {
152 StringBuilder s = new StringBuilder();
153 s.append(_name.toString());
154 s.append(_descriptor.toString());
155 return s.toString();
156 }
157
158 /**
159 * Return a hash code.
160 *
161 * @return hash code
162 */
163 public int hashCode() {
164 return _nameIndex + 6101 * _descriptorIndex;
165 }
166
167 /**
168 * Compare this object and another one.
169 *
170 * @param obj other object
171 *
172 * @return true if the same
173 */
174 public boolean equals(Object obj) {
175 return (obj instanceof NameAndTypePoolInfo) && (
176 (((NameAndTypePoolInfo)obj)._nameIndex == _nameIndex) ||
177 (((NameAndTypePoolInfo)obj)._name == _name)
178 ) && (
179 (((NameAndTypePoolInfo)obj)._descriptorIndex == _descriptorIndex) ||
180 (((NameAndTypePoolInfo)obj)._descriptor == _descriptor)
181 );
182 }
183
184 /**
185 * Execute a visitor.
186 *
187 * @param visitor visitor
188 * @param data visitor-specific parameter
189 *
190 * @return visitor-specific return value
191 */
192 public <R, D> R execute(IPoolInfoVisitor<R, D> visitor, D data) {
193 return visitor.nameAndTypeCase(this, data);
194 }
195 }