mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-05-02 07:04:27 +02:00
[XML] clean unused strings and res id from pool
This commit is contained in:
parent
9914722bac
commit
dfe85947b4
@ -15,15 +15,45 @@
|
|||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.array;
|
package com.reandroid.arsc.array;
|
||||||
|
|
||||||
|
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||||
|
import com.reandroid.arsc.chunk.xml.ResXmlIDMap;
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
import com.reandroid.arsc.item.IntegerArray;
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
import com.reandroid.arsc.item.IntegerItem;
|
||||||
import com.reandroid.arsc.item.ResXmlString;
|
import com.reandroid.arsc.item.ResXmlString;
|
||||||
|
|
||||||
public class ResXmlStringArray extends StringArray<ResXmlString> {
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ResXmlStringArray extends StringArray<ResXmlString> {
|
||||||
public ResXmlStringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
public ResXmlStringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||||
super(offsets, itemCount, itemStart, is_utf8);
|
super(offsets, itemCount, itemStart, is_utf8);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
List<ResXmlString> listUnusedStringsToRemove(){
|
||||||
|
List<ResXmlString> results=new ArrayList<>();
|
||||||
|
ResXmlIDMap idMap = getResXmlIDMap();
|
||||||
|
int lastIndex = -1;
|
||||||
|
if(idMap!=null){
|
||||||
|
lastIndex = idMap.countId();
|
||||||
|
}
|
||||||
|
for(ResXmlString item:listItems()){
|
||||||
|
if(item == null
|
||||||
|
|| item.hasReference()
|
||||||
|
|| item.getIndex()<lastIndex){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
results.add(item);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
private ResXmlIDMap getResXmlIDMap(){
|
||||||
|
ResXmlDocument xmlDocument = getParentInstance(ResXmlDocument.class);
|
||||||
|
if(xmlDocument!=null){
|
||||||
|
return xmlDocument.getResXmlIDMap();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public ResXmlString newInstance() {
|
public ResXmlString newInstance() {
|
||||||
return new ResXmlString(isUtf8());
|
return new ResXmlString(isUtf8());
|
||||||
}
|
}
|
||||||
|
@ -51,13 +51,16 @@ public abstract class StringArray<T extends StringItem> extends OffsetBlockArray
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
public List<T> removeUnusedStrings(){
|
public List<T> removeUnusedStrings(){
|
||||||
List<T> unusedList=listUnusedStrings();
|
List<T> unusedList = listUnusedStringsToRemove();
|
||||||
remove(unusedList);
|
remove(unusedList);
|
||||||
for(T item:unusedList){
|
for(T item:unusedList){
|
||||||
item.onRemoved();
|
item.onRemoved();
|
||||||
}
|
}
|
||||||
return unusedList;
|
return unusedList;
|
||||||
}
|
}
|
||||||
|
List<T> listUnusedStringsToRemove(){
|
||||||
|
return listUnusedStrings();
|
||||||
|
}
|
||||||
public List<T> listUnusedStrings(){
|
public List<T> listUnusedStrings(){
|
||||||
List<T> results=new ArrayList<>();
|
List<T> results=new ArrayList<>();
|
||||||
for(T item:listItems()){
|
for(T item:listItems()){
|
||||||
|
@ -221,7 +221,7 @@ import java.util.*;
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
public Set<TableBlock> getFrameWorks(){
|
public List<TableBlock> getFrameWorks(){
|
||||||
return mFrameWorks;
|
return mFrameWorks;
|
||||||
}
|
}
|
||||||
public void addFramework(TableBlock tableBlock){
|
public void addFramework(TableBlock tableBlock){
|
||||||
@ -229,12 +229,18 @@ import java.util.*;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(TableBlock frm:tableBlock.getFrameWorks()){
|
for(TableBlock frm:tableBlock.getFrameWorks()){
|
||||||
if(frm==this){
|
if(frm==this || frm==tableBlock || tableBlock.equals(frm)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mFrameWorks.add(tableBlock);
|
mFrameWorks.add(tableBlock);
|
||||||
}
|
}
|
||||||
|
public void removeFramework(TableBlock tableBlock){
|
||||||
|
mFrameWorks.remove(tableBlock);
|
||||||
|
}
|
||||||
|
public void clearFrameworks(){
|
||||||
|
mFrameWorks.clear();
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public JSONObject toJson() {
|
public JSONObject toJson() {
|
||||||
JSONObject jsonObject=new JSONObject();
|
JSONObject jsonObject=new JSONObject();
|
||||||
|
@ -40,9 +40,13 @@
|
|||||||
addChild(mStringReference);
|
addChild(mStringReference);
|
||||||
}
|
}
|
||||||
void onRemoved(){
|
void onRemoved(){
|
||||||
unLinkStringReference(getHeaderBlock().getCommentReference());
|
ResXmlStringPool stringPool = getStringPool();
|
||||||
unLinkStringReference(mNamespaceReference);
|
if(stringPool==null){
|
||||||
unLinkStringReference(mStringReference);
|
return;
|
||||||
|
}
|
||||||
|
stringPool.removeReference(getHeaderBlock().getCommentReference());
|
||||||
|
stringPool.removeReference(mNamespaceReference);
|
||||||
|
stringPool.removeReference(mStringReference);
|
||||||
}
|
}
|
||||||
void linkStringReferences(){
|
void linkStringReferences(){
|
||||||
linkStringReference(getHeaderBlock().getCommentReference());
|
linkStringReference(getHeaderBlock().getCommentReference());
|
||||||
@ -68,6 +72,9 @@
|
|||||||
return getHeaderBlock().getLineNumber().get();
|
return getHeaderBlock().getLineNumber().get();
|
||||||
}
|
}
|
||||||
public void setCommentReference(int val){
|
public void setCommentReference(int val){
|
||||||
|
if(val == getCommentReference()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
IntegerItem comment=getHeaderBlock().getCommentReference();
|
IntegerItem comment=getHeaderBlock().getCommentReference();
|
||||||
unLinkStringReference(comment);
|
unLinkStringReference(comment);
|
||||||
getHeaderBlock().getCommentReference().set(val);
|
getHeaderBlock().getCommentReference().set(val);
|
||||||
@ -77,6 +84,9 @@
|
|||||||
return getHeaderBlock().getCommentReference().get();
|
return getHeaderBlock().getCommentReference().get();
|
||||||
}
|
}
|
||||||
public void setNamespaceReference(int val){
|
public void setNamespaceReference(int val){
|
||||||
|
if(val == getNamespaceReference()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
unLinkStringReference(mNamespaceReference);
|
unLinkStringReference(mNamespaceReference);
|
||||||
mNamespaceReference.set(val);
|
mNamespaceReference.set(val);
|
||||||
linkStringReference(mNamespaceReference);
|
linkStringReference(mNamespaceReference);
|
||||||
@ -85,6 +95,9 @@
|
|||||||
return mNamespaceReference.get();
|
return mNamespaceReference.get();
|
||||||
}
|
}
|
||||||
public void setStringReference(int val){
|
public void setStringReference(int val){
|
||||||
|
if(val == getStringReference()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
unLinkStringReference(mStringReference);
|
unLinkStringReference(mStringReference);
|
||||||
mStringReference.set(val);
|
mStringReference.set(val);
|
||||||
linkStringReference(mStringReference);
|
linkStringReference(mStringReference);
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
import com.reandroid.xml.XMLException;
|
import com.reandroid.xml.XMLException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ResXmlAttribute extends ValueItem implements Comparable<ResXmlAttribute>{
|
public class ResXmlAttribute extends ValueItem implements Comparable<ResXmlAttribute>{
|
||||||
private ReferenceItem mNSReference;
|
private ReferenceItem mNSReference;
|
||||||
@ -94,6 +95,9 @@
|
|||||||
setNameReference(xmlID.getIndex());
|
setNameReference(xmlID.getIndex());
|
||||||
}
|
}
|
||||||
public void setName(String name, int resourceId){
|
public void setName(String name, int resourceId){
|
||||||
|
if(Objects.equals(name, getName()) && resourceId==getNameResourceID()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
unlink(mNameReference);
|
unlink(mNameReference);
|
||||||
unLinkNameId(getResXmlID());
|
unLinkNameId(getResXmlID());
|
||||||
ResXmlString xmlString = getOrCreateAttributeName(name, resourceId);
|
ResXmlString xmlString = getOrCreateAttributeName(name, resourceId);
|
||||||
@ -104,13 +108,34 @@
|
|||||||
mNameReference = link(OFFSET_NAME);
|
mNameReference = link(OFFSET_NAME);
|
||||||
linkNameId();
|
linkNameId();
|
||||||
}
|
}
|
||||||
|
private void linkStartNameSpace(){
|
||||||
|
ResXmlElement xmlElement=getParentResXmlElement();
|
||||||
|
if(xmlElement==null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResXmlStartNamespace startNamespace=xmlElement.getStartNamespaceByUriRef(getNamespaceReference());
|
||||||
|
if(startNamespace==null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
startNamespace.addAttributeReference(this);
|
||||||
|
}
|
||||||
|
private void unLinkStartNameSpace(){
|
||||||
|
ResXmlElement xmlElement=getParentResXmlElement();
|
||||||
|
if(xmlElement==null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResXmlStartNamespace startNamespace=xmlElement.getStartNamespaceByUriRef(getNamespaceReference());
|
||||||
|
if(startNamespace==null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
startNamespace.removeAttributeReference(this);
|
||||||
|
}
|
||||||
private ResXmlString getOrCreateAttributeName(String name, int resourceId){
|
private ResXmlString getOrCreateAttributeName(String name, int resourceId){
|
||||||
StringPool<?> stringPool = getStringPool();
|
ResXmlStringPool stringPool = getStringPool();
|
||||||
if(stringPool==null){
|
if(stringPool==null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ResXmlStringPool resXmlStringPool = (ResXmlStringPool) stringPool;
|
return stringPool.getOrCreateAttribute(resourceId, name);
|
||||||
return resXmlStringPool.getOrCreateAttribute(resourceId, name);
|
|
||||||
}
|
}
|
||||||
public ResXmlElement getParentResXmlElement(){
|
public ResXmlElement getParentResXmlElement(){
|
||||||
return getParent(ResXmlElement.class);
|
return getParent(ResXmlElement.class);
|
||||||
@ -161,6 +186,7 @@
|
|||||||
unlink(mNSReference);
|
unlink(mNSReference);
|
||||||
putInteger(getBytesInternal(), OFFSET_NS, ref);
|
putInteger(getBytesInternal(), OFFSET_NS, ref);
|
||||||
mNSReference = link(OFFSET_NS);
|
mNSReference = link(OFFSET_NS);
|
||||||
|
linkStartNameSpace();
|
||||||
}
|
}
|
||||||
int getNameReference(){
|
int getNameReference(){
|
||||||
return getInteger(getBytesInternal(), OFFSET_NAME);
|
return getInteger(getBytesInternal(), OFFSET_NAME);
|
||||||
@ -191,17 +217,17 @@
|
|||||||
public void onReadBytes(BlockReader reader) throws IOException {
|
public void onReadBytes(BlockReader reader) throws IOException {
|
||||||
super.onReadBytes(reader);
|
super.onReadBytes(reader);
|
||||||
linkAll();
|
linkAll();
|
||||||
|
linkStartNameSpace();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onRemoved(){
|
public void onRemoved(){
|
||||||
super.onRemoved();
|
super.onRemoved();
|
||||||
|
unLinkStartNameSpace();
|
||||||
unlinkAll();
|
unlinkAll();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected void onUnlinkDataString(StringItem stringItem){
|
protected void onUnlinkDataString(ReferenceItem referenceItem){
|
||||||
if(!stringItem.hasReference()){
|
unlink(referenceItem);
|
||||||
stringItem.set("");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected void onDataChanged(){
|
protected void onDataChanged(){
|
||||||
@ -228,6 +254,14 @@
|
|||||||
}
|
}
|
||||||
xmlID.removeReference(referenceItem);
|
xmlID.removeReference(referenceItem);
|
||||||
mNameIdReference = null;
|
mNameIdReference = null;
|
||||||
|
if(xmlID.hasReference()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResXmlIDMap xmlIDMap = getResXmlIDMap();
|
||||||
|
if(xmlIDMap == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xmlIDMap.removeSafely(xmlID);
|
||||||
}
|
}
|
||||||
private void linkAll(){
|
private void linkAll(){
|
||||||
unlink(mNSReference);
|
unlink(mNSReference);
|
||||||
@ -270,21 +304,20 @@
|
|||||||
if(reference == null){
|
if(reference == null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StringPool<?> stringPool = getStringPool();
|
ResXmlStringPool stringPool = getStringPool();
|
||||||
if(stringPool==null){
|
if(stringPool==null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StringItem stringItem = stringPool.get(reference.get());
|
stringPool.removeReference(reference);
|
||||||
if(stringItem==null){
|
}
|
||||||
return;
|
@Override
|
||||||
}
|
public ResXmlStringPool getStringPool(){
|
||||||
stringItem.removeReference(reference);
|
StringPool<?> stringPool = super.getStringPool();
|
||||||
if(!stringItem.hasReference()){
|
if(stringPool instanceof ResXmlStringPool){
|
||||||
stringItem.set("");
|
return (ResXmlStringPool) stringPool;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(ResXmlAttribute other) {
|
public int compareTo(ResXmlAttribute other) {
|
||||||
int id1=getNameResourceID();
|
int id1=getNameResourceID();
|
||||||
|
@ -329,14 +329,20 @@
|
|||||||
return getStartElement().getResXmlAttributeArray().remove(resXmlAttribute);
|
return getStartElement().getResXmlAttributeArray().remove(resXmlAttribute);
|
||||||
}
|
}
|
||||||
public boolean removeElement(ResXmlElement element){
|
public boolean removeElement(ResXmlElement element){
|
||||||
if(element.getParent()!=null){
|
if(element !=null && element.getParent()!=null){
|
||||||
element.onRemoved();
|
element.onRemoved();
|
||||||
}
|
}
|
||||||
return mBody.remove(element);
|
return mBody.remove(element);
|
||||||
}
|
}
|
||||||
|
public boolean removeNode(ResXmlNode node){
|
||||||
|
if(node instanceof ResXmlElement){
|
||||||
|
return removeElement((ResXmlElement) node);
|
||||||
|
}
|
||||||
|
return mBody.remove(node);
|
||||||
|
}
|
||||||
public int countElements(){
|
public int countElements(){
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for(ResXmlNode xmlNode:listXmlNodes()){
|
for(ResXmlNode xmlNode: getXmlNodes()){
|
||||||
if(xmlNode instanceof ResXmlElement){
|
if(xmlNode instanceof ResXmlElement){
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
@ -354,11 +360,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public List<ResXmlNode> listXmlNodes(){
|
public List<ResXmlNode> listXmlNodes(){
|
||||||
|
return new ArrayList<>(getXmlNodes());
|
||||||
|
}
|
||||||
|
private List<ResXmlNode> getXmlNodes(){
|
||||||
return mBody.getChildes();
|
return mBody.getChildes();
|
||||||
}
|
}
|
||||||
public List<ResXmlText> listXmlText(){
|
public List<ResXmlText> listXmlText(){
|
||||||
List<ResXmlText> results=new ArrayList<>();
|
List<ResXmlText> results=new ArrayList<>();
|
||||||
for(ResXmlNode xmlNode:listXmlNodes()){
|
for(ResXmlNode xmlNode: getXmlNodes()){
|
||||||
if(xmlNode instanceof ResXmlTextNode){
|
if(xmlNode instanceof ResXmlTextNode){
|
||||||
results.add(((ResXmlTextNode) xmlNode).getResXmlText());
|
results.add(((ResXmlTextNode) xmlNode).getResXmlText());
|
||||||
}
|
}
|
||||||
@ -367,7 +376,7 @@
|
|||||||
}
|
}
|
||||||
public List<ResXmlTextNode> listXmlTextNodes(){
|
public List<ResXmlTextNode> listXmlTextNodes(){
|
||||||
List<ResXmlTextNode> results=new ArrayList<>();
|
List<ResXmlTextNode> results=new ArrayList<>();
|
||||||
for(ResXmlNode xmlNode:listXmlNodes()){
|
for(ResXmlNode xmlNode: getXmlNodes()){
|
||||||
if(xmlNode instanceof ResXmlTextNode){
|
if(xmlNode instanceof ResXmlTextNode){
|
||||||
results.add((ResXmlTextNode) xmlNode);
|
results.add((ResXmlTextNode) xmlNode);
|
||||||
}
|
}
|
||||||
@ -376,7 +385,7 @@
|
|||||||
}
|
}
|
||||||
public List<ResXmlElement> listElements(){
|
public List<ResXmlElement> listElements(){
|
||||||
List<ResXmlElement> results=new ArrayList<>();
|
List<ResXmlElement> results=new ArrayList<>();
|
||||||
for(ResXmlNode xmlNode:listXmlNodes()){
|
for(ResXmlNode xmlNode: getXmlNodes()){
|
||||||
if(xmlNode instanceof ResXmlElement){
|
if(xmlNode instanceof ResXmlElement){
|
||||||
results.add((ResXmlElement) xmlNode);
|
results.add((ResXmlElement) xmlNode);
|
||||||
}
|
}
|
||||||
@ -782,7 +791,7 @@
|
|||||||
jsonObject.put(NAME_attributes, attrArray);
|
jsonObject.put(NAME_attributes, attrArray);
|
||||||
i=0;
|
i=0;
|
||||||
JSONArray childes=new JSONArray();
|
JSONArray childes=new JSONArray();
|
||||||
for(ResXmlNode xmlNode:listXmlNodes()){
|
for(ResXmlNode xmlNode: getXmlNodes()){
|
||||||
childes.put(i, xmlNode.toJson());
|
childes.put(i, xmlNode.toJson());
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -879,7 +888,7 @@
|
|||||||
if(comment!=null){
|
if(comment!=null){
|
||||||
xmlElement.addComment(new XMLComment(comment));
|
xmlElement.addComment(new XMLComment(comment));
|
||||||
}
|
}
|
||||||
for(ResXmlNode xmlNode:listXmlNodes()){
|
for(ResXmlNode xmlNode: getXmlNodes()){
|
||||||
if(xmlNode instanceof ResXmlElement){
|
if(xmlNode instanceof ResXmlElement){
|
||||||
ResXmlElement childResXmlElement=(ResXmlElement)xmlNode;
|
ResXmlElement childResXmlElement=(ResXmlElement)xmlNode;
|
||||||
XMLElement childXMLElement =
|
XMLElement childXMLElement =
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
import com.reandroid.arsc.chunk.Chunk;
|
import com.reandroid.arsc.chunk.Chunk;
|
||||||
import com.reandroid.arsc.header.HeaderBlock;
|
import com.reandroid.arsc.header.HeaderBlock;
|
||||||
import com.reandroid.arsc.item.ResXmlID;
|
import com.reandroid.arsc.item.ResXmlID;
|
||||||
|
import com.reandroid.arsc.item.ResXmlString;
|
||||||
import com.reandroid.arsc.pool.ResXmlStringPool;
|
import com.reandroid.arsc.pool.ResXmlStringPool;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -31,6 +32,32 @@
|
|||||||
this.mResXmlIDArray=new ResXmlIDArray(getHeaderBlock());
|
this.mResXmlIDArray=new ResXmlIDArray(getHeaderBlock());
|
||||||
addChild(mResXmlIDArray);
|
addChild(mResXmlIDArray);
|
||||||
}
|
}
|
||||||
|
void removeSafely(ResXmlID resXmlID){
|
||||||
|
if(resXmlID==null
|
||||||
|
|| resXmlID.getParent()==null
|
||||||
|
|| resXmlID.getIndex()<0
|
||||||
|
|| resXmlID.hasReference()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResXmlString xmlString = resXmlID.getResXmlString();
|
||||||
|
if(xmlString == null
|
||||||
|
|| xmlString.getParent()==null
|
||||||
|
|| xmlString.getIndex()<0
|
||||||
|
|| xmlString.hasReference()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResXmlStringPool stringPool = getXmlStringPool();
|
||||||
|
if(stringPool == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resXmlID.set(0);
|
||||||
|
ResXmlIDArray idArray = getResXmlIDArray();
|
||||||
|
idArray.remove(resXmlID);
|
||||||
|
stringPool.removeString(xmlString);
|
||||||
|
}
|
||||||
|
public int countId(){
|
||||||
|
return getResXmlIDArray().childesCount();
|
||||||
|
}
|
||||||
public void destroy(){
|
public void destroy(){
|
||||||
getResXmlIDArray().clearChildes();
|
getResXmlIDArray().clearChildes();
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,17 @@
|
|||||||
package com.reandroid.arsc.chunk.xml;
|
package com.reandroid.arsc.chunk.xml;
|
||||||
|
|
||||||
import com.reandroid.arsc.chunk.ChunkType;
|
import com.reandroid.arsc.chunk.ChunkType;
|
||||||
import com.reandroid.arsc.item.ResXmlString;
|
|
||||||
import com.reandroid.xml.SchemaAttr;
|
import com.reandroid.xml.SchemaAttr;
|
||||||
import com.reandroid.xml.XMLAttribute;
|
import com.reandroid.xml.XMLAttribute;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ResXmlStartNamespace extends ResXmlNamespace {
|
public class ResXmlStartNamespace extends ResXmlNamespace {
|
||||||
|
private final Set<ResXmlAttribute> mReferencedAttributes;
|
||||||
public ResXmlStartNamespace() {
|
public ResXmlStartNamespace() {
|
||||||
super(ChunkType.XML_START_NAMESPACE);
|
super(ChunkType.XML_START_NAMESPACE);
|
||||||
|
this.mReferencedAttributes = new HashSet<>();
|
||||||
}
|
}
|
||||||
public ResXmlEndNamespace getEnd(){
|
public ResXmlEndNamespace getEnd(){
|
||||||
return (ResXmlEndNamespace) getPair();
|
return (ResXmlEndNamespace) getPair();
|
||||||
@ -46,6 +48,26 @@
|
|||||||
if(end!=null){
|
if(end!=null){
|
||||||
end.onRemoved();
|
end.onRemoved();
|
||||||
}
|
}
|
||||||
|
mReferencedAttributes.clear();
|
||||||
|
}
|
||||||
|
public boolean hasReferencedAttributes(){
|
||||||
|
return mReferencedAttributes.size()>0;
|
||||||
|
}
|
||||||
|
public void clearReferencedAttributes(){
|
||||||
|
mReferencedAttributes.clear();
|
||||||
|
}
|
||||||
|
public Set<ResXmlAttribute> getReferencedAttributes(){
|
||||||
|
return mReferencedAttributes;
|
||||||
|
}
|
||||||
|
void addAttributeReference(ResXmlAttribute attribute){
|
||||||
|
if(attribute!=null){
|
||||||
|
mReferencedAttributes.add(attribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void removeAttributeReference(ResXmlAttribute attribute){
|
||||||
|
if(attribute!=null){
|
||||||
|
mReferencedAttributes.remove(attribute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public XMLAttribute decodeToXml(){
|
public XMLAttribute decodeToXml(){
|
||||||
String uri=getUri();
|
String uri=getUri();
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.item;
|
package com.reandroid.arsc.item;
|
||||||
|
|
||||||
import com.reandroid.arsc.base.Block;
|
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||||
import com.reandroid.arsc.pool.ResXmlStringPool;
|
import com.reandroid.arsc.pool.ResXmlStringPool;
|
||||||
|
|
||||||
@ -55,7 +54,7 @@ public class ResXmlID extends IntegerItem {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onIndexChanged(int oldIndex, int newIndex){
|
public void onIndexChanged(int oldIndex, int newIndex){
|
||||||
reUpdateReferences(newIndex);
|
//TODO: We have to ignore this to avoid conflict with ResXmlIDMap.removeSafely
|
||||||
}
|
}
|
||||||
public String getName(){
|
public String getName(){
|
||||||
ResXmlString xmlString = getResXmlString();
|
ResXmlString xmlString = getResXmlString();
|
||||||
|
@ -22,10 +22,7 @@ import com.reandroid.arsc.array.StyleArray;
|
|||||||
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlIDMap;
|
import com.reandroid.arsc.chunk.xml.ResXmlIDMap;
|
||||||
import com.reandroid.arsc.group.StringGroup;
|
import com.reandroid.arsc.group.StringGroup;
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
import com.reandroid.arsc.item.*;
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
|
||||||
import com.reandroid.arsc.item.ResXmlID;
|
|
||||||
import com.reandroid.arsc.item.ResXmlString;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -34,6 +31,30 @@ import java.util.Objects;
|
|||||||
super(is_utf8);
|
super(is_utf8);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
public ResXmlString removeReference(ReferenceItem referenceItem){
|
||||||
|
if(referenceItem==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ResXmlString stringItem = super.removeReference(referenceItem);
|
||||||
|
removeNotUsedItem(stringItem);
|
||||||
|
return stringItem;
|
||||||
|
}
|
||||||
|
private void removeNotUsedItem(ResXmlString xmlString){
|
||||||
|
if(xmlString == null || xmlString.hasReference()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResXmlIDMap idMap = getResXmlIDMap();
|
||||||
|
int lastIdIndex = -1;
|
||||||
|
if(idMap!=null){
|
||||||
|
lastIdIndex = idMap.countId() - 1;
|
||||||
|
}
|
||||||
|
if(idMap!=null && xmlString.getIndex()>lastIdIndex){
|
||||||
|
removeString(xmlString);
|
||||||
|
}else {
|
||||||
|
xmlString.set("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,9 @@ package com.reandroid.arsc.pool;
|
|||||||
|
|
||||||
mUniqueMap = new HashMap<>();
|
mUniqueMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
public void removeString(T item){
|
||||||
|
getStringsArray().remove(item);
|
||||||
|
}
|
||||||
public void destroy(){
|
public void destroy(){
|
||||||
getStyleArray().clearChildes();
|
getStyleArray().clearChildes();
|
||||||
getStringsArray().clearChildes();
|
getStringsArray().clearChildes();
|
||||||
|
@ -27,6 +27,7 @@ import com.reandroid.json.JSONConvert;
|
|||||||
import com.reandroid.json.JSONObject;
|
import com.reandroid.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public abstract class ValueItem extends BlockItem implements Value,
|
public abstract class ValueItem extends BlockItem implements Value,
|
||||||
JSONConvert<JSONObject>{
|
JSONConvert<JSONObject>{
|
||||||
@ -150,16 +151,14 @@ import java.io.IOException;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mStringReference = null;
|
mStringReference = null;
|
||||||
|
onUnlinkDataString(stringReference);
|
||||||
|
}
|
||||||
|
protected void onUnlinkDataString(ReferenceItem referenceItem){
|
||||||
StringPool<?> stringPool = getStringPool();
|
StringPool<?> stringPool = getStringPool();
|
||||||
if(stringPool == null){
|
if(stringPool == null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StringItem stringItem = stringPool.removeReference(stringReference);
|
stringPool.removeReference(referenceItem);
|
||||||
if(stringItem!=null){
|
|
||||||
onUnlinkDataString(stringItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protected void onUnlinkDataString(StringItem stringItem){
|
|
||||||
}
|
}
|
||||||
public StringPool<?> getStringPool(){
|
public StringPool<?> getStringPool(){
|
||||||
Block parent = getParent();
|
Block parent = getParent();
|
||||||
@ -204,6 +203,10 @@ import java.io.IOException;
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public void setValueAsString(String str){
|
public void setValueAsString(String str){
|
||||||
|
if(getValueType() != ValueType.STRING
|
||||||
|
&& Objects.equals(str, getValueAsString())){
|
||||||
|
return;
|
||||||
|
}
|
||||||
StringItem stringItem = getStringPool().getOrCreate(str);
|
StringItem stringItem = getStringPool().getOrCreate(str);
|
||||||
setData(stringItem.getIndex());
|
setData(stringItem.getIndex());
|
||||||
setValueType(ValueType.STRING);
|
setValueType(ValueType.STRING);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user