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.dex.DexException; 20 import com.android.dx.io.instructions.DecodedInstruction; 21 22 /** 23 * Walks through a block of code and calls visitor call backs. 24 */ 25 public final class CodeReader { 26 private Visitor fallbackVisitor = null; 27 private Visitor stringVisitor = null; 28 private Visitor typeVisitor = null; 29 private Visitor fieldVisitor = null; 30 private Visitor methodVisitor = null; 31 private Visitor methodAndProtoVisitor = null; 32 private Visitor callSiteVisitor = null; 33 34 /** 35 * Sets {@code visitor} as the visitor for all instructions. 36 */ setAllVisitors(Visitor visitor)37 public void setAllVisitors(Visitor visitor) { 38 fallbackVisitor = visitor; 39 stringVisitor = visitor; 40 typeVisitor = visitor; 41 fieldVisitor = visitor; 42 methodVisitor = visitor; 43 methodAndProtoVisitor = visitor; 44 callSiteVisitor = visitor; 45 } 46 47 /** 48 * Sets {@code visitor} as the visitor for all instructions not 49 * otherwise handled. 50 */ setFallbackVisitor(Visitor visitor)51 public void setFallbackVisitor(Visitor visitor) { 52 fallbackVisitor = visitor; 53 } 54 55 /** 56 * Sets {@code visitor} as the visitor for all string instructions. 57 */ setStringVisitor(Visitor visitor)58 public void setStringVisitor(Visitor visitor) { 59 stringVisitor = visitor; 60 } 61 62 /** 63 * Sets {@code visitor} as the visitor for all type instructions. 64 */ setTypeVisitor(Visitor visitor)65 public void setTypeVisitor(Visitor visitor) { 66 typeVisitor = visitor; 67 } 68 69 /** 70 * Sets {@code visitor} as the visitor for all field instructions. 71 */ setFieldVisitor(Visitor visitor)72 public void setFieldVisitor(Visitor visitor) { 73 fieldVisitor = visitor; 74 } 75 76 /** 77 * Sets {@code visitor} as the visitor for all method instructions. 78 */ setMethodVisitor(Visitor visitor)79 public void setMethodVisitor(Visitor visitor) { 80 methodVisitor = visitor; 81 } 82 83 /** Sets {@code visitor} as the visitor for all method and proto instructions. */ setMethodAndProtoVisitor(Visitor visitor)84 public void setMethodAndProtoVisitor(Visitor visitor) { 85 methodAndProtoVisitor = visitor; 86 } 87 88 /** Sets {@code visitor} as the visitor for all call site instructions. */ setCallSiteVisitor(Visitor visitor)89 public void setCallSiteVisitor(Visitor visitor) { 90 callSiteVisitor = visitor; 91 } 92 visitAll(DecodedInstruction[] decodedInstructions)93 public void visitAll(DecodedInstruction[] decodedInstructions) 94 throws DexException { 95 int size = decodedInstructions.length; 96 97 for (int i = 0; i < size; i++) { 98 DecodedInstruction one = decodedInstructions[i]; 99 if (one == null) { 100 continue; 101 } 102 103 callVisit(decodedInstructions, one); 104 } 105 } 106 visitAll(short[] encodedInstructions)107 public void visitAll(short[] encodedInstructions) throws DexException { 108 DecodedInstruction[] decodedInstructions = 109 DecodedInstruction.decodeAll(encodedInstructions); 110 visitAll(decodedInstructions); 111 } 112 callVisit(DecodedInstruction[] all, DecodedInstruction one)113 private void callVisit(DecodedInstruction[] all, DecodedInstruction one) { 114 Visitor visitor = null; 115 116 switch (OpcodeInfo.getIndexType(one.getOpcode())) { 117 case STRING_REF: visitor = stringVisitor; break; 118 case TYPE_REF: visitor = typeVisitor; break; 119 case FIELD_REF: visitor = fieldVisitor; break; 120 case METHOD_REF: visitor = methodVisitor; break; 121 case METHOD_AND_PROTO_REF: visitor = methodAndProtoVisitor; break; 122 case CALL_SITE_REF: visitor = callSiteVisitor; break; 123 } 124 125 if (visitor == null) { 126 visitor = fallbackVisitor; 127 } 128 129 if (visitor != null) { 130 visitor.visit(all, one); 131 } 132 } 133 134 public interface Visitor { visit(DecodedInstruction[] all, DecodedInstruction one)135 void visit(DecodedInstruction[] all, DecodedInstruction one); 136 } 137 } 138