mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-30 22:34:24 +02:00
create XMLEncoder
This commit is contained in:
parent
a7424bbf96
commit
0f29fa6596
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public class EncodeException extends IllegalArgumentException{
|
||||
public EncodeException(String message){
|
||||
super(message);
|
||||
}
|
||||
public EncodeException(String message, Throwable cause){
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* 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.APKLogger;
|
||||
import com.reandroid.lib.apk.ResourceIds;
|
||||
import com.reandroid.lib.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.lib.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.lib.arsc.container.SpecTypePair;
|
||||
import com.reandroid.lib.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.lib.arsc.group.EntryGroup;
|
||||
import com.reandroid.lib.arsc.item.SpecString;
|
||||
import com.reandroid.lib.arsc.util.FrameworkTable;
|
||||
import com.reandroid.lib.arsc.value.EntryBlock;
|
||||
import com.reandroid.lib.common.ResourceResolver;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public class EncodeMaterials implements ResourceResolver {
|
||||
private ResourceIds.Table.Package packageIds;
|
||||
private PackageBlock currentPackage;
|
||||
private final Set<FrameworkTable> frameworkTables = new HashSet<>();
|
||||
private APKLogger apkLogger;
|
||||
public EncodeMaterials(){
|
||||
}
|
||||
public SpecString getSpecString(String name){
|
||||
return currentPackage.getSpecStringPool()
|
||||
.get(name)
|
||||
.get(0);
|
||||
}
|
||||
public void addTableStringPool(Collection<String> stringList){
|
||||
getCurrentPackage()
|
||||
.getTableBlock()
|
||||
.getTableStringPool()
|
||||
.addStrings(stringList);
|
||||
}
|
||||
public int resolveAttributeNameReference(String refString){
|
||||
String packageName = null;
|
||||
String type = "attr";
|
||||
String name = refString;
|
||||
int i=refString.lastIndexOf(':');
|
||||
if(i>=0){
|
||||
packageName=refString.substring(0, i);
|
||||
name=refString.substring(i+1);
|
||||
}
|
||||
if(EncodeUtil.isEmpty(packageName)
|
||||
|| packageName.equals(getCurrentPackageName())
|
||||
|| !isFrameworkPackageName(packageName)){
|
||||
|
||||
return resolveLocalResourceId(type, name);
|
||||
}
|
||||
return resolveFrameworkResourceId(packageName, type, name);
|
||||
}
|
||||
public EntryBlock getAttributeBlock(String refString){
|
||||
String packageName = null;
|
||||
String type = "attr";
|
||||
String name = refString;
|
||||
int i=refString.lastIndexOf(':');
|
||||
if(i>=0){
|
||||
packageName=refString.substring(0, i);
|
||||
name=refString.substring(i+1);
|
||||
}
|
||||
if(EncodeUtil.isEmpty(packageName)
|
||||
|| packageName.equals(getCurrentPackageName())
|
||||
|| !isFrameworkPackageName(packageName)){
|
||||
|
||||
return getLocalEntryBlock(type, name);
|
||||
}
|
||||
return getFrameworkEntry(type, name);
|
||||
}
|
||||
public int resolveReference(String refString){
|
||||
if("@null".equals(refString)){
|
||||
return 0;
|
||||
}
|
||||
Matcher matcher = ValueDecoder.PATTERN_REFERENCE.matcher(refString);
|
||||
if(!matcher.find()){
|
||||
throw new EncodeException(
|
||||
"Not proper reference string: '"+refString+"'");
|
||||
}
|
||||
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 resolveLocalResourceId(type, name);
|
||||
}
|
||||
return resolveFrameworkResourceId(packageName, type, name);
|
||||
}
|
||||
public int resolveLocalResourceId(String type, String name){
|
||||
ResourceIds.Table.Package.Type.Entry entry =
|
||||
this.packageIds.getEntry(type, name);
|
||||
if(entry!=null){
|
||||
return entry.getResourceId();
|
||||
}
|
||||
EntryGroup entryGroup=getLocalEntryGroup(type, name);
|
||||
if(entryGroup!=null){
|
||||
return entryGroup.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Local entry not found: " +
|
||||
"type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public int resolveFrameworkResourceId(String type, String name){
|
||||
EntryBlock entryBlock = getFrameworkEntry(type, name);
|
||||
if(entryBlock!=null){
|
||||
return entryBlock.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Framework entry not found: " +
|
||||
"type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public int resolveFrameworkResourceId(String packageName, String type, String name){
|
||||
EntryBlock entryBlock = getFrameworkEntry(packageName, type, name);
|
||||
if(entryBlock!=null){
|
||||
return entryBlock.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Framework entry not found: " +
|
||||
"package="+packageName+
|
||||
", type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public int resolveFrameworkResourceId(int packageId, String type, String name){
|
||||
EntryBlock entryBlock = getFrameworkEntry(packageId, type, name);
|
||||
if(entryBlock!=null){
|
||||
return entryBlock.getResourceId();
|
||||
}
|
||||
throw new EncodeException("Framework entry not found: " +
|
||||
"packageId="+String.format("0x%02x", packageId)+
|
||||
", type="+type+
|
||||
", name="+name);
|
||||
}
|
||||
public EntryGroup getLocalEntryGroup(String type, String name){
|
||||
for(EntryGroup entryGroup : currentPackage.listEntryGroup()){
|
||||
if(type.equals(entryGroup.getTypeName()) &&
|
||||
name.equals(entryGroup.getSpecName())){
|
||||
return entryGroup;
|
||||
}
|
||||
}
|
||||
for(PackageBlock packageBlock:currentPackage.getTableBlock().listPackages()){
|
||||
if(packageBlock==currentPackage ||
|
||||
packageBlock.getId()!=currentPackage.getId()){
|
||||
continue;
|
||||
}
|
||||
for(EntryGroup entryGroup : currentPackage.listEntryGroup()){
|
||||
if(type.equals(entryGroup.getTypeName()) &&
|
||||
name.equals(entryGroup.getSpecName())){
|
||||
return entryGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public EntryBlock getLocalEntryBlock(String type, String name){
|
||||
for(EntryGroup entryGroup : currentPackage.listEntryGroup()){
|
||||
if(type.equals(entryGroup.getTypeName()) &&
|
||||
name.equals(entryGroup.getSpecName())){
|
||||
return entryGroup.pickOne();
|
||||
}
|
||||
}
|
||||
SpecTypePair specTypePair=currentPackage.searchByTypeName(type);
|
||||
if(specTypePair!=null){
|
||||
for(TypeBlock typeBlock:specTypePair.listTypeBlocks()){
|
||||
for(EntryBlock entryBlock:typeBlock.listEntries()){
|
||||
if(name.equals(entryBlock.getName())){
|
||||
return entryBlock;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(PackageBlock packageBlock:currentPackage.getTableBlock().listPackages()){
|
||||
if(packageBlock==currentPackage ||
|
||||
packageBlock.getId()!=currentPackage.getId()){
|
||||
continue;
|
||||
}
|
||||
specTypePair=packageBlock.searchByTypeName(type);
|
||||
if(specTypePair!=null){
|
||||
for(TypeBlock typeBlock:specTypePair.listTypeBlocks()){
|
||||
for(EntryBlock entryBlock:typeBlock.listEntries()){
|
||||
if(name.equals(entryBlock.getName())){
|
||||
return entryBlock;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public EntryBlock getFrameworkEntry(String type, String name){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
EntryBlock entryBlock = table.searchEntryBlock(type, name);
|
||||
if(entryBlock!=null){
|
||||
return entryBlock;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private boolean isFrameworkPackageName(String packageName){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
for(PackageBlock packageBlock:table.listPackages()){
|
||||
if(packageName.equals(packageBlock.getName())){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public EntryBlock getFrameworkEntry(String packageName, String type, String name){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
for(PackageBlock packageBlock:table.listPackages()){
|
||||
if(packageName.equals(packageBlock.getName())){
|
||||
EntryBlock entryBlock = table.searchEntryBlock(type, name);
|
||||
if(entryBlock!=null){
|
||||
return entryBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public EntryBlock getFrameworkEntry(int packageId, String type, String name){
|
||||
for(FrameworkTable table:frameworkTables){
|
||||
for(PackageBlock packageBlock:table.listPackages()){
|
||||
if(packageId==packageBlock.getId()){
|
||||
EntryBlock entryBlock = table.searchEntryBlock(type, name);
|
||||
if(entryBlock!=null){
|
||||
return entryBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public EncodeMaterials setPackageIds(ResourceIds.Table.Package packageIds) {
|
||||
this.packageIds = packageIds;
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials setCurrentPackage(PackageBlock currentPackage) {
|
||||
this.currentPackage = currentPackage;
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials addFramework(FrameworkTable frameworkTable) {
|
||||
frameworkTable.loadResourceNameMap();
|
||||
this.frameworkTables.add(frameworkTable);
|
||||
return this;
|
||||
}
|
||||
public EncodeMaterials setAPKLogger(APKLogger logger) {
|
||||
this.apkLogger = logger;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResourceIds.Table.Package getPackageIds() {
|
||||
return packageIds;
|
||||
}
|
||||
public PackageBlock getCurrentPackage() {
|
||||
return currentPackage;
|
||||
}
|
||||
public String getCurrentPackageName(){
|
||||
return currentPackage.getName();
|
||||
}
|
||||
public int getCurrentPackageId(){
|
||||
return currentPackage.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int resolveResourceId(String packageName, String type, String name) {
|
||||
if(packageName==null || packageName.equals(getCurrentPackageName())){
|
||||
return resolveLocalResourceId(type, name);
|
||||
}
|
||||
return resolveFrameworkResourceId(packageName, type, name);
|
||||
}
|
||||
@Override
|
||||
public int resolveResourceId(int packageId, String type, String name) {
|
||||
if(packageId==getCurrentPackageId()){
|
||||
return resolveLocalResourceId(type, name);
|
||||
}
|
||||
return resolveFrameworkResourceId(packageId, type, name);
|
||||
}
|
||||
public void logMessage(String msg) {
|
||||
if(apkLogger!=null){
|
||||
apkLogger.logMessage(msg);
|
||||
}
|
||||
}
|
||||
public void logError(String msg, Throwable tr) {
|
||||
if(apkLogger!=null){
|
||||
apkLogger.logError(msg, tr);
|
||||
}
|
||||
}
|
||||
public void logVerbose(String msg) {
|
||||
if(apkLogger!=null){
|
||||
apkLogger.logVerbose(msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 java.io.File;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class EncodeUtil {
|
||||
public static boolean isEmpty(String text){
|
||||
if(text==null){
|
||||
return true;
|
||||
}
|
||||
text=text.trim();
|
||||
return text.length()==0;
|
||||
}
|
||||
public static String getQualifiersFromValuesXml(File valuesXml){
|
||||
String dirName=valuesXml.getParentFile().getName();
|
||||
int i=dirName.indexOf('-');
|
||||
if(i>0){
|
||||
return dirName.substring(i);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
public static String getTypeNameFromValuesXml(File valuesXml){
|
||||
String name=valuesXml.getName();
|
||||
name=name.substring(0, name.length()-4);
|
||||
if(!name.equals("plurals") && name.endsWith("s")){
|
||||
name=name.substring(0, name.length()-1);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
public static String sanitizeType(String type){
|
||||
Matcher matcher=PATTERN_TYPE.matcher(type);
|
||||
if(!matcher.find()){
|
||||
return "";
|
||||
}
|
||||
return matcher.group(1);
|
||||
}
|
||||
public static final String NULL_PACKAGE_NAME = "NULL_PACKAGE_NAME";
|
||||
private static final Pattern PATTERN_TYPE=Pattern.compile("^([a-z]+)[^a-z]*.*$");
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.PackageBlock;
|
||||
import com.reandroid.lib.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.lib.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.lib.arsc.item.SpecString;
|
||||
import com.reandroid.lib.arsc.pool.TypeStringPool;
|
||||
import com.reandroid.lib.arsc.value.EntryBlock;
|
||||
import com.reandroid.lib.arsc.value.ValueType;
|
||||
import com.reandroid.xml.XMLDocument;
|
||||
import com.reandroid.xml.XMLElement;
|
||||
|
||||
public class XMLValuesEncoder {
|
||||
private final EncodeMaterials materials;
|
||||
XMLValuesEncoder(EncodeMaterials materials){
|
||||
this.materials=materials;
|
||||
}
|
||||
public void encode(String type, String qualifiers, XMLDocument xmlDocument){
|
||||
XMLElement documentElement = xmlDocument.getDocumentElement();
|
||||
TypeBlock typeBlock = getTypeBlock(type, qualifiers);
|
||||
|
||||
int count = documentElement.getChildesCount();
|
||||
|
||||
typeBlock.getEntryBlockArray().ensureSize(count);
|
||||
|
||||
for(int i=0;i<count;i++){
|
||||
XMLElement element = documentElement.getChildAt(i);
|
||||
encode(typeBlock, element);
|
||||
}
|
||||
}
|
||||
private void encode(TypeBlock typeBlock, XMLElement element){
|
||||
String name = element.getAttributeValue("name");
|
||||
int resourceId = getMaterials()
|
||||
.resolveLocalResourceId(typeBlock.getTypeName(), name);
|
||||
EntryBlock entryBlock = typeBlock
|
||||
.getOrCreateEntry((short) (0xffff & resourceId));
|
||||
|
||||
encodeValue(entryBlock, element);
|
||||
|
||||
if(!entryBlock.isNull()){
|
||||
SpecString specString = getMaterials().getSpecString(name);
|
||||
entryBlock.setSpecReference(specString);
|
||||
}
|
||||
}
|
||||
void encodeValue(EntryBlock entryBlock, XMLElement element){
|
||||
String value = getValue(element);
|
||||
encodeValue(entryBlock, value);
|
||||
}
|
||||
void encodeValue(EntryBlock entryBlock, String value){
|
||||
if(EncodeUtil.isEmpty(value)){
|
||||
encodeNullValue(entryBlock);
|
||||
}else if(isLiteralEmpty(value)){
|
||||
encodeLiteralEmptyValue(entryBlock, value);
|
||||
}else if(isBoolean(value)){
|
||||
encodeBooleanValue(entryBlock, value);
|
||||
}else if(ValueDecoder.isReference(value)){
|
||||
encodeReferenceValue(entryBlock, value);
|
||||
}else {
|
||||
encodeStringValue(entryBlock, value);
|
||||
}
|
||||
}
|
||||
void encodeNullValue(EntryBlock entryBlock){
|
||||
// Nothing to do
|
||||
}
|
||||
void encodeLiteralEmptyValue(EntryBlock entryBlock, String value){
|
||||
entryBlock.setValueAsRaw(ValueType.NULL, 0);
|
||||
}
|
||||
void encodeBooleanValue(EntryBlock entryBlock, String value){
|
||||
entryBlock.setValueAsBoolean("true".equals(value.toLowerCase()));
|
||||
}
|
||||
void encodeReferenceValue(EntryBlock entryBlock, String value){
|
||||
int resourceId = getMaterials().resolveReference(value);
|
||||
entryBlock.setValueAsReference(resourceId);
|
||||
}
|
||||
void encodeStringValue(EntryBlock entryBlock, String value){
|
||||
|
||||
}
|
||||
private TypeBlock getTypeBlock(String type, String qualifiers){
|
||||
PackageBlock packageBlock = getMaterials().getCurrentPackage();
|
||||
TypeStringPool typeStringPool = packageBlock.getTypeStringPool();
|
||||
byte typeId = typeStringPool.idOf(type);
|
||||
return packageBlock.getSpecTypePairArray()
|
||||
.getOrCreateTypeBlock(typeId, qualifiers);
|
||||
}
|
||||
EncodeMaterials getMaterials() {
|
||||
return materials;
|
||||
}
|
||||
|
||||
|
||||
static String getValue(XMLElement element){
|
||||
String value=element.getTextContent();
|
||||
if(value!=null){
|
||||
return value;
|
||||
}
|
||||
return element.getAttributeValue("value");
|
||||
}
|
||||
static boolean isLiteralEmpty(String value){
|
||||
if(value==null){
|
||||
return false;
|
||||
}
|
||||
value=value.trim().toLowerCase();
|
||||
return value.equals("@empty");
|
||||
}
|
||||
static boolean isBoolean(String value){
|
||||
if(value==null){
|
||||
return false;
|
||||
}
|
||||
value=value.trim().toLowerCase();
|
||||
return value.equals("true")||value.equals("false");
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.array.ResValueBagItemArray;
|
||||
import com.reandroid.lib.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.lib.arsc.value.ResValueBag;
|
||||
import com.reandroid.lib.arsc.value.ResValueBagItem;
|
||||
import com.reandroid.lib.arsc.value.ValueType;
|
||||
import com.reandroid.xml.XMLElement;
|
||||
|
||||
public class XMLValuesEncoderArray extends XMLValuesEncoderBag{
|
||||
XMLValuesEncoderArray(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
@Override
|
||||
void encodeChildes(XMLElement parentElement, ResValueBag resValueBag){
|
||||
int count = parentElement.getChildesCount();
|
||||
boolean tag_string="string-array".equals(parentElement.getTagName());
|
||||
ResValueBagItemArray itemArray = resValueBag.getResValueBagItemArray();
|
||||
for(int i=0;i<count;i++){
|
||||
XMLElement child=parentElement.getChildAt(i);
|
||||
ResValueBagItem bagItem = itemArray.get(i);
|
||||
bagItem.setIdHigh((short) 0x0100);
|
||||
bagItem.setIdLow((short) (i+1));
|
||||
|
||||
String valueText=child.getTextContent();
|
||||
|
||||
if(ValueDecoder.isReference(valueText)){
|
||||
bagItem.setType(ValueType.REFERENCE);
|
||||
bagItem.setData(getMaterials().resolveReference(valueText));
|
||||
}else if(EncodeUtil.isEmpty(valueText)) {
|
||||
bagItem.setType(ValueType.NULL);
|
||||
bagItem.setData(0);
|
||||
}else if(!tag_string){
|
||||
ValueDecoder.EncodeResult encodeResult =
|
||||
ValueDecoder.encodeGuessAny(valueText);
|
||||
if(encodeResult!=null){
|
||||
bagItem.setType(encodeResult.valueType);
|
||||
bagItem.setData(encodeResult.value);
|
||||
}else {
|
||||
bagItem.setValueAsString(valueText);
|
||||
}
|
||||
}else {
|
||||
bagItem.setValueAsString(valueText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.array.ResValueBagItemArray;
|
||||
import com.reandroid.lib.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.lib.arsc.value.ResValueBag;
|
||||
import com.reandroid.lib.arsc.value.ResValueBagItem;
|
||||
import com.reandroid.lib.arsc.value.ValueType;
|
||||
import com.reandroid.lib.arsc.value.attribute.AttributeBag;
|
||||
import com.reandroid.lib.arsc.value.attribute.AttributeItemType;
|
||||
import com.reandroid.lib.arsc.value.attribute.AttributeValueType;
|
||||
import com.reandroid.xml.XMLAttribute;
|
||||
import com.reandroid.xml.XMLElement;
|
||||
|
||||
public class XMLValuesEncoderAttr extends XMLValuesEncoderBag{
|
||||
XMLValuesEncoderAttr(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
@Override
|
||||
int getChildesCount(XMLElement element){
|
||||
int count = element.getChildesCount() + element.getAttributeCount();
|
||||
if(element.getAttribute("formats")!=null){
|
||||
count = count-1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@Override
|
||||
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();
|
||||
ResValueBagItemArray bagItemArray = resValueBag.getResValueBagItemArray();
|
||||
|
||||
int bagIndex=0;
|
||||
|
||||
ResValueBagItem bagItem = bagItemArray.get(bagIndex);
|
||||
|
||||
bagItem.setIdHigh((short) 0x0100);
|
||||
bagItem.setIdLow(AttributeItemType.FORMAT.getValue());
|
||||
bagItem.setType(ValueType.INT_DEC);
|
||||
|
||||
AttributeValueType[] valueTypes = AttributeValueType
|
||||
.valuesOf(parentElement.getAttributeValue("formats"));
|
||||
|
||||
bagItem.setDataLow((short) (0xffff &
|
||||
AttributeValueType.getByte(valueTypes)));
|
||||
|
||||
bagIndex++;
|
||||
|
||||
for(int i=0;i<count;i++){
|
||||
XMLAttribute attribute = parentElement.getAttributeAt(i);
|
||||
String name = attribute.getName();
|
||||
if("name".equals(name) || "formats".equals(name)){
|
||||
continue;
|
||||
}
|
||||
AttributeItemType itemType = AttributeItemType.fromName(name);
|
||||
if(itemType==null){
|
||||
throw new EncodeException("Unknown attribute: '"+name
|
||||
+"', on attribute: "+attribute.toString());
|
||||
}
|
||||
bagItem = bagItemArray.get(bagIndex);
|
||||
bagItem.setIdHigh((short) 0x0100);
|
||||
bagItem.setIdLow(itemType.getValue());
|
||||
bagItem.setType(ValueType.INT_DEC);
|
||||
bagItem.setData(ValueDecoder.parseInteger(attribute.getValue()));
|
||||
bagIndex++;
|
||||
}
|
||||
}
|
||||
private void encodeEnumOrFlag(XMLElement element, ResValueBag resValueBag){
|
||||
int count=element.getChildesCount();
|
||||
if(count==0){
|
||||
return;
|
||||
}
|
||||
int offset = element.getAttributeCount();
|
||||
if(element.getAttribute("formats")!=null){
|
||||
offset = offset-1;
|
||||
}
|
||||
|
||||
EncodeMaterials materials = getMaterials();
|
||||
ResValueBagItemArray bagItemArray = resValueBag.getResValueBagItemArray();
|
||||
|
||||
for(int i=0;i<count;i++){
|
||||
XMLElement child=element.getChildAt(i);
|
||||
|
||||
int resourceId=materials.resolveLocalResourceId("id",
|
||||
child.getAttributeValue("name"));
|
||||
|
||||
ValueDecoder.EncodeResult encodeResult =
|
||||
ValueDecoder.encodeHexOrInt(child.getTextContent());
|
||||
|
||||
if(encodeResult == null){
|
||||
throw new EncodeException("Unknown value for element '"+child.toText()+"'");
|
||||
}
|
||||
|
||||
ResValueBagItem bagItem = bagItemArray.get(i+offset);
|
||||
bagItem.setId(resourceId);
|
||||
bagItem.setType(encodeResult.valueType);
|
||||
bagItem.setData(encodeResult.value);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.value.EntryBlock;
|
||||
import com.reandroid.lib.arsc.value.ResValueBag;
|
||||
import com.reandroid.xml.XMLElement;
|
||||
|
||||
public class XMLValuesEncoderBag extends XMLValuesEncoder{
|
||||
XMLValuesEncoderBag(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
@Override
|
||||
void encodeValue(EntryBlock entryBlock, XMLElement element){
|
||||
ResValueBag resValueBag=new ResValueBag();
|
||||
entryBlock.setResValue(resValueBag);
|
||||
String parent=element.getAttributeValue("parent");
|
||||
if(!EncodeUtil.isEmpty(parent)){
|
||||
int parentId=getMaterials().resolveReference(parent);
|
||||
resValueBag.setParentId(parentId);
|
||||
}
|
||||
resValueBag.setCount(getChildesCount(element));
|
||||
encodeChildes(element, resValueBag);
|
||||
}
|
||||
void encodeChildes(XMLElement element, ResValueBag resValueBag){
|
||||
|
||||
}
|
||||
int getChildesCount(XMLElement element){
|
||||
return element.getChildesCount();
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.value.EntryBlock;
|
||||
|
||||
public class XMLValuesEncoderColor extends XMLValuesEncoder{
|
||||
XMLValuesEncoderColor(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
@Override
|
||||
void encodeStringValue(EntryBlock entryBlock, String value){
|
||||
ValueDecoder.EncodeResult encodeResult=ValueDecoder.encodeColor(value);
|
||||
if(encodeResult!=null){
|
||||
entryBlock.setValueAsRaw(encodeResult.valueType, encodeResult.value);
|
||||
}else {
|
||||
throw new EncodeException("Unknown color value: "+value);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.value.EntryBlock;
|
||||
|
||||
public class XMLValuesEncoderCommon extends XMLValuesEncoder{
|
||||
XMLValuesEncoderCommon(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
@Override
|
||||
void encodeStringValue(EntryBlock entryBlock, String value){
|
||||
entryBlock.setValueAsString(value);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.value.EntryBlock;
|
||||
|
||||
public class XMLValuesEncoderDimen extends XMLValuesEncoder{
|
||||
XMLValuesEncoderDimen(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
@Override
|
||||
void encodeStringValue(EntryBlock entryBlock, String value){
|
||||
ValueDecoder.EncodeResult encodeResult =
|
||||
ValueDecoder.encodeDimensionOrFloat(value);
|
||||
if(encodeResult!=null){
|
||||
entryBlock.setValueAsRaw(encodeResult.valueType, encodeResult.value);
|
||||
}else {
|
||||
throw new EncodeException("Unknown dimen value: "+value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.value.EntryBlock;
|
||||
|
||||
public class XMLValuesEncoderId extends XMLValuesEncoder{
|
||||
public XMLValuesEncoderId(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
|
||||
@Override
|
||||
void encodeStringValue(EntryBlock entryBlock, String value){
|
||||
throw new EncodeException("Unexpected value for id: "+value);
|
||||
}
|
||||
@Override
|
||||
void encodeNullValue(EntryBlock entryBlock){
|
||||
entryBlock.setValueAsString("");
|
||||
setVisibility(entryBlock);
|
||||
}
|
||||
@Override
|
||||
void encodeBooleanValue(EntryBlock entryBlock, String value){
|
||||
super.encodeBooleanValue(entryBlock, value);
|
||||
setVisibility(entryBlock);
|
||||
}
|
||||
private void setVisibility(EntryBlock entryBlock){
|
||||
entryBlock.setEntryTypePublic(true);
|
||||
entryBlock.setEntryTypeShared(true);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.value.EntryBlock;
|
||||
import com.reandroid.lib.arsc.value.ValueType;
|
||||
|
||||
public class XMLValuesEncoderInteger extends XMLValuesEncoder{
|
||||
XMLValuesEncoderInteger(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
@Override
|
||||
void encodeStringValue(EntryBlock entryBlock, String value){
|
||||
value=value.trim();
|
||||
if(ValueDecoder.isInteger(value)){
|
||||
entryBlock.setValueAsRaw(ValueType.INT_DEC, ValueDecoder.parseInteger(value));
|
||||
}else if(ValueDecoder.isHex(value)){
|
||||
entryBlock.setValueAsRaw(ValueType.INT_HEX, ValueDecoder.parseHex(value));
|
||||
}else {
|
||||
throw new EncodeException("Unknown value for type <integer>: '"+value+"'");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.array.ResValueBagItemArray;
|
||||
import com.reandroid.lib.arsc.decoder.ValueDecoder;
|
||||
import com.reandroid.lib.arsc.value.ResValueBag;
|
||||
import com.reandroid.lib.arsc.value.ResValueBagItem;
|
||||
import com.reandroid.lib.arsc.value.ValueType;
|
||||
import com.reandroid.lib.arsc.value.plurals.PluralsQuantity;
|
||||
import com.reandroid.xml.XMLElement;
|
||||
|
||||
public class XMLValuesEncoderPlurals extends XMLValuesEncoderBag{
|
||||
XMLValuesEncoderPlurals(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
@Override
|
||||
void encodeChildes(XMLElement parentElement, ResValueBag resValueBag){
|
||||
int count = parentElement.getChildesCount();
|
||||
ResValueBagItemArray itemArray = resValueBag.getResValueBagItemArray();
|
||||
for(int i=0;i<count;i++){
|
||||
XMLElement child=parentElement.getChildAt(i);
|
||||
ResValueBagItem bagItem = itemArray.get(i);
|
||||
PluralsQuantity quantity = PluralsQuantity
|
||||
.value(child.getAttributeValue("quantity"));
|
||||
if(quantity==null){
|
||||
throw new EncodeException("Unknown plurals quantity: "
|
||||
+child.toText());
|
||||
}
|
||||
bagItem.setIdHigh((short) 0x0100);
|
||||
bagItem.setIdLow(quantity.getId());
|
||||
|
||||
String valueText=child.getTextContent();
|
||||
|
||||
if(ValueDecoder.isReference(valueText)){
|
||||
bagItem.setType(ValueType.REFERENCE);
|
||||
bagItem.setData(getMaterials().resolveReference(valueText));
|
||||
}else if(EncodeUtil.isEmpty(valueText)) {
|
||||
bagItem.setType(ValueType.NULL);
|
||||
bagItem.setData(0);
|
||||
}else{
|
||||
bagItem.setValueAsString(valueText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.value.EntryBlock;
|
||||
import com.reandroid.xml.XMLDocument;
|
||||
import com.reandroid.xml.XMLElement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public 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(value);
|
||||
}
|
||||
@Override
|
||||
void encodeNullValue(EntryBlock entryBlock){
|
||||
entryBlock.setValueAsString("");
|
||||
}
|
||||
@Override
|
||||
void encodeBooleanValue(EntryBlock entryBlock, String value){
|
||||
entryBlock.setValueAsString(value);
|
||||
}
|
||||
private void preloadStringPool(XMLDocument xmlDocument){
|
||||
XMLElement documentElement = xmlDocument.getDocumentElement();
|
||||
List<String> stringList = new ArrayList<>();
|
||||
int count = documentElement.getChildesCount();
|
||||
for(int i=0;i<count;i++){
|
||||
String value=getValue(documentElement.getChildAt(i));
|
||||
if(value==null || ValueDecoder.isReference(value)){
|
||||
continue;
|
||||
}
|
||||
stringList.add(value);
|
||||
}
|
||||
getMaterials().addTableStringPool(stringList);
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.array.ResValueBagItemArray;
|
||||
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.ResValueBagItem;
|
||||
import com.reandroid.lib.arsc.value.ValueType;
|
||||
import com.reandroid.lib.arsc.value.attribute.AttributeBag;
|
||||
import com.reandroid.xml.XMLElement;
|
||||
|
||||
|
||||
public class XMLValuesEncoderStyle extends XMLValuesEncoderBag{
|
||||
XMLValuesEncoderStyle(EncodeMaterials materials) {
|
||||
super(materials);
|
||||
}
|
||||
@Override
|
||||
void encodeChildes(XMLElement parentElement, ResValueBag resValueBag){
|
||||
int count = parentElement.getChildesCount();
|
||||
ResValueBagItemArray itemArray = resValueBag.getResValueBagItemArray();
|
||||
EncodeMaterials materials=getMaterials();
|
||||
for(int i=0;i<count;i++){
|
||||
XMLElement child=parentElement.getChildAt(i);
|
||||
ResValueBagItem bagItem = itemArray.get(i);
|
||||
EntryBlock entryBlock=materials
|
||||
.getAttributeBlock(child.getAttributeValue("name"));
|
||||
if(entryBlock==null){
|
||||
throw new EncodeException("Unknown attribute name: '"+child.toText()+"'");
|
||||
}
|
||||
bagItem.setId(entryBlock.getResourceId());
|
||||
AttributeBag attributeBag=AttributeBag
|
||||
.create((ResValueBag) entryBlock.getResValue());
|
||||
|
||||
String valueText=child.getTextContent();
|
||||
ValueDecoder.EncodeResult encodeResult =
|
||||
attributeBag.encodeName(valueText);
|
||||
if(encodeResult!=null){
|
||||
bagItem.setType(encodeResult.valueType);
|
||||
bagItem.setData(encodeResult.value);
|
||||
continue;
|
||||
}
|
||||
if(ValueDecoder.isReference(valueText)){
|
||||
bagItem.setType(ValueType.REFERENCE);
|
||||
bagItem.setData(getMaterials().resolveReference(valueText));
|
||||
}else if(EncodeUtil.isEmpty(valueText)) {
|
||||
bagItem.setType(ValueType.NULL);
|
||||
bagItem.setData(0);
|
||||
}else{
|
||||
encodeResult=ValueDecoder.encodeGuessAny(valueText);
|
||||
if(encodeResult!=null){
|
||||
bagItem.setType(encodeResult.valueType);
|
||||
bagItem.setData(encodeResult.value);
|
||||
}else {
|
||||
bagItem.setValueAsString(valueText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user