From a28e52fbcd068f9b02eacad1752d2569a770bede Mon Sep 17 00:00:00 2001 From: REAndroid Date: Mon, 2 Jan 2023 13:18:51 -0500 Subject: [PATCH] add FilePathEncoder --- .../lib/apk/xmlencoder/EncodeUtil.java | 35 ++++++++++ .../lib/apk/xmlencoder/FilePathEncoder.java | 65 +++++++++++++++++++ .../lib/apk/xmlencoder/RESEncoder.java | 13 ++-- .../lib/apk/xmlencoder/ValuesEncoder.java | 2 +- .../apk/xmlencoder/XMLValuesEncoderAttr.java | 3 - 5 files changed, 110 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/reandroid/lib/apk/xmlencoder/FilePathEncoder.java diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/EncodeUtil.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/EncodeUtil.java index 4d5e646..3027cb7 100644 --- a/src/main/java/com/reandroid/lib/apk/xmlencoder/EncodeUtil.java +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/EncodeUtil.java @@ -61,6 +61,41 @@ package com.reandroid.lib.apk.xmlencoder; } return ""; } + public static String getEntryPathFromResFile(File resFile){ + File typeDir=resFile.getParentFile(); + File resDir=typeDir.getParentFile(); + return resDir.getName() + +"/"+typeDir.getName() + +"/"+resFile.getName(); + } + public static String getEntryNameFromResFile(File resFile){ + String name=resFile.getName(); + String ninePatch=".9.png"; + if(name.endsWith(ninePatch)){ + return name.substring(0, name.length()-ninePatch.length()); + } + int i=name.lastIndexOf('.'); + if(i>0){ + name = name.substring(0, i); + } + return name; + } + public static String getQualifiersFromResFile(File resFile){ + String name=resFile.getParentFile().getName(); + int i=name.indexOf('-'); + if(i>0){ + return name.substring(i); + } + return ""; + } + public static String getTypeNameFromResFile(File resFile){ + String name=resFile.getParentFile().getName(); + int i=name.indexOf('-'); + if(i>0){ + name=name.substring(0, i); + } + return name; + } public static String getTypeNameFromValuesXml(File valuesXml){ String name=valuesXml.getName(); name=name.substring(0, name.length()-4); diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/FilePathEncoder.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/FilePathEncoder.java new file mode 100644 index 0000000..9e27180 --- /dev/null +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/FilePathEncoder.java @@ -0,0 +1,65 @@ + /* + * Copyright (C) 2022 github.com/REAndroid + * + * 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.reandroid.lib.apk.xmlencoder; + +import com.reandroid.lib.apk.ApkUtil; +import com.reandroid.lib.arsc.chunk.PackageBlock; +import com.reandroid.lib.arsc.chunk.TypeBlock; +import com.reandroid.lib.arsc.value.EntryBlock; + +import java.io.File; +import java.util.List; + +public class FilePathEncoder { + private final EncodeMaterials materials; + public FilePathEncoder(EncodeMaterials encodeMaterials){ + this.materials =encodeMaterials; + } + public void encodeResDir(File resDir){ + materials.logVerbose("Scanning file list: " + +resDir.getParentFile().getName() + +File.separator+resDir.getName()); + List dirList = ApkUtil.listDirectories(resDir); + for(File dir:dirList){ + if(dir.getName().startsWith("values")){ + continue; + } + encodeTypeDir(dir); + } + } + public void encodeTypeDir(File dir){ + List fileList = ApkUtil.listFiles(dir, null); + for(File file:fileList){ + encodeFileEntry(file); + } + } + public void encodeFileEntry(File resFile){ + String type = EncodeUtil.getTypeNameFromResFile(resFile); + PackageBlock packageBlock = materials.getCurrentPackage(); + byte typeId=packageBlock + .getTypeStringPool().idOf(type); + String qualifiers = EncodeUtil.getQualifiersFromResFile(resFile); + TypeBlock typeBlock = packageBlock.getOrCreateTypeBlock(typeId, qualifiers); + String name = EncodeUtil.getEntryNameFromResFile(resFile); + int resourceId=materials.resolveLocalResourceId(type, name); + + EntryBlock entryBlock=typeBlock + .getOrCreateEntry((short) (0xffff & resourceId)); + + entryBlock.setValueAsString(EncodeUtil.getEntryPathFromResFile(resFile)); + entryBlock.setSpecReference(materials.getSpecString(name)); + } +} diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java index badd2da..ec0084f 100644 --- a/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java @@ -35,10 +35,10 @@ public class RESEncoder { private APKLogger apkLogger; private final TableBlock tableBlock; - private final Set parsedFiles; + private final Set parsedValueFiles; public RESEncoder(){ this.tableBlock = new TableBlock(); - this.parsedFiles = new HashSet<>(); + this.parsedValueFiles = new HashSet<>(); } public TableBlock getTableBlock(){ return tableBlock; @@ -54,6 +54,11 @@ addParsedFiles(pubXmlFile); File resDir=toResDirectory(pubXmlFile); encodeResDir(encodeMaterials, resDir); + FilePathEncoder filePathEncoder = new FilePathEncoder(encodeMaterials); + filePathEncoder.encodeResDir(resDir); + PackageBlock packageBlock = encodeMaterials.getCurrentPackage(); + packageBlock.sortTypes(); + packageBlock.refresh(); } tableBlock.refresh(); } @@ -144,10 +149,10 @@ return results; } private boolean isAlreadyParsed(File file){ - return parsedFiles.contains(file); + return parsedValueFiles.contains(file); } private void addParsedFiles(File file){ - parsedFiles.add(file); + parsedValueFiles.add(file); } public void setAPKLogger(APKLogger logger) { this.apkLogger = logger; diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/ValuesEncoder.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/ValuesEncoder.java index 979b5e2..2d1d3b5 100644 --- a/src/main/java/com/reandroid/lib/apk/xmlencoder/ValuesEncoder.java +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/ValuesEncoder.java @@ -58,7 +58,7 @@ class ValuesEncoder { } String simpleName = valuesXmlFile.getParentFile().getName() +File.separator+valuesXmlFile.getName(); - materials.logMessage("Encoding: "+simpleName); + materials.logVerbose("Encoding: "+simpleName); String type = EncodeUtil.getTypeNameFromValuesXml(valuesXmlFile); String qualifiers = EncodeUtil.getQualifiersFromValuesXml(valuesXmlFile); diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLValuesEncoderAttr.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLValuesEncoderAttr.java index a6f09bb..d17e0f6 100644 --- a/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLValuesEncoderAttr.java +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLValuesEncoderAttr.java @@ -42,9 +42,6 @@ class XMLValuesEncoderAttr extends XMLValuesEncoderBag{ void encodeChildes(XMLElement parentElement, ResValueBag resValueBag){ encodeAttributes(parentElement, resValueBag); encodeEnumOrFlag(parentElement, resValueBag); - AttributeBag attributeBag=AttributeBag.create(resValueBag); - getMaterials().logMessage(attributeBag.toString()); - getMaterials().logMessage(attributeBag.toString()); } private void encodeAttributes(XMLElement parentElement, ResValueBag resValueBag){ int count=parentElement.getAttributeCount();