1 17 package org.apache.bcel.classfile; 18 19 import java.io.DataInputStream ; 20 import java.io.DataOutputStream ; 21 import java.io.IOException ; 22 import java.io.Serializable ; 23 import org.apache.bcel.Constants; 24 25 38 public class ConstantPool implements Cloneable , Node, Serializable { 39 40 private int constant_pool_count; 41 private Constant[] constant_pool; 42 43 44 47 public ConstantPool(Constant[] constant_pool) { 48 setConstantPool(constant_pool); 49 } 50 51 52 59 ConstantPool(DataInputStream file) throws IOException , ClassFormatException { 60 byte tag; 61 constant_pool_count = file.readUnsignedShort(); 62 constant_pool = new Constant[constant_pool_count]; 63 66 for (int i = 1; i < constant_pool_count; i++) { 67 constant_pool[i] = Constant.readConstant(file); 68 75 tag = constant_pool[i].getTag(); 76 if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) { 77 i++; 78 } 79 } 80 } 81 82 83 90 public void accept( Visitor v ) { 91 v.visitConstantPool(this); 92 } 93 94 95 101 public String constantToString( Constant c ) throws ClassFormatException { 102 String str; 103 int i; 104 byte tag = c.getTag(); 105 switch (tag) { 106 case Constants.CONSTANT_Class: 107 i = ((ConstantClass) c).getNameIndex(); 108 c = getConstant(i, Constants.CONSTANT_Utf8); 109 str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); 110 break; 111 case Constants.CONSTANT_String: 112 i = ((ConstantString) c).getStringIndex(); 113 c = getConstant(i, Constants.CONSTANT_Utf8); 114 str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\""; 115 break; 116 case Constants.CONSTANT_Utf8: 117 str = ((ConstantUtf8) c).getBytes(); 118 break; 119 case Constants.CONSTANT_Double: 120 str = "" + ((ConstantDouble) c).getBytes(); 121 break; 122 case Constants.CONSTANT_Float: 123 str = "" + ((ConstantFloat) c).getBytes(); 124 break; 125 case Constants.CONSTANT_Long: 126 str = "" + ((ConstantLong) c).getBytes(); 127 break; 128 case Constants.CONSTANT_Integer: 129 str = "" + ((ConstantInteger) c).getBytes(); 130 break; 131 case Constants.CONSTANT_NameAndType: 132 str = (constantToString(((ConstantNameAndType) c).getNameIndex(), 133 Constants.CONSTANT_Utf8) 134 + " " + constantToString(((ConstantNameAndType) c).getSignatureIndex(), 135 Constants.CONSTANT_Utf8)); 136 break; 137 case Constants.CONSTANT_InterfaceMethodref: 138 case Constants.CONSTANT_Methodref: 139 case Constants.CONSTANT_Fieldref: 140 str = (constantToString(((ConstantCP) c).getClassIndex(), Constants.CONSTANT_Class) 141 + "." + constantToString(((ConstantCP) c).getNameAndTypeIndex(), 142 Constants.CONSTANT_NameAndType)); 143 break; 144 default: throw new RuntimeException ("Unknown constant type " + tag); 146 } 147 return str; 148 } 149 150 151 private static final String escape( String str ) { 152 int len = str.length(); 153 StringBuffer buf = new StringBuffer (len + 5); 154 char[] ch = str.toCharArray(); 155 for (int i = 0; i < len; i++) { 156 switch (ch[i]) { 157 case '\n': 158 buf.append("\\n"); 159 break; 160 case '\r': 161 buf.append("\\r"); 162 break; 163 case '\t': 164 buf.append("\\t"); 165 break; 166 case '\b': 167 buf.append("\\b"); 168 break; 169 case '"': 170 buf.append("\\\""); 171 break; 172 default: 173 buf.append(ch[i]); 174 } 175 } 176 return buf.toString(); 177 } 178 179 180 188 public String constantToString( int index, byte tag ) throws ClassFormatException { 189 Constant c = getConstant(index, tag); 190 return constantToString(c); 191 } 192 193 194 200 public void dump( DataOutputStream file ) throws IOException { 201 file.writeShort(constant_pool_count); 202 for (int i = 1; i < constant_pool_count; i++) { 203 if (constant_pool[i] != null) { 204 constant_pool[i].dump(file); 205 } 206 } 207 } 208 209 210 217 public Constant getConstant( int index ) { 218 if (index >= constant_pool.length || index < 0) { 219 throw new ClassFormatException("Invalid constant pool reference: " + index 220 + ". Constant pool size is: " + constant_pool.length); 221 } 222 return constant_pool[index]; 223 } 224 225 226 236 public Constant getConstant( int index, byte tag ) throws ClassFormatException { 237 Constant c; 238 c = getConstant(index); 239 if (c == null) { 240 throw new ClassFormatException("Constant pool at index " + index + " is null."); 241 } 242 if (c.getTag() != tag) { 243 throw new ClassFormatException("Expected class `" + Constants.CONSTANT_NAMES[tag] 244 + "' at index " + index + " and got " + c); 245 } 246 return c; 247 } 248 249 250 254 public Constant[] getConstantPool() { 255 return constant_pool; 256 } 257 258 259 272 public String getConstantString( int index, byte tag ) throws ClassFormatException { 273 Constant c; 274 int i; 275 c = getConstant(index, tag); 276 283 switch (tag) { 284 case Constants.CONSTANT_Class: 285 i = ((ConstantClass) c).getNameIndex(); 286 break; 287 case Constants.CONSTANT_String: 288 i = ((ConstantString) c).getStringIndex(); 289 break; 290 default: 291 throw new RuntimeException ("getConstantString called with illegal tag " + tag); 292 } 293 c = getConstant(i, Constants.CONSTANT_Utf8); 295 return ((ConstantUtf8) c).getBytes(); 296 } 297 298 299 302 public int getLength() { 303 return constant_pool_count; 304 } 305 306 307 310 public void setConstant( int index, Constant constant ) { 311 constant_pool[index] = constant; 312 } 313 314 315 318 public void setConstantPool( Constant[] constant_pool ) { 319 this.constant_pool = constant_pool; 320 constant_pool_count = (constant_pool == null) ? 0 : constant_pool.length; 321 } 322 323 324 327 public String toString() { 328 StringBuffer buf = new StringBuffer (); 329 for (int i = 1; i < constant_pool_count; i++) { 330 buf.append(i).append(")").append(constant_pool[i]).append("\n"); 331 } 332 return buf.toString(); 333 } 334 335 336 339 public ConstantPool copy() { 340 ConstantPool c = null; 341 try { 342 c = (ConstantPool) clone(); 343 c.constant_pool = new Constant[constant_pool_count]; 344 for (int i = 1; i < constant_pool_count; i++) { 345 if (constant_pool[i] != null) { 346 c.constant_pool[i] = constant_pool[i].copy(); 347 } 348 } 349 } catch (CloneNotSupportedException e) { 350 } 351 return c; 352 } 353 } 354 | Popular Tags |