diff options
Diffstat (limited to 'dx/src/com/android/dx/io/CodeReader.java')
-rw-r--r-- | dx/src/com/android/dx/io/CodeReader.java | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/dx/src/com/android/dx/io/CodeReader.java b/dx/src/com/android/dx/io/CodeReader.java new file mode 100644 index 0000000..cab1063 --- /dev/null +++ b/dx/src/com/android/dx/io/CodeReader.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dx.io; + +import com.android.dx.io.instructions.DecodedInstruction; +import com.android.dx.util.DexException; + +/** + * Walks through a block of code and calls visitor call backs. + */ +public final class CodeReader { + private Visitor fallbackVisitor = null; + private Visitor stringVisitor = null; + private Visitor typeVisitor = null; + private Visitor fieldVisitor = null; + private Visitor methodVisitor = null; + + /** + * Sets {@code visitor} as the visitor for all instructions. + */ + public void setAllVisitors(Visitor visitor) { + fallbackVisitor = visitor; + stringVisitor = visitor; + typeVisitor = visitor; + fieldVisitor = visitor; + methodVisitor = visitor; + } + + /** + * Sets {@code visitor} as the visitor for all instructions not + * otherwise handled. + */ + public void setFallbackVisitor(Visitor visitor) { + fallbackVisitor = visitor; + } + + /** + * Sets {@code visitor} as the visitor for all string instructions. + */ + public void setStringVisitor(Visitor visitor) { + stringVisitor = visitor; + } + + /** + * Sets {@code visitor} as the visitor for all type instructions. + */ + public void setTypeVisitor(Visitor visitor) { + typeVisitor = visitor; + } + + /** + * Sets {@code visitor} as the visitor for all field instructions. + */ + public void setFieldVisitor(Visitor visitor) { + fieldVisitor = visitor; + } + + /** + * Sets {@code visitor} as the visitor for all method instructions. + */ + public void setMethodVisitor(Visitor visitor) { + methodVisitor = visitor; + } + + public void visitAll(DecodedInstruction[] decodedInstructions) + throws DexException { + int size = decodedInstructions.length; + + for (int i = 0; i < size; i++) { + DecodedInstruction one = decodedInstructions[i]; + if (one == null) { + continue; + } + + callVisit(decodedInstructions, one); + } + } + + public void visitAll(short[] encodedInstructions) throws DexException { + DecodedInstruction[] decodedInstructions = + DecodedInstruction.decodeAll(encodedInstructions); + visitAll(decodedInstructions); + } + + private void callVisit(DecodedInstruction[] all, DecodedInstruction one) { + Visitor visitor = null; + + switch (OpcodeInfo.getIndexType(one.getOpcode())) { + case STRING_REF: visitor = stringVisitor; break; + case TYPE_REF: visitor = typeVisitor; break; + case FIELD_REF: visitor = fieldVisitor; break; + case METHOD_REF: visitor = methodVisitor; break; + } + + if (visitor == null) { + visitor = fallbackVisitor; + } + + if (visitor != null) { + visitor.visit(all, one); + } + } + + public interface Visitor { + void visit(DecodedInstruction[] all, DecodedInstruction one); + } +} |