1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.cf.direct; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttAnnotationDefault; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttCode; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttConstantValue; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttDeprecated; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttEnclosingMethod; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttExceptions; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttInnerClasses; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttLineNumberTable; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttLocalVariableTable; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttLocalVariableTypeTable; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttRuntimeInvisibleAnnotations; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttRuntimeInvisibleParameterAnnotations; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttRuntimeVisibleAnnotations; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttRuntimeVisibleParameterAnnotations; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttSignature; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttSourceFile; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttSynthetic; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.InnerClassList; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.code.ByteCatchList; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.code.BytecodeArray; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.code.LineNumberList; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.code.LocalVariableList; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.Attribute; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ParseException; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ParseObserver; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.StdAttributeList; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.Annotation; 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.AnnotationVisibility; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.Annotations; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.AnnotationsList; 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.AccessFlags; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.ConstantPool; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstNat; 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstType; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstUtf8; 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.TypedConstant; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ByteArray; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Standard subclass of {@link AttributeFactory}, which knows how to parse 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all the standard attribute types. 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class StdAttributeFactory 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extends AttributeFactory { 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** non-null; shared instance of this class */ 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final StdAttributeFactory THE_ONE = 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new StdAttributeFactory(); 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public StdAttributeFactory() { 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This space intentionally left blank. 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected Attribute parse0(DirectClassFile cf, int context, String name, 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset, int length, ParseObserver observer) { 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (context) { 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case CTX_CLASS: { 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttDeprecated.ATTRIBUTE_NAME) { 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return deprecated(cf, offset, length, observer); 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttEnclosingMethod.ATTRIBUTE_NAME) { 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return enclosingMethod(cf, offset, length, observer); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttInnerClasses.ATTRIBUTE_NAME) { 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return innerClasses(cf, offset, length, observer); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME) { 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return runtimeInvisibleAnnotations(cf, offset, length, 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer); 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME) { 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return runtimeVisibleAnnotations(cf, offset, length, 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer); 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttSynthetic.ATTRIBUTE_NAME) { 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return synthetic(cf, offset, length, observer); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttSignature.ATTRIBUTE_NAME) { 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signature(cf, offset, length, observer); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttSourceFile.ATTRIBUTE_NAME) { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sourceFile(cf, offset, length, observer); 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case CTX_FIELD: { 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttConstantValue.ATTRIBUTE_NAME) { 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return constantValue(cf, offset, length, observer); 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttDeprecated.ATTRIBUTE_NAME) { 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return deprecated(cf, offset, length, observer); 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME) { 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return runtimeInvisibleAnnotations(cf, offset, length, 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME) { 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return runtimeVisibleAnnotations(cf, offset, length, 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer); 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttSignature.ATTRIBUTE_NAME) { 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signature(cf, offset, length, observer); 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttSynthetic.ATTRIBUTE_NAME) { 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return synthetic(cf, offset, length, observer); 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case CTX_METHOD: { 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttAnnotationDefault.ATTRIBUTE_NAME) { 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return annotationDefault(cf, offset, length, observer); 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttCode.ATTRIBUTE_NAME) { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return code(cf, offset, length, observer); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttDeprecated.ATTRIBUTE_NAME) { 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return deprecated(cf, offset, length, observer); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttExceptions.ATTRIBUTE_NAME) { 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return exceptions(cf, offset, length, observer); 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME) { 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return runtimeInvisibleAnnotations(cf, offset, length, 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME) { 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return runtimeVisibleAnnotations(cf, offset, length, 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer); 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttRuntimeInvisibleParameterAnnotations. 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ATTRIBUTE_NAME) { 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return runtimeInvisibleParameterAnnotations( 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cf, offset, length, observer); 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttRuntimeVisibleParameterAnnotations. 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ATTRIBUTE_NAME) { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return runtimeVisibleParameterAnnotations( 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cf, offset, length, observer); 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttSignature.ATTRIBUTE_NAME) { 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return signature(cf, offset, length, observer); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttSynthetic.ATTRIBUTE_NAME) { 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return synthetic(cf, offset, length, observer); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case CTX_CODE: { 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttLineNumberTable.ATTRIBUTE_NAME) { 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return lineNumberTable(cf, offset, length, observer); 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttLocalVariableTable.ATTRIBUTE_NAME) { 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return localVariableTable(cf, offset, length, observer); 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (name == AttLocalVariableTypeTable.ATTRIBUTE_NAME) { 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return localVariableTypeTable(cf, offset, length, 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return super.parse0(cf, context, name, offset, length, observer); 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses an <code>AnnotationDefault</code> attribute. 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute annotationDefault(DirectClassFile cf, 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset, int length, ParseObserver observer) { 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwSeverelyTruncated(); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationParser ap = 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new AnnotationParser(cf, offset, length, observer); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Constant cst = ap.parseValueAttribute(); 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttAnnotationDefault(cst, length); 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>Code</code> attribute. 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute code(DirectClassFile cf, int offset, int length, 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParseObserver observer) { 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 12) { 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwSeverelyTruncated(); 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ConstantPool pool = cf.getConstantPool(); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxStack = bytes.getUnsignedShort(offset); // u2 max_stack 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxLocals = bytes.getUnsignedShort(offset + 2); // u2 max_locals 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int codeLength = bytes.getInt(offset + 4); // u4 code_length 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int origOffset = offset; 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "max_stack: " + Hex.u2(maxStack)); 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset + 2, 2, 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "max_locals: " + Hex.u2(maxLocals)); 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset + 4, 4, 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "code_length: " + Hex.u4(codeLength)); 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += 8; 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length -= 8; 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < (codeLength + 4)) { 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwTruncated(); 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int codeOffset = offset; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += codeLength; 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length -= codeLength; 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project BytecodeArray code = 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new BytecodeArray(bytes.slice(codeOffset, codeOffset + codeLength), 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pool); 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project code.forEach(new CodeObserver(code.getBytes(), observer)); 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // u2 exception_table_length 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int exceptionTableLength = bytes.getUnsignedShort(offset); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteCatchList catches = (exceptionTableLength == 0) ? 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteCatchList.EMPTY : 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new ByteCatchList(exceptionTableLength); 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "exception_table_length: " + 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hex.u2(exceptionTableLength)); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += 2; 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length -= 2; 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < (exceptionTableLength * 8 + 2)) { 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwTruncated(); 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < exceptionTableLength; i++) { 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.changeIndent(1); 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int startPc = bytes.getUnsignedShort(offset); 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int endPc = bytes.getUnsignedShort(offset + 2); 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int handlerPc = bytes.getUnsignedShort(offset + 4); 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int catchTypeIdx = bytes.getUnsignedShort(offset + 6); 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstType catchType = (CstType) pool.get0Ok(catchTypeIdx); 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catches.set(i, startPc, endPc, handlerPc, catchType); 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 8, 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hex.u2(startPc) + ".." + Hex.u2(endPc) + 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " -> " + Hex.u2(handlerPc) + " " + 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((catchType == null) ? "<any>" : 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchType.toHuman())); 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += 8; 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length -= 8; 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.changeIndent(-1); 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catches.setImmutable(); 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AttributeListParser parser = 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new AttributeListParser(cf, CTX_CODE, offset, this); 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parser.setObserver(observer); 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StdAttributeList attributes = parser.getList(); 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project attributes.setImmutable(); 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int attributeByteCount = parser.getEndOffset() - offset; 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (attributeByteCount != length) { 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwBadLength(attributeByteCount + (offset - origOffset)); 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttCode(maxStack, maxLocals, code, catches, attributes); 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>ConstantValue</code> attribute. 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute constantValue(DirectClassFile cf, int offset, int length, 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParseObserver observer) { 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != 2) { 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwBadLength(2); 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ConstantPool pool = cf.getConstantPool(); 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx = bytes.getUnsignedShort(offset); 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypedConstant cst = (TypedConstant) pool.get(idx); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Attribute result = new AttConstantValue(cst); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, "value: " + cst); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>Deprecated</code> attribute. 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute deprecated(DirectClassFile cf, int offset, int length, 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParseObserver observer) { 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != 0) { 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwBadLength(0); 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttDeprecated(); 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses an <code>EnclosingMethod</code> attribute. 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute enclosingMethod(DirectClassFile cf, int offset, 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length, ParseObserver observer) { 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != 4) { 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwBadLength(4); 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ConstantPool pool = cf.getConstantPool(); 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx = bytes.getUnsignedShort(offset); 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstType type = (CstType) pool.get(idx); 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project idx = bytes.getUnsignedShort(offset + 2); 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstNat method = (CstNat) pool.get0Ok(idx); 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Attribute result = new AttEnclosingMethod(type, method); 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, "class: " + type); 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset + 2, 2, "method: " + 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DirectClassFile.stringOrNone(method)); 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses an <code>Exceptions</code> attribute. 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute exceptions(DirectClassFile cf, int offset, int length, 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParseObserver observer) { 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwSeverelyTruncated(); 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = bytes.getUnsignedShort(offset); // number_of_exceptions 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "number_of_exceptions: " + Hex.u2(count)); 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += 2; 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length -= 2; 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != (count * 2)) { 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwBadLength((count * 2) + 2); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeList list = cf.makeTypeList(offset, count); 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttExceptions(list); 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses an <code>InnerClasses</code> attribute. 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute innerClasses(DirectClassFile cf, int offset, int length, 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParseObserver observer) { 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwSeverelyTruncated(); 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ConstantPool pool = cf.getConstantPool(); 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = bytes.getUnsignedShort(offset); // number_of_classes 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "number_of_classes: " + Hex.u2(count)); 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += 2; 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length -= 2; 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != (count * 8)) { 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwBadLength((count * 8) + 2); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InnerClassList list = new InnerClassList(count); 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < count; i++) { 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int innerClassIdx = bytes.getUnsignedShort(offset); 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int outerClassIdx = bytes.getUnsignedShort(offset + 2); 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nameIdx = bytes.getUnsignedShort(offset + 4); 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int accessFlags = bytes.getUnsignedShort(offset + 6); 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstType innerClass = (CstType) pool.get(innerClassIdx); 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstType outerClass = (CstType) pool.get0Ok(outerClassIdx); 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstUtf8 name = (CstUtf8) pool.get0Ok(nameIdx); 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project list.set(i, innerClass, outerClass, name, accessFlags); 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "inner_class: " + 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DirectClassFile.stringOrNone(innerClass)); 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset + 2, 2, 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " outer_class: " + 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DirectClassFile.stringOrNone(outerClass)); 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset + 4, 2, 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " name: " + 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DirectClassFile.stringOrNone(name)); 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset + 6, 2, 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " access_flags: " + 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AccessFlags.innerClassString(accessFlags)); 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += 8; 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project list.setImmutable(); 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttInnerClasses(list); 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>LineNumberTable</code> attribute. 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute lineNumberTable(DirectClassFile cf, int offset, 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length, ParseObserver observer) { 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwSeverelyTruncated(); 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = bytes.getUnsignedShort(offset); // line_number_table_length 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "line_number_table_length: " + Hex.u2(count)); 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += 2; 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length -= 2; 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != (count * 4)) { 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwBadLength((count * 4) + 2); 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LineNumberList list = new LineNumberList(count); 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < count; i++) { 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int startPc = bytes.getUnsignedShort(offset); 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int lineNumber = bytes.getUnsignedShort(offset + 2); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project list.set(i, startPc, lineNumber); 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 4, 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hex.u2(startPc) + " " + lineNumber); 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += 4; 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project list.setImmutable(); 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttLineNumberTable(list); 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>LocalVariableTable</code> attribute. 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute localVariableTable(DirectClassFile cf, int offset, 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length, ParseObserver observer) { 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwSeverelyTruncated(); 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = bytes.getUnsignedShort(offset); 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "local_variable_table_length: " + Hex.u2(count)); 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalVariableList list = parseLocalVariables( 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytes.slice(offset + 2, offset + length), cf.getConstantPool(), 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer, count, false); 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttLocalVariableTable(list); 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>LocalVariableTypeTable</code> attribute. 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute localVariableTypeTable(DirectClassFile cf, int offset, 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length, ParseObserver observer) { 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwSeverelyTruncated(); 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = bytes.getUnsignedShort(offset); 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "local_variable_type_table_length: " + Hex.u2(count)); 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalVariableList list = parseLocalVariables( 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytes.slice(offset + 2, offset + length), cf.getConstantPool(), 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer, count, true); 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttLocalVariableTypeTable(list); 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the table part of either a <code>LocalVariableTable</code> 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or a <code>LocalVariableTypeTable</code>. 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param bytes non-null; bytes to parse, which should <i>only</i> 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contain the table data (no header) 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param pool non-null; constant pool to use 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param count >= 0; the number of entries 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param typeTable <code>true</code> iff this is for a type table 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return non-null; the constructed list 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private LocalVariableList parseLocalVariables(ByteArray bytes, 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ConstantPool pool, ParseObserver observer, int count, 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean typeTable) { 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytes.size() != (count * 10)) { 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // "+ 2" is for the count. 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwBadLength((count * 10) + 2); 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray.MyDataInputStream in = bytes.makeDataInputStream(); 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalVariableList list = new LocalVariableList(count); 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < count; i++) { 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int startPc = in.readUnsignedShort(); 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length = in.readUnsignedShort(); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nameIdx = in.readUnsignedShort(); 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int typeIdx = in.readUnsignedShort(); 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int index = in.readUnsignedShort(); 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstUtf8 name = (CstUtf8) pool.get(nameIdx); 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstUtf8 type = (CstUtf8) pool.get(typeIdx); 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstUtf8 descriptor = null; 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstUtf8 signature = null; 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (typeTable) { 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = type; 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project descriptor = type; 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project list.set(i, startPc, length, name, 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project descriptor, signature, index); 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, i * 10, 10, Hex.u2(startPc) + 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ".." + Hex.u2(startPc + length) + " " + 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hex.u2(index) + " " + name.toHuman() + " " + 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type.toHuman()); 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException ex) { 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("shouldn't happen", ex); 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project list.setImmutable(); 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return list; 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>RuntimeInvisibleAnnotations</code> attribute. 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute runtimeInvisibleAnnotations(DirectClassFile cf, 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset, int length, ParseObserver observer) { 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwSeverelyTruncated(); 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationParser ap = 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new AnnotationParser(cf, offset, length, observer); 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Annotations annotations = 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ap.parseAnnotationAttribute(AnnotationVisibility.BUILD); 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttRuntimeInvisibleAnnotations(annotations, length); 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>RuntimeVisibleAnnotations</code> attribute. 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute runtimeVisibleAnnotations(DirectClassFile cf, 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset, int length, ParseObserver observer) { 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwSeverelyTruncated(); 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationParser ap = 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new AnnotationParser(cf, offset, length, observer); 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Annotations annotations = 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ap.parseAnnotationAttribute(AnnotationVisibility.RUNTIME); 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttRuntimeVisibleAnnotations(annotations, length); 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>RuntimeInvisibleParameterAnnotations</code> attribute. 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute runtimeInvisibleParameterAnnotations(DirectClassFile cf, 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset, int length, ParseObserver observer) { 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwSeverelyTruncated(); 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationParser ap = 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new AnnotationParser(cf, offset, length, observer); 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationsList list = 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ap.parseParameterAttribute(AnnotationVisibility.BUILD); 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttRuntimeInvisibleParameterAnnotations(list, length); 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>RuntimeVisibleParameterAnnotations</code> attribute. 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute runtimeVisibleParameterAnnotations(DirectClassFile cf, 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset, int length, ParseObserver observer) { 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length < 2) { 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwSeverelyTruncated(); 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationParser ap = 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new AnnotationParser(cf, offset, length, observer); 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AnnotationsList list = 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ap.parseParameterAttribute(AnnotationVisibility.RUNTIME); 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttRuntimeVisibleParameterAnnotations(list, length); 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>Signature</code> attribute. 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute signature(DirectClassFile cf, int offset, int length, 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParseObserver observer) { 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != 2) { 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwBadLength(2); 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ConstantPool pool = cf.getConstantPool(); 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx = bytes.getUnsignedShort(offset); 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstUtf8 cst = (CstUtf8) pool.get(idx); 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Attribute result = new AttSignature(cst); 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, "signature: " + cst); 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>SourceFile</code> attribute. 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute sourceFile(DirectClassFile cf, int offset, int length, 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParseObserver observer) { 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != 2) { 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwBadLength(2); 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArray bytes = cf.getBytes(); 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ConstantPool pool = cf.getConstantPool(); 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx = bytes.getUnsignedShort(offset); 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstUtf8 cst = (CstUtf8) pool.get(idx); 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Attribute result = new AttSourceFile(cst); 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, "source: " + cst); 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parses a <code>Synthetic</code> attribute. 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Attribute synthetic(DirectClassFile cf, int offset, int length, 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParseObserver observer) { 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != 0) { 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwBadLength(0); 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new AttSynthetic(); 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Throws the right exception when a known attribute has a way too short 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * length. 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return never 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws ParseException always thrown 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static Attribute throwSeverelyTruncated() { 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new ParseException("severely truncated attribute"); 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Throws the right exception when a known attribute has a too short 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * length. 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return never 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws ParseException always thrown 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static Attribute throwTruncated() { 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new ParseException("truncated attribute"); 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Throws the right exception when an attribute has an unexpected length 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (given its contents). 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param expected expected length 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return never 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws ParseException always thrown 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static Attribute throwBadLength(int expected) { 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new ParseException("bad attribute length; expected length " + 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Hex.u4(expected)); 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 765