| /******************************************************************************* |
| * Copyright (c) 2000, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-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(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(classFileBytes, 1, this.constantPoolOffset[index])); |
| break; |
| case IConstantPoolConstant.CONSTANT_Integer : |
| constantPoolEntry.setIntegerValue(i4At(classFileBytes, 1, this.constantPoolOffset[index])); |
| break; |
| case IConstantPoolConstant.CONSTANT_Long : |
| constantPoolEntry.setLongValue(i8At(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 this.u1At(this.classFileBytes, 0, this.constantPoolOffset[index]); |
| } |
| |
| private char[] getUtf8ValueAt(int utf8Index) { |
| int utf8Offset = this.constantPoolOffset[utf8Index]; |
| return utf8At(classFileBytes, 0, utf8Offset + 3, u2At(classFileBytes, 0, utf8Offset + 1)); |
| } |
| } |