<s> package org . eclipse . jdt . internal . core . util ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . core . util . ClassFormatException ; import org . eclipse . jdt . core . util . IAttributeNamesConstants ; import org . eclipse . jdt . core . util . IClassFileAttribute ; import org . eclipse . jdt . core . util . IClassFileReader ; import org . eclipse . jdt . core . util . IConstantPool ; import org . eclipse . jdt . core . util . IConstantPoolConstant ; import org . eclipse . jdt . core . util . IFieldInfo ; import org . eclipse . jdt . core . util . IInnerClassesAttribute ; import org . eclipse . jdt . core . util . IMethodInfo ; import org . eclipse . jdt . core . util . IModifierConstants ; import org . eclipse . jdt . core . util . ISourceAttribute ; import org . eclipse . jdt . internal . compiler . util . Util ; public class ClassFileReader extends ClassFileStruct implements IClassFileReader { private static final IFieldInfo [ ] NO_FIELD_INFOS = new IFieldInfo [ 0 ] ; private static final char [ ] [ ] NO_INTERFACES_NAMES = CharOperation . NO_CHAR_CHAR ; private static final IMethodInfo [ ] NO_METHOD_INFOS = new IMethodInfo [ 0 ] ; private int accessFlags ; private IClassFileAttribute [ ] attributes ; private int attributesCount ; private char [ ] className ; private int classNameIndex ; private IConstantPool constantPool ; private IFieldInfo [ ] fields ; private int fieldsCount ; private IInnerClassesAttribute innerClassesAttribute ; private int [ ] interfaceIndexes ; private char [ ] [ ] interfaceNames ; private int interfacesCount ; private int magicNumber ; private int majorVersion ; private IMethodInfo [ ] methods ; private int methodsCount ; private int minorVersion ; private ISourceAttribute sourceFileAttribute ; private char [ ] superclassName ; private int superclassNameIndex ; public ClassFileReader ( byte [ ] classFileBytes , int decodingFlags ) throws ClassFormatException { int constantPoolCount ; int [ ] constantPoolOffsets ; try { this . magicNumber = ( int ) u4At ( classFileBytes , 0 , 0 ) ; if ( this . magicNumber != 0xCAFEBABE ) { throw new ClassFormatException ( ClassFormatException . INVALID_MAGIC_NUMBER ) ; } int readOffset = 10 ; this . minorVersion = u2At ( classFileBytes , 4 , 0 ) ; this . majorVersion = u2At ( classFileBytes , 6 , 0 ) ; if ( ( decodingFlags & IClassFileReader . CONSTANT_POOL ) == 0 ) { return ; } constantPoolCount = u2At ( classFileBytes , 8 , 0 ) ; constantPoolOffsets = new int [ constantPoolCount ] ; for ( int i = 1 ; i < constantPoolCount ; i ++ ) { int tag = u1At ( classFileBytes , readOffset , 0 ) ; switch ( tag ) { case IConstantPoolConstant . CONSTANT_Utf8 : constantPoolOffsets [ i ] = readOffset ; readOffset += u2At ( classFileBytes , readOffset + 1 , 0 ) ; readOffset += IConstantPoolConstant . CONSTANT_Utf8_SIZE ; break ; case IConstantPoolConstant . CONSTANT_Integer : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_Integer_SIZE ; break ; case IConstantPoolConstant . CONSTANT_Float : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_Float_SIZE ; break ; case IConstantPoolConstant . CONSTANT_Long : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_Long_SIZE ; i ++ ; break ; case IConstantPoolConstant . CONSTANT_Double : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_Double_SIZE ; i ++ ; break ; case IConstantPoolConstant . CONSTANT_Class : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_Class_SIZE ; break ; case IConstantPoolConstant . CONSTANT_String : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_String_SIZE ; break ; case IConstantPoolConstant . CONSTANT_Fieldref : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_Fieldref_SIZE ; break ; case IConstantPoolConstant . CONSTANT_Methodref : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_Methodref_SIZE ; break ; case IConstantPoolConstant . CONSTANT_InterfaceMethodref : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_InterfaceMethodref_SIZE ; break ; case IConstantPoolConstant . CONSTANT_NameAndType : constantPoolOffsets [ i ] = readOffset ; readOffset += IConstantPoolConstant . CONSTANT_NameAndType_SIZE ; break ; default : throw new ClassFormatException ( ClassFormatException . INVALID_TAG_CONSTANT ) ; } } this . constantPool = new ConstantPool ( classFileBytes , constantPoolOffsets ) ; this . accessFlags = u2At ( classFileBytes , readOffset , 0 ) ; readOffset += 2 ; this . classNameIndex = u2At ( classFileBytes , readOffset , 0 ) ; this . className = getConstantClassNameAt ( classFileBytes , constantPoolOffsets , this . classNameIndex ) ; readOffset += 2 ; this . superclassNameIndex = u2At ( classFileBytes , readOffset , 0 ) ; readOffset += 2 ; if ( this . superclassNameIndex != 0 ) { this . superclassName = getConstantClassNameAt ( classFileBytes , constantPoolOffsets , this . superclassNameIndex ) ; } this . interfacesCount = u2At ( classFileBytes , readOffset , 0 ) ; readOffset += 2 ; this . interfaceNames = NO_INTERFACES_NAMES ; this . interfaceIndexes = Util . EMPTY_INT_ARRAY ; if ( this . interfacesCount != 0 ) { if ( ( decodingFlags & IClassFileReader . SUPER_INTERFACES ) != IClassFileReader . CONSTANT_POOL ) { this . interfaceNames = new char [ this . interfacesCount ] [ ] ; this . interfaceIndexes = new int [ this . interfacesCount ] ; for ( int i = 0 ; i < this . interfacesCount ; i ++ ) { this . interfaceIndexes [ i ] = u2At ( classFileBytes , readOffset , 0 ) ; this . interfaceNames [ i ] = getConstantClassNameAt ( classFileBytes , constantPoolOffsets , this . interfaceIndexes [ i ] ) ; readOffset += 2 ; } } else { readOffset += ( 2 * this . interfacesCount ) ; } } this . fieldsCount = u2At ( classFileBytes , readOffset , 0 ) ; readOffset += 2 ; this . fields = NO_FIELD_INFOS ; if ( this . fieldsCount != 0 ) { if ( ( decodingFlags & IClassFileReader . FIELD_INFOS ) != IClassFileReader . CONSTANT_POOL ) { FieldInfo field ; this . fields = new FieldInfo [ this . fieldsCount ] ; for ( int i = 0 ; i < this . fieldsCount ; i ++ ) { field = new FieldInfo ( classFileBytes , this . constantPool , readOffset ) ; this . fields [ i ] = field ; readOffset += field . sizeInBytes ( ) ; } } else { for ( int i = 0 ; i < this . fieldsCount ; i ++ ) { int attributeCountForField = u2At ( classFileBytes , 6 , readOffset ) ; readOffset += 8 ; if ( attributeCountForField != 0 ) { for ( int j = 0 ; j < attributeCountForField ; j ++ ) { int attributeLength = ( int ) u4At ( classFileBytes , 2 , readOffset ) ; readOffset += ( 6 + attributeLength ) ; } } } } } this . methodsCount = u2At ( classFileBytes , readOffset , 0 ) ; readOffset += 2 ; this . methods = NO_METHOD_INFOS ; if ( this . methodsCount != 0 ) { if ( ( decodingFlags & IClassFileReader . METHOD_INFOS ) != IClassFileReader . CONSTANT_POOL ) { this . methods = new MethodInfo [ this . methodsCount ] ; MethodInfo method ; for ( int i = 0 ; i < this . methodsCount ; i ++ ) { method = new MethodInfo ( classFileBytes , this . constantPool , readOffset , decodingFlags ) ; this . methods [ i ] = method ; readOffset += method . sizeInBytes ( ) ; } } else { for ( int i = 0 ; i < this . methodsCount ; i ++ ) { int attributeCountForMethod = u2At ( classFileBytes , 6 , readOffset ) ; readOffset += 8 ; if ( attributeCountForMethod != 0 ) { for ( int j = 0 ; j < attributeCountForMethod ; j ++ ) { int attributeLength = ( int ) u4At ( classFileBytes , 2 , readOffset ) ; readOffset += ( 6 + attributeLength ) ; } } } } } this . attributesCount = u2At ( classFileBytes , readOffset , 0 ) ; readOffset += 2 ; int attributesIndex = 0 ; this . attributes = ClassFileAttribute . NO_ATTRIBUTES ; if ( this . attributesCount != 0 ) { if ( ( decodingFlags & IClassFileReader . CLASSFILE_ATTRIBUTES ) != IClassFileReader . CONSTANT_POOL ) { this . attributes = new IClassFileAttribute [ this . attributesCount ] ; for ( int i = 0 ; i < this . attributesCount ; i ++ ) { int utf8Offset = constantPoolOffsets [ u2At ( classFileBytes , readOffset , 0 ) ] ; char [ ] attributeName = utf8At ( classFileBytes , utf8Offset + 3 , 0 , u2At ( classFileBytes , utf8Offset + 1 , 0 ) ) ; if ( equals ( attributeName , IAttributeNamesConstants . INNER_CLASSES ) ) { this . innerClassesAttribute = new InnerClassesAttribute ( classFileBytes , this . constantPool , readOffset ) ; this . attributes [ attributesIndex ++ ] = this . innerClassesAttribute ; } else if ( equals ( attributeName , IAttributeNamesConstants . SOURCE ) ) { this . sourceFileAttribute = new SourceFileAttribute ( classFileBytes , this . constantPool , readOffset ) ; this . attributes [ attributesIndex ++ ] = this . sourceFileAttribute ; } else if ( equals ( attributeName , IAttributeNamesConstants . ENCLOSING_METHOD ) ) { this . attributes [ attributesIndex ++ ] = new EnclosingMethodAttribute ( classFileBytes , this . constantPool , readOffset ) ; } else if ( equals ( attributeName , IAttributeNamesConstants . SIGNATURE ) ) { this . attributes [ attributesIndex ++ ] = new SignatureAttribute ( classFileBytes , this . constantPool , readOffset ) ; } else if ( equals ( attributeName , IAttributeNamesConstants . RUNTIME_VISIBLE_ANNOTATIONS ) ) { this . attributes [ attributesIndex ++ ] = new RuntimeVisibleAnnotationsAttribute ( classFileBytes , this . constantPool , readOffset ) ; } else if ( equals ( attributeName , IAttributeNamesConstants . RUNTIME_INVISIBLE_ANNOTATIONS ) ) { this . attributes [ attributesIndex ++ ] = new RuntimeInvisibleAnnotationsAttribute ( classFileBytes , this . constantPool , readOffset ) ; } else { this . attributes [ attributesIndex ++ ] = new ClassFileAttribute ( classFileBytes , this . constantPool , readOffset ) ; } readOffset += ( 6 + u4At ( classFileBytes , readOffset + 2 , 0 ) ) ; } } else { for ( int i = 0 ; i < this . attributesCount ; i ++ ) { readOffset += ( 6 + u4At ( classFileBytes , readOffset + 2 , 0 ) ) ; } } } if ( readOffset != classFileBytes . length ) { throw new ClassFormatException ( ClassFormatException . TOO_MANY_BYTES ) ; } } catch ( ClassFormatException e ) { throw e ; } catch ( Exception e ) { e . printStackTrace ( ) ; throw new ClassFormatException ( ClassFormatException . ERROR_TRUNCATED_INPUT ) ; } } public int getAccessFlags ( ) { return this . accessFlags ; } public int getAttributeCount ( ) { return this . attributesCount ; } public IClassFileAttribute [ ] getAttributes ( ) { return this . attributes ; } public int getClassIndex ( ) { return this . classNameIndex ; } public char [ ] getClassName ( ) { return this . className ; } private char [ ] getConstantClassNameAt ( byte [ ] classFileBytes , int [ ] constantPoolOffsets , int constantPoolIndex ) { int utf8Offset = constantPoolOffsets [ u2At ( classFileBytes , constantPoolOffsets [ constantPoolIndex ] + 1 , 0 ) ] ; return utf8At ( classFileBytes , utf8Offset + 3 , 0 , u2At ( classFileBytes , utf8Offset + 1 , 0 ) ) ; } public IConstantPool getConstantPool ( ) { return this . constantPool ; } public IFieldInfo [ ] getFieldInfos ( ) { return this . fields ; } public int getFieldsCount ( ) { return this . fieldsCount ; } public IInnerClassesAttribute getInnerClassesAttribute ( ) { return this . innerClassesAttribute ; } public int [ ] getInterfaceIndexes ( ) { return this . interfaceIndexes ; } public char [ ] [ ] getInterfaceNames ( ) { return this . interfaceNames ; } public int getMagic ( ) { return this . magicNumber ; } public int getMajorVersion ( ) { return this . majorVersion ; } public IMethodInfo [ ] getMethodInfos ( ) { return this . methods ; } public int getMethodsCount ( ) { return this . methodsCount ; } public int getMinorVersion ( ) { return this . minorVersion ; } public ISourceAttribute getSourceFileAttribute ( ) { return this . sourceFileAttribute ; } public int getSuperclassIndex ( ) { return this . superclassNameIndex ; } public char [ ] getSuperclassName ( ) { return this . superclassName ; } public boolean isClass ( ) { return ! isInterface ( ) ; } public boolean isInterface ( ) { return ( getAccessFlags ( ) & IModifierConstants . ACC_INTERFACE ) != 0 ; } } </s>