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 &gt;= 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