blob: b83dde3e07b44bc835351251a7abb31f239ac51a [file] [log] [blame]
/**********************************************************************
Copyright (c) 2002 IBM Corp. and others.
All rights reserved.   This program and the accompanying materials
are made available under the terms of the Common Public License v0.5
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v05.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;
private ConstantPoolEntry constantPoolEntry;
ConstantPool(byte[] reference, int[] constantPoolOffset) {
this.constantPoolCount = constantPoolOffset.length;
this.constantPoolOffset = constantPoolOffset;
this.classFileBytes = reference;
this.constantPoolEntry = new ConstantPoolEntry();
}
/**
* @see IConstantPool#decodeEntry(int)
*/
public IConstantPoolEntry decodeEntry(int index) {
this.constantPoolEntry.reset();
int kind = getEntryKind(index);
this.constantPoolEntry.setKind(kind);
switch(kind) {
case IConstantPoolConstant.CONSTANT_Class :
this.constantPoolEntry.setClassInfoNameIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index]));
this.constantPoolEntry.setClassInfoName(getUtf8ValueAt(this.constantPoolEntry.getClassInfoNameIndex()));
break;
case IConstantPoolConstant.CONSTANT_Double :
this.constantPoolEntry.setDoubleValue(doubleAt(classFileBytes, 1, this.constantPoolOffset[index]));
break;
case IConstantPoolConstant.CONSTANT_Fieldref :
this.constantPoolEntry.setClassIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index]));
int declaringClassIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[this.constantPoolEntry.getClassIndex()]);
this.constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex));
this.constantPoolEntry.setNameAndTypeIndex(u2At(this.classFileBytes, 3, this.constantPoolOffset[index]));
int fieldNameIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[this.constantPoolEntry.getNameAndTypeIndex()]);
int fieldDescriptorIndex = u2At(this.classFileBytes, 3, this.constantPoolOffset[this.constantPoolEntry.getNameAndTypeIndex()]);
this.constantPoolEntry.setFieldName(getUtf8ValueAt(fieldNameIndex));
this.constantPoolEntry.setFieldDescriptor(getUtf8ValueAt(fieldDescriptorIndex));
break;
case IConstantPoolConstant.CONSTANT_Methodref :
case IConstantPoolConstant.CONSTANT_InterfaceMethodref :
this.constantPoolEntry.setClassIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index]));
declaringClassIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[this.constantPoolEntry.getClassIndex()]);
this.constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex));
this.constantPoolEntry.setNameAndTypeIndex(u2At(this.classFileBytes, 3, this.constantPoolOffset[index]));
int methodNameIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[this.constantPoolEntry.getNameAndTypeIndex()]);
int methodDescriptorIndex = u2At(this.classFileBytes, 3, this.constantPoolOffset[this.constantPoolEntry.getNameAndTypeIndex()]);
this.constantPoolEntry.setMethodName(getUtf8ValueAt(methodNameIndex));
this.constantPoolEntry.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex));
break;
case IConstantPoolConstant.CONSTANT_Float :
this.constantPoolEntry.setFloatValue(floatAt(classFileBytes, 1, this.constantPoolOffset[index]));
break;
case IConstantPoolConstant.CONSTANT_Integer :
this.constantPoolEntry.setIntegerValue(i4At(classFileBytes, 1, this.constantPoolOffset[index]));
break;
case IConstantPoolConstant.CONSTANT_Long :
this.constantPoolEntry.setLongValue(i8At(classFileBytes, 1, this.constantPoolOffset[index]));
break;
case IConstantPoolConstant.CONSTANT_NameAndType :
this.constantPoolEntry.setNameAndTypeNameIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index]));
this.constantPoolEntry.setNameAndTypeDescriptorIndex(u2At(this.classFileBytes, 3, this.constantPoolOffset[index]));
break;
case IConstantPoolConstant.CONSTANT_String :
this.constantPoolEntry.setStringIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index]));
this.constantPoolEntry.setStringValue(getUtf8ValueAt(this.constantPoolEntry.getStringIndex()));
break;
case IConstantPoolConstant.CONSTANT_Utf8 :
this.constantPoolEntry.setUtf8Length(u2At(this.classFileBytes, 1, this.constantPoolOffset[index]));
this.constantPoolEntry.setUtf8Value(getUtf8ValueAt(index));
}
return this.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));
}
}