1 25 26 package org.netbeans.modules.classfile; 27 28 import java.io.*; 29 import java.util.*; 30 31 36 public final class ConstantPool { 37 38 private static final int CONSTANT_POOL_START = 1; 39 40 static final int CONSTANT_Utf8 = 1; 42 static final int CONSTANT_Integer = 3; 43 static final int CONSTANT_Float = 4; 44 static final int CONSTANT_Long = 5; 45 static final int CONSTANT_Double = 6; 46 static final int CONSTANT_Class = 7; 47 static final int CONSTANT_String = 8; 48 static final int CONSTANT_FieldRef = 9; 49 static final int CONSTANT_MethodRef = 10; 50 static final int CONSTANT_InterfaceMethodRef = 11; 51 static final int CONSTANT_NameAndType = 12; 52 53 CPEntry[] cpEntries; 54 55 int constantPoolCount = 0; 56 57 63 ConstantPool(int size, InputStream bytes) 64 throws IOException { 65 if (size < 0) 66 throw new IllegalArgumentException ("size cannot be negative"); 67 if (bytes == null) 68 throw new IllegalArgumentException ("byte stream not specified"); 69 constantPoolCount = size; 70 cpEntries = new CPEntry[constantPoolCount]; 71 load(bytes); 72 } 73 74 78 ConstantPool() { 79 constantPoolCount = CONSTANT_POOL_START; 80 cpEntries = new CPEntry[constantPoolCount]; 81 } 82 83 88 public final CPEntry get(int index) { 89 if (index <= 0 || index >= cpEntries.length) 90 throw new IndexOutOfBoundsException (Integer.toString(index)); 91 return cpEntries[index]; 92 } 93 94 99 public final CPClassInfo getClass(int index) { 100 if (index <= 0) 101 throw new IndexOutOfBoundsException (Integer.toString(index)); 102 return (CPClassInfo)get(index); 103 } 104 105 109 public final Collection getAllConstants(Class classType) { 110 return Collections.unmodifiableCollection( 111 getAllConstantsImpl(classType)); 112 } 113 114 private Collection<CPEntry> getAllConstantsImpl(Class classType) { 115 int n = cpEntries.length; 116 Collection<CPEntry> c = new ArrayList<CPEntry>(n); 117 for (int i = CONSTANT_POOL_START; i < n; i++) { 118 if (cpEntries[i] != null && 119 cpEntries[i].getClass().equals(classType)) { 120 c.add(cpEntries[i]); 121 } 122 } 123 return c; 124 } 125 126 134 public final Set getAllClassNames() { 135 Set<ClassName> set = new HashSet<ClassName>(); 136 137 Collection c = getAllConstantsImpl(CPClassInfo.class); 139 for (Iterator i = c.iterator(); i.hasNext();) { 140 CPClassInfo ci = (CPClassInfo)i.next(); 141 set.add(ci.getClassName()); 142 } 143 return Collections.unmodifiableSet(set); 144 } 145 146 final String getString(int index) { 147 CPUTF8Info utf = (CPUTF8Info)cpEntries[index]; 148 return utf.getName(); 149 } 150 151 private void load(InputStream cpBytes) throws IOException { 152 try { 153 ConstantPoolReader cpr = new ConstantPoolReader(cpBytes); 154 155 for (int i = CONSTANT_POOL_START; i < constantPoolCount; i++) { 157 CPEntry newEntry = getConstantPoolEntry(cpr); 158 cpEntries[i] = newEntry; 159 160 if (newEntry.usesTwoSlots()) 161 i++; 162 } 163 164 for (int i = CONSTANT_POOL_START; i < constantPoolCount; i++) { 166 CPEntry entry = cpEntries[i]; 167 if (entry == null) { 168 continue; 169 } 170 entry.resolve(cpEntries); 171 } 172 } catch (IllegalArgumentException ioe) { 173 throw new InvalidClassFormatException(ioe); 174 } catch (IndexOutOfBoundsException iobe) { 175 throw new InvalidClassFormatException(iobe); 176 } 177 } 178 179 private CPEntry getConstantPoolEntry(ConstantPoolReader cpr) 180 throws IOException { 181 CPEntry newEntry; 182 byte type = cpr.readByte(); 183 switch (type) { 184 case CONSTANT_Utf8: 185 newEntry = new CPUTF8Info(this, cpr.readRawUTF()); 186 break; 187 188 case CONSTANT_Integer: 189 newEntry = new CPIntegerInfo(this, cpr.readInt()); 190 break; 191 192 case CONSTANT_Float: 193 newEntry = new CPFloatInfo(this, cpr.readFloat()); 194 break; 195 196 case CONSTANT_Long: 197 newEntry = new CPLongInfo(this, cpr.readLong()); 198 break; 199 200 case CONSTANT_Double: 201 newEntry = new CPDoubleInfo(this, cpr.readDouble()); 202 break; 203 204 case CONSTANT_Class: { 205 int nameIndex = cpr.readUnsignedShort(); 206 newEntry = new CPClassInfo(this, nameIndex); 207 break; 208 } 209 210 case CONSTANT_String: { 211 int nameIndex = cpr.readUnsignedShort(); 212 newEntry = new CPStringInfo(this, nameIndex); 213 break; 214 } 215 216 case CONSTANT_FieldRef: { 217 int classIndex = cpr.readUnsignedShort(); 218 int natIndex = cpr.readUnsignedShort(); 219 newEntry = new CPFieldInfo(this, classIndex, natIndex); 220 break; 221 } 222 223 case CONSTANT_MethodRef: { 224 int classIndex = cpr.readUnsignedShort(); 225 int natIndex = cpr.readUnsignedShort(); 226 newEntry = new CPMethodInfo(this, classIndex, natIndex); 227 break; 228 } 229 230 case CONSTANT_InterfaceMethodRef: { 231 int classIndex = cpr.readUnsignedShort(); 232 int natIndex = cpr.readUnsignedShort(); 233 newEntry = new CPInterfaceMethodInfo(this, classIndex, natIndex); 234 break; 235 } 236 237 case CONSTANT_NameAndType: { 238 int nameIndex = cpr.readUnsignedShort(); 239 int descIndex = cpr.readUnsignedShort(); 240 newEntry = new CPNameAndTypeInfo(this, nameIndex, descIndex); 241 break; 242 } 243 244 default: 245 throw new IllegalArgumentException ( 246 "invalid constant pool type: " + type); 247 } 248 249 return newEntry; 250 } 251 } 252 | Popular Tags |