/******************************************************************************* * 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)); } }