package com.meituan.robust.autopatch; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; /** * Created by mivanzhang on 17/1/19. * * Reading mapping from mapping.txt,which is generated by Progaurd */ public class ReadMapping { private static ReadMapping instance; private Map<String, ClassMapping> usedInModifiedClassMappingInfo = new HashMap<String, ClassMapping>(); public static ReadMapping getInstance() { if (instance == null) { instance = new ReadMapping(); } return instance; } public static void init() { instance = new ReadMapping(); } private ReadMapping() { } /*** * read all class mapping info * * @return */ public void initMappingInfo() { //查找mapping文件 InputStream is = null; boolean needBacktrace = true; String line; try { is = new FileInputStream(Config.mappingFilePath); BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"), 1024); // 读取一行,存储于字符串列表中 line = reader.readLine().trim(); while (line != null) { line = line.trim(); if (!needBacktrace) { line = reader.readLine(); if (line == null) { break; } line = line.trim(); } needBacktrace = false; if (line.indexOf("->") > 0 && line.indexOf(":") == line.length() - 1) { ClassMapping classMapping = new ClassMapping(); classMapping.setClassName(line.substring(0, line.indexOf("->") - 1).trim()); classMapping.setValueName(line.split("->")[1].substring(0, line.split("->")[1].length() - 1).trim()); line = reader.readLine().trim(); while (line != null) { if (line.endsWith(":")) { needBacktrace = true; break; } String[] lineinfo = line.split(" "); if (lineinfo.length != 4) { throw new RuntimeException("line info is error " + line); } if (lineinfo[1].contains("(") && lineinfo[1].contains(")")) { //methods need return type classMapping.getMemberMapping().put(getMethodSigureWithReturnTypeInMapping(lineinfo[0].trim(), lineinfo[1].trim()), lineinfo[3].trim()); } else { classMapping.getMemberMapping().put(lineinfo[1].trim(), lineinfo[3].trim()); } line = reader.readLine(); if (line == null) { break; } line = line.trim(); } usedInModifiedClassMappingInfo.put(classMapping.getClassName(), classMapping); } } } catch (IOException ioe) { ioe.printStackTrace(); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { e.printStackTrace(); } } } public ClassMapping getClassMapping(String classname) { return usedInModifiedClassMappingInfo.get(classname); } public ClassMapping getClassMappingOrDefault(String classname) { ClassMapping defaultClassMapping=new ClassMapping(); if(!Config.supportProGuard){ defaultClassMapping.setValueName(classname); } return usedInModifiedClassMappingInfo.getOrDefault(classname,defaultClassMapping); } /*** * @param returnTypeWithNumber * @param methodSignure * @return returnType+" "+methodSignure,just one blank */ public String getMethodSigureWithReturnTypeInMapping(String returnTypeWithNumber, String methodSignure) { //初步观察mapping文件,使用":"来截取返回值,还可以通过寻找第一个字符, return getMethodSignureWithReturnType(returnTypeWithNumber.substring(returnTypeWithNumber.lastIndexOf(":") + 1), methodSignure); } public String getMethodSignureWithReturnType(String returnType, String methodSignure) { //只有一个空格 return returnType + " " + methodSignure; } }