diff --git a/src/main/java/com/reandroid/arsc/array/ResXmlIDArray.java b/src/main/java/com/reandroid/arsc/array/ResXmlIDArray.java index bfbe10c..450de3a 100755 --- a/src/main/java/com/reandroid/arsc/array/ResXmlIDArray.java +++ b/src/main/java/com/reandroid/arsc/array/ResXmlIDArray.java @@ -59,6 +59,10 @@ public class ResXmlIDArray extends BlockArray { updateIdMap(); return mResIdMap.get(resId); } + public void refreshIdMap(){ + mUpdated = false; + updateIdMap(); + } private void updateIdMap(){ if(mUpdated){ return; diff --git a/src/main/java/com/reandroid/arsc/chunk/xml/ResXmlAttribute.java b/src/main/java/com/reandroid/arsc/chunk/xml/ResXmlAttribute.java index 474cb6f..ba421b5 100755 --- a/src/main/java/com/reandroid/arsc/chunk/xml/ResXmlAttribute.java +++ b/src/main/java/com/reandroid/arsc/chunk/xml/ResXmlAttribute.java @@ -94,21 +94,23 @@ setNameReference(xmlID.getIndex()); } public void setName(String name, int resourceId){ - if(resourceId!=0){ - setNameResourceID(resourceId); + unlink(mNameReference); + unLinkNameId(getResXmlID()); + ResXmlString xmlString = getOrCreateAttributeName(name, resourceId); + if(xmlString==null){ return; } - if(name==null){ - name=""; - } - ResXmlIDMap xmlIDMap = getResXmlIDMap(); + setNameReference(xmlString.getIndex()); + mNameReference = link(OFFSET_NAME); + linkNameId(); + } + private ResXmlString getOrCreateAttributeName(String name, int resourceId){ StringPool stringPool = getStringPool(); - if(stringPool==null || xmlIDMap==null){ - return; + if(stringPool==null){ + return null; } ResXmlStringPool resXmlStringPool = (ResXmlStringPool) stringPool; - ResXmlString xmlString = resXmlStringPool.getOrCreateAttributeName(xmlIDMap.getResXmlIDArray().childesCount(), name); - setNameReference(xmlString.getIndex()); + return resXmlStringPool.getOrCreateAttribute(resourceId, name); } public ResXmlElement getParentResXmlElement(){ return getParent(ResXmlElement.class); diff --git a/src/main/java/com/reandroid/arsc/pool/ResXmlStringPool.java b/src/main/java/com/reandroid/arsc/pool/ResXmlStringPool.java index 039beb8..ab625de 100755 --- a/src/main/java/com/reandroid/arsc/pool/ResXmlStringPool.java +++ b/src/main/java/com/reandroid/arsc/pool/ResXmlStringPool.java @@ -15,15 +15,21 @@ */ package com.reandroid.arsc.pool; +import com.reandroid.arsc.array.ResXmlIDArray; import com.reandroid.arsc.array.StringArray; import com.reandroid.arsc.array.ResXmlStringArray; import com.reandroid.arsc.array.StyleArray; +import com.reandroid.arsc.chunk.xml.ResXmlDocument; +import com.reandroid.arsc.chunk.xml.ResXmlIDMap; import com.reandroid.arsc.group.StringGroup; import com.reandroid.arsc.item.IntegerArray; import com.reandroid.arsc.item.IntegerItem; +import com.reandroid.arsc.item.ResXmlID; import com.reandroid.arsc.item.ResXmlString; -public class ResXmlStringPool extends StringPool { +import java.util.Objects; + + public class ResXmlStringPool extends StringPool { public ResXmlStringPool(boolean is_utf8) { super(is_utf8); } @@ -31,6 +37,73 @@ public class ResXmlStringPool extends StringPool { StringArray newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) { return new ResXmlStringArray(offsets, itemCount, itemStart, is_utf8); } + public ResXmlString getOrCreate(String str){ + return getOrCreateAttribute(0, str); + } + public ResXmlString getOrCreateAttribute(int resourceId, String str){ + ResXmlIDMap resXmlIDMap = getResXmlIDMap(); + if(resXmlIDMap == null){ + return super.getOrCreate(str); + } + ResXmlIDArray idArray = resXmlIDMap.getResXmlIDArray(); + int count = idArray.childesCount(); + if(resourceId == 0){ + return getOrCreateAfter(count, str); + } + StringArray stringsArray = getStringsArray(); + ResXmlID xmlID = idArray.getByResId(resourceId); + if(xmlID != null){ + ResXmlString xmlString = stringsArray.get(xmlID.getIndex()); + if(xmlString!=null && Objects.equals(str, xmlString.get())){ + return xmlString; + } + } + count = idArray.childesCount() + 1; + stringsArray.ensureSize(count); + idArray.setChildesCount(count); + int index = count - 1; + xmlID = idArray.get(index); + xmlID.set(resourceId); + idArray.refreshIdMap(); + + ResXmlString xmlString = stringsArray.newInstance(); + xmlString.set(str); + stringsArray.insertItem(index, xmlString); + + updateUniqueIdMap(xmlString); + return xmlString; + } + private ResXmlString getOrCreateAfter(int position, String str){ + if(position<0){ + position=0; + } + StringGroup group = get(str); + if(group!=null){ + for(ResXmlString xmlString:group.listItems()){ + int index = xmlString.getIndex(); + if(index > position || (position==0 && position == index)){ + return xmlString; + } + } + } + StringArray stringsArray = getStringsArray(); + int count = stringsArray.childesCount(); + if(count < position){ + count = position; + } + stringsArray.ensureSize(count+1); + ResXmlString xmlString = stringsArray.get(count); + xmlString.set(str); + super.updateUniqueIdMap(xmlString); + return xmlString; + } + private ResXmlIDMap getResXmlIDMap(){ + ResXmlDocument resXmlDocument = getParentInstance(ResXmlDocument.class); + if(resXmlDocument!=null){ + return resXmlDocument.getResXmlIDMap(); + } + return null; + } public ResXmlString getOrCreateAttributeName(int idMapCount, String str){ StringGroup group = get(str); if(group!=null){