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 16f9835..560556a 100644 --- a/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/RESEncoder.java @@ -66,6 +66,7 @@ throw new IOException("No .*/values/" +ApkUtil.FILE_NAME_PUBLIC_XML+" file found in '"+mainDir); } + preloadStringPool(pubXmlFileList); for(File pubXmlFile:pubXmlFileList){ EncodeMaterials encodeMaterials = loadPublicXml(pubXmlFile); addParsedFiles(pubXmlFile); @@ -90,6 +91,20 @@ } tableBlock.refresh(); } + private void preloadStringPool(List pubXmlFileList){ + logMessage("Loading string pool ..."); + ValuesStringPoolBuilder poolBuilder=new ValuesStringPoolBuilder(); + for(File pubXml:pubXmlFileList){ + File resDir=toResDirectory(pubXml); + logMessage("Scanning: "+resDir.getParentFile().getName()); + List valuesDirList = listValuesDir(resDir); + for(File dir:valuesDirList){ + logVerbose(poolBuilder.size()+" building pool: "+dir.getName()); + poolBuilder.scanValuesDirectory(dir); + } + } + poolBuilder.addTo(tableBlock.getTableStringPool()); + } private EncodeMaterials loadPublicXml(File pubXmlFile) throws IOException, XMLException { ResourceIds resourceIds=new ResourceIds(); resourceIds.fromXml(pubXmlFile); diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/ValuesStringPoolBuilder.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/ValuesStringPoolBuilder.java new file mode 100644 index 0000000..328ea98 --- /dev/null +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/ValuesStringPoolBuilder.java @@ -0,0 +1,104 @@ + /* + * 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.arsc.decoder.ValueDecoder; +import com.reandroid.lib.arsc.pool.TableStringPool; +import com.reandroid.xml.XMLDocument; +import com.reandroid.xml.XMLElement; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +public class ValuesStringPoolBuilder { + private final Set stringList; + public ValuesStringPoolBuilder(){ + this.stringList=new HashSet<>(); + } + public void addTo(TableStringPool stringPool){ + stringPool.addStrings(stringList); + stringList.clear(); + } + public void scanValuesDirectory(File dir){ + addStringsFile(new File(dir, "strings.xml")); + addBagsFile(new File(dir, "plurals.xml")); + } + public int size(){ + return stringList.size(); + } + private void addStringsFile(File file) { + if(file==null||!file.isFile()){ + return; + } + try { + XMLDocument xmlDocument = XMLDocument.load(file); + addStrings(xmlDocument); + } catch (Exception ignored) { + } + } + private void addBagsFile(File file) { + if(file==null||!file.isFile()){ + return; + } + try { + XMLDocument xmlDocument = XMLDocument.load(file); + addBagStrings(xmlDocument); + } catch (Exception ignored) { + } + } + private void addBagStrings(XMLDocument xmlDocument){ + if(xmlDocument == null){ + return; + } + XMLElement documentElement = xmlDocument.getDocumentElement(); + if(documentElement==null){ + return; + } + int count = documentElement.getChildesCount(); + for(int i=0;i0 && text.charAt(0)!='@'){ + stringList.add(text); + } + } + +} diff --git a/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLValuesEncoderString.java b/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLValuesEncoderString.java index 5d133c3..ae47bf4 100644 --- a/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLValuesEncoderString.java +++ b/src/main/java/com/reandroid/lib/apk/xmlencoder/XMLValuesEncoderString.java @@ -27,11 +27,7 @@ class XMLValuesEncoderString extends XMLValuesEncoder{ XMLValuesEncoderString(EncodeMaterials materials) { super(materials); } - @Override - public void encode(String type, String qualifiers, XMLDocument xmlDocument){ - preloadStringPool(xmlDocument); - super.encode(type, qualifiers, xmlDocument); - } + @Override void encodeStringValue(EntryBlock entryBlock, String value){ entryBlock.setValueAsString(ValueDecoder.unEscapeSpecialCharacter(value)); @@ -44,17 +40,4 @@ class XMLValuesEncoderString extends XMLValuesEncoder{ void encodeBooleanValue(EntryBlock entryBlock, String value){ entryBlock.setValueAsString(value); } - private void preloadStringPool(XMLDocument xmlDocument){ - XMLElement documentElement = xmlDocument.getDocumentElement(); - List stringList = new ArrayList<>(); - int count = documentElement.getChildesCount(); - for(int i=0;i