diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/BaseTypeBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/BaseTypeBlock.java deleted file mode 100755 index 0729df1..0000000 --- a/src/main/java/com/reandroid/lib/arsc/chunk/BaseTypeBlock.java +++ /dev/null @@ -1,153 +0,0 @@ - /* - * Copyright (C) 2022 github.com/REAndroid - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.reandroid.lib.arsc.chunk; - -import com.reandroid.lib.arsc.base.Block; -import com.reandroid.lib.arsc.container.SpecTypePair; -import com.reandroid.lib.arsc.item.ByteItem; -import com.reandroid.lib.arsc.item.IntegerItem; -import com.reandroid.lib.arsc.item.TypeString; -import com.reandroid.lib.arsc.pool.TypeStringPool; - -abstract class BaseTypeBlock extends BaseChunk { - private final ByteItem mTypeId; - private final ByteItem mTypeFlags; - private final ByteItem mReserved1; - private final ByteItem mReserved2; - private final IntegerItem mEntryCount; - private TypeString mTypeString; - BaseTypeBlock(ChunkType chunkType, int initialChildesCount) { - super(chunkType, initialChildesCount); - this.mTypeId=new ByteItem(); - this.mTypeFlags=new ByteItem(); - this.mReserved1=new ByteItem(); - this.mReserved2=new ByteItem(); - this.mEntryCount=new IntegerItem(); - addToHeader(mTypeId); - addToHeader(mTypeFlags); - addToHeader(mReserved1); - addToHeader(mReserved2); - addToHeader(mEntryCount); - } - public byte getTypeId(){ - return mTypeId.get(); - } - public int getTypeIdInt(){ - return (0xff & mTypeId.get()); - } - public void setTypeId(int id){ - setTypeId((byte) (0xff & id)); - } - public void setTypeId(byte id){ - mTypeId.set(id); - } - public void setTypeName(String name){ - TypeStringPool typeStringPool=getTypeStringPool(); - int id=getTypeIdInt(); - TypeString typeString=typeStringPool.getById(id); - if(typeString==null){ - typeString=typeStringPool.getOrCreate(id, name); - } - typeString.set(name); - } - public void setEntryCount(int count){ - if(count == mEntryCount.get()){ - return; - } - mEntryCount.set(count); - onSetEntryCount(count); - } - public int getEntryCount(){ - return mEntryCount.get(); - } - public PackageBlock getPackageBlock(){ - Block parent=getParent(); - while (parent!=null){ - if(parent instanceof SpecTypePair){ - return ((SpecTypePair)parent).getPackageBlock(); - } - parent=parent.getParent(); - } - return null; - } - public String getTypeName(){ - TypeString typeString=getTypeString(); - if(typeString==null){ - return null; - } - return typeString.get(); - } - public TypeString getTypeString(){ - if(mTypeString!=null){ - if(mTypeString.getId()==getTypeId()){ - return mTypeString; - } - mTypeString=null; - } - PackageBlock packageBlock=getPackageBlock(); - if(packageBlock==null){ - return null; - } - TypeStringPool typeStringPool=packageBlock.getTypeStringPool(); - mTypeString=typeStringPool.getById(getTypeIdInt()); - return mTypeString; - } - SpecTypePair getSpecTypePair(){ - Block parent=getParent(); - while (parent!=null){ - if(parent instanceof SpecTypePair){ - return (SpecTypePair)parent; - } - parent=parent.getParent(); - } - return null; - } - abstract void onSetEntryCount(int count); - IntegerItem getEntryCountBlock(){ - return mEntryCount; - } - private TypeStringPool getTypeStringPool(){ - PackageBlock packageBlock=getPackageBlock(); - if(packageBlock!=null){ - return packageBlock.getTypeStringPool(); - } - return null; - } - @Override - public String toString(){ - StringBuilder builder=new StringBuilder(); - builder.append(getClass().getSimpleName()); - builder.append(": "); - PackageBlock packageBlock=getPackageBlock(); - if(packageBlock!=null){ - builder.append("PKG="); - builder.append(String.format("0x%02x", packageBlock.getId())); - builder.append(" "); - } - builder.append(getHeaderBlock().toString()); - builder.append(" entries="); - builder.append(getEntryCount()); - builder.append(", id="); - builder.append(String.format("0x%02x", getTypeId())); - TypeString typeString=getTypeString(); - if(typeString!=null){ - builder.append('('); - builder.append(typeString.get()); - builder.append(')'); - } - return builder.toString(); - } -} diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/SpecBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/SpecBlock.java index ed5a94a..0e17f3d 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/SpecBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/SpecBlock.java @@ -13,71 +13,101 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.reandroid.lib.arsc.chunk; + package com.reandroid.lib.arsc.chunk; -import com.reandroid.lib.arsc.array.TypeBlockArray; -import com.reandroid.lib.arsc.base.Block; -import com.reandroid.lib.arsc.container.SpecTypePair; -import com.reandroid.lib.arsc.io.BlockLoad; -import com.reandroid.lib.arsc.io.BlockReader; -import com.reandroid.lib.arsc.item.IntegerArray; -import com.reandroid.lib.arsc.item.IntegerItem; -import com.reandroid.lib.json.JSONConvert; -import com.reandroid.lib.json.JSONObject; + import com.reandroid.lib.arsc.array.TypeBlockArray; + import com.reandroid.lib.arsc.base.Block; + import com.reandroid.lib.arsc.container.SpecTypePair; + import com.reandroid.lib.arsc.item.*; + import com.reandroid.lib.json.JSONConvert; + import com.reandroid.lib.json.JSONObject; -import java.io.IOException; + import java.util.List; -public class SpecBlock extends BaseTypeBlock implements BlockLoad , JSONConvert { - private final IntegerArray mOffsets; - public SpecBlock() { - super(ChunkType.SPEC, 1); - this.mOffsets=new IntegerArray(); - addChild(mOffsets); + public class SpecBlock extends BaseChunk implements JSONConvert { + private final SpecFlagsArray specFlagsArray; + private final ByteItem mTypeId; + public SpecBlock() { + super(ChunkType.SPEC, 1); + this.mTypeId=new ByteItem(); + ByteItem res0 = new ByteItem(); + ShortItem res1 = new ShortItem(); + IntegerItem entryCount = new IntegerItem(); + this.specFlagsArray = new SpecFlagsArray(entryCount); + addToHeader(mTypeId); + addToHeader(res0); + addToHeader(res1); + addToHeader(entryCount); - getEntryCountBlock().setBlockLoad(this); - } - public TypeBlockArray getTypeBlockArray(){ - SpecTypePair specTypePair=getSpecTypePair(); - if(specTypePair!=null){ - return specTypePair.getTypeBlockArray(); - } - return null; - } - @Override - void onSetEntryCount(int count) { - mOffsets.setSize(count); - } - @Override - protected void onChunkRefreshed() { - } - @Override - public void onBlockLoaded(BlockReader reader, Block sender) throws IOException { - IntegerItem entryCount=getEntryCountBlock(); - if(sender==entryCount){ - mOffsets.setSize(entryCount.get()); - } - } - @Override - public String toString(){ - StringBuilder builder=new StringBuilder(); - builder.append(super.toString()); - TypeBlockArray typeBlockArray=getTypeBlockArray(); - if(typeBlockArray!=null){ - builder.append(", typesCount="); - builder.append(typeBlockArray.childesCount()); - } - return builder.toString(); - } + addChild(specFlagsArray); + } + public SpecFlagsArray getSpecFlagsArray(){ + return specFlagsArray; + } + public List listSpecFlags(){ + return specFlagsArray.toList(); + } + public byte getTypeId(){ + return mTypeId.get(); + } + public int getTypeIdInt(){ + return (0xff & mTypeId.get()); + } + public void setTypeId(int id){ + setTypeId((byte) (0xff & id)); + } + public void setTypeId(byte id){ + mTypeId.set(id); + } + public TypeBlockArray getTypeBlockArray(){ + SpecTypePair specTypePair=getSpecTypePair(); + if(specTypePair!=null){ + return specTypePair.getTypeBlockArray(); + } + return null; + } + SpecTypePair getSpecTypePair(){ + Block parent=getParent(); + while (parent!=null){ + if(parent instanceof SpecTypePair){ + return (SpecTypePair)parent; + } + parent=parent.getParent(); + } + return null; + } + public int getEntryCount() { + return specFlagsArray.size(); + } + public void setEntryCount(int count){ + specFlagsArray.setSize(count); + specFlagsArray.refresh(); + } + @Override + protected void onChunkRefreshed() { + specFlagsArray.refresh(); + } + @Override + public String toString(){ + StringBuilder builder=new StringBuilder(); + builder.append(super.toString()); + TypeBlockArray typeBlockArray=getTypeBlockArray(); + if(typeBlockArray!=null){ + builder.append(", typesCount="); + builder.append(typeBlockArray.childesCount()); + } + return builder.toString(); + } - @Override - public JSONObject toJson() { - JSONObject jsonObject=new JSONObject(); - jsonObject.put(TypeBlock.NAME_id, getTypeIdInt()); - return jsonObject; - } + @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put(TypeBlock.NAME_id, getTypeIdInt()); + return jsonObject; + } - @Override - public void fromJson(JSONObject json) { - setTypeId(json.getInt(TypeBlock.NAME_id)); - } -} + @Override + public void fromJson(JSONObject json) { + setTypeId(json.getInt(TypeBlock.NAME_id)); + } + } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java index 499853a..30f850e 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java @@ -19,9 +19,10 @@ import com.reandroid.lib.arsc.array.EntryBlockArray; import com.reandroid.lib.arsc.array.TypeBlockArray; import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.container.SpecTypePair; -import com.reandroid.lib.arsc.item.IntegerArray; -import com.reandroid.lib.arsc.item.IntegerItem; -import com.reandroid.lib.arsc.item.TypeString; +import com.reandroid.lib.arsc.io.BlockLoad; +import com.reandroid.lib.arsc.io.BlockReader; +import com.reandroid.lib.arsc.item.*; +import com.reandroid.lib.arsc.pool.TypeStringPool; import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.ResConfig; import com.reandroid.lib.json.JSONConvert; @@ -33,25 +34,105 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -public class TypeBlock extends BaseTypeBlock - implements JSONConvert, Comparable { - private final IntegerItem mEntriesStart; +public class TypeBlock extends BaseChunk + implements BlockLoad, JSONConvert, Comparable { + private final ByteItem mTypeId; + private final ByteItem mTypeFlags; + private final IntegerItem mEntryCount; private final ResConfig mResConfig; - private final IntegerArray mEntryOffsets; private final EntryBlockArray mEntryArray; + private TypeString mTypeString; public TypeBlock() { super(ChunkType.TYPE, 2); - this.mEntriesStart=new IntegerItem(); - this.mResConfig =new ResConfig(); - this.mEntryOffsets=new IntegerArray(); - this.mEntryArray=new EntryBlockArray(mEntryOffsets, getEntryCountBlock(), mEntriesStart); + this.mTypeId=new ByteItem(); + this.mTypeFlags=new ByteItem(); + ShortItem reserved = new ShortItem(); + this.mEntryCount=new IntegerItem(); - addToHeader(mEntriesStart); + IntegerItem entriesStart = new IntegerItem(); + this.mResConfig =new ResConfig(); + IntegerArray entryOffsets = new IntegerArray(); + this.mEntryArray = new EntryBlockArray(entryOffsets, mEntryCount, entriesStart); + + mTypeFlags.setBlockLoad(this); + + addToHeader(mTypeId); + addToHeader(mTypeFlags); + addToHeader(reserved); + addToHeader(mEntryCount); + addToHeader(entriesStart); addToHeader(mResConfig); - addChild(mEntryOffsets); + addChild(entryOffsets); addChild(mEntryArray); } + public PackageBlock getPackageBlock(){ + Block parent=getParent(); + while (parent!=null){ + if(parent instanceof SpecTypePair){ + return ((SpecTypePair)parent).getPackageBlock(); + } + parent=parent.getParent(); + } + return null; + } + public String getTypeName(){ + TypeString typeString=getTypeString(); + if(typeString==null){ + return null; + } + return typeString.get(); + } + public TypeString getTypeString(){ + if(mTypeString!=null){ + if(mTypeString.getId()==getTypeId()){ + return mTypeString; + } + mTypeString=null; + } + PackageBlock packageBlock=getPackageBlock(); + if(packageBlock==null){ + return null; + } + TypeStringPool typeStringPool=packageBlock.getTypeStringPool(); + mTypeString=typeStringPool.getById(getTypeIdInt()); + return mTypeString; + } + public byte getTypeId(){ + return mTypeId.get(); + } + public int getTypeIdInt(){ + return (0xff & mTypeId.get()); + } + public void setTypeId(int id){ + setTypeId((byte) (0xff & id)); + } + public void setTypeId(byte id){ + mTypeId.set(id); + } + public void setTypeName(String name){ + TypeStringPool typeStringPool=getTypeStringPool(); + int id=getTypeIdInt(); + TypeString typeString=typeStringPool.getById(id); + if(typeString==null){ + typeString=typeStringPool.getOrCreate(id, name); + } + typeString.set(name); + } + private TypeStringPool getTypeStringPool(){ + PackageBlock packageBlock=getPackageBlock(); + if(packageBlock!=null){ + return packageBlock.getTypeStringPool(); + } + return null; + } + public void setEntryCount(int count){ + if(count == mEntryCount.get()){ + return; + } + mEntryCount.set(count); + onSetEntryCount(count); + } public boolean isEmpty(){ return getEntryBlockArray().isEmpty(); } @@ -121,8 +202,8 @@ public class TypeBlock extends BaseTypeBlock public EntryBlock getEntryBlock(int entryId){ return getEntryBlockArray().get(entryId); } - @Override - void onSetEntryCount(int count) { + + private void onSetEntryCount(int count) { getEntryBlockArray().setChildesCount(count); } @Override @@ -198,6 +279,14 @@ public class TypeBlock extends BaseTypeBlock return getEntryBlockArray().searchByEntryName(entryName); } @Override + public void onBlockLoaded(BlockReader reader, Block sender) throws IOException { + if(sender==mTypeFlags){ + if(mTypeFlags.get()==0x1){ + //ResTable_sparseTypeEntry ? + } + } + } + @Override public String toString(){ StringBuilder builder=new StringBuilder(); builder.append(getResConfig().toString()); diff --git a/src/main/java/com/reandroid/lib/arsc/item/SpecFlagsArray.java b/src/main/java/com/reandroid/lib/arsc/item/SpecFlagsArray.java new file mode 100644 index 0000000..3d56031 --- /dev/null +++ b/src/main/java/com/reandroid/lib/arsc/item/SpecFlagsArray.java @@ -0,0 +1,52 @@ + /* + * Copyright (C) 2022 github.com/REAndroid + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.reandroid.lib.arsc.item; + +import com.reandroid.lib.arsc.base.Block; +import com.reandroid.lib.arsc.io.BlockLoad; +import com.reandroid.lib.arsc.io.BlockReader; + +import java.io.IOException; + +public class SpecFlagsArray extends IntegerArray implements BlockLoad { + private final IntegerItem entryCount; + public SpecFlagsArray(IntegerItem entryCount) { + super(); + this.entryCount = entryCount; + this.entryCount.setBlockLoad(this); + setBlockLoad(this); + } + public void set(int entryId, int value){ + entryId = 0xffff & entryId; + ensureArraySize(entryId); + super.put(entryId, value); + refresh(); + } + @Override + public Integer get(int entryId){ + entryId = 0xffff & entryId; + return super.get(entryId); + } + @Override + public void onBlockLoaded(BlockReader reader, Block sender) throws IOException { + if(sender==this.entryCount){ + super.setSize(entryCount.get()); + } + } + public void refresh(){ + entryCount.set(size()); + } +}