Initial commit

This commit is contained in:
REAndroid 2021-11-17 02:46:27 +08:00
parent 3fa01a02d5
commit 503b7d6a01
12 changed files with 274 additions and 31 deletions

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-6.5.1-all.zip distributionUrl=https://home/d/services.gradle.org/distributions/gradle-6.5.1-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -189,7 +189,6 @@ public class PackageBlock extends BaseChunk {
return; return;
} }
updateEntryGroup(entryBlock); updateEntryGroup(entryBlock);
updateEntrySpecReference(entryBlock);
updateEntryTableReferences(entryBlock); updateEntryTableReferences(entryBlock);
} }
private void updateEntryTableReferences(EntryBlock entryBlock){ private void updateEntryTableReferences(EntryBlock entryBlock){
@ -201,11 +200,6 @@ public class PackageBlock extends BaseChunk {
TableStringPool tableStringPool=tableBlock.getTableStringPool(); TableStringPool tableStringPool=tableBlock.getTableStringPool();
tableStringPool.addReferences(tableReferences); tableStringPool.addReferences(tableReferences);
} }
private void updateEntrySpecReference(EntryBlock entryBlock){
ReferenceItem specRef=entryBlock.getSpecReferenceBlock();
SpecStringPool specStringPool=getSpecStringPool();
specStringPool.addReference(specRef);
}
private void updateEntryGroup(EntryBlock entryBlock){ private void updateEntryGroup(EntryBlock entryBlock){
int resId=entryBlock.getResourceId(); int resId=entryBlock.getResourceId();
EntryGroup group=mEntriesGroup.get(resId); EntryGroup group=mEntriesGroup.get(resId);

View File

@ -8,6 +8,8 @@ import com.reandroid.lib.arsc.item.TypeString;
import com.reandroid.lib.arsc.pool.SpecStringPool; import com.reandroid.lib.arsc.pool.SpecStringPool;
import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.EntryBlock;
import java.util.Iterator;
public class EntryGroup extends ItemGroup<EntryBlock> { public class EntryGroup extends ItemGroup<EntryBlock> {
private final int resourceId; private final int resourceId;
public EntryGroup(int resId) { public EntryGroup(int resId) {
@ -17,44 +19,56 @@ public class EntryGroup extends ItemGroup<EntryBlock> {
public int getResourceId(){ public int getResourceId(){
return resourceId; return resourceId;
} }
public void renameSpec(String name){ public boolean renameSpec(String name){
EntryBlock[] items=getItems(); EntryBlock[] items=getItems();
if(items==null){ if(items==null || name==null){
return; return false;
} }
SpecStringPool specStringPool=getSpecStringPool(); SpecStringPool specStringPool=getSpecStringPool();
if(specStringPool==null){ if(specStringPool==null){
return; return false;
}
String oldName=getSpecName();
if(name.equals(oldName)){
return false;
} }
SpecString specString=specStringPool.getOrCreate(name); SpecString specString=specStringPool.getOrCreate(name);
renameSpec(specString.getIndex()); return renameSpec(specString.getIndex());
} }
public void renameSpec(int specReference){ public boolean renameSpec(int specReference){
EntryBlock[] items=getItems(); EntryBlock[] items=getItems();
if(items==null){ if(items==null){
return; return false;
} }
boolean renameOk=false;
for(EntryBlock block:items){ for(EntryBlock block:items){
if(block==null||block.isNull()){ if(block==null||block.isNull()){
continue; continue;
} }
block.setSpecReference(specReference); if(block.getSpecReference()==specReference){
continue;
} }
block.setSpecReference(specReference);
renameOk=true;
}
return renameOk;
} }
public TypeString getTypeString(){ public TypeString getTypeString(){
EntryBlock entryBlock=get(0); Iterator<EntryBlock> itr=iterator(true);
if(entryBlock==null){ while (itr.hasNext()){
return null; EntryBlock entryBlock=itr.next();
}
return entryBlock.getTypeString(); return entryBlock.getTypeString();
} }
public SpecString getSpecString(){
EntryBlock entryBlock=get(0);
if(entryBlock==null){
return null; return null;
} }
public SpecString getSpecString(){
Iterator<EntryBlock> itr=iterator(true);
while (itr.hasNext()){
EntryBlock entryBlock=itr.next();
return entryBlock.getSpecString(); return entryBlock.getSpecString();
} }
return null;
}
public String getTypeName(){ public String getTypeName(){
TypeString typeString=getTypeString(); TypeString typeString=getTypeString();
if(typeString==null){ if(typeString==null){

View File

@ -4,6 +4,7 @@ import com.reandroid.lib.arsc.base.Block;
import com.reandroid.lib.arsc.base.BlockArrayCreator; import com.reandroid.lib.arsc.base.BlockArrayCreator;
import java.util.AbstractList; import java.util.AbstractList;
import java.util.Iterator;
import java.util.List; import java.util.List;
public class ItemGroup<T extends Block> { public class ItemGroup<T extends Block> {
@ -17,6 +18,12 @@ public class ItemGroup<T extends Block> {
this.items=blockArrayCreator.newInstance(0); this.items=blockArrayCreator.newInstance(0);
this.hashCode=(getClass().getName()+"-"+name).hashCode(); this.hashCode=(getClass().getName()+"-"+name).hashCode();
} }
public Iterator<T> iterator(){
return iterator(false);
}
public Iterator<T> iterator(boolean skipNullBlock){
return new GroupIterator(skipNullBlock);
}
public List<T> listItems(){ public List<T> listItems(){
return new AbstractList<T>() { return new AbstractList<T>() {
@Override @Override
@ -128,4 +135,47 @@ public class ItemGroup<T extends Block> {
public String toString(){ public String toString(){
return items.length+"{"+name+"}"; return items.length+"{"+name+"}";
} }
private class GroupIterator implements Iterator<T> {
private int mCursor;
private int mMaxSize;
private final boolean mSkipNullBlock;
GroupIterator(boolean skipNullBlock){
mSkipNullBlock=skipNullBlock;
mCursor=0;
mMaxSize=ItemGroup.this.size();
}
@Override
public boolean hasNext() {
checkCursor();
return !isFinished();
}
@Override
public T next() {
if(!isFinished()){
T item=ItemGroup.this.get(mCursor);
mCursor++;
checkCursor();
return item;
}
return null;
}
private boolean isFinished(){
return mCursor>=mMaxSize;
}
private void checkCursor(){
if(!mSkipNullBlock || isFinished()){
return;
}
T item=ItemGroup.this.get(mCursor);
while (item==null||item.isNull()){
mCursor++;
item=ItemGroup.this.get(mCursor);
if(mCursor>=mMaxSize){
break;
}
}
}
}
} }

View File

@ -24,8 +24,14 @@ public class StringItem extends BlockItem {
this.mUtf8=utf8; this.mUtf8=utf8;
this.mReferencedList=new ArrayList<>(); this.mReferencedList=new ArrayList<>();
} }
public void removeReference(IntegerItem ref){ public boolean removeReference(ReferenceItem ref){
mReferencedList.remove(ref); return mReferencedList.remove(ref);
}
public boolean removeAllReference(Collection<ReferenceItem> referenceItems){
return mReferencedList.removeAll(referenceItems);
}
public void removeAllReference(){
mReferencedList.clear();
} }
public List<ReferenceItem> getReferencedList(){ public List<ReferenceItem> getReferencedList(){
return mReferencedList; return mReferencedList;

View File

@ -5,8 +5,8 @@ public class TypeString extends StringItem {
public TypeString(boolean utf8) { public TypeString(boolean utf8) {
super(utf8); super(utf8);
} }
public int getId(){ public byte getId(){
return getIndex()+1; return (byte) (getIndex()+1);
} }
@Override @Override
StyleItem getStyle(){ StyleItem getStyle(){

View File

@ -66,6 +66,16 @@ public abstract class BaseStringPool<T extends StringItem> extends BaseChunk imp
} }
public boolean removeReference(ReferenceItem ref){
if(ref==null){
return false;
}
T item=get(ref.get());
if(item!=null){
return item.removeReference(ref);
}
return false;
}
public void addReference(ReferenceItem ref){ public void addReference(ReferenceItem ref){
if(ref==null){ if(ref==null){
return; return;

View File

@ -1,9 +1,13 @@
package com.reandroid.lib.arsc.value; package com.reandroid.lib.arsc.value;
import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.base.Block;
import com.reandroid.lib.arsc.chunk.PackageBlock;
import com.reandroid.lib.arsc.chunk.TableBlock;
import com.reandroid.lib.arsc.item.BlockItem; import com.reandroid.lib.arsc.item.BlockItem;
import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.item.ReferenceItem; import com.reandroid.lib.arsc.item.ReferenceItem;
import com.reandroid.lib.arsc.pool.SpecStringPool;
import com.reandroid.lib.arsc.pool.TableStringPool;
import java.util.List; import java.util.List;
@ -24,6 +28,35 @@ public abstract class BaseResValue extends BlockItem {
return null; return null;
} }
boolean removeSpecReference(ReferenceItem ref){
EntryBlock entryBlock=getEntryBlock();
if(entryBlock==null){
return false;
}
return entryBlock.removeSpecReference(ref);
}
boolean removeTableReference(ReferenceItem ref){
EntryBlock entryBlock=getEntryBlock();
if(entryBlock==null){
return false;
}
return entryBlock.removeTableReference(ref);
}
void addSpecReference(ReferenceItem ref){
EntryBlock entryBlock=getEntryBlock();
if(entryBlock==null){
return;
}
entryBlock.addSpecReference(ref);
}
void addTableReference(ReferenceItem ref){
EntryBlock entryBlock=getEntryBlock();
if(entryBlock==null){
return;
}
entryBlock.addTableReference(ref);
}
@Override @Override

View File

@ -17,6 +17,18 @@ public abstract class BaseResValueItem extends BaseResValue implements ResValueI
} }
return mReferenceItem; return mReferenceItem;
} }
boolean removeTableReference(){
ReferenceItem ref=mReferenceItem;
if(ref==null){
return false;
}
EntryBlock entryBlock=getEntryBlock();
if(entryBlock==null){
return false;
}
mReferenceItem=null;
return entryBlock.removeTableReference(ref);
}
private ReferenceItem createReferenceItem(){ private ReferenceItem createReferenceItem(){
return new ReferenceItem() { return new ReferenceItem() {
@Override @Override

View File

@ -3,10 +3,12 @@ package com.reandroid.lib.arsc.value;
import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.base.Block;
import com.reandroid.lib.arsc.base.BlockCounter; import com.reandroid.lib.arsc.base.BlockCounter;
import com.reandroid.lib.arsc.chunk.PackageBlock; import com.reandroid.lib.arsc.chunk.PackageBlock;
import com.reandroid.lib.arsc.chunk.TableBlock;
import com.reandroid.lib.arsc.chunk.TypeBlock; import com.reandroid.lib.arsc.chunk.TypeBlock;
import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.io.BlockReader;
import com.reandroid.lib.arsc.item.*; import com.reandroid.lib.arsc.item.*;
import com.reandroid.lib.arsc.pool.SpecStringPool; import com.reandroid.lib.arsc.pool.SpecStringPool;
import com.reandroid.lib.arsc.pool.TableStringPool;
import java.io.IOException; import java.io.IOException;
@ -43,6 +45,59 @@ public class EntryBlock extends Block {
} }
return results; return results;
} }
boolean removeSpecReference(ReferenceItem ref){
if(ref==null){
return false;
}
PackageBlock packageBlock=getPackageBlock();
if(packageBlock==null){
return false;
}
SpecStringPool specStringPool=packageBlock.getSpecStringPool();
return specStringPool.removeReference(ref);
}
boolean removeTableReference(ReferenceItem ref){
if(ref==null){
return false;
}
PackageBlock packageBlock=getPackageBlock();
if(packageBlock==null){
return false;
}
TableBlock tableBlock=packageBlock.getTableBlock();
if(tableBlock==null){
return false;
}
TableStringPool tableStringPool=tableBlock.getTableStringPool();
return tableStringPool.removeReference(ref);
}
void addSpecReference(ReferenceItem ref){
if(ref==null){
return;
}
PackageBlock packageBlock=getPackageBlock();
if(packageBlock==null){
return;
}
SpecStringPool specStringPool=packageBlock.getSpecStringPool();
specStringPool.addReference(ref);
}
void addTableReference(ReferenceItem ref){
if(ref==null){
return;
}
PackageBlock packageBlock=getPackageBlock();
if(packageBlock==null){
return;
}
TableBlock tableBlock=packageBlock.getTableBlock();
if(tableBlock==null){
return;
}
TableStringPool tableStringPool=tableBlock.getTableStringPool();
tableStringPool.addReference(ref);
}
public short getFlags(){ public short getFlags(){
return mFlags.get(); return mFlags.get();
@ -57,7 +112,12 @@ public class EntryBlock extends Block {
return mSpecReference.get(); return mSpecReference.get();
} }
public void setSpecReference(int ref){ public void setSpecReference(int ref){
int old=mSpecReference.get();
if(ref==old){
return;
}
mSpecReference.set(ref); mSpecReference.set(ref);
updateSpecRef(old, ref);
} }
public BaseResValue getResValue(){ public BaseResValue getResValue(){
return mResValue; return mResValue;
@ -74,6 +134,7 @@ public class EntryBlock extends Block {
boolean is_complex=(resValue instanceof ResValueBag); boolean is_complex=(resValue instanceof ResValueBag);
setFlagComplex(is_complex); setFlagComplex(is_complex);
updatePackage(); updatePackage();
updateSpecRef();
} }
} }
private void setResValueInternal(BaseResValue resValue){ private void setResValueInternal(BaseResValue resValue){
@ -111,11 +172,7 @@ public class EntryBlock extends Block {
return null; return null;
} }
public SpecString getSpecString(){ public SpecString getSpecString(){
TypeBlock typeBlock=getTypeBlock(); PackageBlock packageBlock=getPackageBlock();
if(typeBlock==null){
return null;
}
PackageBlock packageBlock=typeBlock.getPackageBlock();
if(packageBlock==null){ if(packageBlock==null){
return null; return null;
} }
@ -173,6 +230,13 @@ public class EntryBlock extends Block {
int entryId=getIndex(); int entryId=getIndex();
return ((pkgId << 24) | (typeId << 16) | entryId); return ((pkgId << 24) | (typeId << 16) | entryId);
} }
public PackageBlock getPackageBlock(){
TypeBlock typeBlock=getTypeBlock();
if(typeBlock!=null){
return typeBlock.getPackageBlock();
}
return null;
}
public TypeBlock getTypeBlock(){ public TypeBlock getTypeBlock(){
Block parent=getParent(); Block parent=getParent();
while (parent!=null){ while (parent!=null){
@ -326,6 +390,28 @@ public class EntryBlock extends Block {
return result; return result;
} }
private void updateSpecRef(){
updateSpecRef(-1, getSpecReference());
}
private void updateSpecRef(int oldRef, int newNef){
TypeBlock typeBlock=getTypeBlock();
if(typeBlock==null){
return;
}
PackageBlock packageBlock=typeBlock.getPackageBlock();
if(packageBlock==null){
return;
}
SpecStringPool specStringPool=packageBlock.getSpecStringPool();
SpecString specString=specStringPool.get(oldRef);
if(specString!=null){
specString.removeReference(getSpecReferenceBlock());
}
SpecString specStringNew=specStringPool.get(newNef);
if(specStringNew!=null){
specStringNew.addReference(getSpecReferenceBlock());
}
}
private void updatePackage(){ private void updatePackage(){
TypeBlock typeBlock=getTypeBlock(); TypeBlock typeBlock=getTypeBlock();
if(typeBlock==null){ if(typeBlock==null){
@ -347,6 +433,7 @@ public class EntryBlock extends Block {
createResValue(); createResValue();
mResValue.readBytes(reader); mResValue.readBytes(reader);
updatePackage(); updatePackage();
updateSpecRef();
} }
public String toString(){ public String toString(){
StringBuilder builder=new StringBuilder(); StringBuilder builder=new StringBuilder();

View File

@ -1,5 +1,7 @@
package com.reandroid.lib.arsc.value; package com.reandroid.lib.arsc.value;
import com.reandroid.lib.arsc.item.ReferenceItem;
public class ResValueBagItem extends BaseResValueItem{ public class ResValueBagItem extends BaseResValueItem{
public ResValueBagItem() { public ResValueBagItem() {
@ -41,7 +43,16 @@ public class ResValueBagItem extends BaseResValueItem{
} }
@Override @Override
public void setType(byte type){ public void setType(byte type){
byte old=getType();
if(type==old){
return;
}
removeTableReference();
setByte(OFFSET_TYPE, type); setByte(OFFSET_TYPE, type);
if(type==ValueType.STRING.getByte()){
ReferenceItem ref=getTableStringReference();
removeTableReference(ref);
}
} }
@Override @Override
public byte getType(){ public byte getType(){
@ -53,7 +64,17 @@ public class ResValueBagItem extends BaseResValueItem{
} }
@Override @Override
public void setData(int data){ public void setData(int data){
int old=getData();
if(data==old){
return;
}
if(getValueType()==ValueType.STRING){
removeTableReference();
}
setInt(OFFSET_DATA, data); setInt(OFFSET_DATA, data);
if(getValueType()==ValueType.STRING){
addTableReference(getTableStringReference());
}
} }
@Override @Override

View File

@ -29,7 +29,15 @@ public class ResValueInt extends BaseResValueItem {
} }
@Override @Override
public void setType(byte type){ public void setType(byte type){
byte old=getType();
if(type==old){
return;
}
removeTableReference();
setByte(OFFSET_TYPE, type); setByte(OFFSET_TYPE, type);
if(type==ValueType.STRING.getByte()){
addTableReference(getTableStringReference());
}
} }
@Override @Override
public byte getType(){ public byte getType(){
@ -41,7 +49,15 @@ public class ResValueInt extends BaseResValueItem {
} }
@Override @Override
public void setData(int data){ public void setData(int data){
int old=getData();
if(data==old){
return;
}
removeTableReference();
setInt(OFFSET_DATA, data); setInt(OFFSET_DATA, data);
if(getValueType()==ValueType.STRING){
addTableReference(getTableStringReference());
}
} }