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 19b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonimport com.android.dx.cf.attrib.AttBootstrapMethods; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttSourceFile; 21b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonimport com.android.dx.cf.code.BootstrapMethodsList; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.cst.ConstantPoolParser; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.Attribute; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.AttributeList; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ClassFile; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.FieldList; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.MethodList; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ParseException; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ParseObserver; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.StdAttributeList; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.AccessFlags; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.ConstantPool; 33333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilsonimport com.android.dx.rop.cst.CstString; 34fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.cst.CstType; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.StdConstantPool; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ByteArray; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Class file with info taken from a {@code byte[]} or slice thereof. 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class DirectClassFile implements ClassFile { 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** the expected value of the ClassFile.magic field */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int CLASS_FILE_MAGIC = 0xcafebabe; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * minimum {@code .class} file major version 51de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 52092412605d5d500456e9fff475c90691e668b914Elliott Hughes * See http://en.wikipedia.org/wiki/Java_class_file for an up-to-date 53092412605d5d500456e9fff475c90691e668b914Elliott Hughes * list of version numbers. Currently known (taken from that table) are: 54de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 556988f303309054c572876156e2f46d539419a73dTobias Thierer * Java SE 9 = 53 (0x35 hex), 566988f303309054c572876156e2f46d539419a73dTobias Thierer * Java SE 8 = 52 (0x34 hex), 576988f303309054c572876156e2f46d539419a73dTobias Thierer * Java SE 7 = 51 (0x33 hex), 586988f303309054c572876156e2f46d539419a73dTobias Thierer * Java SE 6.0 = 50 (0x32 hex), 596988f303309054c572876156e2f46d539419a73dTobias Thierer * Java SE 5.0 = 49 (0x31 hex), 60092412605d5d500456e9fff475c90691e668b914Elliott Hughes * JDK 1.4 = 48 (0x30 hex), 61092412605d5d500456e9fff475c90691e668b914Elliott Hughes * JDK 1.3 = 47 (0x2F hex), 62092412605d5d500456e9fff475c90691e668b914Elliott Hughes * JDK 1.2 = 46 (0x2E hex), 63092412605d5d500456e9fff475c90691e668b914Elliott Hughes * JDK 1.1 = 45 (0x2D hex). 64de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Valid ranges are typically of the form 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "A.0 through B.C inclusive" where A <= B and C >= 0, 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION. 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int CLASS_FILE_MIN_MAJOR_VERSION = 45; 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 71092412605d5d500456e9fff475c90691e668b914Elliott Hughes /** 72092412605d5d500456e9fff475c90691e668b914Elliott Hughes * maximum {@code .class} file major version 73092412605d5d500456e9fff475c90691e668b914Elliott Hughes * 74092412605d5d500456e9fff475c90691e668b914Elliott Hughes * Note: if you change this, please change "java.class.version" in System.java. 75092412605d5d500456e9fff475c90691e668b914Elliott Hughes */ 766988f303309054c572876156e2f46d539419a73dTobias Thierer private static final int CLASS_FILE_MAX_MAJOR_VERSION = 53; 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** maximum {@code .class} file minor version */ 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int CLASS_FILE_MAX_MINOR_VERSION = 0; 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code non-null;} the file path for the class, excluding any base directory 83de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * specification 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final String filePath; 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 8799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} the bytes of the file */ 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ByteArray bytes; 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * whether to be strict about parsing; if 9299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code false}, this avoids doing checks that only exist 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for purposes of verification (such as magic number matching and 94de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * path-package consistency checking) 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean strictParse; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 9999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the constant pool; only ever {@code null} 100de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * before the constant pool is successfully parsed 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private StdConstantPool pool; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the class file field {@code access_flags}; will be {@code -1} 106de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * before the file is successfully parsed 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int accessFlags; 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 11199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the class file field {@code this_class}, 11299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * interpreted as a type constant; only ever {@code null} 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * before the file is successfully parsed 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private CstType thisClass; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 11899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the class file field {@code super_class}, interpreted 119de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * as a type constant if non-zero 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private CstType superClass; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 12499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the class file field {@code interfaces}; only 12599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * ever {@code null} before the file is successfully 126de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * parsed 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private TypeList interfaces; 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the class file field {@code fields}; only ever 132de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * {@code null} before the file is successfully parsed 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private FieldList fields; 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 13799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the class file field {@code methods}; only ever 138de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * {@code null} before the file is successfully parsed 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private MethodList methods; 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 14399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the class file field {@code attributes}; only 14499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * ever {@code null} before the file is successfully 145de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * parsed 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private StdAttributeList attributes; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 14999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} attribute factory, if any */ 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private AttributeFactory attributeFactory; 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 15299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} parse observer, if any */ 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private ParseObserver observer; 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 15699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Returns the string form of an object or {@code "(none)"} 15799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * (rather than {@code "null"}) for {@code null}. 158de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 15999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param obj {@code null-ok;} the object to stringify 16099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the appropriate string form 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static String stringOrNone(Object obj) { 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == null) { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return "(none)"; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return obj.toString(); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 172de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 17399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param bytes {@code non-null;} the bytes of the file 17499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param filePath {@code non-null;} the file path for the class, 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * excluding any base directory specification 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param strictParse whether to be strict about parsing; if 17799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code false}, this avoids doing checks that only exist 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for purposes of verification (such as magic number matching and 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * path-package consistency checking) 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public DirectClassFile(ByteArray bytes, String filePath, 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean strictParse) { 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytes == null) { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("bytes == null"); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (filePath == null) { 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("filePath == null"); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.filePath = filePath; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.bytes = bytes; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.strictParse = strictParse; 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.accessFlags = -1; 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 199de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 20099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param bytes {@code non-null;} the bytes of the file 20199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param filePath {@code non-null;} the file path for the class, 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * excluding any base directory specification 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param strictParse whether to be strict about parsing; if 20499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code false}, this avoids doing checks that only exist 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for purposes of verification (such as magic number matching and 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * path-package consistency checking) 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public DirectClassFile(byte[] bytes, String filePath, 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean strictParse) { 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(new ByteArray(bytes), filePath, strictParse); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the parse observer for this instance. 215de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 21699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param observer {@code null-ok;} the observer 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void setObserver(ParseObserver observer) { 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.observer = observer; 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the attribute factory to use. 224de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 22599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param attributeFactory {@code non-null;} the attribute factory 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void setAttributeFactory(AttributeFactory attributeFactory) { 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (attributeFactory == null) { 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("attributeFactory == null"); 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.attributeFactory = attributeFactory; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 2364c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche * Gets the path where this class file is located. 2374c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche * 2384c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche * @return {@code non-null;} the filePath 2394c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche */ 2404c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche public String getFilePath() { 2414c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche return filePath; 2424c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche } 2434c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche 2444c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche /** 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the {@link ByteArray} that this instance's data comes from. 246de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 24799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the bytes 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ByteArray getBytes() { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytes; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 2549dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getMagic() { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToInterfacesIfNecessary(); 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getMagic0(); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 2619dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getMinorVersion() { 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToInterfacesIfNecessary(); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getMinorVersion0(); 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 2689dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getMajorVersion() { 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToInterfacesIfNecessary(); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return getMajorVersion0(); 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 2759dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getAccessFlags() { 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToInterfacesIfNecessary(); 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return accessFlags; 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 2829dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public CstType getThisClass() { 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToInterfacesIfNecessary(); 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return thisClass; 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 2899dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public CstType getSuperclass() { 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToInterfacesIfNecessary(); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return superClass; 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 2969dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ConstantPool getConstantPool() { 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToInterfacesIfNecessary(); 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pool; 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 3039dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeList getInterfaces() { 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToInterfacesIfNecessary(); 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return interfaces; 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 3109dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public FieldList getFields() { 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToEndIfNecessary(); 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return fields; 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 3179dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public MethodList getMethods() { 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToEndIfNecessary(); 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return methods; 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 3249dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public AttributeList getAttributes() { 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parseToEndIfNecessary(); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return attributes; 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 331b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson @Override 332b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson public BootstrapMethodsList getBootstrapMethods() { 333b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson AttBootstrapMethods bootstrapMethodsAttribute = 334b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson (AttBootstrapMethods) getAttributes().findFirst(AttBootstrapMethods.ATTRIBUTE_NAME); 335b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson if (bootstrapMethodsAttribute != null) { 336b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson return bootstrapMethodsAttribute.getBootstrapMethods(); 337b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson } else { 338b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson return BootstrapMethodsList.EMPTY; 339b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson } 340b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson } 341b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson 342b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson /** {@inheritDoc} */ 3439dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 344333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson public CstString getSourceFile() { 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AttributeList attribs = getAttributes(); 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Attribute attSf = attribs.findFirst(AttSourceFile.ATTRIBUTE_NAME); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (attSf instanceof AttSourceFile) { 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((AttSourceFile) attSf).getSourceFile(); 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs and returns an instance of {@link TypeList} whose 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * data comes from the bytes of this instance, interpreted as a 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * list of constant pool indices for classes, which are in turn 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * translated to type constants. Instance construction will fail 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if any of the (alleged) indices turn out not to refer to 36199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * constant pool entries of type {@code Class}. 362de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param offset offset into {@link #bytes} for the start of the 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * data 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param size number of elements in the list (not number of bytes) 36699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed class list 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeList makeTypeList(int offset, int size) { 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size == 0) { 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return StdTypeList.EMPTY; 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pool == null) { 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalStateException("pool not yet initialized"); 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 376de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new DcfTypeList(bytes, offset, size, pool, observer); 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 38199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the class file field {@code magic}, but without doing any 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * checks or parsing first. 383de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the magic value 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getMagic0() { 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytes.getInt(0); 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 39199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the class file field {@code minor_version}, but 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * without doing any checks or parsing first. 393de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the minor version 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getMinorVersion0() { 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytes.getUnsignedShort(4); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 40199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the class file field {@code major_version}, but 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * without doing any checks or parsing first. 403de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the major version 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getMajorVersion0() { 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytes.getUnsignedShort(6); 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Runs {@link #parse} if it has not yet been run to cover up to 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the interfaces list. 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void parseToInterfacesIfNecessary() { 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (accessFlags == -1) { 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parse(); 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Runs {@link #parse} if it has not yet been run successfully. 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void parseToEndIfNecessary() { 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (attributes == null) { 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parse(); 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does the parsing, handing exceptions. 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void parse() { 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parse0(); 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (ParseException ex) { 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ex.addContext("...while parsing " + filePath); 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw ex; 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (RuntimeException ex) { 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParseException pe = new ParseException(ex); 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pe.addContext("...while parsing " + filePath); 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw pe; 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 44645fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin * Sees if the .class file header magic has the good value. 447de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param magic the value of a classfile "magic" field 44945fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin * @return true if the magic is valid 45045fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin */ 45145fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin private boolean isGoodMagic(int magic) { 45245fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin return magic == CLASS_FILE_MAGIC; 45345fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin } 45445fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin 45545fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin /** 45645fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin * Sees if the .class file header version are within 45745fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin * range. 45845fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin * 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param minorVersion the value of a classfile "minor_version" field 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param majorVersion the value of a classfile "major_version" field 46145fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin * @return true if the parameters are valid and within range 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 46345fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin private boolean isGoodVersion(int minorVersion, int majorVersion) { 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Valid version ranges are typically of the form 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "A.0 through B.C inclusive" where A <= B and C >= 0, 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION. 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 46845fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin if (minorVersion >= 0) { 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Check against max first to handle the case where 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MIN_MAJOR == MAX_MAJOR. 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (majorVersion == CLASS_FILE_MAX_MAJOR_VERSION) { 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (minorVersion <= CLASS_FILE_MAX_MINOR_VERSION) { 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (majorVersion < CLASS_FILE_MAX_MAJOR_VERSION && 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project majorVersion >= CLASS_FILE_MIN_MAJOR_VERSION) { 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does the actual parsing. 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void parse0() { 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytes.size() < 10) { 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new ParseException("severely truncated class file"); 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, 0, 0, "begin classfile"); 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, 0, 4, "magic: " + Hex.u4(getMagic0())); 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, 4, 2, 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "minor_version: " + Hex.u2(getMinorVersion0())); 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, 6, 2, 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "major_version: " + Hex.u2(getMajorVersion0())); 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strictParse) { 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Make sure that this looks like a valid class file with a 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * version that we can handle. 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 50645fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin if (!isGoodMagic(getMagic0())) { 50745fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin throw new ParseException("bad class file magic (" + Hex.u4(getMagic0()) + ")"); 50845fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin } 50945fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin 51045fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin if (!isGoodVersion(getMinorVersion0(), getMajorVersion0())) { 51145fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin throw new ParseException("unsupported class file version " + 51245fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin getMajorVersion0() + "." + 51345fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin getMinorVersion0()); 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ConstantPoolParser cpParser = new ConstantPoolParser(bytes); 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cpParser.setObserver(observer); 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pool = cpParser.getPool(); 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pool.setImmutable(); 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int at = cpParser.getEndOffset(); 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int accessFlags = bytes.getUnsignedShort(at); // u2 access_flags; 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cpi = bytes.getUnsignedShort(at + 2); // u2 this_class; 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisClass = (CstType) pool.get(cpi); 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cpi = bytes.getUnsignedShort(at + 4); // u2 super_class; 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project superClass = (CstType) pool.get0Ok(cpi); 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = bytes.getUnsignedShort(at + 6); // u2 interfaces_count 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, at, 2, 532de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro "access_flags: " + 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AccessFlags.classString(accessFlags)); 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, at + 2, 2, "this_class: " + thisClass); 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, at + 4, 2, "super_class: " + 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stringOrNone(superClass)); 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, at + 6, 2, 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "interfaces_count: " + Hex.u2(count)); 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count != 0) { 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, at + 8, 0, "interfaces:"); 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at += 8; 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interfaces = makeTypeList(at, count); 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at += count * 2; 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strictParse) { 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure that the file/jar path matches the declared 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * package/class name. 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String thisClassName = thisClass.getClassType().getClassName(); 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(filePath.endsWith(".class") && 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project filePath.startsWith(thisClassName) && 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (filePath.length() == (thisClassName.length() + 6)))) { 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new ParseException("class name (" + thisClassName + 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ") does not match path (" + 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project filePath + ")"); 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Only set the instance variable accessFlags here, since 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that's what signals a successful parse of the first part of 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the file (through the interfaces list). 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.accessFlags = accessFlags; 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FieldListParser flParser = 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new FieldListParser(this, thisClass, at, attributeFactory); 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flParser.setObserver(observer); 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fields = flParser.getList(); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at = flParser.getEndOffset(); 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodListParser mlParser = 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new MethodListParser(this, thisClass, at, attributeFactory); 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mlParser.setObserver(observer); 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methods = mlParser.getList(); 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at = mlParser.getEndOffset(); 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AttributeListParser alParser = 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new AttributeListParser(this, AttributeFactory.CTX_CLASS, at, 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project attributeFactory); 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project alParser.setObserver(observer); 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project attributes = alParser.getList(); 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project attributes.setImmutable(); 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at = alParser.getEndOffset(); 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (at != bytes.size()) { 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new ParseException("extra bytes at end of class file, " + 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "at offset " + Hex.u4(at)); 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, at, 0, "end classfile"); 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implementation of {@link TypeList} whose data comes directly 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from the bytes of an instance of this (outer) class, 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interpreted as a list of constant pool indices for classes 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which are in turn returned as type constants. Instance 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * construction will fail if any of the (alleged) indices turn out 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not to refer to constant pool entries of type 60799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code Class}. 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static class DcfTypeList implements TypeList { 61099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} array containing the data */ 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ByteArray bytes; 612de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** number of elements in the list (not number of bytes) */ 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int size; 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} the constant pool */ 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final StdConstantPool pool; 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 621de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 62299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param bytes {@code non-null;} original classfile's bytes 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param offset offset into {@link #bytes} for the start of the 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * data 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param size number of elements in the list (not number of bytes) 62699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param pool {@code non-null;} the constant pool to use 62799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param observer {@code null-ok;} parse observer to use, if any 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public DcfTypeList(ByteArray bytes, int offset, int size, 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StdConstantPool pool, ParseObserver observer) { 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size < 0) { 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("size < 0"); 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bytes = bytes.slice(offset, offset + size * 2); 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.bytes = bytes; 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.size = size; 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.pool = pool; 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < size; i++) { 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = i * 2; 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx = bytes.getUnsignedShort(offset); 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstType type; 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = (CstType) pool.get(idx); 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (ClassCastException ex) { 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Translate the exception. 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("bogus class cpi", ex); 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (observer != null) { 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project observer.parsed(bytes, offset, 2, " " + type); 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 6579dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isMutable() { 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 6639dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int size() { 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return size; 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 6699dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getWordCount() { 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // It is the same as size because all elements are classes. 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return size; 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 6769dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Type getType(int n) { 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx = bytes.getUnsignedShort(n * 2); 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((CstType) pool.get(idx)).getClassType(); 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 6839dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeList withAddedType(Type type) { 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new UnsupportedOperationException("unsupported"); 686de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro } 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 689