OSDN Git Service

Don't emit multiple copies of annotations when merging dex files.
[android-x86/dalvik.git] / dx / src / com / android / dx / io / EncodedValueReader.java
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.dx.io;
18
19 import com.android.dx.util.ByteInput;
20 import com.android.dx.util.Leb128Utils;
21
22 /**
23  * SAX-style reader for encoded values.
24  * TODO: convert this to a pull-style reader
25  */
26 public class EncodedValueReader {
27     public static final int ENCODED_BYTE = 0x00;
28     public static final int ENCODED_SHORT = 0x02;
29     public static final int ENCODED_CHAR = 0x03;
30     public static final int ENCODED_INT = 0x04;
31     public static final int ENCODED_LONG = 0x06;
32     public static final int ENCODED_FLOAT = 0x10;
33     public static final int ENCODED_DOUBLE = 0x11;
34     public static final int ENCODED_STRING = 0x17;
35     public static final int ENCODED_TYPE = 0x18;
36     public static final int ENCODED_FIELD = 0x19;
37     public static final int ENCODED_ENUM = 0x1b;
38     public static final int ENCODED_METHOD = 0x1a;
39     public static final int ENCODED_ARRAY = 0x1c;
40     public static final int ENCODED_ANNOTATION = 0x1d;
41     public static final int ENCODED_NULL = 0x1e;
42     public static final int ENCODED_BOOLEAN = 0x1f;
43
44     protected final ByteInput in;
45
46     public EncodedValueReader(ByteInput in) {
47         this.in = in;
48     }
49
50     public EncodedValueReader(EncodedValue in) {
51         this(in.asByteInput());
52     }
53
54     public final void readArray() {
55         int size = Leb128Utils.readUnsignedLeb128(in);
56         visitArray(size);
57
58         for (int i = 0; i < size; i++) {
59             readValue();
60         }
61     }
62
63     public final void readAnnotation() {
64         int typeIndex = Leb128Utils.readUnsignedLeb128(in);
65         int size = Leb128Utils.readUnsignedLeb128(in);
66         visitAnnotation(typeIndex, size);
67
68         for (int i = 0; i < size; i++) {
69             visitAnnotationName(Leb128Utils.readUnsignedLeb128(in));
70             readValue();
71         }
72     }
73
74     public final void readValue() {
75         int argAndType = in.readByte() & 0xff;
76         int type = argAndType & 0x1f;
77         int arg = (argAndType & 0xe0) >> 5;
78         int size = arg + 1;
79
80         switch (type) {
81         case ENCODED_BYTE:
82         case ENCODED_SHORT:
83         case ENCODED_CHAR:
84         case ENCODED_INT:
85         case ENCODED_LONG:
86         case ENCODED_FLOAT:
87         case ENCODED_DOUBLE:
88             visitPrimitive(argAndType, type, arg, size);
89             break;
90         case ENCODED_STRING:
91             visitString(type, readIndex(in, size));
92             break;
93         case ENCODED_TYPE:
94             visitType(type, readIndex(in, size));
95             break;
96         case ENCODED_FIELD:
97         case ENCODED_ENUM:
98             visitField(type, readIndex(in, size));
99             break;
100         case ENCODED_METHOD:
101             visitMethod(type, readIndex(in, size));
102             break;
103         case ENCODED_ARRAY:
104             visitArrayValue(argAndType);
105             readArray();
106             break;
107         case ENCODED_ANNOTATION:
108             visitAnnotationValue(argAndType);
109             readAnnotation();
110             break;
111         case ENCODED_NULL:
112             visitEncodedNull(argAndType);
113             break;
114         case ENCODED_BOOLEAN:
115             visitEncodedBoolean(argAndType);
116             break;
117         }
118     }
119
120     protected void visitArray(int size) {}
121     protected void visitAnnotation(int typeIndex, int size) {}
122     protected void visitAnnotationName(int nameIndex) {}
123     protected void visitPrimitive(int argAndType, int type, int arg, int size) {
124         for (int i = 0; i < size; i++) {
125             in.readByte();
126         }
127     }
128     protected void visitString(int type, int index) {}
129     protected void visitType(int type, int index) {}
130     protected void visitField(int type, int index) {}
131     protected void visitMethod(int type, int index) {}
132     protected void visitArrayValue(int argAndType) {}
133     protected void visitAnnotationValue(int argAndType) {}
134     protected void visitEncodedBoolean(int argAndType) {}
135     protected void visitEncodedNull(int argAndType) {}
136
137     private int readIndex(ByteInput in, int byteCount) {
138         int result = 0;
139         int shift = 0;
140         for (int i = 0; i < byteCount; i++) {
141             result += (in.readByte() & 0xff) << shift;
142             shift += 8;
143         }
144         return result;
145     }
146 }