mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-05-01 06:34:26 +02:00
create source xml to binary xml encoder
This commit is contained in:
parent
ebc1efed0e
commit
6ed3de8991
@ -107,6 +107,29 @@
|
|||||||
}
|
}
|
||||||
return resolveFrameworkResourceId(packageName, type, name);
|
return resolveFrameworkResourceId(packageName, type, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntryBlock resolveEntryReference(String refString){
|
||||||
|
if("@null".equals(refString)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Matcher matcher = ValueDecoder.PATTERN_REFERENCE.matcher(refString);
|
||||||
|
if(!matcher.find()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String prefix=matcher.group(1);
|
||||||
|
String packageName = matcher.group(2);
|
||||||
|
if(packageName!=null && packageName.endsWith(":")){
|
||||||
|
packageName=packageName.substring(0, packageName.length()-1);
|
||||||
|
}
|
||||||
|
String type = matcher.group(4);
|
||||||
|
String name = matcher.group(5);
|
||||||
|
if(EncodeUtil.isEmpty(packageName)
|
||||||
|
|| packageName.equals(getCurrentPackageName())
|
||||||
|
|| !isFrameworkPackageName(packageName)){
|
||||||
|
return getLocalEntryBlock(type, name);
|
||||||
|
}
|
||||||
|
return getFrameworkEntry(packageName, type, name);
|
||||||
|
}
|
||||||
public int resolveLocalResourceId(String type, String name){
|
public int resolveLocalResourceId(String type, String name){
|
||||||
ResourceIds.Table.Package.Type.Entry entry =
|
ResourceIds.Table.Package.Type.Entry entry =
|
||||||
this.packageIds.getEntry(type, name);
|
this.packageIds.getEntry(type, name);
|
||||||
|
@ -61,5 +61,9 @@ public class FilePathEncoder {
|
|||||||
|
|
||||||
entryBlock.setValueAsString(EncodeUtil.getEntryPathFromResFile(resFile));
|
entryBlock.setValueAsString(EncodeUtil.getEntryPathFromResFile(resFile));
|
||||||
entryBlock.setSpecReference(materials.getSpecString(name));
|
entryBlock.setSpecReference(materials.getSpecString(name));
|
||||||
|
if(resFile.getName().endsWith(".xml")){
|
||||||
|
XMLFileEncoder fileEncoder=new XMLFileEncoder(materials);
|
||||||
|
fileEncoder.encode(resFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* 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.chunk.xml.ResIdBuilder;
|
||||||
|
import com.reandroid.lib.arsc.chunk.xml.ResXmlAttribute;
|
||||||
|
import com.reandroid.lib.arsc.chunk.xml.ResXmlBlock;
|
||||||
|
import com.reandroid.lib.arsc.chunk.xml.ResXmlElement;
|
||||||
|
import com.reandroid.lib.arsc.decoder.ValueDecoder;
|
||||||
|
import com.reandroid.lib.arsc.value.EntryBlock;
|
||||||
|
import com.reandroid.lib.arsc.value.ResValueBag;
|
||||||
|
import com.reandroid.lib.arsc.value.ValueType;
|
||||||
|
import com.reandroid.lib.arsc.value.attribute.AttributeBag;
|
||||||
|
import com.reandroid.xml.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class XMLFileEncoder {
|
||||||
|
private final EncodeMaterials materials;
|
||||||
|
private ResXmlBlock resXmlBlock;
|
||||||
|
public XMLFileEncoder(EncodeMaterials materials){
|
||||||
|
this.materials=materials;
|
||||||
|
}
|
||||||
|
public void encode(String xmlString){
|
||||||
|
try {
|
||||||
|
encode(XMLDocument.load(xmlString));
|
||||||
|
} catch (XMLException ex) {
|
||||||
|
materials.logMessage(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void encode(InputStream inputStream){
|
||||||
|
try {
|
||||||
|
encode(XMLDocument.load(inputStream));
|
||||||
|
} catch (XMLException ex) {
|
||||||
|
materials.logMessage(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void encode(File xmlFile){
|
||||||
|
try {
|
||||||
|
encode(XMLDocument.load(xmlFile));
|
||||||
|
} catch (XMLException ex) {
|
||||||
|
materials.logMessage(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void encode(XMLDocument xmlDocument){
|
||||||
|
resXmlBlock=new ResXmlBlock();
|
||||||
|
buildIdMap(xmlDocument);
|
||||||
|
buildElement(xmlDocument);
|
||||||
|
resXmlBlock.refresh();
|
||||||
|
}
|
||||||
|
public ResXmlBlock getResXmlBlock(){
|
||||||
|
return resXmlBlock;
|
||||||
|
}
|
||||||
|
private void buildElement(XMLDocument xmlDocument){
|
||||||
|
XMLElement element = xmlDocument.getDocumentElement();
|
||||||
|
ResXmlElement resXmlElement = resXmlBlock.createRootElement(element.getTagName());
|
||||||
|
buildElement(element, resXmlElement);
|
||||||
|
}
|
||||||
|
private void buildElement(XMLElement element, ResXmlElement resXmlElement){
|
||||||
|
ensureNamespaces(element, resXmlElement);
|
||||||
|
resXmlElement.setTag(element.getTagName());
|
||||||
|
buildAttributes(element, resXmlElement);
|
||||||
|
int count=element.getChildesCount();
|
||||||
|
for(int i=0;i<count;i++){
|
||||||
|
XMLElement child=element.getChildAt(i);
|
||||||
|
ResXmlElement childXml=resXmlElement.createChildElement();
|
||||||
|
buildElement(child, childXml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void buildAttributes(XMLElement element, ResXmlElement resXmlElement){
|
||||||
|
int count=element.getAttributeCount();
|
||||||
|
for(int i=0;i<count;i++){
|
||||||
|
XMLAttribute attribute=element.getAttributeAt(i);
|
||||||
|
if(SchemaAttr.looksSchema(attribute.getName(), attribute.getValue())){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EntryBlock entryBlock=materials.getAttributeBlock(attribute.getName());
|
||||||
|
int resourceId=0;
|
||||||
|
if(entryBlock!=null){
|
||||||
|
resourceId=entryBlock.getResourceId();
|
||||||
|
}
|
||||||
|
String valueText=attribute.getValue();
|
||||||
|
|
||||||
|
ResXmlAttribute xmlAttribute =
|
||||||
|
resXmlElement.createAttribute(attribute.getName(), resourceId);
|
||||||
|
if(entryBlock!=null){
|
||||||
|
AttributeBag attributeBag=AttributeBag
|
||||||
|
.create((ResValueBag) entryBlock.getResValue());
|
||||||
|
|
||||||
|
ValueDecoder.EncodeResult encodeResult =
|
||||||
|
attributeBag.encodeName(valueText);
|
||||||
|
if(encodeResult!=null){
|
||||||
|
xmlAttribute.setValueType(encodeResult.valueType);
|
||||||
|
xmlAttribute.setRawValue(encodeResult.value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ValueDecoder.isReference(valueText)){
|
||||||
|
xmlAttribute.setValueType(ValueType.REFERENCE);
|
||||||
|
xmlAttribute.setRawValue(materials.resolveReference(valueText));
|
||||||
|
}else if(EncodeUtil.isEmpty(valueText)) {
|
||||||
|
xmlAttribute.setValueType(ValueType.NULL);
|
||||||
|
xmlAttribute.setRawValue(0);
|
||||||
|
}else{
|
||||||
|
ValueDecoder.EncodeResult encodeResult =
|
||||||
|
ValueDecoder.encodeGuessAny(valueText);
|
||||||
|
if(encodeResult!=null){
|
||||||
|
xmlAttribute.setValueType(encodeResult.valueType);
|
||||||
|
xmlAttribute.setRawValue(encodeResult.value);
|
||||||
|
}else {
|
||||||
|
xmlAttribute.setValueAsString(valueText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void ensureNamespaces(XMLElement element, ResXmlElement resXmlElement){
|
||||||
|
int count=element.getAttributeCount();
|
||||||
|
for(int i=0;i<count;i++){
|
||||||
|
XMLAttribute attribute = element.getAttributeAt(i);
|
||||||
|
String prefix = SchemaAttr.getPrefix(attribute.getName());
|
||||||
|
if(prefix==null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String uri=attribute.getValue();
|
||||||
|
resXmlElement.getOrCreateNamespace(uri, prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void buildIdMap(XMLDocument xmlDocument){
|
||||||
|
ResIdBuilder idBuilder=new ResIdBuilder();
|
||||||
|
XMLElement element= xmlDocument.getDocumentElement();
|
||||||
|
searchResIds(idBuilder, element);
|
||||||
|
idBuilder.buildTo(resXmlBlock.getResXmlIDMap());
|
||||||
|
}
|
||||||
|
private void searchResIds(ResIdBuilder idBuilder, XMLElement element){
|
||||||
|
int count=element.getAttributeCount();
|
||||||
|
for(int i=0;i<count;i++){
|
||||||
|
XMLAttribute attribute = element.getAttributeAt(i);
|
||||||
|
addResourceId(idBuilder, attribute);
|
||||||
|
}
|
||||||
|
count=element.getChildesCount();
|
||||||
|
for(int i=0;i<count;i++){
|
||||||
|
searchResIds(idBuilder, element.getChildAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void addResourceId(ResIdBuilder idBuilder, XMLAttribute attribute){
|
||||||
|
EntryBlock entryBlock = materials.getAttributeBlock(attribute.getName());
|
||||||
|
if(entryBlock!=null){
|
||||||
|
idBuilder.add(entryBlock.getResourceId(), entryBlock.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user