From e68ee0dfc75c354e82c428e00c307ff5057cf68c Mon Sep 17 00:00:00 2001 From: REAndroid Date: Fri, 25 Nov 2022 16:09:40 -0500 Subject: [PATCH] V1.0.2 --- .../lib/arsc/array/ResXmlAttributeArray.java | 20 +- .../lib/arsc/base/BlockContainer.java | 5 + .../arsc/chunk/xml/AndroidManifestBlock.java | 62 +++++- .../lib/arsc/chunk/xml/ResXmlAttribute.java | 96 +++++++++- .../lib/arsc/chunk/xml/ResXmlElement.java | 47 ++--- .../arsc/chunk/xml/ResXmlEndNamespace.java | 50 +---- .../lib/arsc/chunk/xml/ResXmlNamespace.java | 72 +++++++ .../arsc/chunk/xml/ResXmlStartElement.java | 6 +- .../arsc/chunk/xml/ResXmlStartNamespace.java | 48 +---- .../lib/arsc/container/BlockList.java | 23 ++- .../reandroid/lib/arsc/item/ByteArray.java | 27 +++ .../reandroid/lib/arsc/value/ResConfig.java | 181 ++++++++++++------ 12 files changed, 454 insertions(+), 183 deletions(-) create mode 100644 src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlNamespace.java diff --git a/src/main/java/com/reandroid/lib/arsc/array/ResXmlAttributeArray.java b/src/main/java/com/reandroid/lib/arsc/array/ResXmlAttributeArray.java index 9c529ba..1f61f67 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/ResXmlAttributeArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/ResXmlAttributeArray.java @@ -9,8 +9,12 @@ import com.reandroid.lib.arsc.chunk.xml.ResXmlAttribute; import com.reandroid.lib.arsc.item.ShortItem; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; -public class ResXmlAttributeArray extends BlockArray { +public class ResXmlAttributeArray extends BlockArray implements Comparator { private final HeaderBlock mHeaderBlock; private final ShortItem mAttributeStart; private final ShortItem mAttributeCount; @@ -19,6 +23,16 @@ public class ResXmlAttributeArray extends BlockArray { this.mAttributeStart=attributeStart; this.mAttributeCount=attributeCount; } + public void sortAttributes(){ + Collection items = listItems(); + if(items.size()<2){ + return; + } + List elementList = new ArrayList<>(items); + elementList.sort(this); + clearChildes(); + addAll(elementList.toArray(new ResXmlAttribute[0])); + } private void refreshCount(){ short count= (short) childesCount(); mAttributeCount.set(count); @@ -52,4 +66,8 @@ public class ResXmlAttributeArray extends BlockArray { setChildesCount(mAttributeCount.get()); super.onReadBytes(reader); } + @Override + public int compare(ResXmlAttribute attr1, ResXmlAttribute attr2) { + return attr1.compareTo(attr2); + } } diff --git a/src/main/java/com/reandroid/lib/arsc/base/BlockContainer.java b/src/main/java/com/reandroid/lib/arsc/base/BlockContainer.java index b31f542..70a2dac 100755 --- a/src/main/java/com/reandroid/lib/arsc/base/BlockContainer.java +++ b/src/main/java/com/reandroid/lib/arsc/base/BlockContainer.java @@ -1,5 +1,6 @@ package com.reandroid.lib.arsc.base; +import com.reandroid.lib.arsc.container.BlockList; import com.reandroid.lib.arsc.io.BlockReader; import java.io.IOException; @@ -43,6 +44,10 @@ public abstract class BlockContainer extends Block{ BlockContainer container=(BlockContainer)item; container.refresh(); } + if(item instanceof BlockList){ + BlockList blockList=(BlockList)item; + blockList.refresh(); + } } } } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java index cefa6ea..48161c2 100644 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java @@ -30,18 +30,39 @@ public class AndroidManifestBlock extends ResXmlBlock{ } return results; } + public ResXmlElement getUsesPermission(String permissionName){ + ResXmlElement manifestElement=getManifestElement(); + if(manifestElement==null){ + return null; + } + List permissionList = manifestElement.searchElementsByTagName(TAG_uses_permission); + for(ResXmlElement permission:permissionList){ + ResXmlAttribute nameAttr = permission.searchAttributeById(ID_name); + if(nameAttr==null){ + continue; + } + String val=nameAttr.getValueString(); + if(val==null){ + continue; + } + if(val.equals(permissionName)){ + return permission; + } + } + return null; + } public ResXmlElement addUsesPermission(String permissionName){ ResXmlElement manifestElement=getManifestElement(); if(manifestElement==null){ return null; } - manifestElement.getStartElement().getOrCreateString(TAG_uses_permission); + ResXmlElement exist=getUsesPermission(permissionName); + if(exist!=null){ + return exist; + } ResXmlElement result=manifestElement.createChildElement(TAG_uses_permission); ResXmlAttribute attr = result.createAndroidAttribute(NAME_name, ID_name); - ResXmlString strPermission = result.getStartElement().getOrCreateString(permissionName); - attr.setRawValue(strPermission.getIndex()); - attr.setValueType(ValueType.STRING); - attr.setValueStringReference(strPermission.getIndex()); + attr.setValueAsString(permissionName); return result; } public String getPackageName(){ @@ -54,13 +75,13 @@ public class AndroidManifestBlock extends ResXmlBlock{ return getManifestAttributeInt(NAME_compileSdkVersion); } public boolean setCompileSdkVersion(int val){ - return setManifestAttributeInt(NAME_compileSdkVersion, val); + return setManifestAttributeInt(ID_compileSdkVersion, val); } public String getCompileSdkVersionCodename(){ return getManifestAttributeString(NAME_compileSdkVersionCodename); } public boolean setCompileSdkVersionCodename(String val){ - return setManifestAttributeString(NAME_compileSdkVersionCodename, val); + return setManifestAttributeString(ID_compileSdkVersionCodename, val); } public Integer getVersionCode(){ return getManifestAttributeInt(NAME_versionCode); @@ -91,6 +112,19 @@ public class AndroidManifestBlock extends ResXmlBlock{ } return resXmlString.getHtml(); } + private boolean setManifestAttributeString(int resId, String value){ + ResXmlElement manifestElement=getManifestElement(); + if(manifestElement==null){ + return false; + } + ResXmlAttribute attribute= manifestElement.searchAttributeById(resId); + if(attribute==null){ + return false; + } + attribute.setValueType(ValueType.STRING); + ResXmlString resXmlString=attribute.setValueString(value); + return resXmlString!=null; + } private boolean setManifestAttributeString(String name, String value){ ResXmlElement manifestElement=getManifestElement(); if(manifestElement==null){ @@ -104,6 +138,20 @@ public class AndroidManifestBlock extends ResXmlBlock{ ResXmlString resXmlString=attribute.setValueString(value); return resXmlString!=null; } + private boolean setManifestAttributeInt(int resId, int value){ + ResXmlElement manifestElement=getManifestElement(); + if(manifestElement==null){ + return false; + } + ResXmlAttribute attribute= manifestElement.searchAttributeById(resId); + if(attribute==null){ + return false; + } + attribute.setValueType(ValueType.INT_DEC); + attribute.setValueString(String.valueOf(value)); + attribute.setRawValue(value); + return true; + } private boolean setManifestAttributeInt(String name, int value){ ResXmlElement manifestElement=getManifestElement(); if(manifestElement==null){ diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java index 011fe02..a4ed4da 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java @@ -7,7 +7,7 @@ import com.reandroid.lib.arsc.item.*; import com.reandroid.lib.arsc.pool.ResXmlStringPool; import com.reandroid.lib.arsc.value.ValueType; -public class ResXmlAttribute extends FixedBlockContainer { +public class ResXmlAttribute extends FixedBlockContainer implements Comparable{ private final IntegerItem mNamespaceReference; private final IntegerItem mNameReference; private final IntegerItem mValueStringReference; @@ -249,6 +249,100 @@ public class ResXmlAttribute extends FixedBlockContainer { } return null; } + public String getValueAsString(){ + int ref=getRawValue(); + ResXmlString xmlString=getResXmlString(ref); + if(xmlString==null){ + return null; + } + return xmlString.getHtml(); + } + public boolean getValueAsBoolean(){ + int ref=getRawValue(); + return ref!=0; + } + public void setValueAsString(String str){ + setValueType(ValueType.STRING); + ResXmlString xmlString=getOrCreateResXmlString(str); + if(xmlString==null){ + throw new IllegalStateException("ResXmlString is null, attribute must be added to parent element first"); + } + int ref=xmlString.getIndex(); + setRawValue(ref); + setValueStringReference(ref); + } + public void setValueAsBoolean(boolean val){ + setValueType(ValueType.INT_BOOLEAN); + int ref=val?0xffff:0; + setRawValue(ref); + setValueStringReference(-1); + } + public void setValueAsInteger(int val){ + setValueType(ValueType.FIRST_INT); + setRawValue(val); + setValueStringReference(-1); + } + public void setValueAsHex(int val){ + setValueType(ValueType.INT_HEX); + setRawValue(val); + setValueStringReference(-1); + } + public void setValueAsFraction(float fraction){ + int val=Float.floatToIntBits(fraction); + setValueAsFraction(val); + } + public void setValueAsFraction(int val){ + setValueType(ValueType.FRACTION); + setRawValue(val); + setValueStringReference(-1); + } + public void setValueAsResourceId(int resId){ + setValueType(ValueType.REFERENCE); + setRawValue(resId); + setValueStringReference(-1); + } + public void setValueAsAttributeId(int attrId){ + setValueType(ValueType.ATTRIBUTE); + setRawValue(attrId); + setValueStringReference(-1); + } + public void setValueAsColorRGB4(int val){ + setValueType(ValueType.INT_COLOR_RGB4); + setRawValue(val); + setValueStringReference(-1); + } + public void setValueAsColorRGB8(int val){ + setValueType(ValueType.INT_COLOR_RGB8); + setRawValue(val); + setValueStringReference(-1); + } + public void setValueAsColorARGB4(int val){ + setValueType(ValueType.INT_COLOR_ARGB4); + setRawValue(val); + setValueStringReference(-1); + } + public void setValueAsColorARGB8(int val){ + setValueType(ValueType.INT_COLOR_ARGB8); + setRawValue(val); + setValueStringReference(-1); + } + + private String getCompareName(){ + int id=getNameResourceID(); + StringBuilder builder=new StringBuilder(); + if(id!=0){ + builder.append("0 "); + builder.append(String.format("%08x", id)); + }else { + builder.append("1 "); + builder.append(getName()); + } + return builder.toString(); + } + @Override + public int compareTo(ResXmlAttribute other) { + return getCompareName().compareTo(other.getCompareName()); + } @Override public String toString(){ diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlElement.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlElement.java index 4f369da..9ec14f6 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlElement.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlElement.java @@ -40,25 +40,30 @@ public class ResXmlElement extends FixedBlockContainer { addChild(5, mEndNamespaceList); } @Override - protected void refreshChildes(){ - List elementList = listElements(); - for (ResXmlElement element:elementList){ - element.refresh(); + protected void onPreRefreshRefresh(){ + ResXmlStartElement start = getStartElement(); + if(start==null){ + return; } - super.refreshChildes(); + start.getResXmlAttributeArray().sortAttributes(); } public ResXmlElement createChildElement(String tag){ ResXmlElement resXmlElement=new ResXmlElement(); ResXmlStartElement startElement=new ResXmlStartElement(); resXmlElement.setStartElement(startElement); + ResXmlEndElement endElement=new ResXmlEndElement(); + startElement.setResXmlEndElement(endElement); + resXmlElement.setEndElement(endElement); + endElement.setResXmlStartElement(startElement); + addElement(resXmlElement); + resXmlElement.setTag(tag); int lineNo=getStartElement().getLineNumber()+1; startElement.setLineNumber(lineNo); endElement.setLineNumber(lineNo); - endElement.setStringReference(startElement.getStringReference()); return resXmlElement; } public ResXmlAttribute createAndroidAttribute(String name, int resourceId){ @@ -230,24 +235,21 @@ public class ResXmlElement extends FixedBlockContainer { return null; } public ResXmlStartNamespace getOrCreateNamespace(String uri, String prefix){ - ResXmlStartNamespace namespace=getStartNamespaceByUri(uri); - if(namespace!=null){ - return namespace; + ResXmlStartNamespace exist=getStartNamespaceByUri(uri); + if(exist!=null){ + return exist; } - ResXmlStartElement startElement = getStartElement(); - ResXmlString uriString = startElement.getOrCreateString(uri); - ResXmlString prefixString = startElement.getOrCreateString(prefix); - namespace=new ResXmlStartNamespace(); - addStartNamespace(namespace); - namespace.setUriReference(uriString.getIndex()); - namespace.setPrefixReference(prefixString.getIndex()); + ResXmlStartNamespace startNamespace=new ResXmlStartNamespace(); ResXmlEndNamespace endNamespace=new ResXmlEndNamespace(); + startNamespace.setEnd(endNamespace); + + addStartNamespace(startNamespace); addEndNamespace(endNamespace); - endNamespace.setUriReference(uriString.getIndex()); - endNamespace.setPrefixReference(prefixString.getIndex()); - namespace.setResXmlEndNamespace(endNamespace); - endNamespace.setResXmlStartNamespace(namespace); - return namespace; + + startNamespace.setUri(uri); + startNamespace.setPrefix(prefix); + + return startNamespace; } public ResXmlStartNamespace getStartNamespaceByUri(String uri){ if(uri==null){ @@ -354,8 +356,7 @@ public class ResXmlElement extends FixedBlockContainer { for(int i=0;i{ public ResXmlEndNamespace() { - super(ChunkType.XML_END_NAMESPACE, 0); + super(ChunkType.XML_END_NAMESPACE); } - - public void setResXmlStartNamespace(ResXmlStartNamespace ns){ - mResXmlStartNamespace=ns; + public ResXmlStartNamespace getStart(){ + return getPair(); } - public ResXmlStartNamespace getResXmlStartNamespace(){ - return mResXmlStartNamespace; - } - - - @Override - public String getUri(){ - return getString(getUriReference()); - } - public String getPrefix(){ - return getString(getPrefixReference()); - } - public int getUriReference(){ - return getStringReference(); - } - public void setUriReference(int ref){ - setStringReference(ref); - if(mResXmlStartNamespace!=null){ - mResXmlStartNamespace.setStringReference(ref); - } - } - public int getPrefixReference(){ - return getNamespaceReference(); - } - public void setPrefixReference(int ref){ - setNamespaceReference(ref); - if(mResXmlStartNamespace!=null){ - mResXmlStartNamespace.setNamespaceReference(ref); - } - } - - @Override - public String toString(){ - String uri=getUri(); - if(uri==null){ - return super.toString(); - } - return "xmlns:"+getPrefix()+"=\""+getUri()+"\""; + public void setStart(ResXmlStartNamespace namespace){ + setPair(namespace); } } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlNamespace.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlNamespace.java new file mode 100644 index 0000000..2dddcd8 --- /dev/null +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlNamespace.java @@ -0,0 +1,72 @@ +package com.reandroid.lib.arsc.chunk.xml; + +import com.reandroid.lib.arsc.chunk.ChunkType; +import com.reandroid.lib.arsc.item.ResXmlString; + +abstract class ResXmlNamespace extends BaseXmlChunk{ + private PAIR mPair; + ResXmlNamespace(ChunkType chunkType) { + super(chunkType, 0); + } + @Override + public String getUri(){ + return getString(getUriReference()); + } + public void setUri(String uri){ + ResXmlString xmlString = getOrCreateString(uri); + if(xmlString==null){ + throw new IllegalArgumentException("Null ResXmlString, add to parent element first"); + } + setUriReference(xmlString.getIndex()); + } + public String getPrefix(){ + return getString(getPrefixReference()); + } + public void setPrefix(String prefix){ + ResXmlString xmlString = getOrCreateString(prefix); + if(xmlString==null){ + throw new IllegalArgumentException("Null ResXmlString, add to parent element first"); + } + setPrefixReference(xmlString.getIndex()); + } + public int getUriReference(){ + return getStringReference(); + } + public void setUriReference(int ref){ + setStringReference(ref); + PAIR pair=getPair(); + if(pair!=null && pair.getUriReference()!=ref){ + pair.setUriReference(ref); + } + } + public int getPrefixReference(){ + return getNamespaceReference(); + } + public void setPrefixReference(int ref){ + setNamespaceReference(ref); + PAIR pair=getPair(); + if(pair!=null && pair.getPrefixReference()!=ref){ + pair.setPrefixReference(ref); + } + } + PAIR getPair(){ + return mPair; + } + void setPair(PAIR pair){ + if(pair==this){ + return; + } + this.mPair=pair; + if(pair !=null && pair.getPair()!=this){ + pair.setPair(this); + } + } + @Override + public String toString(){ + String uri=getUri(); + if(uri==null){ + return super.toString(); + } + return "xmlns:"+getPrefix()+"=\""+getUri()+"\""; + } +} diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java index 1fc1cd3..8e4679d 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java @@ -1,10 +1,8 @@ package com.reandroid.lib.arsc.chunk.xml; -import com.reandroid.lib.arsc.base.BlockContainer; import com.reandroid.lib.arsc.chunk.ChunkType; import com.reandroid.lib.arsc.array.ResXmlAttributeArray; import com.reandroid.lib.arsc.item.IntegerItem; -import com.reandroid.lib.arsc.item.ResXmlString; import com.reandroid.lib.arsc.item.ShortItem; import java.util.Collection; @@ -65,6 +63,10 @@ public class ResXmlStartElement extends BaseXmlChunk { } public void setName(String name){ setString(name); + ResXmlEndElement endElement = getResXmlEndElement(); + if(endElement!=null){ + endElement.setString(name); + } } public Collection listResXmlAttributes(){ return getResXmlAttributeArray().listItems(); diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartNamespace.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartNamespace.java index 7201c05..6a33f65 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartNamespace.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartNamespace.java @@ -2,50 +2,14 @@ package com.reandroid.lib.arsc.chunk.xml; import com.reandroid.lib.arsc.chunk.ChunkType; -public class ResXmlStartNamespace extends BaseXmlChunk { - private ResXmlEndNamespace mResXmlEndNamespace; +public class ResXmlStartNamespace extends ResXmlNamespace { public ResXmlStartNamespace() { - super(ChunkType.XML_START_NAMESPACE, 0); + super(ChunkType.XML_START_NAMESPACE); } - public void setResXmlEndNamespace(ResXmlEndNamespace ns){ - mResXmlEndNamespace=ns; + public ResXmlEndNamespace getEnd(){ + return getPair(); } - - @Override - public String getUri(){ - return getString(getUriReference()); - } - public String getPrefix(){ - return getString(getPrefixReference()); - } - public int getUriReference(){ - return getStringReference(); - } - public void setUriReference(int ref){ - setStringReference(ref); - if(mResXmlEndNamespace!=null){ - mResXmlEndNamespace.setStringReference(ref); - } - } - public int getPrefixReference(){ - return getNamespaceReference(); - } - public void setPrefixReference(int ref){ - setNamespaceReference(ref); - if(mResXmlEndNamespace!=null){ - mResXmlEndNamespace.setNamespaceReference(ref); - } - } - - public ResXmlEndNamespace getResXmlEndNamespace(){ - return mResXmlEndNamespace; - } - @Override - public String toString(){ - String uri=getUri(); - if(uri==null){ - return super.toString(); - } - return "xmlns:"+getPrefix()+"=\""+getUri()+"\""; + public void setEnd(ResXmlEndNamespace namespace){ + setPair(namespace); } } diff --git a/src/main/java/com/reandroid/lib/arsc/container/BlockList.java b/src/main/java/com/reandroid/lib/arsc/container/BlockList.java index bc9496f..30a5bba 100755 --- a/src/main/java/com/reandroid/lib/arsc/container/BlockList.java +++ b/src/main/java/com/reandroid/lib/arsc/container/BlockList.java @@ -1,6 +1,7 @@ package com.reandroid.lib.arsc.container; import com.reandroid.lib.arsc.base.Block; +import com.reandroid.lib.arsc.base.BlockContainer; import com.reandroid.lib.arsc.base.BlockCounter; import com.reandroid.lib.arsc.io.BlockReader; @@ -15,6 +16,9 @@ public class BlockList extends Block { super(); mItems=new ArrayList<>(); } + public void remove(T item){ + mItems.remove(item); + } public void add(T item){ if(item==null){ return; @@ -32,7 +36,24 @@ public class BlockList extends Block { public List getChildes(){ return mItems; } - + public final void refresh(){ + if(isNull()){ + return; + } + refreshChildes(); + } + private void refreshChildes(){ + for(T item:getChildes()){ + if(item instanceof BlockContainer){ + BlockContainer container=(BlockContainer)item; + container.refresh(); + } + if(item instanceof BlockList){ + BlockList blockList=(BlockList)item; + blockList.refresh(); + } + } + } @Override public byte[] getBytes() { byte[] results=null; diff --git a/src/main/java/com/reandroid/lib/arsc/item/ByteArray.java b/src/main/java/com/reandroid/lib/arsc/item/ByteArray.java index 6aca56c..09919b8 100755 --- a/src/main/java/com/reandroid/lib/arsc/item/ByteArray.java +++ b/src/main/java/com/reandroid/lib/arsc/item/ByteArray.java @@ -28,6 +28,29 @@ public class ByteArray extends BlockItem { public final void set(byte[] values){ super.setBytesInternal(values); } + public final void setInt(short val){ + byte[] bts = getBytesInternal(); + bts[3]= (byte) (val >>> 24 & 0xff); + bts[2]= (byte) (val >>> 16 & 0xff); + bts[1]= (byte) (val >>> 8 & 0xff); + bts[0]= (byte) (val & 0xff); + } + public final void setShort(short val){ + byte[] bts = getBytesInternal(); + bts[1]= (byte) (val >>> 8 & 0xff); + bts[0]= (byte) (val & 0xff); + } + public final short getShort(){ + byte[] bts = getBytesInternal(); + return (short) (bts[0] & 0xff | (bts[1] & 0xff) << 8); + } + public final int getInt(){ + byte[] bts = getBytesInternal(); + return bts[0] & 0xff | + (bts[1] & 0xff) << 8 | + (bts[2] & 0xff) << 16 | + (bts[3] & 0xff) << 24; + } public final List toList(){ List results=new AbstractList() { @Override @@ -88,4 +111,8 @@ public class ByteArray extends BlockItem { public void onBytesChanged() { } + @Override + public String toString(){ + return "size="+size(); + } } diff --git a/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java b/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java index 2e37f20..11a8d68 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java +++ b/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java @@ -30,16 +30,16 @@ public class ResConfig extends BlockArray implements BlockLoad { private final ShortItem screenHeight; private final ShortItem sdkVersion; private final ShortItem minorVersion; - private final ByteItem screenLayout; - private final ByteItem uiMode; - private final ShortItem smallestScreenWidthDp; - private final ShortItem screenWidthDp; - private final ShortItem screenHeightDp; + private final ByteArray screenLayout; + private final ByteArray uiMode; + private final ByteArray smallestScreenWidthDp; + private final ByteArray screenWidthDp; + private final ByteArray screenHeightDp; private final ByteArray localeScript; private final ByteArray localeVariant; - private final ByteItem screenLayout2; - private final ByteItem colorMode; - private final ShortItem reservedPadding; + private final ByteArray screenLayout2; + private final ByteArray colorMode; + private final ByteArray reservedPadding; private final ByteArray skipSizeGreater56; private final ByteArray exceedingSize; private final ByteArray remainingSize; @@ -52,35 +52,36 @@ public class ResConfig extends BlockArray implements BlockLoad { public ResConfig(){ super(); - this.configSize = new IntegerItem(64); - this.mcc = new ShortItem(); - this.mnc = new ShortItem(); - this.languageIn0 = new ByteItem(); - this.languageIn1 = new ByteItem(); - this.countryIn0 = new ByteItem(); - this.countryIn1 = new ByteItem(); - this.orientation = new ByteItem(); - this.touchscreen = new ByteItem(); - this.density = new ShortItem(); - this.keyboard = new ByteItem(); - this.navigation = new ByteItem(); - this.inputFlags = new ByteItem(); - this.inputPad0 = new ByteItem(); - this.screenWidth = new ShortItem(); - this.screenHeight = new ShortItem(); - this.sdkVersion = new ShortItem(); - this.minorVersion = new ShortItem(); - this.screenLayout = new ByteItem(); - this.uiMode = new ByteItem(); - this.smallestScreenWidthDp = new ShortItem(); - this.screenWidthDp = new ShortItem(); - this.screenHeightDp = new ShortItem(); + this.configSize = new IntegerItem(64);//4 + this.mcc = new ShortItem();//6 + this.mnc = new ShortItem();//8 + this.languageIn0 = new ByteItem();//9 + this.languageIn1 = new ByteItem();//10 + this.countryIn0 = new ByteItem();//11 + this.countryIn1 = new ByteItem();//12 + this.orientation = new ByteItem();//13 + this.touchscreen = new ByteItem();//14 + this.density = new ShortItem();//16 + this.keyboard = new ByteItem();//17 + this.navigation = new ByteItem();//18 + this.inputFlags = new ByteItem();//19 + this.inputPad0 = new ByteItem();//20 + this.screenWidth = new ShortItem();//22 + this.screenHeight = new ShortItem();//24 + this.sdkVersion = new ShortItem();//26 + this.minorVersion = new ShortItem();//28 + //28 + this.screenLayout = new ByteArray();//29 + this.uiMode = new ByteArray();//30 + this.smallestScreenWidthDp = new ByteArray();//32 + this.screenWidthDp = new ByteArray();//34 + this.screenHeightDp = new ByteArray();//36 // size sum=44; this.localeScript = new ByteArray(4); this.localeVariant = new ByteArray(8); - this.screenLayout2 = new ByteItem(); - this.colorMode = new ByteItem(); - this.reservedPadding = new ShortItem(); + this.screenLayout2 = new ByteArray(); + this.colorMode = new ByteArray(); + this.reservedPadding = new ByteArray(); this.skipSizeGreater56 = new ByteArray(4); this.exceedingSize = new ByteArray(8); this.remainingSize = new ByteArray(); @@ -164,16 +165,16 @@ public class ResConfig extends BlockArray implements BlockLoad { screenHeight.set((short) 0); sdkVersion.set((short) 0); minorVersion.set((short) 0); - screenLayout.set((byte)0); - uiMode.set((byte)0); - smallestScreenWidthDp.set((byte)0); - screenWidthDp.set((byte)0); - screenHeightDp.set((byte)0); + screenLayout.setSize(0); + uiMode.setSize((byte)0); + smallestScreenWidthDp.setSize((byte)0); + screenWidthDp.setSize((byte)0); + screenHeightDp.setSize((byte)0); localeScript.clear(); localeVariant.clear(); - screenLayout2.set((byte)0); - colorMode.set((byte)0); - reservedPadding.set((short) 0); + screenLayout2.setSize(0); + colorMode.setSize(0); + reservedPadding.setSize( 0); skipSizeGreater56.clear(); exceedingSize.clear(); remainingSize.clear(); @@ -344,34 +345,64 @@ public class ResConfig extends BlockArray implements BlockLoad { return this.minorVersion.get(); } public void setScreenLayout(byte b){ - this.screenLayout.set(b); + if(screenLayout.size()==0){ + return; + } + this.screenLayout.put(0,b); } public byte getScreenLayout(){ - return this.screenLayout.get(); + if(screenLayout.size()==0){ + return 0; + } + return this.screenLayout.get(0); } public void setUiMode(byte b){ - this.uiMode.set(b); + if(uiMode.size()==0){ + return; + } + this.uiMode.put(0, b); } public byte getUiMode(){ - return this.uiMode.get(); + if(uiMode.size()==0){ + return 0; + } + return this.uiMode.get(0); } public void setSmallestScreenWidthDp(short sh){ - this.smallestScreenWidthDp.set(sh); + if(smallestScreenWidthDp.size()==0){ + return; + } + this.smallestScreenWidthDp.setShort(sh); } public short getSmallestScreenWidthDp(){ - return this.smallestScreenWidthDp.get(); + if(this.smallestScreenWidthDp.size()==0){ + return 0; + } + return smallestScreenWidthDp.getShort(); } public void setScreenWidthDp(short sh){ - this.screenWidthDp.set(sh); + if(screenWidthDp.size()==0){ + return; + } + this.screenWidthDp.setShort(sh); } public short getScreenWidthDp(){ - return this.screenWidthDp.get(); + if(screenWidthDp.size()==0){ + return 0; + } + return screenWidthDp.getShort(); } public void setScreenHeightDp(short sh){ - this.screenHeightDp.set(sh); + if(screenHeightDp.size()==0){ + return; + } + this.screenHeightDp.setShort(sh); } public short getScreenHeightDp(){ - return this.screenHeightDp.get(); + if(screenHeightDp.size()==0){ + return 0; + } + return this.screenHeightDp.getShort(); } public void setLocaleScript(byte[] bts){ this.localeScript.set(bts); @@ -395,22 +426,40 @@ public class ResConfig extends BlockArray implements BlockLoad { return toCharArray(localeVariant.toArray()); } public void setScreenLayout2(byte b){ - this.screenLayout2.set(b); + if(screenLayout2.size()==0){ + return; + } + this.screenLayout2.put(0,b); } public byte getScreenLayout2(){ - return this.screenLayout2.get(); + if(screenLayout2.size()==0){ + return 0; + } + return this.screenLayout2.get(0); } public void setColorMode(byte b){ - this.colorMode.set(b); + if(colorMode.size()==0){ + return; + } + this.colorMode.put(0,b); } public byte getColorMode(){ - return this.colorMode.get(); + if(colorMode.size()==0){ + return 0; + } + return this.colorMode.get(0); } public void setReservedPadding(short sh){ - this.reservedPadding.set(sh); + if(reservedPadding.size()==0){ + return; + } + this.reservedPadding.setShort(sh); } public short getReservedPadding(){ - return this.reservedPadding.get(); + if(reservedPadding.size()==0){ + return 0; + } + return this.reservedPadding.get(0); } private void valuesChanged(int val, int old){ @@ -443,7 +492,19 @@ public class ResConfig extends BlockArray implements BlockLoad { } mIsUpdatingSize=true; mCurrentSize=sz; + localeScript.setSize(0); + skipSizeGreater56.setSize(0); + localeVariant.setSize(0); + exceedingSize.setSize(0); + if(sz==28){ + mIsUpdatingSize=false; + return; + } localeScript.setSize(4); + if(sz==32){ + mIsUpdatingSize=false; + return; + } if(sz<=48){ localeVariant.setSize(4); exceedingSize.setSize(0); @@ -481,13 +542,9 @@ public class ResConfig extends BlockArray implements BlockLoad { @Override public void onBlockLoaded(BlockReader reader, Block sender) throws IOException { if(sender==configSize){ - if(configSize.get()!=64){ - configSize.get(); - } setConfigSize(configSize.get()); } } - public boolean isEqualQualifiers(String qualifiers){ if(qualifiers==null){ qualifiers="";