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