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 EncodedValueReader(ByteInput in)46 public EncodedValueReader(ByteInput in) { 47 this.in = in; 48 } 49 EncodedValueReader(EncodedValue in)50 public EncodedValueReader(EncodedValue in) { 51 this(in.asByteInput()); 52 } 53 readArray()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 readAnnotation()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 readValue()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 visitArray(int size)120 protected void visitArray(int size) {} visitAnnotation(int typeIndex, int size)121 protected void visitAnnotation(int typeIndex, int size) {} visitAnnotationName(int nameIndex)122 protected void visitAnnotationName(int nameIndex) {} visitPrimitive(int argAndType, int type, int arg, int size)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 } visitString(int type, int index)128 protected void visitString(int type, int index) {} visitType(int type, int index)129 protected void visitType(int type, int index) {} visitField(int type, int index)130 protected void visitField(int type, int index) {} visitMethod(int type, int index)131 protected void visitMethod(int type, int index) {} visitArrayValue(int argAndType)132 protected void visitArrayValue(int argAndType) {} visitAnnotationValue(int argAndType)133 protected void visitAnnotationValue(int argAndType) {} visitEncodedBoolean(int argAndType)134 protected void visitEncodedBoolean(int argAndType) {} visitEncodedNull(int argAndType)135 protected void visitEncodedNull(int argAndType) {} 136 readIndex(ByteInput in, int byteCount)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 } 147