mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-06-13 05:37:41 +02:00
allow xml encoder/decoder to process root apk files
This commit is contained in:
@ -40,7 +40,7 @@ public class ApkModule {
|
||||
private AndroidManifestBlock mManifestBlock;
|
||||
private final UncompressedFiles mUncompressedFiles;
|
||||
private APKLogger apkLogger;
|
||||
ApkModule(String moduleName, APKArchive apkArchive){
|
||||
public ApkModule(String moduleName, APKArchive apkArchive){
|
||||
this.moduleName=moduleName;
|
||||
this.apkArchive=apkArchive;
|
||||
this.mUncompressedFiles=new UncompressedFiles();
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.reandroid.lib.apk;
|
||||
|
||||
import com.reandroid.archive.InputSource;
|
||||
import com.reandroid.lib.apk.xmlencoder.XMLEncodeSource;
|
||||
import com.reandroid.lib.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.lib.arsc.chunk.xml.ResXmlBlock;
|
||||
import com.reandroid.lib.arsc.value.EntryBlock;
|
||||
@ -101,9 +102,14 @@ public class ResFile {
|
||||
return mBinXml;
|
||||
}
|
||||
mBinXmlChecked=true;
|
||||
try {
|
||||
mBinXml=ResXmlBlock.isResXmlBlock(getInputSource().openStream());
|
||||
} catch (IOException exception) {
|
||||
InputSource inputSource=getInputSource();
|
||||
if(inputSource instanceof XMLEncodeSource){
|
||||
mBinXml=true;
|
||||
}else{
|
||||
try {
|
||||
mBinXml=ResXmlBlock.isResXmlBlock(getInputSource().openStream());
|
||||
} catch (IOException exception) {
|
||||
}
|
||||
}
|
||||
return mBinXml;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
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.TableBlock;
|
||||
import com.reandroid.lib.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.lib.arsc.container.SpecTypePair;
|
||||
import com.reandroid.lib.arsc.decoder.ValueDecoder;
|
||||
@ -25,6 +26,7 @@
|
||||
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.Frameworks;
|
||||
import com.reandroid.lib.common.ResourceResolver;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -336,5 +338,21 @@
|
||||
apkLogger.logVerbose(msg);
|
||||
}
|
||||
}
|
||||
public static EncodeMaterials create(TableBlock tableBlock){
|
||||
PackageBlock packageBlock = tableBlock.pickOne();
|
||||
if(packageBlock==null){
|
||||
throw new EncodeException("No packages found on table block");
|
||||
}
|
||||
return create(packageBlock);
|
||||
}
|
||||
public static EncodeMaterials create(PackageBlock packageBlock){
|
||||
ResourceIds resourceIds = new ResourceIds();
|
||||
resourceIds.loadPackageBlock(packageBlock);
|
||||
ResourceIds.Table.Package packageId = resourceIds.getTable().listPackages().get(0);
|
||||
return new EncodeMaterials()
|
||||
.setPackageIds(packageId)
|
||||
.setCurrentPackage(packageBlock)
|
||||
.addFramework(Frameworks.getAndroid());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,19 +15,34 @@
|
||||
*/
|
||||
package com.reandroid.lib.apk.xmlencoder;
|
||||
|
||||
import com.reandroid.lib.apk.ApkUtil;
|
||||
import com.reandroid.lib.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.lib.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.lib.arsc.value.EntryBlock;
|
||||
import com.reandroid.archive.APKArchive;
|
||||
import com.reandroid.archive.FileInputSource;
|
||||
import com.reandroid.archive.InputSource;
|
||||
import com.reandroid.lib.apk.ApkUtil;
|
||||
import com.reandroid.lib.apk.UncompressedFiles;
|
||||
import com.reandroid.lib.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.lib.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.lib.arsc.value.EntryBlock;
|
||||
import com.reandroid.xml.source.XMLFileSource;
|
||||
import com.reandroid.xml.source.XMLSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class FilePathEncoder {
|
||||
public class FilePathEncoder {
|
||||
private final EncodeMaterials materials;
|
||||
private APKArchive apkArchive;
|
||||
private UncompressedFiles uncompressedFiles;
|
||||
public FilePathEncoder(EncodeMaterials encodeMaterials){
|
||||
this.materials =encodeMaterials;
|
||||
}
|
||||
|
||||
public void setApkArchive(APKArchive apkArchive) {
|
||||
this.apkArchive = apkArchive;
|
||||
}
|
||||
public void setUncompressedFiles(UncompressedFiles uncompressedFiles){
|
||||
this.uncompressedFiles=uncompressedFiles;
|
||||
}
|
||||
public void encodeResDir(File resDir){
|
||||
materials.logVerbose("Scanning file list: "
|
||||
+resDir.getParentFile().getName()
|
||||
@ -46,7 +61,7 @@ public class FilePathEncoder {
|
||||
encodeFileEntry(file);
|
||||
}
|
||||
}
|
||||
public void encodeFileEntry(File resFile){
|
||||
public InputSource encodeFileEntry(File resFile){
|
||||
String type = EncodeUtil.getTypeNameFromResFile(resFile);
|
||||
PackageBlock packageBlock = materials.getCurrentPackage();
|
||||
byte typeId=packageBlock
|
||||
@ -59,11 +74,43 @@ public class FilePathEncoder {
|
||||
EntryBlock entryBlock=typeBlock
|
||||
.getOrCreateEntry((short) (0xffff & resourceId));
|
||||
|
||||
entryBlock.setValueAsString(EncodeUtil.getEntryPathFromResFile(resFile));
|
||||
String path=EncodeUtil.getEntryPathFromResFile(resFile);
|
||||
entryBlock.setValueAsString(path);
|
||||
entryBlock.setSpecReference(materials.getSpecString(name));
|
||||
if(resFile.getName().endsWith(".xml")){
|
||||
XMLFileEncoder fileEncoder=new XMLFileEncoder(materials);
|
||||
fileEncoder.encode(resFile);
|
||||
InputSource inputSource=createInputSource(path, resFile);
|
||||
addInputSource(inputSource);
|
||||
return inputSource;
|
||||
}
|
||||
private InputSource createInputSource(String path, File resFile){
|
||||
if(isXmlFile(resFile)){
|
||||
return createXMLEncodeInputSource(path, resFile);
|
||||
}
|
||||
addUncompressedFiles(path);
|
||||
return createRawFileInputSource(path, resFile);
|
||||
}
|
||||
private InputSource createRawFileInputSource(String path, File resFile){
|
||||
return new FileInputSource(resFile, path);
|
||||
}
|
||||
private InputSource createXMLEncodeInputSource(String path, File resFile){
|
||||
XMLSource xmlSource = new XMLFileSource(path, resFile);
|
||||
return new XMLEncodeSource(materials, xmlSource);
|
||||
}
|
||||
private boolean isXmlFile(File resFile){
|
||||
String name=resFile.getName();
|
||||
if(!name.endsWith(".xml")){
|
||||
return false;
|
||||
}
|
||||
String type=EncodeUtil.getTypeNameFromResFile(resFile);
|
||||
return !type.equals("raw");
|
||||
}
|
||||
private void addInputSource(InputSource inputSource){
|
||||
if(inputSource!=null && this.apkArchive!=null){
|
||||
apkArchive.add(inputSource);
|
||||
}
|
||||
}
|
||||
private void addUncompressedFiles(String path){
|
||||
if(uncompressedFiles!=null){
|
||||
uncompressedFiles.addPath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,15 +15,17 @@
|
||||
*/
|
||||
package com.reandroid.lib.apk.xmlencoder;
|
||||
|
||||
import com.reandroid.lib.apk.APKLogger;
|
||||
import com.reandroid.lib.apk.ApkUtil;
|
||||
import com.reandroid.lib.apk.ResourceIds;
|
||||
import com.reandroid.archive.APKArchive;
|
||||
import com.reandroid.archive.FileInputSource;
|
||||
import com.reandroid.lib.apk.*;
|
||||
import com.reandroid.lib.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.lib.arsc.chunk.TableBlock;
|
||||
import com.reandroid.lib.arsc.chunk.xml.AndroidManifestBlock;
|
||||
import com.reandroid.lib.common.Frameworks;
|
||||
import com.reandroid.xml.XMLDocument;
|
||||
import com.reandroid.xml.XMLException;
|
||||
import com.reandroid.xml.source.XMLFileSource;
|
||||
import com.reandroid.xml.source.XMLSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -35,19 +37,37 @@
|
||||
public class RESEncoder {
|
||||
private APKLogger apkLogger;
|
||||
private final TableBlock tableBlock;
|
||||
private final Set<File> parsedValueFiles;
|
||||
private final Set<File> parsedFiles = new HashSet<>();
|
||||
private final ApkModule apkModule;
|
||||
public RESEncoder(){
|
||||
this.tableBlock = new TableBlock();
|
||||
this.parsedValueFiles = new HashSet<>();
|
||||
this(new ApkModule("encoded",
|
||||
new APKArchive()), new TableBlock());
|
||||
}
|
||||
public RESEncoder(ApkModule module, TableBlock block){
|
||||
this.apkModule = module;
|
||||
this.tableBlock = block;
|
||||
if(!module.hasTableBlock()){
|
||||
BlockInputSource<TableBlock> inputSource=
|
||||
new BlockInputSource<>(TableBlock.FILE_NAME, block);
|
||||
this.apkModule.getApkArchive().add(inputSource);
|
||||
}
|
||||
}
|
||||
public TableBlock getTableBlock(){
|
||||
return tableBlock;
|
||||
}
|
||||
public void scanDirectory(File rootDir) throws IOException, XMLException {
|
||||
List<File> pubXmlFileList = searchPublicXmlFiles(rootDir);
|
||||
public ApkModule getApkModule(){
|
||||
return apkModule;
|
||||
}
|
||||
public void scanDirectory(File mainDir) throws IOException, XMLException {
|
||||
scanResourceFiles(mainDir);
|
||||
File rootDir=new File(mainDir, "root");
|
||||
scanRootDir(rootDir);
|
||||
}
|
||||
private void scanResourceFiles(File mainDir) throws IOException, XMLException {
|
||||
List<File> pubXmlFileList = searchPublicXmlFiles(mainDir);
|
||||
if(pubXmlFileList.size()==0){
|
||||
throw new IOException("No .*/values/"
|
||||
+ApkUtil.FILE_NAME_PUBLIC_XML+" file found in '"+rootDir);
|
||||
+ApkUtil.FILE_NAME_PUBLIC_XML+" file found in '"+mainDir);
|
||||
}
|
||||
for(File pubXmlFile:pubXmlFileList){
|
||||
EncodeMaterials encodeMaterials = loadPublicXml(pubXmlFile);
|
||||
@ -55,10 +75,21 @@
|
||||
File resDir=toResDirectory(pubXmlFile);
|
||||
encodeResDir(encodeMaterials, resDir);
|
||||
FilePathEncoder filePathEncoder = new FilePathEncoder(encodeMaterials);
|
||||
filePathEncoder.setApkArchive(getApkModule().getApkArchive());
|
||||
filePathEncoder.setUncompressedFiles(getApkModule().getUncompressedFiles());
|
||||
filePathEncoder.encodeResDir(resDir);
|
||||
|
||||
PackageBlock packageBlock = encodeMaterials.getCurrentPackage();
|
||||
packageBlock.sortTypes();
|
||||
packageBlock.refresh();
|
||||
|
||||
File manifestFile=toAndroidManifest(pubXmlFile);
|
||||
XMLSource xmlSource =
|
||||
new XMLFileSource(AndroidManifestBlock.FILE_NAME, manifestFile);
|
||||
XMLEncodeSource xmlEncodeSource =
|
||||
new XMLEncodeSource(encodeMaterials, xmlSource);
|
||||
|
||||
getApkModule().getApkArchive().add(xmlEncodeSource);
|
||||
}
|
||||
tableBlock.refresh();
|
||||
}
|
||||
@ -137,9 +168,17 @@
|
||||
}
|
||||
return results;
|
||||
}
|
||||
private List<File> searchPublicXmlFiles(File rootDir){
|
||||
logVerbose("Searching public.xml: "+rootDir);
|
||||
List<File> xmlFiles = ApkUtil.recursiveFiles(rootDir, ApkUtil.FILE_NAME_PUBLIC_XML);
|
||||
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(mainDir, ApkUtil.FILE_NAME_PUBLIC_XML));
|
||||
}
|
||||
List<File> results = new ArrayList<>();
|
||||
for(File file:xmlFiles){
|
||||
if(toAndroidManifest(file).isFile()){
|
||||
@ -148,11 +187,23 @@
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
//TODO: do this in separate class
|
||||
private void scanRootDir(File rootDir){
|
||||
APKArchive archive=getApkModule().getApkArchive();
|
||||
List<File> rootFileList=ApkUtil.recursiveFiles(rootDir);
|
||||
for(File file:rootFileList){
|
||||
String path=ApkUtil.toArchivePath(rootDir, file);
|
||||
FileInputSource inputSource=new FileInputSource(file, path);
|
||||
archive.add(inputSource);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAlreadyParsed(File file){
|
||||
return parsedValueFiles.contains(file);
|
||||
return parsedFiles.contains(file);
|
||||
}
|
||||
private void addParsedFiles(File file){
|
||||
parsedValueFiles.add(file);
|
||||
parsedFiles.add(file);
|
||||
}
|
||||
public void setAPKLogger(APKLogger logger) {
|
||||
this.apkLogger = logger;
|
||||
|
@ -15,15 +15,13 @@
|
||||
*/
|
||||
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.chunk.xml.*;
|
||||
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.lib.arsc.value.attribute.AttributeValueType;
|
||||
import com.reandroid.xml.*;
|
||||
|
||||
import java.io.File;
|
||||
@ -35,32 +33,36 @@ public class XMLFileEncoder {
|
||||
public XMLFileEncoder(EncodeMaterials materials){
|
||||
this.materials=materials;
|
||||
}
|
||||
public void encode(String xmlString){
|
||||
public ResXmlBlock encode(String xmlString){
|
||||
try {
|
||||
encode(XMLDocument.load(xmlString));
|
||||
return encode(XMLDocument.load(xmlString));
|
||||
} catch (XMLException ex) {
|
||||
materials.logMessage(ex.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void encode(InputStream inputStream){
|
||||
public ResXmlBlock encode(InputStream inputStream){
|
||||
try {
|
||||
encode(XMLDocument.load(inputStream));
|
||||
return encode(XMLDocument.load(inputStream));
|
||||
} catch (XMLException ex) {
|
||||
materials.logMessage(ex.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void encode(File xmlFile){
|
||||
public ResXmlBlock encode(File xmlFile){
|
||||
try {
|
||||
encode(XMLDocument.load(xmlFile));
|
||||
return encode(XMLDocument.load(xmlFile));
|
||||
} catch (XMLException ex) {
|
||||
materials.logMessage(ex.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void encode(XMLDocument xmlDocument){
|
||||
public ResXmlBlock encode(XMLDocument xmlDocument){
|
||||
resXmlBlock=new ResXmlBlock();
|
||||
buildIdMap(xmlDocument);
|
||||
buildElement(xmlDocument);
|
||||
resXmlBlock.refresh();
|
||||
return resXmlBlock;
|
||||
}
|
||||
public ResXmlBlock getResXmlBlock(){
|
||||
return resXmlBlock;
|
||||
@ -93,27 +95,39 @@ public class XMLFileEncoder {
|
||||
if(entryBlock!=null){
|
||||
resourceId=entryBlock.getResourceId();
|
||||
}
|
||||
ResXmlAttribute xmlAttribute =
|
||||
resXmlElement.createAttribute(attribute.getNameWoPrefix(), resourceId);
|
||||
String prefix=attribute.getNamePrefix();
|
||||
if(prefix!=null){
|
||||
ResXmlStartNamespace ns = resXmlElement.getStartNamespaceByPrefix(prefix);
|
||||
xmlAttribute.setNamespaceReference(ns.getUriReference());
|
||||
}
|
||||
|
||||
String valueText=attribute.getValue();
|
||||
|
||||
ResXmlAttribute xmlAttribute =
|
||||
resXmlElement.createAttribute(attribute.getName(), resourceId);
|
||||
if(ValueDecoder.isReference(valueText)){
|
||||
xmlAttribute.setValueType(ValueType.REFERENCE);
|
||||
xmlAttribute.setRawValue(materials.resolveReference(valueText));
|
||||
continue;
|
||||
}
|
||||
if(entryBlock!=null){
|
||||
AttributeBag attributeBag=AttributeBag
|
||||
.create((ResValueBag) entryBlock.getResValue());
|
||||
|
||||
ValueDecoder.EncodeResult encodeResult =
|
||||
attributeBag.encodeName(valueText);
|
||||
attributeBag.encodeEnumOrFlagValue(valueText);
|
||||
if(encodeResult!=null){
|
||||
xmlAttribute.setValueType(encodeResult.valueType);
|
||||
xmlAttribute.setRawValue(encodeResult.value);
|
||||
continue;
|
||||
}
|
||||
if(attributeBag.contains(AttributeValueType.STRING)) {
|
||||
xmlAttribute.setValueAsString(valueText);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(ValueDecoder.isReference(valueText)){
|
||||
xmlAttribute.setValueType(ValueType.REFERENCE);
|
||||
xmlAttribute.setRawValue(materials.resolveReference(valueText));
|
||||
}else if(EncodeUtil.isEmpty(valueText)) {
|
||||
if(EncodeUtil.isEmpty(valueText)) {
|
||||
xmlAttribute.setValueType(ValueType.NULL);
|
||||
xmlAttribute.setRawValue(0);
|
||||
}else{
|
||||
|
@ -40,17 +40,16 @@ class XMLValuesEncoderArray extends XMLValuesEncoderBag{
|
||||
String valueText=child.getTextContent();
|
||||
|
||||
if(ValueDecoder.isReference(valueText)){
|
||||
bagItem.setType(ValueType.REFERENCE);
|
||||
bagItem.setData(getMaterials().resolveReference(valueText));
|
||||
bagItem.setTypeAndData(ValueType.REFERENCE,
|
||||
getMaterials().resolveReference(valueText));
|
||||
}else if(EncodeUtil.isEmpty(valueText)) {
|
||||
bagItem.setType(ValueType.NULL);
|
||||
bagItem.setData(0);
|
||||
bagItem.setTypeAndData(ValueType.NULL, 0);
|
||||
}else if(!tag_string){
|
||||
ValueDecoder.EncodeResult encodeResult =
|
||||
ValueDecoder.encodeGuessAny(valueText);
|
||||
if(encodeResult!=null){
|
||||
bagItem.setType(encodeResult.valueType);
|
||||
bagItem.setData(encodeResult.value);
|
||||
bagItem.setTypeAndData(encodeResult.valueType,
|
||||
encodeResult.value);
|
||||
}else {
|
||||
bagItem.setValueAsString(valueText);
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ class XMLValuesEncoderBag extends XMLValuesEncoder{
|
||||
encodeChildes(element, resValueBag);
|
||||
}
|
||||
void encodeChildes(XMLElement element, ResValueBag resValueBag){
|
||||
throw new EncodeException("Unimplemented bag type encoder: "
|
||||
+element.getTagName());
|
||||
|
||||
}
|
||||
int getChildesCount(XMLElement element){
|
||||
|
@ -22,6 +22,7 @@ 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.AttributeValueType;
|
||||
import com.reandroid.xml.XMLElement;
|
||||
|
||||
|
||||
@ -33,41 +34,48 @@ class XMLValuesEncoderStyle extends XMLValuesEncoderBag{
|
||||
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
|
||||
EntryBlock attributeEntry=getMaterials()
|
||||
.getAttributeBlock(child.getAttributeValue("name"));
|
||||
if(entryBlock==null){
|
||||
throw new EncodeException("Unknown attribute name: '"+child.toText()+"'");
|
||||
if(attributeEntry==null){
|
||||
throw new EncodeException("Unknown attribute name: '"+child.toText()
|
||||
+"', for style: "+parentElement.getAttributeValue("name"));
|
||||
}
|
||||
bagItem.setId(entryBlock.getResourceId());
|
||||
AttributeBag attributeBag=AttributeBag
|
||||
.create((ResValueBag) entryBlock.getResValue());
|
||||
encodeChild(parentElement.getChildAt(i), attributeEntry, itemArray.get(i));
|
||||
}
|
||||
}
|
||||
private void encodeChild(XMLElement child, EntryBlock attributeEntry, ResValueBagItem bagItem){
|
||||
|
||||
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.setId(attributeEntry.getResourceId());
|
||||
AttributeBag attributeBag=AttributeBag
|
||||
.create((ResValueBag) attributeEntry.getResValue());
|
||||
|
||||
String valueText=child.getTextContent();
|
||||
ValueDecoder.EncodeResult encodeEnumFlag =
|
||||
attributeBag.encodeEnumOrFlagValue(valueText);
|
||||
if(encodeEnumFlag!=null){
|
||||
bagItem.setTypeAndData(encodeEnumFlag.valueType, encodeEnumFlag.value);
|
||||
return;
|
||||
}
|
||||
if(ValueDecoder.isReference(valueText)){
|
||||
if(valueText.startsWith("?")){
|
||||
bagItem.setType(ValueType.ATTRIBUTE);
|
||||
}else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
bagItem.setData(getMaterials().resolveReference(valueText));
|
||||
}else if(attributeBag.contains(AttributeValueType.STRING)) {
|
||||
bagItem.setValueAsString(valueText);
|
||||
}else if(EncodeUtil.isEmpty(valueText)) {
|
||||
bagItem.setTypeAndData(ValueType.NULL, 0);
|
||||
}else{
|
||||
ValueDecoder.EncodeResult encodeResult = ValueDecoder.encodeGuessAny(valueText);
|
||||
if(encodeResult!=null){
|
||||
bagItem.setTypeAndData(encodeResult.valueType,
|
||||
encodeResult.value);
|
||||
}else {
|
||||
bagItem.setValueAsString(valueText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,12 @@ public class AttributeBag {
|
||||
public AttributeBag(AttributeBagItem[] bagItems){
|
||||
this.mBagItems=bagItems;
|
||||
}
|
||||
public ValueDecoder.EncodeResult encodeName(String valueString){
|
||||
if(valueString==null){
|
||||
|
||||
public boolean contains(AttributeValueType valueType){
|
||||
return getFormat().contains(valueType);
|
||||
}
|
||||
public ValueDecoder.EncodeResult encodeEnumOrFlagValue(String valueString){
|
||||
if(valueString==null || !isEnumOrFlag()){
|
||||
return null;
|
||||
}
|
||||
int value=0;
|
||||
@ -45,7 +49,8 @@ public class AttributeBag {
|
||||
if(!foundOnce){
|
||||
return null;
|
||||
}
|
||||
return new ValueDecoder.EncodeResult(ValueType.INT_HEX, value);
|
||||
ValueType valueType = isFlag()?ValueType.INT_HEX:ValueType.INT_DEC;
|
||||
return new ValueDecoder.EncodeResult(valueType, value);
|
||||
}
|
||||
public String decodeAttributeValue(EntryStore entryStore, int attrValue){
|
||||
AttributeBagItem[] bagItems=searchValue(attrValue);
|
||||
@ -197,6 +202,9 @@ public class AttributeBag {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private boolean isEnumOrFlag(){
|
||||
return isFlag() || isEnum();
|
||||
}
|
||||
public boolean isFlag(){
|
||||
return getFormat().isFlag();
|
||||
}
|
||||
|
@ -84,6 +84,14 @@ public class AttributeBagItem {
|
||||
ResValueBagItem item=getBagItem();
|
||||
return item.getIdHigh()==0x0100;
|
||||
}
|
||||
public boolean contains(AttributeValueType valueType){
|
||||
if(valueType == null || getItemType()!=AttributeItemType.FORMAT){
|
||||
return false;
|
||||
}
|
||||
int value = 0xff & valueType.getByte();
|
||||
int dataLow = 0xffff & getBagItem().getDataLow();
|
||||
return (dataLow & value) == value;
|
||||
}
|
||||
public AttributeValueType[] getValueTypes(){
|
||||
AttributeItemType type=getItemType();
|
||||
if(type!=AttributeItemType.FORMAT){
|
||||
|
Reference in New Issue
Block a user