Fix xml attribute encoding

This commit is contained in:
REAndroid 2022-12-12 12:09:00 -05:00
parent b75cb1f163
commit 34a9742d6b
2 changed files with 56 additions and 50 deletions

View File

@ -3,7 +3,6 @@ package com.reandroid.lib.arsc.chunk.xml;
import com.reandroid.lib.arsc.array.ResXmlIDArray; import com.reandroid.lib.arsc.array.ResXmlIDArray;
import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.base.Block;
import com.reandroid.lib.arsc.container.FixedBlockContainer; import com.reandroid.lib.arsc.container.FixedBlockContainer;
import com.reandroid.lib.arsc.decoder.ValueDecoder;
import com.reandroid.lib.arsc.item.*; import com.reandroid.lib.arsc.item.*;
import com.reandroid.lib.arsc.pool.ResXmlStringPool; import com.reandroid.lib.arsc.pool.ResXmlStringPool;
import com.reandroid.lib.arsc.value.ValueType; import com.reandroid.lib.arsc.value.ValueType;
@ -22,7 +21,7 @@ public class ResXmlAttribute extends FixedBlockContainer
public ResXmlAttribute() { public ResXmlAttribute() {
super(7); super(7);
mNamespaceReference =new IntegerItem(-1); mNamespaceReference =new IntegerItem(-1);
mNameReference =new IntegerItem(); mNameReference =new IntegerItem(-1);
mValueStringReference =new IntegerItem(-1); mValueStringReference =new IntegerItem(-1);
mNameType=new ShortItem((short) 0x0008); mNameType=new ShortItem((short) 0x0008);
mReserved =new ByteItem(); mReserved =new ByteItem();
@ -138,60 +137,29 @@ public class ResXmlAttribute extends FixedBlockContainer
public int getNameResourceID(){ public int getNameResourceID(){
return getResourceId(getNameReference()); return getResourceId(getNameReference());
} }
public boolean setName(String name, int resourceId){ public void setNameResourceID(int resourceId){
ResXmlStringPool stringPool=getStringPool();
if(stringPool==null){
return false;
}
String old=getName();
if(resourceId==0){
if(name.equals(old)){
return false;
}
ResXmlString resXmlString=stringPool.getOrCreate(name);
setNameReference(resXmlString.getIndex());
return true;
}
ResXmlIDMap xmlIDMap=getResXmlIDMap(); ResXmlIDMap xmlIDMap=getResXmlIDMap();
if(xmlIDMap==null){ if(xmlIDMap==null){
return false; return;
} }
int oldId=getNameResourceID(); ResXmlID xmlID = xmlIDMap.getOrCreate(resourceId);
if(oldId==resourceId){ setNameReference(xmlID.getIndex());
if(name.equals(old)){ }
return false; public void setName(String name, int resourceId){
} if(resourceId!=0){
setNameResourceID(resourceId);
return;
} }
ResXmlID resXmlID=xmlIDMap.getByResId(resourceId); if(name==null){
if(resXmlID!=null){ name="";
int ref=resXmlID.getIndex();
ResXmlString idName=stringPool.get(ref);
if(idName != null){
if(name.equals(idName.getHtml())){
setNameReference(ref);
}else {
idName.set(name);
}
return true;
}
} }
int stringsCount=stringPool.countStrings(); ResXmlIDMap xmlIDMap=getResXmlIDMap();
int idCount=xmlIDMap.getResXmlIDArray().childesCount(); ResXmlStringPool stringPool=getStringPool();
if(idCount>stringsCount){ if(stringPool==null || xmlIDMap==null){
xmlIDMap.addResourceId(idCount, resourceId);; return;
stringPool.getStringsArray().ensureSize(idCount+1);
ResXmlString resXmlString=stringPool.get(idCount);
resXmlString.set(name);
setNameReference(idCount);
return true;
} }
xmlIDMap.addResourceId(stringsCount, resourceId); ResXmlString xmlString = stringPool.getOrCreateAttributeName(xmlIDMap.getResXmlIDArray().childesCount(), name);
stringPool.getStringsArray().ensureSize(stringsCount+1); setNameReference(xmlString.getIndex());
ResXmlString resXmlString=stringPool.get(stringsCount);
resXmlString.set(name);
setNameReference(stringsCount);
return true;
} }
private int getResourceId(int ref){ private int getResourceId(int ref){
if(ref<0){ if(ref<0){

View File

@ -2,6 +2,8 @@ package com.reandroid.lib.arsc.pool;
import com.reandroid.lib.arsc.array.StringArray; import com.reandroid.lib.arsc.array.StringArray;
import com.reandroid.lib.arsc.array.ResXmlStringArray; import com.reandroid.lib.arsc.array.ResXmlStringArray;
import com.reandroid.lib.arsc.array.StyleArray;
import com.reandroid.lib.arsc.group.StringGroup;
import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerArray;
import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.item.ResXmlString; import com.reandroid.lib.arsc.item.ResXmlString;
@ -14,4 +16,40 @@ public class ResXmlStringPool extends BaseStringPool<ResXmlString> {
StringArray<ResXmlString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) { StringArray<ResXmlString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
return new ResXmlStringArray(offsets, itemCount, itemStart, is_utf8); return new ResXmlStringArray(offsets, itemCount, itemStart, is_utf8);
} }
public ResXmlString getOrCreateAttributeName(int idMapCount, String str){
StringGroup<ResXmlString> group = get(str);
if(group!=null){
for(ResXmlString xmlString:group.listItems()){
if(xmlString.getIndex()>idMapCount){
return xmlString;
}
}
}
StringArray<ResXmlString> stringsArray = getStringsArray();
stringsArray.ensureSize(idMapCount);
int i=stringsArray.childesCount();
stringsArray.ensureSize(i+1);
ResXmlString xmlString=stringsArray.get(i);
xmlString.set(str);
refreshUniqueIdMap();
return xmlString;
}
@Override
public void onChunkLoaded() {
super.onChunkLoaded();
StyleArray styleArray = getStyleArray();
if(styleArray.childesCount()>0){
notifyResXmlStringPoolHasStyles(styleArray.childesCount());
}
}
private static void notifyResXmlStringPoolHasStyles(int styleArrayCount){
if(HAS_STYLE_NOTIFIED){
return;
}
String msg="Not expecting ResXmlStringPool to have styles count="
+styleArrayCount+",\n please create issue along with this apk/file on https://github.com/REAndroid/ARSCEditor";
System.err.println(msg);
HAS_STYLE_NOTIFIED=true;
}
private static boolean HAS_STYLE_NOTIFIED;
} }