mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-05-02 15:14:26 +02:00
fix multi-package xml compiling #40
This commit is contained in:
parent
e136a8d570
commit
ada5aaf17d
@ -18,8 +18,11 @@ package com.reandroid.apk;
|
|||||||
import com.reandroid.archive.APKArchive;
|
import com.reandroid.archive.APKArchive;
|
||||||
import com.reandroid.archive.FileInputSource;
|
import com.reandroid.archive.FileInputSource;
|
||||||
import com.reandroid.apk.xmlencoder.RESEncoder;
|
import com.reandroid.apk.xmlencoder.RESEncoder;
|
||||||
|
import com.reandroid.archive.InputSource;
|
||||||
|
import com.reandroid.archive.InputSourceUtil;
|
||||||
import com.reandroid.archive2.block.ApkSignatureBlock;
|
import com.reandroid.archive2.block.ApkSignatureBlock;
|
||||||
import com.reandroid.arsc.chunk.TableBlock;
|
import com.reandroid.arsc.chunk.TableBlock;
|
||||||
|
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
|
||||||
import com.reandroid.json.JSONArray;
|
import com.reandroid.json.JSONArray;
|
||||||
import com.reandroid.xml.XMLException;
|
import com.reandroid.xml.XMLException;
|
||||||
|
|
||||||
@ -43,6 +46,7 @@ public class ApkModuleXmlEncoder {
|
|||||||
scanRootDir(rootDir);
|
scanRootDir(rootDir);
|
||||||
restorePathMap(mainDirectory);
|
restorePathMap(mainDirectory);
|
||||||
restoreSignatures(mainDirectory);
|
restoreSignatures(mainDirectory);
|
||||||
|
sortFiles();
|
||||||
}
|
}
|
||||||
private void restoreSignatures(File dir) throws IOException {
|
private void restoreSignatures(File dir) throws IOException {
|
||||||
File sigDir = new File(dir, ApkUtil.SIGNATURE_DIR_NAME);
|
File sigDir = new File(dir, ApkUtil.SIGNATURE_DIR_NAME);
|
||||||
@ -79,6 +83,24 @@ public class ApkModuleXmlEncoder {
|
|||||||
archive.add(inputSource);
|
archive.add(inputSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void sortFiles(){
|
||||||
|
APKArchive archive=getApkModule().getApkArchive();
|
||||||
|
int i = 1;
|
||||||
|
for(InputSource inputSource:archive.listInputSources()){
|
||||||
|
if(inputSource.getSort() == 0){
|
||||||
|
inputSource.setSort(i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InputSource manifest = archive.getInputSource(AndroidManifestBlock.FILE_NAME);
|
||||||
|
if(manifest != null){
|
||||||
|
manifest.setSort(0);
|
||||||
|
}
|
||||||
|
List<InputSource> sourceList = archive.listInputSources();
|
||||||
|
InputSourceUtil.sort(sourceList);
|
||||||
|
archive.clear();
|
||||||
|
archive.addAll(sourceList);
|
||||||
|
}
|
||||||
private void loadUncompressedFiles(File mainDirectory) throws IOException, XMLException {
|
private void loadUncompressedFiles(File mainDirectory) throws IOException, XMLException {
|
||||||
File file=new File(mainDirectory, UncompressedFiles.JSON_FILE);
|
File file=new File(mainDirectory, UncompressedFiles.JSON_FILE);
|
||||||
UncompressedFiles uncompressedFiles = getApkModule().getUncompressedFiles();
|
UncompressedFiles uncompressedFiles = getApkModule().getUncompressedFiles();
|
||||||
|
@ -29,7 +29,6 @@ import com.reandroid.arsc.util.FrameworkTable;
|
|||||||
import com.reandroid.arsc.util.HexUtil;
|
import com.reandroid.arsc.util.HexUtil;
|
||||||
import com.reandroid.arsc.util.ResNameMap;
|
import com.reandroid.arsc.util.ResNameMap;
|
||||||
import com.reandroid.arsc.value.Entry;
|
import com.reandroid.arsc.value.Entry;
|
||||||
import com.reandroid.common.Frameworks;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -38,6 +37,7 @@ import java.util.regex.Matcher;
|
|||||||
public class EncodeMaterials {
|
public class EncodeMaterials {
|
||||||
private final Set<ResourceIds.Table.Package> packageIdSet = new HashSet<>();
|
private final Set<ResourceIds.Table.Package> packageIdSet = new HashSet<>();
|
||||||
private PackageBlock currentPackage;
|
private PackageBlock currentPackage;
|
||||||
|
private ResourceIds.Table.Package currentLocalPackage;
|
||||||
private final Set<FrameworkTable> frameworkTables = new HashSet<>();
|
private final Set<FrameworkTable> frameworkTables = new HashSet<>();
|
||||||
private APKLogger apkLogger;
|
private APKLogger apkLogger;
|
||||||
private boolean mForceCreateNamespaces = true;
|
private boolean mForceCreateNamespaces = true;
|
||||||
@ -99,6 +99,10 @@ public class EncodeMaterials {
|
|||||||
}
|
}
|
||||||
String type = matcher.group(4);
|
String type = matcher.group(4);
|
||||||
String name = matcher.group(5);
|
String name = matcher.group(5);
|
||||||
|
if(isLocalPackageName(packageName)){
|
||||||
|
return resolveLocalResourceId(packageName, type, name);
|
||||||
|
}
|
||||||
|
|
||||||
if(EncodeUtil.isEmpty(packageName)
|
if(EncodeUtil.isEmpty(packageName)
|
||||||
|| packageName.equals(getCurrentPackageName())
|
|| packageName.equals(getCurrentPackageName())
|
||||||
|| !isFrameworkPackageName(packageName)){
|
|| !isFrameworkPackageName(packageName)){
|
||||||
@ -106,12 +110,35 @@ public class EncodeMaterials {
|
|||||||
}
|
}
|
||||||
return resolveFrameworkResourceId(packageName, type, name);
|
return resolveFrameworkResourceId(packageName, type, name);
|
||||||
}
|
}
|
||||||
|
private int resolveLocalResourceId(String packageName, String type, String name){
|
||||||
|
ResourceIds.Table.Package pkg = getLocalPackage(packageName);
|
||||||
|
Integer resourceId = pkg.getResourceId(type, name);
|
||||||
|
if(resourceId != null){
|
||||||
|
return resourceId;
|
||||||
|
}
|
||||||
|
EntryGroup entryGroup=getLocalEntryGroup(type, name);
|
||||||
|
if(entryGroup!=null){
|
||||||
|
return entryGroup.getResourceId();
|
||||||
|
}
|
||||||
|
throw new EncodeException("Local entry not found: " +
|
||||||
|
"package=" + packageName +
|
||||||
|
", type=" + type +
|
||||||
|
", name=" + name);
|
||||||
|
}
|
||||||
public int resolveLocalResourceId(String type, String name){
|
public int resolveLocalResourceId(String type, String name){
|
||||||
for(ResourceIds.Table.Package pkg:packageIdSet){
|
ResourceIds.Table.Package current = this.currentLocalPackage;
|
||||||
Integer resId = pkg.getResourceId(type, name);
|
if(current != null){
|
||||||
if(resId!=null){
|
Integer resId = current.getResourceId(type, name);
|
||||||
|
if(resId != null){
|
||||||
return resId;
|
return resId;
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
for(ResourceIds.Table.Package pkg:packageIdSet){
|
||||||
|
Integer resId = pkg.getResourceId(type, name);
|
||||||
|
if(resId!=null){
|
||||||
|
return resId;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EntryGroup entryGroup=getLocalEntryGroup(type, name);
|
EntryGroup entryGroup=getLocalEntryGroup(type, name);
|
||||||
if(entryGroup!=null){
|
if(entryGroup!=null){
|
||||||
@ -286,8 +313,73 @@ public class EncodeMaterials {
|
|||||||
}
|
}
|
||||||
public EncodeMaterials setCurrentPackage(PackageBlock currentPackage) {
|
public EncodeMaterials setCurrentPackage(PackageBlock currentPackage) {
|
||||||
this.currentPackage = currentPackage;
|
this.currentPackage = currentPackage;
|
||||||
|
onCurrentPackageChanged(currentPackage);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public EncodeMaterials setCurrentLocalPackage(ResourceIds.Table.Package currentLocalPackage) {
|
||||||
|
this.currentLocalPackage = currentLocalPackage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
private void onCurrentPackageChanged(PackageBlock currentPackage){
|
||||||
|
if(currentPackage == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResourceIds.Table.Package current = null;
|
||||||
|
if(isUniquePackageIds()){
|
||||||
|
current = getLocalPackage(currentPackage.getId());
|
||||||
|
}
|
||||||
|
if(current == null && isUniquePackageNames()){
|
||||||
|
current = getLocalPackage(currentPackage.getName());
|
||||||
|
}
|
||||||
|
if(current != null){
|
||||||
|
this.currentLocalPackage = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private ResourceIds.Table.Package getLocalPackage(int packageId){
|
||||||
|
byte id = (byte) packageId;
|
||||||
|
for(ResourceIds.Table.Package pkg : packageIdSet){
|
||||||
|
if(id == pkg.id){
|
||||||
|
return pkg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private ResourceIds.Table.Package getLocalPackage(String name){
|
||||||
|
if(name == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for(ResourceIds.Table.Package pkg : packageIdSet){
|
||||||
|
if(name.equals(pkg.name)){
|
||||||
|
return pkg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private boolean isLocalPackageName(String packageName){
|
||||||
|
if(packageName == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(ResourceIds.Table.Package pkg : packageIdSet){
|
||||||
|
if(packageName.equals(pkg.name)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private boolean isUniquePackageNames(){
|
||||||
|
Set<String> names = new HashSet<>();
|
||||||
|
for(ResourceIds.Table.Package pkg : packageIdSet){
|
||||||
|
names.add(pkg.name);
|
||||||
|
}
|
||||||
|
return names.size() == packageIdSet.size();
|
||||||
|
}
|
||||||
|
private boolean isUniquePackageIds(){
|
||||||
|
Set<Byte> ids = new HashSet<>();
|
||||||
|
for(ResourceIds.Table.Package pkg : packageIdSet){
|
||||||
|
ids.add(pkg.id);
|
||||||
|
}
|
||||||
|
return ids.size() == packageIdSet.size();
|
||||||
|
}
|
||||||
public EncodeMaterials addFramework(FrameworkApk frameworkApk) {
|
public EncodeMaterials addFramework(FrameworkApk frameworkApk) {
|
||||||
if(frameworkApk!=null){
|
if(frameworkApk!=null){
|
||||||
addFramework(frameworkApk.getTableBlock());
|
addFramework(frameworkApk.getTableBlock());
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.apk.xmlencoder;
|
package com.reandroid.apk.xmlencoder;
|
||||||
|
|
||||||
import com.reandroid.archive.APKArchive;
|
import com.reandroid.archive.APKArchive;
|
||||||
import com.reandroid.archive.FileInputSource;
|
import com.reandroid.archive.FileInputSource;
|
||||||
import com.reandroid.archive.InputSource;
|
import com.reandroid.archive.InputSource;
|
||||||
import com.reandroid.apk.ApkUtil;
|
import com.reandroid.apk.ApkUtil;
|
||||||
import com.reandroid.apk.UncompressedFiles;
|
import com.reandroid.apk.UncompressedFiles;
|
||||||
import com.reandroid.arsc.chunk.PackageBlock;
|
import com.reandroid.arsc.chunk.PackageBlock;
|
||||||
import com.reandroid.arsc.chunk.TypeBlock;
|
import com.reandroid.arsc.chunk.TypeBlock;
|
||||||
import com.reandroid.arsc.value.Entry;
|
import com.reandroid.arsc.value.Entry;
|
||||||
import com.reandroid.xml.source.XMLFileSource;
|
import com.reandroid.xml.source.XMLFileSource;
|
||||||
import com.reandroid.xml.source.XMLSource;
|
import com.reandroid.xml.source.XMLSource;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class FilePathEncoder {
|
public class FilePathEncoder {
|
||||||
private final EncodeMaterials materials;
|
private final EncodeMaterials materials;
|
||||||
private APKArchive apkArchive;
|
private APKArchive apkArchive;
|
||||||
private UncompressedFiles uncompressedFiles;
|
private UncompressedFiles uncompressedFiles;
|
||||||
@ -78,6 +78,9 @@ package com.reandroid.apk.xmlencoder;
|
|||||||
entry.setValueAsString(path);
|
entry.setValueAsString(path);
|
||||||
entry.setSpecReference(materials.getSpecString(name));
|
entry.setSpecReference(materials.getSpecString(name));
|
||||||
InputSource inputSource=createInputSource(path, resFile);
|
InputSource inputSource=createInputSource(path, resFile);
|
||||||
|
if(inputSource instanceof XMLEncodeSource){
|
||||||
|
((XMLEncodeSource)inputSource).setEntry(entry);
|
||||||
|
}
|
||||||
addInputSource(inputSource);
|
addInputSource(inputSource);
|
||||||
return inputSource;
|
return inputSource;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.apk.xmlencoder;
|
package com.reandroid.apk.xmlencoder;
|
||||||
|
|
||||||
import com.reandroid.apk.APKLogger;
|
import com.reandroid.apk.APKLogger;
|
||||||
@ -45,14 +45,13 @@ class PackageCreator {
|
|||||||
}
|
}
|
||||||
public PackageBlock createNew(TableBlock tableBlock, ResourceIds.Table.Package pkgResourceIds){
|
public PackageBlock createNew(TableBlock tableBlock, ResourceIds.Table.Package pkgResourceIds){
|
||||||
loadNames(pkgResourceIds);
|
loadNames(pkgResourceIds);
|
||||||
PackageBlock packageBlock=new PackageBlock();
|
PackageBlock packageBlock = tableBlock.getPackageArray().createNext();
|
||||||
packageBlock.setName(mPackageName);
|
packageBlock.setName(mPackageName);
|
||||||
packageBlock.setId(mPackageId);
|
packageBlock.setId(mPackageId);
|
||||||
|
|
||||||
loadPackageInfoJson(packageBlock);
|
loadPackageInfoJson(packageBlock);
|
||||||
|
this.mPackageName = packageBlock.getName();
|
||||||
|
|
||||||
tableBlock.getPackageArray()
|
|
||||||
.add(packageBlock);
|
|
||||||
packageBlock.getSpecStringPool()
|
packageBlock.getSpecStringPool()
|
||||||
.addStrings(mSpecNames);
|
.addStrings(mSpecNames);
|
||||||
|
|
||||||
|
@ -1,306 +1,315 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.apk.xmlencoder;
|
package com.reandroid.apk.xmlencoder;
|
||||||
|
|
||||||
import com.reandroid.apk.*;
|
import com.reandroid.apk.*;
|
||||||
import com.reandroid.archive.APKArchive;
|
import com.reandroid.archive.APKArchive;
|
||||||
import com.reandroid.arsc.chunk.PackageBlock;
|
import com.reandroid.arsc.chunk.PackageBlock;
|
||||||
import com.reandroid.arsc.chunk.TableBlock;
|
import com.reandroid.arsc.chunk.TableBlock;
|
||||||
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
|
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
|
||||||
import com.reandroid.xml.XMLDocument;
|
import com.reandroid.xml.XMLDocument;
|
||||||
import com.reandroid.xml.XMLException;
|
import com.reandroid.xml.XMLException;
|
||||||
import com.reandroid.xml.source.XMLFileSource;
|
import com.reandroid.xml.source.XMLFileSource;
|
||||||
import com.reandroid.xml.source.XMLSource;
|
import com.reandroid.xml.source.XMLSource;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
|
||||||
public class RESEncoder {
|
public class RESEncoder {
|
||||||
private APKLogger apkLogger;
|
private APKLogger apkLogger;
|
||||||
private final TableBlock tableBlock;
|
private final TableBlock tableBlock;
|
||||||
private final Set<File> parsedFiles = new HashSet<>();
|
private final Set<File> parsedFiles = new HashSet<>();
|
||||||
private final ApkModule apkModule;
|
private final ApkModule apkModule;
|
||||||
public RESEncoder(){
|
public RESEncoder(){
|
||||||
this(new ApkModule("encoded",
|
this(new ApkModule("encoded",
|
||||||
new APKArchive()), new TableBlock());
|
new APKArchive()), new TableBlock());
|
||||||
}
|
}
|
||||||
public RESEncoder(ApkModule module, TableBlock block){
|
public RESEncoder(ApkModule module, TableBlock block){
|
||||||
this.apkModule = module;
|
this.apkModule = module;
|
||||||
this.tableBlock = block;
|
this.tableBlock = block;
|
||||||
if(!module.hasTableBlock()){
|
if(!module.hasTableBlock()){
|
||||||
BlockInputSource<TableBlock> inputSource=
|
BlockInputSource<TableBlock> inputSource=
|
||||||
new BlockInputSource<>(TableBlock.FILE_NAME, block);
|
new BlockInputSource<>(TableBlock.FILE_NAME, block);
|
||||||
inputSource.setMethod(ZipEntry.STORED);
|
inputSource.setMethod(ZipEntry.STORED);
|
||||||
this.apkModule.getUncompressedFiles().addPath(inputSource);
|
this.apkModule.getUncompressedFiles().addPath(inputSource);
|
||||||
this.apkModule.getApkArchive().add(inputSource);
|
this.apkModule.getApkArchive().add(inputSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public TableBlock getTableBlock(){
|
public TableBlock getTableBlock(){
|
||||||
return tableBlock;
|
return tableBlock;
|
||||||
}
|
}
|
||||||
public ApkModule getApkModule(){
|
public ApkModule getApkModule(){
|
||||||
return apkModule;
|
return apkModule;
|
||||||
}
|
}
|
||||||
public void scanDirectory(File mainDir) throws IOException, XMLException {
|
public void scanDirectory(File mainDir) throws IOException, XMLException {
|
||||||
scanResourceFiles(mainDir);
|
scanResourceFiles(mainDir);
|
||||||
}
|
}
|
||||||
private void scanResourceFiles(File mainDir) throws IOException, XMLException {
|
private void scanResourceFiles(File mainDir) throws IOException, XMLException {
|
||||||
List<File> pubXmlFileList = searchPublicXmlFiles(mainDir);
|
List<File> pubXmlFileList = searchPublicXmlFiles(mainDir);
|
||||||
if(pubXmlFileList.size()==0){
|
if(pubXmlFileList.size()==0){
|
||||||
throw new IOException("No .*/values/"
|
throw new IOException("No .*/values/"
|
||||||
+ ApkUtil.FILE_NAME_PUBLIC_XML+" file found in '"+mainDir);
|
+ ApkUtil.FILE_NAME_PUBLIC_XML+" file found in '"+mainDir);
|
||||||
}
|
}
|
||||||
preloadStringPool(pubXmlFileList);
|
preloadStringPool(pubXmlFileList);
|
||||||
|
|
||||||
EncodeMaterials encodeMaterials=new EncodeMaterials();
|
EncodeMaterials encodeMaterials=new EncodeMaterials();
|
||||||
|
|
||||||
Map<File, ResourceIds.Table.Package> map =
|
Map<File, ResourceIds.Table.Package> map =
|
||||||
initializeEncodeMaterials(pubXmlFileList, encodeMaterials);
|
initializeEncodeMaterials(pubXmlFileList, encodeMaterials);
|
||||||
|
|
||||||
Map<File, PackageBlock> packageBlockMap=new HashMap<>();
|
Map<File, PackageBlock> packageBlockMap=new HashMap<>();
|
||||||
|
|
||||||
for(File pubXmlFile:pubXmlFileList){
|
for(File pubXmlFile:pubXmlFileList){
|
||||||
ResourceIds.Table.Package pkgResourceIds=map.get(pubXmlFile);
|
ResourceIds.Table.Package pkgResourceIds = map.get(pubXmlFile);
|
||||||
if(pkgResourceIds==null){
|
if(pkgResourceIds==null){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
addParsedFiles(pubXmlFile);
|
addParsedFiles(pubXmlFile);
|
||||||
|
|
||||||
PackageBlock packageBlock = createPackage(pkgResourceIds, pubXmlFile);
|
PackageBlock packageBlock = createPackage(pkgResourceIds, pubXmlFile);
|
||||||
encodeMaterials.setCurrentPackage(packageBlock);
|
encodeMaterials.setCurrentPackage(packageBlock);
|
||||||
packageBlockMap.put(pubXmlFile, packageBlock);
|
encodeMaterials.setCurrentLocalPackage(pkgResourceIds);
|
||||||
|
packageBlockMap.put(pubXmlFile, packageBlock);
|
||||||
|
|
||||||
ValuesEncoder valuesEncoder = new ValuesEncoder(encodeMaterials);
|
ValuesEncoder valuesEncoder = new ValuesEncoder(encodeMaterials);
|
||||||
File fileIds = toId(pubXmlFile);
|
File fileIds = toId(pubXmlFile);
|
||||||
if(fileIds.isFile()){
|
if(fileIds.isFile()){
|
||||||
valuesEncoder.encodeValuesXml(fileIds);
|
valuesEncoder.encodeValuesXml(fileIds);
|
||||||
packageBlock.sortTypes();
|
packageBlock.sortTypes();
|
||||||
packageBlock.refresh();
|
packageBlock.refresh();
|
||||||
addParsedFiles(fileIds);
|
addParsedFiles(fileIds);
|
||||||
}
|
}
|
||||||
File fileAttrs = toAttr(pubXmlFile);
|
File fileAttrs = toAttr(pubXmlFile);
|
||||||
if(fileAttrs.isFile()){
|
if(fileAttrs.isFile()){
|
||||||
valuesEncoder.encodeValuesXml(fileAttrs);
|
valuesEncoder.encodeValuesXml(fileAttrs);
|
||||||
packageBlock.sortTypes();
|
packageBlock.sortTypes();
|
||||||
packageBlock.refresh();
|
packageBlock.refresh();
|
||||||
addParsedFiles(fileAttrs);
|
addParsedFiles(fileAttrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(File pubXmlFile:pubXmlFileList){
|
File manifestFile = null;
|
||||||
ResourceIds.Table.Package pkgResourceIds=map.get(pubXmlFile);
|
for(File pubXmlFile:pubXmlFileList){
|
||||||
if(pkgResourceIds==null){
|
ResourceIds.Table.Package pkgResourceIds = map.get(pubXmlFile);
|
||||||
continue;
|
if(pkgResourceIds==null){
|
||||||
}
|
continue;
|
||||||
addParsedFiles(pubXmlFile);
|
}
|
||||||
|
addParsedFiles(pubXmlFile);
|
||||||
|
if(manifestFile == null){
|
||||||
|
manifestFile = toAndroidManifest(pubXmlFile);
|
||||||
|
}
|
||||||
|
|
||||||
PackageBlock packageBlock=packageBlockMap.get(pubXmlFile);
|
PackageBlock packageBlock=packageBlockMap.get(pubXmlFile);
|
||||||
|
|
||||||
if(packageBlock==null){
|
if(packageBlock==null){
|
||||||
packageBlock = createPackage(pkgResourceIds, pubXmlFile);
|
packageBlock = createPackage(pkgResourceIds, pubXmlFile);
|
||||||
}
|
}
|
||||||
encodeMaterials.setCurrentPackage(packageBlock);
|
encodeMaterials.setCurrentPackage(packageBlock);
|
||||||
|
encodeMaterials.setCurrentLocalPackage(pkgResourceIds);
|
||||||
|
|
||||||
File resDir=toResDirectory(pubXmlFile);
|
File resDir=toResDirectory(pubXmlFile);
|
||||||
encodeResDir(encodeMaterials, resDir);
|
encodeResDir(encodeMaterials, resDir);
|
||||||
FilePathEncoder filePathEncoder = new FilePathEncoder(encodeMaterials);
|
FilePathEncoder filePathEncoder = new FilePathEncoder(encodeMaterials);
|
||||||
filePathEncoder.setApkArchive(getApkModule().getApkArchive());
|
filePathEncoder.setApkArchive(getApkModule().getApkArchive());
|
||||||
filePathEncoder.setUncompressedFiles(getApkModule().getUncompressedFiles());
|
filePathEncoder.setUncompressedFiles(getApkModule().getUncompressedFiles());
|
||||||
filePathEncoder.encodeResDir(resDir);
|
filePathEncoder.encodeResDir(resDir);
|
||||||
|
|
||||||
packageBlock.sortTypes();
|
packageBlock.sortTypes();
|
||||||
packageBlock.refresh();
|
packageBlock.refresh();
|
||||||
|
}
|
||||||
|
tableBlock.refresh();
|
||||||
|
PackageBlock packageBlock = tableBlock.pickOne();
|
||||||
|
if(manifestFile != null){
|
||||||
|
if(packageBlock != null){
|
||||||
|
encodeMaterials.setCurrentPackage(packageBlock);
|
||||||
|
}
|
||||||
|
XMLSource xmlSource =
|
||||||
|
new XMLFileSource(AndroidManifestBlock.FILE_NAME, manifestFile);
|
||||||
|
XMLEncodeSource xmlEncodeSource =
|
||||||
|
new XMLEncodeSource(encodeMaterials, xmlSource);
|
||||||
|
getApkModule().getApkArchive().add(xmlEncodeSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private PackageBlock createPackage(ResourceIds.Table.Package pkgResourceIds
|
||||||
|
, File pubXmlFile){
|
||||||
|
PackageCreator packageCreator = new PackageCreator();
|
||||||
|
packageCreator.setPackageName(pkgResourceIds.name);
|
||||||
|
packageCreator.setAPKLogger(apkLogger);
|
||||||
|
packageCreator.setPackageDirectory(toPackageDirectory(pubXmlFile));
|
||||||
|
return packageCreator.createNew(this.tableBlock, pkgResourceIds);
|
||||||
|
}
|
||||||
|
private void preloadStringPool(List<File> pubXmlFileList){
|
||||||
|
logMessage("Loading string pool ...");
|
||||||
|
ValuesStringPoolBuilder poolBuilder=new ValuesStringPoolBuilder();
|
||||||
|
for(File pubXml:pubXmlFileList){
|
||||||
|
File resDir=toResDirectory(pubXml);
|
||||||
|
List<File> valuesDirList = listValuesDir(resDir);
|
||||||
|
for(File dir:valuesDirList){
|
||||||
|
logVerbose(poolBuilder.size()+" building pool: "+dir.getName());
|
||||||
|
poolBuilder.scanValuesDirectory(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
poolBuilder.addTo(tableBlock.getTableStringPool());
|
||||||
|
}
|
||||||
|
|
||||||
File manifestFile=toAndroidManifest(pubXmlFile);
|
private Map<File, ResourceIds.Table.Package> initializeEncodeMaterials(
|
||||||
XMLSource xmlSource =
|
List<File> pubXmlFileList, EncodeMaterials encodeMaterials)
|
||||||
new XMLFileSource(AndroidManifestBlock.FILE_NAME, manifestFile);
|
throws IOException, XMLException {
|
||||||
XMLEncodeSource xmlEncodeSource =
|
|
||||||
new XMLEncodeSource(encodeMaterials, xmlSource);
|
|
||||||
|
|
||||||
getApkModule().getApkArchive().add(xmlEncodeSource);
|
encodeMaterials.setAPKLogger(apkLogger);
|
||||||
}
|
|
||||||
tableBlock.refresh();
|
|
||||||
}
|
|
||||||
private PackageBlock createPackage(ResourceIds.Table.Package pkgResourceIds
|
|
||||||
, File pubXmlFile){
|
|
||||||
PackageCreator packageCreator = new PackageCreator();
|
|
||||||
packageCreator.setPackageName(pkgResourceIds.name);
|
|
||||||
packageCreator.setAPKLogger(apkLogger);
|
|
||||||
packageCreator.setPackageDirectory(toPackageDirectory(pubXmlFile));
|
|
||||||
return packageCreator.createNew(this.tableBlock, pkgResourceIds);
|
|
||||||
}
|
|
||||||
private void preloadStringPool(List<File> pubXmlFileList){
|
|
||||||
logMessage("Loading string pool ...");
|
|
||||||
ValuesStringPoolBuilder poolBuilder=new ValuesStringPoolBuilder();
|
|
||||||
for(File pubXml:pubXmlFileList){
|
|
||||||
File resDir=toResDirectory(pubXml);
|
|
||||||
List<File> valuesDirList = listValuesDir(resDir);
|
|
||||||
for(File dir:valuesDirList){
|
|
||||||
logVerbose(poolBuilder.size()+" building pool: "+dir.getName());
|
|
||||||
poolBuilder.scanValuesDirectory(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
poolBuilder.addTo(tableBlock.getTableStringPool());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<File, ResourceIds.Table.Package> initializeEncodeMaterials(
|
Map<File, ResourceIds.Table.Package> results = new HashMap<>();
|
||||||
List<File> pubXmlFileList, EncodeMaterials encodeMaterials)
|
|
||||||
throws IOException, XMLException {
|
|
||||||
|
|
||||||
encodeMaterials.setAPKLogger(apkLogger);
|
String packageName=null;
|
||||||
|
for(File pubXmlFile:pubXmlFileList){
|
||||||
|
if(packageName==null){
|
||||||
|
File manifestFile = toAndroidManifest(pubXmlFile);
|
||||||
|
packageName=readManifestPackageName(manifestFile);
|
||||||
|
FrameworkApk frameworkApk = getApkModule()
|
||||||
|
.initializeAndroidFramework(XMLDocument.load(manifestFile));
|
||||||
|
encodeMaterials.addFramework(frameworkApk);
|
||||||
|
}
|
||||||
|
ResourceIds resourceIds=new ResourceIds();
|
||||||
|
resourceIds.fromXml(pubXmlFile);
|
||||||
|
List<ResourceIds.Table.Package> pkgList = resourceIds.getTable()
|
||||||
|
.listPackages();
|
||||||
|
if(pkgList.size()==0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ResourceIds.Table.Package pkg = pkgList.get(0);
|
||||||
|
if(pkg.name==null){
|
||||||
|
pkg.name=packageName;
|
||||||
|
}
|
||||||
|
encodeMaterials.addPackageIds(pkg);
|
||||||
|
results.put(pubXmlFile, pkg);
|
||||||
|
}
|
||||||
|
|
||||||
Map<File, ResourceIds.Table.Package> results = new HashMap<>();
|
encodeMaterials.setAPKLogger(apkLogger);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
private String readManifestPackageName(File manifestFile) throws XMLException {
|
||||||
|
XMLDocument manifestDocument = XMLDocument.load(manifestFile);
|
||||||
|
return manifestDocument
|
||||||
|
.getDocumentElement().getAttributeValue("package");
|
||||||
|
}
|
||||||
|
private void encodeResDir(EncodeMaterials materials, File resDir) throws XMLException {
|
||||||
|
|
||||||
String packageName=null;
|
List<File> valuesDirList = listValuesDir(resDir);
|
||||||
for(File pubXmlFile:pubXmlFileList){
|
for(File valuesDir:valuesDirList){
|
||||||
if(packageName==null){
|
encodeValuesDir(materials, valuesDir);
|
||||||
File manifestFile = toAndroidManifest(pubXmlFile);
|
}
|
||||||
packageName=readManifestPackageName(manifestFile);
|
}
|
||||||
FrameworkApk frameworkApk = getApkModule()
|
private void encodeValuesDir(EncodeMaterials materials, File valuesDir) throws XMLException {
|
||||||
.initializeAndroidFramework(XMLDocument.load(manifestFile));
|
ValuesEncoder valuesEncoder = new ValuesEncoder(materials);
|
||||||
encodeMaterials.addFramework(frameworkApk);
|
List<File> xmlFiles = ApkUtil.listFiles(valuesDir, ".xml");
|
||||||
}
|
EncodeUtil.sortValuesXml(xmlFiles);
|
||||||
ResourceIds resourceIds=new ResourceIds();
|
for(File file:xmlFiles){
|
||||||
resourceIds.fromXml(pubXmlFile);
|
if(isAlreadyParsed(file)){
|
||||||
List<ResourceIds.Table.Package> pkgList = resourceIds.getTable()
|
continue;
|
||||||
.listPackages();
|
}
|
||||||
if(pkgList.size()==0){
|
addParsedFiles(file);
|
||||||
continue;
|
valuesEncoder.encodeValuesXml(file);
|
||||||
}
|
}
|
||||||
ResourceIds.Table.Package pkg = pkgList.get(0);
|
}
|
||||||
if(pkg.name==null){
|
private File toAndroidManifest(File pubXmlFile){
|
||||||
pkg.name=packageName;
|
File resDirectory = toResDirectory(pubXmlFile);
|
||||||
}
|
File packageDirectory = resDirectory.getParentFile();
|
||||||
encodeMaterials.addPackageIds(pkg);
|
File root = packageDirectory.getParentFile();
|
||||||
results.put(pubXmlFile, pkg);
|
return new File(root, AndroidManifestBlock.FILE_NAME);
|
||||||
}
|
}
|
||||||
|
private File toPackageDirectory(File pubXmlFile){
|
||||||
|
return toResDirectory(pubXmlFile)
|
||||||
|
.getParentFile();
|
||||||
|
}
|
||||||
|
private File toResDirectory(File pubXmlFile){
|
||||||
|
return pubXmlFile
|
||||||
|
.getParentFile()
|
||||||
|
.getParentFile();
|
||||||
|
}
|
||||||
|
private File toId(File pubXmlFile){
|
||||||
|
return new File(pubXmlFile.getParentFile(), "ids.xml");
|
||||||
|
}
|
||||||
|
private File toAttr(File pubXmlFile){
|
||||||
|
return new File(pubXmlFile.getParentFile(), "attrs.xml");
|
||||||
|
}
|
||||||
|
private List<File> listValuesDir(File resDir){
|
||||||
|
List<File> results=new ArrayList<>();
|
||||||
|
File def=new File(resDir, "values");
|
||||||
|
results.add(def);
|
||||||
|
File[] dirList=resDir.listFiles();
|
||||||
|
if(dirList!=null){
|
||||||
|
for(File dir:dirList){
|
||||||
|
if(def.equals(dir) || !dir.isDirectory()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(dir.getName().startsWith("values-")){
|
||||||
|
results.add(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
private List<File> searchPublicXmlFiles(File mainDir){
|
||||||
|
logVerbose("Searching public.xml: "+mainDir);
|
||||||
|
List<File> dirList=ApkUtil.listDirectories(mainDir);
|
||||||
|
List<File> xmlFiles = new ArrayList<>();
|
||||||
|
for(File dir:dirList){
|
||||||
|
if(dir.getName().equals("root")){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
xmlFiles.addAll(
|
||||||
|
ApkUtil.recursiveFiles(dir, ApkUtil.FILE_NAME_PUBLIC_XML));
|
||||||
|
}
|
||||||
|
List<File> results = new ArrayList<>();
|
||||||
|
for(File file:xmlFiles){
|
||||||
|
if(!EncodeUtil.isPublicXml(file)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(toAndroidManifest(file).isFile()){
|
||||||
|
results.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EncodeUtil.sortPublicXml(results);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
encodeMaterials.setAPKLogger(apkLogger);
|
private boolean isAlreadyParsed(File file){
|
||||||
return results;
|
return parsedFiles.contains(file);
|
||||||
}
|
}
|
||||||
private String readManifestPackageName(File manifestFile) throws XMLException {
|
private void addParsedFiles(File file){
|
||||||
XMLDocument manifestDocument = XMLDocument.load(manifestFile);
|
parsedFiles.add(file);
|
||||||
return manifestDocument
|
}
|
||||||
.getDocumentElement().getAttributeValue("package");
|
public void setAPKLogger(APKLogger logger) {
|
||||||
}
|
this.apkLogger = logger;
|
||||||
private void encodeResDir(EncodeMaterials materials, File resDir) throws XMLException {
|
this.apkModule.setAPKLogger(logger);
|
||||||
|
}
|
||||||
List<File> valuesDirList = listValuesDir(resDir);
|
private void logMessage(String msg) {
|
||||||
for(File valuesDir:valuesDirList){
|
if(apkLogger!=null){
|
||||||
encodeValuesDir(materials, valuesDir);
|
apkLogger.logMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void encodeValuesDir(EncodeMaterials materials, File valuesDir) throws XMLException {
|
private void logError(String msg, Throwable tr) {
|
||||||
ValuesEncoder valuesEncoder = new ValuesEncoder(materials);
|
if(apkLogger!=null){
|
||||||
List<File> xmlFiles = ApkUtil.listFiles(valuesDir, ".xml");
|
apkLogger.logError(msg, tr);
|
||||||
EncodeUtil.sortValuesXml(xmlFiles);
|
}
|
||||||
for(File file:xmlFiles){
|
}
|
||||||
if(isAlreadyParsed(file)){
|
private void logVerbose(String msg) {
|
||||||
continue;
|
if(apkLogger!=null){
|
||||||
}
|
apkLogger.logVerbose(msg);
|
||||||
addParsedFiles(file);
|
}
|
||||||
valuesEncoder.encodeValuesXml(file);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
private File toAndroidManifest(File pubXmlFile){
|
|
||||||
File resDirectory = toResDirectory(pubXmlFile);
|
|
||||||
File packageDirectory = resDirectory.getParentFile();
|
|
||||||
File root = packageDirectory.getParentFile();
|
|
||||||
return new File(root, AndroidManifestBlock.FILE_NAME);
|
|
||||||
}
|
|
||||||
private File toPackageDirectory(File pubXmlFile){
|
|
||||||
return toResDirectory(pubXmlFile)
|
|
||||||
.getParentFile();
|
|
||||||
}
|
|
||||||
private File toResDirectory(File pubXmlFile){
|
|
||||||
return pubXmlFile
|
|
||||||
.getParentFile()
|
|
||||||
.getParentFile();
|
|
||||||
}
|
|
||||||
private File toId(File pubXmlFile){
|
|
||||||
return new File(pubXmlFile.getParentFile(), "ids.xml");
|
|
||||||
}
|
|
||||||
private File toAttr(File pubXmlFile){
|
|
||||||
return new File(pubXmlFile.getParentFile(), "attrs.xml");
|
|
||||||
}
|
|
||||||
private List<File> listValuesDir(File resDir){
|
|
||||||
List<File> results=new ArrayList<>();
|
|
||||||
File def=new File(resDir, "values");
|
|
||||||
results.add(def);
|
|
||||||
File[] dirList=resDir.listFiles();
|
|
||||||
if(dirList!=null){
|
|
||||||
for(File dir:dirList){
|
|
||||||
if(def.equals(dir) || !dir.isDirectory()){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(dir.getName().startsWith("values-")){
|
|
||||||
results.add(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
private List<File> searchPublicXmlFiles(File mainDir){
|
|
||||||
logVerbose("Searching public.xml: "+mainDir);
|
|
||||||
List<File> dirList=ApkUtil.listDirectories(mainDir);
|
|
||||||
List<File> xmlFiles = new ArrayList<>();
|
|
||||||
for(File dir:dirList){
|
|
||||||
if(dir.getName().equals("root")){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
xmlFiles.addAll(
|
|
||||||
ApkUtil.recursiveFiles(dir, ApkUtil.FILE_NAME_PUBLIC_XML));
|
|
||||||
}
|
|
||||||
List<File> results = new ArrayList<>();
|
|
||||||
for(File file:xmlFiles){
|
|
||||||
if(!EncodeUtil.isPublicXml(file)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(toAndroidManifest(file).isFile()){
|
|
||||||
results.add(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EncodeUtil.sortPublicXml(results);
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isAlreadyParsed(File file){
|
|
||||||
return parsedFiles.contains(file);
|
|
||||||
}
|
|
||||||
private void addParsedFiles(File file){
|
|
||||||
parsedFiles.add(file);
|
|
||||||
}
|
|
||||||
public void setAPKLogger(APKLogger logger) {
|
|
||||||
this.apkLogger = logger;
|
|
||||||
this.apkModule.setAPKLogger(logger);
|
|
||||||
}
|
|
||||||
private void logMessage(String msg) {
|
|
||||||
if(apkLogger!=null){
|
|
||||||
apkLogger.logMessage(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void logError(String msg, Throwable tr) {
|
|
||||||
if(apkLogger!=null){
|
|
||||||
apkLogger.logError(msg, tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void logVerbose(String msg) {
|
|
||||||
if(apkLogger!=null){
|
|
||||||
apkLogger.logVerbose(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -17,7 +17,9 @@ package com.reandroid.apk.xmlencoder;
|
|||||||
|
|
||||||
import com.reandroid.archive.ByteInputSource;
|
import com.reandroid.archive.ByteInputSource;
|
||||||
import com.reandroid.apk.CrcOutputStream;
|
import com.reandroid.apk.CrcOutputStream;
|
||||||
|
import com.reandroid.arsc.chunk.PackageBlock;
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||||
|
import com.reandroid.arsc.value.Entry;
|
||||||
import com.reandroid.xml.XMLException;
|
import com.reandroid.xml.XMLException;
|
||||||
import com.reandroid.xml.source.XMLSource;
|
import com.reandroid.xml.source.XMLSource;
|
||||||
|
|
||||||
@ -28,11 +30,27 @@ public class XMLEncodeSource extends ByteInputSource {
|
|||||||
private final EncodeMaterials encodeMaterials;
|
private final EncodeMaterials encodeMaterials;
|
||||||
private final XMLSource xmlSource;
|
private final XMLSource xmlSource;
|
||||||
private ResXmlDocument resXmlDocument;
|
private ResXmlDocument resXmlDocument;
|
||||||
public XMLEncodeSource(EncodeMaterials encodeMaterials, XMLSource xmlSource){
|
private Entry mEntry;
|
||||||
|
public XMLEncodeSource(EncodeMaterials encodeMaterials, XMLSource xmlSource, Entry entry){
|
||||||
super(new byte[0], xmlSource.getPath());
|
super(new byte[0], xmlSource.getPath());
|
||||||
this.encodeMaterials=encodeMaterials;
|
this.encodeMaterials = encodeMaterials;
|
||||||
this.xmlSource=xmlSource;
|
this.xmlSource = xmlSource;
|
||||||
|
this.mEntry = entry;
|
||||||
}
|
}
|
||||||
|
public XMLEncodeSource(EncodeMaterials encodeMaterials, XMLSource xmlSource){
|
||||||
|
this(encodeMaterials, xmlSource, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XMLSource getXmlSource() {
|
||||||
|
return xmlSource;
|
||||||
|
}
|
||||||
|
public Entry getEntry(){
|
||||||
|
return mEntry;
|
||||||
|
}
|
||||||
|
public void setEntry(Entry entry) {
|
||||||
|
this.mEntry = entry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLength() throws IOException{
|
public long getLength() throws IOException{
|
||||||
return getResXmlBlock().countBytes();
|
return getResXmlBlock().countBytes();
|
||||||
@ -64,7 +82,13 @@ public class XMLEncodeSource extends ByteInputSource {
|
|||||||
try {
|
try {
|
||||||
XMLFileEncoder xmlFileEncoder=new XMLFileEncoder(encodeMaterials);
|
XMLFileEncoder xmlFileEncoder=new XMLFileEncoder(encodeMaterials);
|
||||||
xmlFileEncoder.setCurrentPath(xmlSource.getPath());
|
xmlFileEncoder.setCurrentPath(xmlSource.getPath());
|
||||||
encodeMaterials.logVerbose("Encoding xml: "+xmlSource.getPath());
|
EncodeMaterials encodeMaterials = this.encodeMaterials;
|
||||||
|
encodeMaterials.logVerbose("Encoding xml: " + xmlSource.getPath());
|
||||||
|
PackageBlock currentPackage = encodeMaterials.getCurrentPackage();
|
||||||
|
PackageBlock packageBlock = getEntryPackageBlock();
|
||||||
|
if(packageBlock != null && packageBlock != currentPackage){
|
||||||
|
encodeMaterials.setCurrentPackage(packageBlock);
|
||||||
|
}
|
||||||
resXmlDocument = xmlFileEncoder.encode(xmlSource.getXMLDocument());
|
resXmlDocument = xmlFileEncoder.encode(xmlSource.getXMLDocument());
|
||||||
} catch (XMLException ex) {
|
} catch (XMLException ex) {
|
||||||
throw new EncodeException("XMLException on: '"+xmlSource.getPath()
|
throw new EncodeException("XMLException on: '"+xmlSource.getPath()
|
||||||
@ -72,6 +96,13 @@ public class XMLEncodeSource extends ByteInputSource {
|
|||||||
}
|
}
|
||||||
return resXmlDocument;
|
return resXmlDocument;
|
||||||
}
|
}
|
||||||
|
private PackageBlock getEntryPackageBlock(){
|
||||||
|
Entry entry = getEntry();
|
||||||
|
if(entry != null){
|
||||||
|
return entry.getPackageBlock();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void disposeInputSource(){
|
public void disposeInputSource(){
|
||||||
this.xmlSource.disposeXml();
|
this.xmlSource.disposeXml();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user