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