xref: /aosp_15_r20/dalvik/dx/src/com/android/dex/EncodedValueReader.java (revision 055d459012065f78d96b68be8421640240ddf631)
1*055d4590SKeyi Gui /*
2*055d4590SKeyi Gui  * Copyright (C) 2011 The Android Open Source Project
3*055d4590SKeyi Gui  *
4*055d4590SKeyi Gui  * Licensed under the Apache License, Version 2.0 (the "License");
5*055d4590SKeyi Gui  * you may not use this file except in compliance with the License.
6*055d4590SKeyi Gui  * You may obtain a copy of the License at
7*055d4590SKeyi Gui  *
8*055d4590SKeyi Gui  *      http://www.apache.org/licenses/LICENSE-2.0
9*055d4590SKeyi Gui  *
10*055d4590SKeyi Gui  * Unless required by applicable law or agreed to in writing, software
11*055d4590SKeyi Gui  * distributed under the License is distributed on an "AS IS" BASIS,
12*055d4590SKeyi Gui  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*055d4590SKeyi Gui  * See the License for the specific language governing permissions and
14*055d4590SKeyi Gui  * limitations under the License.
15*055d4590SKeyi Gui  */
16*055d4590SKeyi Gui 
17*055d4590SKeyi Gui package com.android.dex;
18*055d4590SKeyi Gui 
19*055d4590SKeyi Gui import com.android.dex.util.ByteInput;
20*055d4590SKeyi Gui 
21*055d4590SKeyi Gui /**
22*055d4590SKeyi Gui  * Pull parser for encoded values.
23*055d4590SKeyi Gui  */
24*055d4590SKeyi Gui public final class EncodedValueReader {
25*055d4590SKeyi Gui     public static final int ENCODED_BYTE = 0x00;
26*055d4590SKeyi Gui     public static final int ENCODED_SHORT = 0x02;
27*055d4590SKeyi Gui     public static final int ENCODED_CHAR = 0x03;
28*055d4590SKeyi Gui     public static final int ENCODED_INT = 0x04;
29*055d4590SKeyi Gui     public static final int ENCODED_LONG = 0x06;
30*055d4590SKeyi Gui     public static final int ENCODED_FLOAT = 0x10;
31*055d4590SKeyi Gui     public static final int ENCODED_DOUBLE = 0x11;
32*055d4590SKeyi Gui     public static final int ENCODED_METHOD_TYPE = 0x15;
33*055d4590SKeyi Gui     public static final int ENCODED_METHOD_HANDLE = 0x16;
34*055d4590SKeyi Gui     public static final int ENCODED_STRING = 0x17;
35*055d4590SKeyi Gui     public static final int ENCODED_TYPE = 0x18;
36*055d4590SKeyi Gui     public static final int ENCODED_FIELD = 0x19;
37*055d4590SKeyi Gui     public static final int ENCODED_ENUM = 0x1b;
38*055d4590SKeyi Gui     public static final int ENCODED_METHOD = 0x1a;
39*055d4590SKeyi Gui     public static final int ENCODED_ARRAY = 0x1c;
40*055d4590SKeyi Gui     public static final int ENCODED_ANNOTATION = 0x1d;
41*055d4590SKeyi Gui     public static final int ENCODED_NULL = 0x1e;
42*055d4590SKeyi Gui     public static final int ENCODED_BOOLEAN = 0x1f;
43*055d4590SKeyi Gui 
44*055d4590SKeyi Gui     /** placeholder type if the type is not yet known */
45*055d4590SKeyi Gui     private static final int MUST_READ = -1;
46*055d4590SKeyi Gui 
47*055d4590SKeyi Gui     protected final ByteInput in;
48*055d4590SKeyi Gui     private int type = MUST_READ;
49*055d4590SKeyi Gui     private int annotationType;
50*055d4590SKeyi Gui     private int arg;
51*055d4590SKeyi Gui 
EncodedValueReader(ByteInput in)52*055d4590SKeyi Gui     public EncodedValueReader(ByteInput in) {
53*055d4590SKeyi Gui         this.in = in;
54*055d4590SKeyi Gui     }
55*055d4590SKeyi Gui 
EncodedValueReader(EncodedValue in)56*055d4590SKeyi Gui     public EncodedValueReader(EncodedValue in) {
57*055d4590SKeyi Gui         this(in.asByteInput());
58*055d4590SKeyi Gui     }
59*055d4590SKeyi Gui 
60*055d4590SKeyi Gui     /**
61*055d4590SKeyi Gui      * Creates a new encoded value reader whose only value is the specified
62*055d4590SKeyi Gui      * known type. This is useful for encoded values without a type prefix,
63*055d4590SKeyi Gui      * such as class_def_item's encoded_array or annotation_item's
64*055d4590SKeyi Gui      * encoded_annotation.
65*055d4590SKeyi Gui      */
EncodedValueReader(ByteInput in, int knownType)66*055d4590SKeyi Gui     public EncodedValueReader(ByteInput in, int knownType) {
67*055d4590SKeyi Gui         this.in = in;
68*055d4590SKeyi Gui         this.type = knownType;
69*055d4590SKeyi Gui     }
70*055d4590SKeyi Gui 
EncodedValueReader(EncodedValue in, int knownType)71*055d4590SKeyi Gui     public EncodedValueReader(EncodedValue in, int knownType) {
72*055d4590SKeyi Gui         this(in.asByteInput(), knownType);
73*055d4590SKeyi Gui     }
74*055d4590SKeyi Gui 
75*055d4590SKeyi Gui     /**
76*055d4590SKeyi Gui      * Returns the type of the next value to read.
77*055d4590SKeyi Gui      */
peek()78*055d4590SKeyi Gui     public int peek() {
79*055d4590SKeyi Gui         if (type == MUST_READ) {
80*055d4590SKeyi Gui             int argAndType = in.readByte() & 0xff;
81*055d4590SKeyi Gui             type = argAndType & 0x1f;
82*055d4590SKeyi Gui             arg = (argAndType & 0xe0) >> 5;
83*055d4590SKeyi Gui         }
84*055d4590SKeyi Gui         return type;
85*055d4590SKeyi Gui     }
86*055d4590SKeyi Gui 
87*055d4590SKeyi Gui     /**
88*055d4590SKeyi Gui      * Begins reading the elements of an array, returning the array's size. The
89*055d4590SKeyi Gui      * caller must follow up by calling a read method for each element in the
90*055d4590SKeyi Gui      * array. For example, this reads a byte array: <pre>   {@code
91*055d4590SKeyi Gui      *   int arraySize = readArray();
92*055d4590SKeyi Gui      *   for (int i = 0, i < arraySize; i++) {
93*055d4590SKeyi Gui      *     readByte();
94*055d4590SKeyi Gui      *   }
95*055d4590SKeyi Gui      * }</pre>
96*055d4590SKeyi Gui      */
readArray()97*055d4590SKeyi Gui     public int readArray() {
98*055d4590SKeyi Gui         checkType(ENCODED_ARRAY);
99*055d4590SKeyi Gui         type = MUST_READ;
100*055d4590SKeyi Gui         return Leb128.readUnsignedLeb128(in);
101*055d4590SKeyi Gui     }
102*055d4590SKeyi Gui 
103*055d4590SKeyi Gui     /**
104*055d4590SKeyi Gui      * Begins reading the fields of an annotation, returning the number of
105*055d4590SKeyi Gui      * fields. The caller must follow up by making alternating calls to {@link
106*055d4590SKeyi Gui      * #readAnnotationName()} and another read method. For example, this reads
107*055d4590SKeyi Gui      * an annotation whose fields are all bytes: <pre>   {@code
108*055d4590SKeyi Gui      *   int fieldCount = readAnnotation();
109*055d4590SKeyi Gui      *   int annotationType = getAnnotationType();
110*055d4590SKeyi Gui      *   for (int i = 0; i < fieldCount; i++) {
111*055d4590SKeyi Gui      *       readAnnotationName();
112*055d4590SKeyi Gui      *       readByte();
113*055d4590SKeyi Gui      *   }
114*055d4590SKeyi Gui      * }</pre>
115*055d4590SKeyi Gui      */
readAnnotation()116*055d4590SKeyi Gui     public int readAnnotation() {
117*055d4590SKeyi Gui         checkType(ENCODED_ANNOTATION);
118*055d4590SKeyi Gui         type = MUST_READ;
119*055d4590SKeyi Gui         annotationType = Leb128.readUnsignedLeb128(in);
120*055d4590SKeyi Gui         return Leb128.readUnsignedLeb128(in);
121*055d4590SKeyi Gui     }
122*055d4590SKeyi Gui 
123*055d4590SKeyi Gui     /**
124*055d4590SKeyi Gui      * Returns the type of the annotation just returned by {@link
125*055d4590SKeyi Gui      * #readAnnotation()}. This method's value is undefined unless the most
126*055d4590SKeyi Gui      * recent call was to {@link #readAnnotation()}.
127*055d4590SKeyi Gui      */
getAnnotationType()128*055d4590SKeyi Gui     public int getAnnotationType() {
129*055d4590SKeyi Gui         return annotationType;
130*055d4590SKeyi Gui     }
131*055d4590SKeyi Gui 
readAnnotationName()132*055d4590SKeyi Gui     public int readAnnotationName() {
133*055d4590SKeyi Gui         return Leb128.readUnsignedLeb128(in);
134*055d4590SKeyi Gui     }
135*055d4590SKeyi Gui 
readByte()136*055d4590SKeyi Gui     public byte readByte() {
137*055d4590SKeyi Gui         checkType(ENCODED_BYTE);
138*055d4590SKeyi Gui         type = MUST_READ;
139*055d4590SKeyi Gui         return (byte) EncodedValueCodec.readSignedInt(in, arg);
140*055d4590SKeyi Gui     }
141*055d4590SKeyi Gui 
readShort()142*055d4590SKeyi Gui     public short readShort() {
143*055d4590SKeyi Gui         checkType(ENCODED_SHORT);
144*055d4590SKeyi Gui         type = MUST_READ;
145*055d4590SKeyi Gui         return (short) EncodedValueCodec.readSignedInt(in, arg);
146*055d4590SKeyi Gui     }
147*055d4590SKeyi Gui 
readChar()148*055d4590SKeyi Gui     public char readChar() {
149*055d4590SKeyi Gui         checkType(ENCODED_CHAR);
150*055d4590SKeyi Gui         type = MUST_READ;
151*055d4590SKeyi Gui         return (char) EncodedValueCodec.readUnsignedInt(in, arg, false);
152*055d4590SKeyi Gui     }
153*055d4590SKeyi Gui 
readInt()154*055d4590SKeyi Gui     public int readInt() {
155*055d4590SKeyi Gui         checkType(ENCODED_INT);
156*055d4590SKeyi Gui         type = MUST_READ;
157*055d4590SKeyi Gui         return EncodedValueCodec.readSignedInt(in, arg);
158*055d4590SKeyi Gui     }
159*055d4590SKeyi Gui 
readLong()160*055d4590SKeyi Gui     public long readLong() {
161*055d4590SKeyi Gui         checkType(ENCODED_LONG);
162*055d4590SKeyi Gui         type = MUST_READ;
163*055d4590SKeyi Gui         return EncodedValueCodec.readSignedLong(in, arg);
164*055d4590SKeyi Gui     }
165*055d4590SKeyi Gui 
readFloat()166*055d4590SKeyi Gui     public float readFloat() {
167*055d4590SKeyi Gui         checkType(ENCODED_FLOAT);
168*055d4590SKeyi Gui         type = MUST_READ;
169*055d4590SKeyi Gui         return Float.intBitsToFloat(EncodedValueCodec.readUnsignedInt(in, arg, true));
170*055d4590SKeyi Gui     }
171*055d4590SKeyi Gui 
readDouble()172*055d4590SKeyi Gui     public double readDouble() {
173*055d4590SKeyi Gui         checkType(ENCODED_DOUBLE);
174*055d4590SKeyi Gui         type = MUST_READ;
175*055d4590SKeyi Gui         return Double.longBitsToDouble(EncodedValueCodec.readUnsignedLong(in, arg, true));
176*055d4590SKeyi Gui     }
177*055d4590SKeyi Gui 
readMethodType()178*055d4590SKeyi Gui     public int readMethodType() {
179*055d4590SKeyi Gui         checkType(ENCODED_METHOD_TYPE);
180*055d4590SKeyi Gui         type = MUST_READ;
181*055d4590SKeyi Gui         return EncodedValueCodec.readUnsignedInt(in, arg, false);
182*055d4590SKeyi Gui     }
183*055d4590SKeyi Gui 
readMethodHandle()184*055d4590SKeyi Gui     public int readMethodHandle() {
185*055d4590SKeyi Gui         checkType(ENCODED_METHOD_HANDLE);
186*055d4590SKeyi Gui         type = MUST_READ;
187*055d4590SKeyi Gui         return EncodedValueCodec.readUnsignedInt(in, arg, false);
188*055d4590SKeyi Gui     }
189*055d4590SKeyi Gui 
readString()190*055d4590SKeyi Gui     public int readString() {
191*055d4590SKeyi Gui         checkType(ENCODED_STRING);
192*055d4590SKeyi Gui         type = MUST_READ;
193*055d4590SKeyi Gui         return EncodedValueCodec.readUnsignedInt(in, arg, false);
194*055d4590SKeyi Gui     }
195*055d4590SKeyi Gui 
readType()196*055d4590SKeyi Gui     public int readType() {
197*055d4590SKeyi Gui         checkType(ENCODED_TYPE);
198*055d4590SKeyi Gui         type = MUST_READ;
199*055d4590SKeyi Gui         return EncodedValueCodec.readUnsignedInt(in, arg, false);
200*055d4590SKeyi Gui     }
201*055d4590SKeyi Gui 
readField()202*055d4590SKeyi Gui     public int readField() {
203*055d4590SKeyi Gui         checkType(ENCODED_FIELD);
204*055d4590SKeyi Gui         type = MUST_READ;
205*055d4590SKeyi Gui         return EncodedValueCodec.readUnsignedInt(in, arg, false);
206*055d4590SKeyi Gui     }
207*055d4590SKeyi Gui 
readEnum()208*055d4590SKeyi Gui     public int readEnum() {
209*055d4590SKeyi Gui         checkType(ENCODED_ENUM);
210*055d4590SKeyi Gui         type = MUST_READ;
211*055d4590SKeyi Gui         return EncodedValueCodec.readUnsignedInt(in, arg, false);
212*055d4590SKeyi Gui     }
213*055d4590SKeyi Gui 
readMethod()214*055d4590SKeyi Gui     public int readMethod() {
215*055d4590SKeyi Gui         checkType(ENCODED_METHOD);
216*055d4590SKeyi Gui         type = MUST_READ;
217*055d4590SKeyi Gui         return EncodedValueCodec.readUnsignedInt(in, arg, false);
218*055d4590SKeyi Gui     }
219*055d4590SKeyi Gui 
readNull()220*055d4590SKeyi Gui     public void readNull() {
221*055d4590SKeyi Gui         checkType(ENCODED_NULL);
222*055d4590SKeyi Gui         type = MUST_READ;
223*055d4590SKeyi Gui     }
224*055d4590SKeyi Gui 
readBoolean()225*055d4590SKeyi Gui     public boolean readBoolean() {
226*055d4590SKeyi Gui         checkType(ENCODED_BOOLEAN);
227*055d4590SKeyi Gui         type = MUST_READ;
228*055d4590SKeyi Gui         return arg != 0;
229*055d4590SKeyi Gui     }
230*055d4590SKeyi Gui 
231*055d4590SKeyi Gui     /**
232*055d4590SKeyi Gui      * Skips a single value, including its nested values if it is an array or
233*055d4590SKeyi Gui      * annotation.
234*055d4590SKeyi Gui      */
skipValue()235*055d4590SKeyi Gui     public void skipValue() {
236*055d4590SKeyi Gui         switch (peek()) {
237*055d4590SKeyi Gui         case ENCODED_BYTE:
238*055d4590SKeyi Gui             readByte();
239*055d4590SKeyi Gui             break;
240*055d4590SKeyi Gui         case ENCODED_SHORT:
241*055d4590SKeyi Gui             readShort();
242*055d4590SKeyi Gui             break;
243*055d4590SKeyi Gui         case ENCODED_CHAR:
244*055d4590SKeyi Gui             readChar();
245*055d4590SKeyi Gui             break;
246*055d4590SKeyi Gui         case ENCODED_INT:
247*055d4590SKeyi Gui             readInt();
248*055d4590SKeyi Gui             break;
249*055d4590SKeyi Gui         case ENCODED_LONG:
250*055d4590SKeyi Gui             readLong();
251*055d4590SKeyi Gui             break;
252*055d4590SKeyi Gui         case ENCODED_FLOAT:
253*055d4590SKeyi Gui             readFloat();
254*055d4590SKeyi Gui             break;
255*055d4590SKeyi Gui         case ENCODED_DOUBLE:
256*055d4590SKeyi Gui             readDouble();
257*055d4590SKeyi Gui             break;
258*055d4590SKeyi Gui         case ENCODED_METHOD_TYPE:
259*055d4590SKeyi Gui             readMethodType();
260*055d4590SKeyi Gui             break;
261*055d4590SKeyi Gui         case ENCODED_METHOD_HANDLE:
262*055d4590SKeyi Gui             readMethodHandle();
263*055d4590SKeyi Gui             break;
264*055d4590SKeyi Gui         case ENCODED_STRING:
265*055d4590SKeyi Gui             readString();
266*055d4590SKeyi Gui             break;
267*055d4590SKeyi Gui         case ENCODED_TYPE:
268*055d4590SKeyi Gui             readType();
269*055d4590SKeyi Gui             break;
270*055d4590SKeyi Gui         case ENCODED_FIELD:
271*055d4590SKeyi Gui             readField();
272*055d4590SKeyi Gui             break;
273*055d4590SKeyi Gui         case ENCODED_ENUM:
274*055d4590SKeyi Gui             readEnum();
275*055d4590SKeyi Gui             break;
276*055d4590SKeyi Gui         case ENCODED_METHOD:
277*055d4590SKeyi Gui             readMethod();
278*055d4590SKeyi Gui             break;
279*055d4590SKeyi Gui         case ENCODED_ARRAY:
280*055d4590SKeyi Gui             for (int i = 0, size = readArray(); i < size; i++) {
281*055d4590SKeyi Gui                 skipValue();
282*055d4590SKeyi Gui             }
283*055d4590SKeyi Gui             break;
284*055d4590SKeyi Gui         case ENCODED_ANNOTATION:
285*055d4590SKeyi Gui             for (int i = 0, size = readAnnotation(); i < size; i++) {
286*055d4590SKeyi Gui                 readAnnotationName();
287*055d4590SKeyi Gui                 skipValue();
288*055d4590SKeyi Gui             }
289*055d4590SKeyi Gui             break;
290*055d4590SKeyi Gui         case ENCODED_NULL:
291*055d4590SKeyi Gui             readNull();
292*055d4590SKeyi Gui             break;
293*055d4590SKeyi Gui         case ENCODED_BOOLEAN:
294*055d4590SKeyi Gui             readBoolean();
295*055d4590SKeyi Gui             break;
296*055d4590SKeyi Gui         default:
297*055d4590SKeyi Gui             throw new DexException("Unexpected type: " + Integer.toHexString(type));
298*055d4590SKeyi Gui         }
299*055d4590SKeyi Gui     }
300*055d4590SKeyi Gui 
checkType(int expected)301*055d4590SKeyi Gui     private void checkType(int expected) {
302*055d4590SKeyi Gui         if (peek() != expected) {
303*055d4590SKeyi Gui             throw new IllegalStateException(
304*055d4590SKeyi Gui                     String.format("Expected %x but was %x", expected, peek()));
305*055d4590SKeyi Gui         }
306*055d4590SKeyi Gui     }
307*055d4590SKeyi Gui }
308