/* * Tencent is pleased to support the open source community by making Tinker available. * * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. * * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * 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.taobao.common.dexpatcher.algorithms.diff.utils; import com.taobao.dex.Dex; import java.util.HashMap; import java.util.Map; /** * Created by tangyinsheng on 2016/9/11. */ public final class OffsetToIndexConverter { private final Map<Integer, Integer> typeListOffsetToIndexMap = new HashMap<Integer, Integer>(); private final Map<Integer, Integer> classDataOffsetToIndexMap = new HashMap<Integer, Integer>(); private final Map<Integer, Integer> encodedArrayOffsetToIndexMap = new HashMap<Integer, Integer>(); private final Map<Integer, Integer> annotationOffsetToIndexMap = new HashMap<Integer, Integer>(); private final Map<Integer, Integer> annotationSetOffsetToIndexMap = new HashMap<Integer, Integer>(); private final Map<Integer, Integer> annotationSetRefListOffsetToIndexMap = new HashMap<Integer, Integer>(); private final Map<Integer, Integer> annotationsDirectoryOffsetToIndexMap = new HashMap<Integer, Integer>(); private final Map<Integer, Integer> codeOffsetToIndexMap = new HashMap<Integer, Integer>(); private final Map<Integer, Integer> debugInfoItemOffsetToIndexMap = new HashMap<Integer, Integer>(); public OffsetToIndexConverter(Dex dex) { if (dex == null) { throw new IllegalArgumentException("dex is null."); } if (dex.getTableOfContents().typeLists.exists()) { Dex.Section typeListSec = dex.openSection(dex.getTableOfContents().typeLists); int typeListCount = dex.getTableOfContents().typeLists.size; for (int i = 0; i < typeListCount; ++i) { typeListOffsetToIndexMap.put(typeListSec.readTypeList().off, i); } } if (dex.getTableOfContents().classDatas.exists()) { Dex.Section classDataSec = dex.openSection(dex.getTableOfContents().classDatas); int classDataCount = dex.getTableOfContents().classDatas.size; for (int i = 0; i < classDataCount; ++i) { classDataOffsetToIndexMap.put(classDataSec.readClassData().off, i); } } if (dex.getTableOfContents().encodedArrays.exists()) { Dex.Section encodedArraySec = dex.openSection(dex.getTableOfContents().encodedArrays); int encodedArrayCount = dex.getTableOfContents().encodedArrays.size; for (int i = 0; i < encodedArrayCount; ++i) { encodedArrayOffsetToIndexMap.put(encodedArraySec.readEncodedArray().off, i); } } if (dex.getTableOfContents().annotations.exists()) { Dex.Section annotationSec = dex.openSection(dex.getTableOfContents().annotations); int annotationCount = dex.getTableOfContents().annotations.size; for (int i = 0; i < annotationCount; ++i) { annotationOffsetToIndexMap.put(annotationSec.readAnnotation().off, i); } } if (dex.getTableOfContents().annotationSets.exists()) { Dex.Section annotationSetSec = dex.openSection(dex.getTableOfContents().annotationSets); int annotationSetCount = dex.getTableOfContents().annotationSets.size; for (int i = 0; i < annotationSetCount; ++i) { annotationSetOffsetToIndexMap.put(annotationSetSec.readAnnotationSet().off, i); } } if (dex.getTableOfContents().annotationSetRefLists.exists()) { Dex.Section annotationSetRefListSec = dex.openSection(dex.getTableOfContents().annotationSetRefLists); int annotationSetRefListCount = dex.getTableOfContents().annotationSetRefLists.size; for (int i = 0; i < annotationSetRefListCount; ++i) { annotationSetRefListOffsetToIndexMap.put(annotationSetRefListSec.readAnnotationSetRefList().off, i); } } if (dex.getTableOfContents().annotationsDirectories.exists()) { Dex.Section annotationsDirectorySec = dex.openSection(dex.getTableOfContents().annotationsDirectories); int annotationsDirectoryCount = dex.getTableOfContents().annotationsDirectories.size; for (int i = 0; i < annotationsDirectoryCount; ++i) { annotationsDirectoryOffsetToIndexMap.put(annotationsDirectorySec.readAnnotationsDirectory().off, i); } } if (dex.getTableOfContents().codes.exists()) { Dex.Section codeSec = dex.openSection(dex.getTableOfContents().codes); int codeCount = dex.getTableOfContents().codes.size; for (int i = 0; i < codeCount; ++i) { codeOffsetToIndexMap.put(codeSec.readCode().off, i); } } if (dex.getTableOfContents().debugInfos.exists()) { Dex.Section debugInfoItemSec = dex.openSection(dex.getTableOfContents().debugInfos); int debugInfoItemCount = dex.getTableOfContents().debugInfos.size; for (int i = 0; i < debugInfoItemCount; ++i) { debugInfoItemOffsetToIndexMap.put(debugInfoItemSec.readDebugInfoItem().off, i); } } } public int getTypeListIndexByOffset(int offset) { if (typeListOffsetToIndexMap.containsKey(offset)) { return typeListOffsetToIndexMap.get(offset); } else { throw new IllegalArgumentException("cannot find corresponding index of offset: " + offset); } } public int getClassDataIndexByOffset(int offset) { if (classDataOffsetToIndexMap.containsKey(offset)) { return classDataOffsetToIndexMap.get(offset); } else { throw new IllegalArgumentException("cannot find corresponding index of offset: " + offset); } } public int getEncodedArrayIndexByOffset(int offset) { if (encodedArrayOffsetToIndexMap.containsKey(offset)) { return encodedArrayOffsetToIndexMap.get(offset); } else { throw new IllegalArgumentException("cannot find corresponding index of offset: " + offset); } } public int getAnnotationIndexByOffset(int offset) { if (annotationOffsetToIndexMap.containsKey(offset)) { return annotationOffsetToIndexMap.get(offset); } else { throw new IllegalArgumentException("cannot find corresponding index of offset: " + offset); } } public int getAnnotationSetIndexByOffset(int offset) { if (annotationSetOffsetToIndexMap.containsKey(offset)) { return annotationSetOffsetToIndexMap.get(offset); } else { throw new IllegalArgumentException("cannot find corresponding index of offset: " + offset); } } public int getAnnotationSetRefListIndexByOffset(int offset) { if (annotationSetRefListOffsetToIndexMap.containsKey(offset)) { return annotationSetRefListOffsetToIndexMap.get(offset); } else { throw new IllegalArgumentException("cannot find corresponding index of offset: " + offset); } } public int getAnnotationsDirectoryIndexByOffset(int offset) { if (annotationsDirectoryOffsetToIndexMap.containsKey(offset)) { return annotationsDirectoryOffsetToIndexMap.get(offset); } else { throw new IllegalArgumentException("cannot find corresponding index of offset: " + offset); } } public int getCodeIndexByOffset(int offset) { if (codeOffsetToIndexMap.containsKey(offset)) { return codeOffsetToIndexMap.get(offset); } else { throw new IllegalArgumentException("cannot find corresponding index of offset: " + offset); } } public int getDebugInfoItemIndexByOffset(int offset) { if (debugInfoItemOffsetToIndexMap.containsKey(offset)) { return debugInfoItemOffsetToIndexMap.get(offset); } else { throw new IllegalArgumentException("cannot find corresponding index of offset: " + offset); } } }