1ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson/* 2ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * Copyright (C) 2011 The Android Open Source Project 3ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * 4ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * you may not use this file except in compliance with the License. 6ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * You may obtain a copy of the License at 7ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * 8ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * 10ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * See the License for the specific language governing permissions and 14ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * limitations under the License. 15ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson */ 16ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 17ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilsonpackage com.android.dx.io; 18ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 19bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilsonimport com.android.dx.util.ByteInput; 20bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilsonimport com.android.dx.util.Leb128Utils; 21bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson 22ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson/** 23ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * SAX-style reader for encoded values. 24ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson * TODO: convert this to a pull-style reader 25ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson */ 26ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilsonpublic class EncodedValueReader { 27ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_BYTE = 0x00; 28ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_SHORT = 0x02; 29ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_CHAR = 0x03; 30ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_INT = 0x04; 31ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_LONG = 0x06; 32ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_FLOAT = 0x10; 33ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_DOUBLE = 0x11; 34ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_STRING = 0x17; 35ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_TYPE = 0x18; 36ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_FIELD = 0x19; 37ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_ENUM = 0x1b; 38ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_METHOD = 0x1a; 39ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_ARRAY = 0x1c; 40ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_ANNOTATION = 0x1d; 41ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_NULL = 0x1e; 42ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public static final int ENCODED_BOOLEAN = 0x1f; 43ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 44bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson protected final ByteInput in; 45ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 46bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson public EncodedValueReader(ByteInput in) { 47ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson this.in = in; 48ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 49ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 50bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson public EncodedValueReader(EncodedValue in) { 51bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson this(in.asByteInput()); 52bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson } 53bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson 54ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public final void readArray() { 55bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson int size = Leb128Utils.readUnsignedLeb128(in); 56ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitArray(size); 57ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 58ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson for (int i = 0; i < size; i++) { 59ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson readValue(); 60ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 61ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 62ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 63ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public final void readAnnotation() { 64bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson int typeIndex = Leb128Utils.readUnsignedLeb128(in); 65bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson int size = Leb128Utils.readUnsignedLeb128(in); 66ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitAnnotation(typeIndex, size); 67ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 68ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson for (int i = 0; i < size; i++) { 69bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson visitAnnotationName(Leb128Utils.readUnsignedLeb128(in)); 70ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson readValue(); 71ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 72ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 73ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 74ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson public final void readValue() { 75ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson int argAndType = in.readByte() & 0xff; 76ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson int type = argAndType & 0x1f; 77ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson int arg = (argAndType & 0xe0) >> 5; 78ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson int size = arg + 1; 79ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 80ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson switch (type) { 81ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_BYTE: 82ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_SHORT: 83ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_CHAR: 84ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_INT: 85ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_LONG: 86ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_FLOAT: 87ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_DOUBLE: 88ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitPrimitive(argAndType, type, arg, size); 89ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson break; 90ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_STRING: 91ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitString(type, readIndex(in, size)); 92ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson break; 93ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_TYPE: 94ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitType(type, readIndex(in, size)); 95ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson break; 96ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_FIELD: 97ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_ENUM: 98ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitField(type, readIndex(in, size)); 99ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson break; 100ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_METHOD: 101ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitMethod(type, readIndex(in, size)); 102ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson break; 103ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_ARRAY: 104ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitArrayValue(argAndType); 105ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson readArray(); 106ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson break; 107ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_ANNOTATION: 108ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitAnnotationValue(argAndType); 109ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson readAnnotation(); 110ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson break; 111ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_NULL: 112ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitEncodedNull(argAndType); 113ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson break; 114ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson case ENCODED_BOOLEAN: 115ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson visitEncodedBoolean(argAndType); 116ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson break; 117ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 118ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 119ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 120ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitArray(int size) {} 121ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitAnnotation(int typeIndex, int size) {} 122ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitAnnotationName(int nameIndex) {} 123ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitPrimitive(int argAndType, int type, int arg, int size) { 124ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson for (int i = 0; i < size; i++) { 125ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson in.readByte(); 126ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 127ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 128ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitString(int type, int index) {} 129ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitType(int type, int index) {} 130ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitField(int type, int index) {} 131ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitMethod(int type, int index) {} 132ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitArrayValue(int argAndType) {} 133ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitAnnotationValue(int argAndType) {} 134ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitEncodedBoolean(int argAndType) {} 135ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson protected void visitEncodedNull(int argAndType) {} 136ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson 137bd3dba4346223593ac6033a3d2a7d8ec6f20738bJesse Wilson private int readIndex(ByteInput in, int byteCount) { 138ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson int result = 0; 139ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson int shift = 0; 140ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson for (int i = 0; i < byteCount; i++) { 141ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson result += (in.readByte() & 0xff) << shift; 142ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson shift += 8; 143ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 144ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson return result; 145ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson } 146ae38a1e705253b53abf1beff7dc3467d52c58f32Jesse Wilson} 147