/******************************************************************************* * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.core.util; import org.eclipse.jdt.core.util.IConstantPool; import org.eclipse.jdt.core.util.IConstantPoolConstant; import org.eclipse.jdt.core.util.IConstantPoolEntry; /** * Default implementation of IConstantPool. */ public class ConstantPool extends ClassFileStruct implements IConstantPool { private int constantPoolCount; private int[] constantPoolOffset; private byte[] classFileBytes; ConstantPool(byte[] reference, int[] constantPoolOffset) { this.constantPoolCount = constantPoolOffset.length; this.constantPoolOffset = constantPoolOffset; this.classFileBytes = reference; } /** * @see IConstantPool#decodeEntry(int) */ public IConstantPoolEntry decodeEntry(int index) { ConstantPoolEntry constantPoolEntry = new ConstantPoolEntry(); constantPoolEntry.reset(); int kind = getEntryKind(index); constantPoolEntry.setKind(kind); switch(kind) { case IConstantPoolConstant.CONSTANT_Class : constantPoolEntry.setClassInfoNameIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); constantPoolEntry.setClassInfoName(getUtf8ValueAt(constantPoolEntry.getClassInfoNameIndex())); break; case IConstantPoolConstant.CONSTANT_Double : constantPoolEntry.setDoubleValue(doubleAt(this.classFileBytes, 1, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_Fieldref : constantPoolEntry.setClassIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); int declaringClassIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[constantPoolEntry.getClassIndex()]); constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex)); constantPoolEntry.setNameAndTypeIndex(u2At(this.classFileBytes, 3, this.constantPoolOffset[index])); int fieldNameIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[constantPoolEntry.getNameAndTypeIndex()]); int fieldDescriptorIndex = u2At(this.classFileBytes, 3, this.constantPoolOffset[constantPoolEntry.getNameAndTypeIndex()]); constantPoolEntry.setFieldName(getUtf8ValueAt(fieldNameIndex)); constantPoolEntry.setFieldDescriptor(getUtf8ValueAt(fieldDescriptorIndex)); break; case IConstantPoolConstant.CONSTANT_Methodref : case IConstantPoolConstant.CONSTANT_InterfaceMethodref : constantPoolEntry.setClassIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); declaringClassIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[constantPoolEntry.getClassIndex()]); constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex)); constantPoolEntry.setNameAndTypeIndex(u2At(this.classFileBytes, 3, this.constantPoolOffset[index])); int methodNameIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[constantPoolEntry.getNameAndTypeIndex()]); int methodDescriptorIndex = u2At(this.classFileBytes, 3, this.constantPoolOffset[constantPoolEntry.getNameAndTypeIndex()]); constantPoolEntry.setMethodName(getUtf8ValueAt(methodNameIndex)); constantPoolEntry.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex)); break; case IConstantPoolConstant.CONSTANT_Float : constantPoolEntry.setFloatValue(floatAt(this.classFileBytes, 1, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_Integer : constantPoolEntry.setIntegerValue(i4At(this.classFileBytes, 1, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_Long : constantPoolEntry.setLongValue(i8At(this.classFileBytes, 1, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_NameAndType : constantPoolEntry.setNameAndTypeNameIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); constantPoolEntry.setNameAndTypeDescriptorIndex(u2At(this.classFileBytes, 3, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_String : constantPoolEntry.setStringIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); constantPoolEntry.setStringValue(getUtf8ValueAt(constantPoolEntry.getStringIndex())); break; case IConstantPoolConstant.CONSTANT_Utf8 : constantPoolEntry.setUtf8Length(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); constantPoolEntry.setUtf8Value(getUtf8ValueAt(index)); } return constantPoolEntry; } /** * @see IConstantPool#getConstantPoolCount() */ public int getConstantPoolCount() { return this.constantPoolCount; } /** * @see IConstantPool#getEntryKind(int) */ public int getEntryKind(int index) { return u1At(this.classFileBytes, 0, this.constantPoolOffset[index]); } private char[] getUtf8ValueAt(int utf8Index) { int utf8Offset = this.constantPoolOffset[utf8Index]; return utf8At(this.classFileBytes, 0, utf8Offset + 3, u2At(this.classFileBytes, 0, utf8Offset + 1)); } }