/* * 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.tencent.tinker.loader.shareutil; import com.tencent.tinker.loader.TinkerRuntimeException; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.regex.Pattern; /** * Created by zhangshaowen on 16/8/9. */ public class ShareResPatchInfo { public String arscBaseCrc = null; public String resArscMd5 = null; public ArrayList<String> addRes = new ArrayList<>(); public ArrayList<String> deleteRes = new ArrayList<>(); public ArrayList<String> modRes = new ArrayList<>(); //use linkHashMap instead? public ArrayList<String> largeModRes = new ArrayList<>(); public HashMap<String, LargeModeInfo> largeModMap = new HashMap<>(); public HashSet<Pattern> patterns = new HashSet<>(); public static void parseAllResPatchInfo(String meta, ShareResPatchInfo info) { if (meta == null || meta.length() == 0) { return; } String[] lines = meta.split("\n"); for (int i = 0; i < lines.length; i++) { String line = lines[i]; if (line == null || line.length() <= 0) { continue; } if (line.startsWith(ShareConstants.RES_TITLE)) { final String[] kv = line.split(",", 3); info.arscBaseCrc = kv[1]; info.resArscMd5 = kv[2]; } else if (line.startsWith(ShareConstants.RES_PATTERN_TITLE)) { final String[] kv = line.split(":", 2); int size = Integer.parseInt(kv[1]); for (; size > 0; size--) { info.patterns.add(convertToPatternString(lines[i + 1])); i++; } } else if (line.startsWith(ShareConstants.RES_ADD_TITLE)) { final String[] kv = line.split(":", 2); int size = Integer.parseInt(kv[1]); for (; size > 0; size--) { info.addRes.add(lines[i + 1]); i++; } } else if (line.startsWith(ShareConstants.RES_MOD_TITLE)) { final String[] kv = line.split(":", 2); int size = Integer.parseInt(kv[1]); for (; size > 0; size--) { info.modRes.add(lines[i + 1]); i++; } } else if (line.startsWith(ShareConstants.RES_LARGE_MOD_TITLE)) { final String[] kv = line.split(":", 2); int size = Integer.parseInt(kv[1]); for (; size > 0; size--) { String nextLine = lines[i + 1]; final String[] data = nextLine.split(",", 3); String name = data[0]; LargeModeInfo largeModeInfo = new LargeModeInfo(); largeModeInfo.md5 = data[1]; largeModeInfo.crc = Long.parseLong(data[2]); info.largeModRes.add(name); info.largeModMap.put(name, largeModeInfo); i++; } } else if (line.startsWith(ShareConstants.RES_DEL_TITLE)) { final String[] kv = line.split(":", 2); int size = Integer.parseInt(kv[1]); for (; size > 0; size--) { info.deleteRes.add(lines[i + 1]); i++; } } } } public static boolean checkFileInPattern(HashSet<Pattern> patterns, String key) { if (!patterns.isEmpty()) { for (Iterator<Pattern> it = patterns.iterator(); it.hasNext();) { Pattern p = it.next(); if (p.matcher(key).matches()) { return true; } } } return false; } public static boolean checkResPatchInfo(ShareResPatchInfo info) { if (info == null) { return false; } String md5 = info.resArscMd5; if (md5 == null || md5.length() != ShareConstants.MD5_LENGTH) { return false; } return true; } private static Pattern convertToPatternString(String input) { //convert \\. if (input.contains(".")) { input = input.replaceAll("\\.", "\\\\."); } //convert ?to . if (input.contains("?")) { input = input.replaceAll("\\?", "\\."); } //convert * to.* if (input.contains("*")) { input = input.replace("*", ".*"); } Pattern pattern = Pattern.compile(input); return pattern; } public static void parseResPatchInfoFirstLine(String meta, ShareResPatchInfo info) { if (meta == null || meta.length() == 0) { return; } String[] lines = meta.split("\n"); String firstLine = lines[0]; if (firstLine == null || firstLine.length() <= 0) { throw new TinkerRuntimeException("res meta Corrupted:" + meta); } final String[] kv = firstLine.split(",", 3); info.arscBaseCrc = kv[1]; info.resArscMd5 = kv[2]; } @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("resArscMd5:" + resArscMd5 + "\n"); sb.append("arscBaseCrc:" + arscBaseCrc + "\n"); for (Pattern pattern : patterns) { sb.append("pattern:" + pattern + "\n"); } for (String add : addRes) { sb.append("addedSet:" + add + "\n"); } for (String mod : modRes) { sb.append("modifiedSet:" + mod + "\n"); } for (String largeMod : largeModRes) { sb.append("largeModifiedSet:" + largeMod + "\n"); } for (String del : deleteRes) { sb.append("deletedSet:" + del + "\n"); } return sb.toString(); } public static class LargeModeInfo { public String md5 = null; public long crc; public File file = null; } }