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