diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8a91a6b..dd8d4fc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-6.5.1-all.zip +distributionUrl=file:///home/d/services.gradle.org/distributions/gradle-6.5.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/LibraryBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/LibraryBlock.java index 52ee1c1..5d97241 100644 --- a/src/main/java/com/reandroid/lib/arsc/chunk/LibraryBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/LibraryBlock.java @@ -4,6 +4,8 @@ import com.reandroid.lib.arsc.array.LibraryInfoArray; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.value.LibraryInfo; +import java.util.List; + public class LibraryBlock extends BaseChunk { private final IntegerItem mLibCount; private final LibraryInfoArray mLibraryInfoArray; @@ -37,6 +39,9 @@ public class LibraryBlock extends BaseChunk { mLibraryInfoArray.add(info); mLibCount.set(mLibraryInfoArray.childesCount()); } + public List listLibraryInfo(){ + return mLibraryInfoArray.listItems(); + } @Override public boolean isNull(){ return mLibraryInfoArray.childesCount()==0; diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java index d08697f..3626424 100644 --- a/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java @@ -3,12 +3,18 @@ package com.reandroid.lib.arsc.chunk; import com.reandroid.lib.arsc.array.SpecTypePairArray; import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.container.PackageLastBlocks; +import com.reandroid.lib.arsc.container.SpecTypePair; +import com.reandroid.lib.arsc.group.EntryGroup; +import com.reandroid.lib.arsc.group.ItemGroup; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.PackageName; import com.reandroid.lib.arsc.pool.SpecStringPool; import com.reandroid.lib.arsc.pool.TypeStringPool; +import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.LibraryInfo; +import java.util.*; + public class PackageBlock extends BaseChunk { private final IntegerItem mPackageId; @@ -28,6 +34,8 @@ public class PackageBlock extends BaseChunk { private final PackageLastBlocks mPackageLastBlocks; + private final Map mEntriesGroup; + public PackageBlock() { super(ChunkType.PACKAGE, 3); this.mPackageId=new IntegerItem(); @@ -45,6 +53,8 @@ public class PackageBlock extends BaseChunk { this.mLibraryBlock=new LibraryBlock(); this.mPackageLastBlocks=new PackageLastBlocks(mSpecTypePairArray, mLibraryBlock); + this.mEntriesGroup=new HashMap<>(); + addToHeader(mPackageId); addToHeader(mPackageName); addToHeader(mTypeStrings); @@ -83,12 +93,57 @@ public class PackageBlock extends BaseChunk { } return null; } + public int getPackageId(){ + return mPackageId.get(); + } + public int setPackageId(){ + return mPackageId.get(); + } + public String getPackageName(){ + return mPackageName.get(); + } + public void setPackageName(String name){ + mPackageName.set(name); + } + public void setTypeStrings(int i){ + mTypeStrings.set(i); + } + public int getLastPublicType(){ + return mLastPublicType.get(); + } + public void setLastPublicType(int i){ + mLastPublicType.set(i); + } + public int getKeyStrings(){ + return mKeyStrings.get(); + } + public void setKeyStrings(int i){ + mKeyStrings.set(i); + } + public int getLastPublicKey(){ + return mLastPublicKey.get(); + } + public void setLastPublicKey(int i){ + mLastPublicKey.set(i); + } + public int getTypeIdOffset(){ + return mTypeIdOffset.get(); + } + public void setTypeIdOffset(int i){ + mTypeIdOffset.set(i); + } public TypeStringPool getTypeStringPool(){ return mTypeStringPool; } public SpecStringPool getSpecStringPool(){ return mSpecStringPool; } + public SpecTypePairArray getSpecTypePairArray(){ + return mSpecTypePairArray; + } + public List listLibraryInfo(){ + return mLibraryBlock.listLibraryInfo(); + } public void addLibrary(LibraryBlock libraryBlock){ if(libraryBlock==null){ @@ -105,11 +160,51 @@ public class PackageBlock extends BaseChunk { public void addLibraryInfo(LibraryInfo info){ mLibraryBlock.addLibraryInfo(info); } + public Set listResourceIds(){ + return mEntriesGroup.keySet(); + } + public Collection listEntryGroup(){ + return mEntriesGroup.values(); + } + public EntryGroup getEntryGroup(int resId){ + return mEntriesGroup.get(resId); + } + private void updateEntryGroup(EntryBlock entryBlock){ + int resId=entryBlock.getResourceId(); + EntryGroup group=mEntriesGroup.get(resId); + if(group==null){ + group=new EntryGroup(resId); + mEntriesGroup.put(resId, group); + } + group.add(entryBlock); + } + public List listEntries(byte typeId, int entryId){ + List results=new ArrayList<>(); + for(SpecTypePair pair:listSpecTypePair(typeId)){ + results.addAll(pair.listEntries(entryId)); + } + return results; + } + public List listSpecTypePair(byte typeId){ + List results=new ArrayList<>(); + for(SpecTypePair pair:listAllSpecTypePair()){ + if(typeId==pair.getTypeId()){ + results.add(pair); + } + } + return results; + } + public List listAllSpecTypePair(){ + return getSpecTypePairArray().listItems(); + } private void refreshKeyStrings(){ int pos=countUpTo(mSpecStringPool); mKeyStrings.set(pos); } + public void onEntryAdded(EntryBlock entryBlock){ + updateEntryGroup(entryBlock); + } @Override public void onChunkLoaded() { } 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 3b27b0d..7e8bb7f 100644 --- a/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java @@ -3,8 +3,12 @@ package com.reandroid.lib.arsc.chunk; import com.reandroid.lib.arsc.array.EntryBlockArray; import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerItem; +import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.ResConfig; +import java.util.ArrayList; +import java.util.List; + public class TypeBlock extends BaseTypeBlock { private final IntegerItem mEntriesStart; private final ResConfig mResConfig; @@ -29,6 +33,24 @@ public class TypeBlock extends BaseTypeBlock { public EntryBlockArray getEntryBlockArray(){ return mEntryArray; } + public List listEntries(){ + return listEntries(false); + } + public List listEntries(boolean includeNull){ + List results=new ArrayList<>(); + for(EntryBlock entryBlock:mEntryArray.listItems()){ + if(!includeNull){ + if(entryBlock.isNull()){ + continue; + } + } + results.add(entryBlock); + } + return results; + } + public EntryBlock getEntryBlock(int entryId){ + return mEntryArray.get(entryId); + } @Override void onSetEntryCount(int count) { mEntryArray.setChildesCount(count); diff --git a/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java b/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java index c91c90e..7c73fbe 100644 --- a/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java +++ b/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java @@ -6,11 +6,14 @@ import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.base.BlockContainer; import com.reandroid.lib.arsc.chunk.PackageBlock; import com.reandroid.lib.arsc.chunk.SpecBlock; +import com.reandroid.lib.arsc.chunk.TypeBlock; import com.reandroid.lib.arsc.header.HeaderBlock; import com.reandroid.lib.arsc.io.BlockReader; +import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.ResConfig; import java.io.IOException; +import java.util.ArrayList; import java.util.List; public class SpecTypePair extends BlockContainer { @@ -55,6 +58,20 @@ public class SpecTypePair extends BlockContainer { } return null; } + public List listEntries(int entryId){ + List results=new ArrayList<>(); + for(TypeBlock typeBlock:listTypeBlocks()){ + EntryBlock entryBlock=typeBlock.getEntryBlock(entryId); + if(entryBlock==null||entryBlock.isNull()){ + continue; + } + results.add(entryBlock); + } + return results; + } + public List listTypeBlocks(){ + return mTypeBlockArray.listItems(); + } @Override protected void onRefreshed() { diff --git a/src/main/java/com/reandroid/lib/arsc/group/EntryGroup.java b/src/main/java/com/reandroid/lib/arsc/group/EntryGroup.java new file mode 100644 index 0000000..b05d633 --- /dev/null +++ b/src/main/java/com/reandroid/lib/arsc/group/EntryGroup.java @@ -0,0 +1,100 @@ +package com.reandroid.lib.arsc.group; + +import com.reandroid.lib.arsc.base.BlockArrayCreator; +import com.reandroid.lib.arsc.chunk.PackageBlock; +import com.reandroid.lib.arsc.chunk.TypeBlock; +import com.reandroid.lib.arsc.item.SpecString; +import com.reandroid.lib.arsc.item.TypeString; +import com.reandroid.lib.arsc.pool.SpecStringPool; +import com.reandroid.lib.arsc.value.EntryBlock; + +public class EntryGroup extends ItemGroup { + private final int resourceId; + public EntryGroup(int resId) { + super(create(), String.format("0x%08x", resId)); + this.resourceId=resId; + } + public int getResourceId(){ + return resourceId; + } + public void renameSpec(String name){ + EntryBlock[] items=getItems(); + if(items==null){ + return; + } + SpecStringPool specStringPool=getSpecStringPool(); + if(specStringPool==null){ + return; + } + SpecString specString=specStringPool.getOrCreate(name); + renameSpec(specString.getIndex()); + } + public void renameSpec(int specReference){ + EntryBlock[] items=getItems(); + if(items==null){ + return; + } + for(EntryBlock block:items){ + if(block==null||block.isNull()){ + continue; + } + block.setSpecReference(specReference); + } + } + public TypeString getTypeString(){ + EntryBlock entryBlock=get(0); + if(entryBlock==null){ + return null; + } + return entryBlock.getTypeString(); + } + public SpecString getSpecString(){ + EntryBlock entryBlock=get(0); + if(entryBlock==null){ + return null; + } + return entryBlock.getSpecString(); + } + public String getTypeName(){ + TypeString typeString=getTypeString(); + if(typeString==null){ + return null; + } + return typeString.get(); + } + public String getSpecName(){ + SpecString specString=getSpecString(); + if(specString==null){ + return null; + } + return specString.get(); + } + private SpecStringPool getSpecStringPool(){ + EntryBlock entryBlock=get(0); + if(entryBlock==null){ + return null; + } + TypeBlock typeBlock=entryBlock.getTypeBlock(); + if(typeBlock==null){ + return null; + } + PackageBlock packageBlock=typeBlock.getPackageBlock(); + if(packageBlock==null){ + return null; + } + return packageBlock.getSpecStringPool(); + } + private static BlockArrayCreator create(){ + return new BlockArrayCreator(){ + @Override + public EntryBlock newInstance() { + return new EntryBlock(); + } + + @Override + public EntryBlock[] newInstance(int len) { + return new EntryBlock[len]; + } + }; + } +} diff --git a/src/main/java/com/reandroid/lib/arsc/pool/StringGroup.java b/src/main/java/com/reandroid/lib/arsc/group/ItemGroup.java similarity index 63% rename from src/main/java/com/reandroid/lib/arsc/pool/StringGroup.java rename to src/main/java/com/reandroid/lib/arsc/group/ItemGroup.java index 51c6115..bd84d56 100644 --- a/src/main/java/com/reandroid/lib/arsc/pool/StringGroup.java +++ b/src/main/java/com/reandroid/lib/arsc/group/ItemGroup.java @@ -1,41 +1,67 @@ -package com.reandroid.lib.arsc.pool; +package com.reandroid.lib.arsc.group; +import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.base.BlockArrayCreator; -import com.reandroid.lib.arsc.item.StringItem; -import java.lang.reflect.Array; +import java.util.AbstractList; +import java.util.List; -public class StringGroup { +public class ItemGroup { private final BlockArrayCreator mBlockArrayCreator; private final String name; private T[] items; private final int hashCode; - StringGroup(BlockArrayCreator blockArrayCreator, String name, T[] items){ + public ItemGroup(BlockArrayCreator blockArrayCreator, String name){ this.mBlockArrayCreator=blockArrayCreator; this.name=name; - this.items=items; + this.items=blockArrayCreator.newInstance(0); this.hashCode=(getClass().getName()+"-"+name).hashCode(); } - public boolean contains(T strItem){ - if(strItem==null){ + public List listItems(){ + return new AbstractList() { + @Override + public T get(int i) { + return ItemGroup.this.get(i); + } + + @Override + public int size() { + return ItemGroup.this.size(); + } + }; + } + public T get(int i){ + if(i<0||i>= size()){ + return null; + } + return items[i]; + } + public int size(){ + if(items==null){ + return 0; + } + return items.length; + } + public boolean contains(T block){ + if(block==null){ return false; } int len=items.length; for(int i=0;i { trimToSize(); } } - public void add(T strItem){ - if(strItem==null){ + public void add(T block){ + if(block==null){ return; } int index=items.length; T[] update=createNew(index+1); System.arraycopy(items, 0, update, 0, index); - update[index]=strItem; + update[index]=block; items=update; } public T[] getItems(){ @@ -94,7 +120,7 @@ public class StringGroup { public boolean equals(Object obj){ if(obj instanceof StringGroup){ StringGroup other=(StringGroup)obj; - return name.equals(other.name); + return hashCode==other.hashCode(); } return false; } diff --git a/src/main/java/com/reandroid/lib/arsc/group/StringGroup.java b/src/main/java/com/reandroid/lib/arsc/group/StringGroup.java new file mode 100644 index 0000000..48e3e14 --- /dev/null +++ b/src/main/java/com/reandroid/lib/arsc/group/StringGroup.java @@ -0,0 +1,10 @@ +package com.reandroid.lib.arsc.group; + +import com.reandroid.lib.arsc.base.BlockArrayCreator; +import com.reandroid.lib.arsc.item.StringItem; + +public class StringGroup extends ItemGroup{ + public StringGroup(BlockArrayCreator blockArrayCreator, String name){ + super(blockArrayCreator, name); + } +} diff --git a/src/main/java/com/reandroid/lib/arsc/pool/BaseStringPool.java b/src/main/java/com/reandroid/lib/arsc/pool/BaseStringPool.java index 34b9db7..e324820 100644 --- a/src/main/java/com/reandroid/lib/arsc/pool/BaseStringPool.java +++ b/src/main/java/com/reandroid/lib/arsc/pool/BaseStringPool.java @@ -5,6 +5,7 @@ import com.reandroid.lib.arsc.array.StringArray; import com.reandroid.lib.arsc.array.StyleArray; import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.chunk.BaseChunk; +import com.reandroid.lib.arsc.group.StringGroup; import com.reandroid.lib.arsc.io.BlockLoad; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.*; @@ -87,8 +88,7 @@ public abstract class BaseStringPool extends BaseChunk imp if(group!=null){ return group; } - T[] items=mArrayStrings.newInstance(0); - group=new StringGroup<>(mArrayStrings, str, items); + group=new StringGroup<>(mArrayStrings, str); mUniqueMap.put(str, group); return group; } diff --git a/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java b/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java index 883260d..0644105 100644 --- a/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java @@ -288,6 +288,17 @@ public class EntryBlock extends Block { return result; } + private void updatePackage(){ + TypeBlock typeBlock=getTypeBlock(); + if(typeBlock==null){ + return; + } + PackageBlock packageBlock=typeBlock.getPackageBlock(); + if(packageBlock==null){ + return; + } + packageBlock.onEntryAdded(this); + } @Override public void onReadBytes(BlockReader reader) throws IOException{ setNull(false); @@ -297,6 +308,7 @@ public class EntryBlock extends Block { mSpecReference.readBytes(reader); createResValue(); mResValue.readBytes(reader); + updatePackage(); } public String toString(){ StringBuilder builder=new StringBuilder();