mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-06-13 05:37:41 +02:00
Entries
This commit is contained in:
@ -9,9 +9,20 @@ public class EntryBlockArray extends OffsetBlockArray<EntryBlock> {
|
||||
public EntryBlockArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart){
|
||||
super(offsets, itemCount, itemStart);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setEntry(short entryId, EntryBlock entryBlock){
|
||||
setItem(entryId, entryBlock);
|
||||
}
|
||||
public EntryBlock getOrCreate(short entryId){
|
||||
EntryBlock entryBlock=get(entryId);
|
||||
if(entryBlock!=null){
|
||||
return entryBlock;
|
||||
}
|
||||
ensureSize(entryId+1);
|
||||
return get(entryId);
|
||||
}
|
||||
public EntryBlock getEntry(short entryId){
|
||||
return get(entryId);
|
||||
}
|
||||
@Override
|
||||
public EntryBlock newInstance() {
|
||||
return new EntryBlock();
|
||||
|
@ -1,15 +1,84 @@
|
||||
package com.reandroid.lib.arsc.array;
|
||||
|
||||
import com.reandroid.lib.arsc.base.BlockArray;
|
||||
import com.reandroid.lib.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.lib.arsc.container.SpecTypePair;
|
||||
import com.reandroid.lib.arsc.value.EntryBlock;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class SpecTypePairArray extends BlockArray<SpecTypePair> {
|
||||
public SpecTypePairArray(){
|
||||
super();
|
||||
}
|
||||
|
||||
public EntryBlock getOrCreateEntry(byte typeId, short entryId, String qualifiers){
|
||||
TypeBlock typeBlock=getOrCreateTypeBlock(typeId, qualifiers);
|
||||
return typeBlock.getOrCreateEntry(entryId);
|
||||
}
|
||||
public EntryBlock getEntry(byte typeId, short entryId, String qualifiers){
|
||||
TypeBlock typeBlock=getTypeBlock(typeId, qualifiers);
|
||||
if(typeBlock==null){
|
||||
return null;
|
||||
}
|
||||
return typeBlock.getEntry(entryId);
|
||||
}
|
||||
public TypeBlock getOrCreateTypeBlock(byte typeId, String qualifiers){
|
||||
SpecTypePair pair=getOrCreate(typeId);
|
||||
return pair.getOrCreateTypeBlock(qualifiers);
|
||||
}
|
||||
public TypeBlock getTypeBlock(byte typeId, String qualifiers){
|
||||
SpecTypePair pair=getPair(typeId);
|
||||
if(pair==null){
|
||||
return null;
|
||||
}
|
||||
return pair.getTypeBlock(qualifiers);
|
||||
}
|
||||
public SpecTypePair getOrCreate(byte typeId){
|
||||
SpecTypePair pair=getPair(typeId);
|
||||
if(pair!=null){
|
||||
return pair;
|
||||
}
|
||||
pair=createNext();
|
||||
pair.setTypeId(typeId);
|
||||
return pair;
|
||||
}
|
||||
public SpecTypePair getPair(byte typeId){
|
||||
SpecTypePair[] items=getChildes();
|
||||
if(items==null){
|
||||
return null;
|
||||
}
|
||||
int max=items.length;
|
||||
for(int i=0;i<max;i++){
|
||||
SpecTypePair pair=items[i];
|
||||
if(pair==null){
|
||||
continue;
|
||||
}
|
||||
if(pair.getTypeId()==typeId){
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public byte getTypeId(){
|
||||
SpecTypePair[] items=getChildes();
|
||||
if(items==null){
|
||||
return 0;
|
||||
}
|
||||
int max=items.length;
|
||||
for(int i=0;i<max;i++){
|
||||
SpecTypePair pair=items[i];
|
||||
if(pair!=null){
|
||||
return pair.getTypeId();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public SpecTypePair newInstance() {
|
||||
return new SpecTypePair();
|
||||
SpecTypePair pair=new SpecTypePair();
|
||||
pair.setTypeId(getTypeId());
|
||||
return pair;
|
||||
}
|
||||
@Override
|
||||
public SpecTypePair[] newInstance(int len) {
|
||||
|
@ -7,6 +7,7 @@ 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;
|
||||
@ -18,6 +19,58 @@ public class TypeBlockArray extends BlockArray<TypeBlock> {
|
||||
public TypeBlockArray(){
|
||||
super();
|
||||
}
|
||||
public EntryBlock getOrCreateEntry(short entryId, String qualifiers){
|
||||
TypeBlock typeBlock=getOrCreate(qualifiers);
|
||||
return typeBlock.getOrCreateEntry(entryId);
|
||||
}
|
||||
public EntryBlock getEntry(short entryId, String qualifiers){
|
||||
TypeBlock typeBlock=getTypeBlock(qualifiers);
|
||||
if(typeBlock==null){
|
||||
return null;
|
||||
}
|
||||
return typeBlock.getEntry(entryId);
|
||||
}
|
||||
public TypeBlock getOrCreate(String qualifiers){
|
||||
TypeBlock typeBlock=getTypeBlock(qualifiers);
|
||||
if(typeBlock!=null){
|
||||
return typeBlock;
|
||||
}
|
||||
typeBlock=createNext();
|
||||
ResConfig config=typeBlock.getResConfig();
|
||||
config.parseQualifiers(qualifiers);
|
||||
return typeBlock;
|
||||
}
|
||||
public TypeBlock getTypeBlock(String qualifiers){
|
||||
TypeBlock[] items=getChildes();
|
||||
if(items==null){
|
||||
return null;
|
||||
}
|
||||
int max=items.length;
|
||||
for(int i=0;i<max;i++){
|
||||
TypeBlock block=items[i];
|
||||
if(block.getResConfig().isEqualQualifiers(qualifiers)){
|
||||
return block;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public TypeBlock getTypeBlock(ResConfig config){
|
||||
if(config==null){
|
||||
return null;
|
||||
}
|
||||
TypeBlock[] items=getChildes();
|
||||
if(items==null){
|
||||
return null;
|
||||
}
|
||||
int max=items.length;
|
||||
for(int i=0;i<max;i++){
|
||||
TypeBlock block=items[i];
|
||||
if(config.equals(block.getResConfig())){
|
||||
return block;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void setTypeId(byte id){
|
||||
this.mTypeId=id;
|
||||
TypeBlock[] allChildes=getChildes();
|
||||
|
@ -7,7 +7,7 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public abstract class Block {
|
||||
private int mIndex;
|
||||
private int mIndex=-1;
|
||||
private Block mParent;
|
||||
private boolean mNull;
|
||||
private BlockLoad mBlockLoad;
|
||||
@ -52,7 +52,17 @@ public abstract class Block {
|
||||
return mIndex;
|
||||
}
|
||||
public final void setIndex(int index){
|
||||
int old=mIndex;
|
||||
if(index==old){
|
||||
return;
|
||||
}
|
||||
mIndex=index;
|
||||
if(old!=-1 && index!=-1){
|
||||
onIndexChanged(old, index);
|
||||
}
|
||||
}
|
||||
public void onIndexChanged(int oldIndex, int newIndex){
|
||||
|
||||
}
|
||||
public final void setParent(Block parent){
|
||||
if(parent==this){
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.reandroid.lib.arsc.base;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public abstract class BlockArray<T extends Block> extends BlockContainer<T> implements BlockArrayCreator<T> {
|
||||
@ -10,11 +8,16 @@ public abstract class BlockArray<T extends Block> extends BlockContainer<T> impl
|
||||
public BlockArray(){
|
||||
elementData= newInstance(0);
|
||||
}
|
||||
public List<T> listItems(){
|
||||
return new AbstractList<T>() {
|
||||
|
||||
public Collection<T> listItems(){
|
||||
return new AbstractCollection<T>() {
|
||||
@Override
|
||||
public T get(int i) {
|
||||
return BlockArray.this.get(i);
|
||||
public Iterator<T> iterator(){
|
||||
return BlockArray.this.iterator();
|
||||
}
|
||||
@Override
|
||||
public boolean contains(Object o){
|
||||
return BlockArray.this.contains(o);
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
@ -95,6 +98,12 @@ public abstract class BlockArray<T extends Block> extends BlockContainer<T> impl
|
||||
trimNullBlocks();
|
||||
}
|
||||
}
|
||||
public void setItem(int index, T item){
|
||||
ensureSize(index+1);
|
||||
elementData[index]=item;
|
||||
item.setIndex(index);
|
||||
item.setParent(this);
|
||||
}
|
||||
public void add(T block){
|
||||
if(block==null){
|
||||
return;
|
||||
@ -123,7 +132,41 @@ public abstract class BlockArray<T extends Block> extends BlockContainer<T> impl
|
||||
}
|
||||
return elementData[i];
|
||||
}
|
||||
public boolean contains(T block){
|
||||
public int indexOf(Object block){
|
||||
T[] items=elementData;
|
||||
if(items==null){
|
||||
return -1;
|
||||
}
|
||||
int len=items.length;
|
||||
for(int i=0;i<len;i++){
|
||||
if(block==items[i]){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public int lastIndexOf(Object block){
|
||||
T[] items=elementData;
|
||||
if(items==null){
|
||||
return -1;
|
||||
}
|
||||
int len=items.length;
|
||||
int result=-1;
|
||||
for(int i=0;i<len;i++){
|
||||
if(block==items[i]){
|
||||
result=-1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Iterator<T> iterator() {
|
||||
return iterator(false);
|
||||
}
|
||||
public Iterator<T> iterator(boolean skipNullBlock) {
|
||||
return new BlockIterator(skipNullBlock);
|
||||
}
|
||||
public boolean contains(Object block){
|
||||
T[] items=elementData;
|
||||
if(block==null || items==null){
|
||||
return false;
|
||||
@ -217,4 +260,46 @@ public abstract class BlockArray<T extends Block> extends BlockContainer<T> impl
|
||||
public String toString(){
|
||||
return "count="+ childesCount();
|
||||
}
|
||||
|
||||
private class BlockIterator implements Iterator<T> {
|
||||
private int mCursor;
|
||||
private int mMaxSize;
|
||||
private final boolean mSkipNullBlock;
|
||||
BlockIterator(boolean skipNullBlock){
|
||||
mSkipNullBlock=skipNullBlock;
|
||||
mCursor=0;
|
||||
mMaxSize=BlockArray.this.childesCount();
|
||||
}
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
checkCursor();
|
||||
return !isFinished();
|
||||
}
|
||||
@Override
|
||||
public T next() {
|
||||
if(!isFinished()){
|
||||
T item=BlockArray.this.get(mCursor);
|
||||
mCursor++;
|
||||
checkCursor();
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private boolean isFinished(){
|
||||
return mCursor>=mMaxSize;
|
||||
}
|
||||
private void checkCursor(){
|
||||
if(!mSkipNullBlock || isFinished()){
|
||||
return;
|
||||
}
|
||||
T item=BlockArray.this.get(mCursor);
|
||||
while (item==null||item.isNull()){
|
||||
mCursor++;
|
||||
item=BlockArray.this.get(mCursor);
|
||||
if(mCursor>=mMaxSize){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.reandroid.lib.arsc.array.LibraryInfoArray;
|
||||
import com.reandroid.lib.arsc.item.IntegerItem;
|
||||
import com.reandroid.lib.arsc.value.LibraryInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class LibraryBlock extends BaseChunk {
|
||||
@ -39,7 +40,7 @@ public class LibraryBlock extends BaseChunk {
|
||||
mLibraryInfoArray.add(info);
|
||||
mLibCount.set(mLibraryInfoArray.childesCount());
|
||||
}
|
||||
public List<LibraryInfo> listLibraryInfo(){
|
||||
public Collection<LibraryInfo> listLibraryInfo(){
|
||||
return mLibraryInfoArray.listItems();
|
||||
}
|
||||
@Override
|
||||
|
@ -8,7 +8,10 @@ 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.item.ReferenceItem;
|
||||
import com.reandroid.lib.arsc.item.SpecString;
|
||||
import com.reandroid.lib.arsc.pool.SpecStringPool;
|
||||
import com.reandroid.lib.arsc.pool.TableStringPool;
|
||||
import com.reandroid.lib.arsc.pool.TypeStringPool;
|
||||
import com.reandroid.lib.arsc.value.EntryBlock;
|
||||
import com.reandroid.lib.arsc.value.LibraryInfo;
|
||||
@ -141,7 +144,7 @@ public class PackageBlock extends BaseChunk {
|
||||
public SpecTypePairArray getSpecTypePairArray(){
|
||||
return mSpecTypePairArray;
|
||||
}
|
||||
public List<LibraryInfo> listLibraryInfo(){
|
||||
public Collection<LibraryInfo> listLibraryInfo(){
|
||||
return mLibraryBlock.listLibraryInfo();
|
||||
}
|
||||
|
||||
@ -163,12 +166,46 @@ public class PackageBlock extends BaseChunk {
|
||||
public Set<Integer> listResourceIds(){
|
||||
return mEntriesGroup.keySet();
|
||||
}
|
||||
public EntryBlock getOrCreateEntry(byte typeId, short entryId, String qualifiers){
|
||||
return getSpecTypePairArray().getOrCreateEntry(typeId, entryId, qualifiers);
|
||||
}
|
||||
public EntryBlock getEntry(byte typeId, short entryId, String qualifiers){
|
||||
return getSpecTypePairArray().getEntry(typeId, entryId, qualifiers);
|
||||
}
|
||||
public TypeBlock getOrCreateTypeBlock(byte typeId, String qualifiers){
|
||||
return getSpecTypePairArray().getOrCreateTypeBlock(typeId, qualifiers);
|
||||
}
|
||||
public TypeBlock getTypeBlock(byte typeId, String qualifiers){
|
||||
return getSpecTypePairArray().getTypeBlock(typeId, qualifiers);
|
||||
}
|
||||
public Collection<EntryGroup> listEntryGroup(){
|
||||
return mEntriesGroup.values();
|
||||
}
|
||||
public EntryGroup getEntryGroup(int resId){
|
||||
return mEntriesGroup.get(resId);
|
||||
}
|
||||
public void updateEntry(EntryBlock entryBlock){
|
||||
if(entryBlock==null||entryBlock.isNull()){
|
||||
return;
|
||||
}
|
||||
updateEntryGroup(entryBlock);
|
||||
updateEntrySpecReference(entryBlock);
|
||||
updateEntryTableReferences(entryBlock);
|
||||
}
|
||||
private void updateEntryTableReferences(EntryBlock entryBlock){
|
||||
TableBlock tableBlock=getTableBlock();
|
||||
if(tableBlock==null){
|
||||
return;
|
||||
}
|
||||
List<ReferenceItem> tableReferences=entryBlock.getTableStringReferences();
|
||||
TableStringPool tableStringPool=tableBlock.getTableStringPool();
|
||||
tableStringPool.addReferences(tableReferences);
|
||||
}
|
||||
private void updateEntrySpecReference(EntryBlock entryBlock){
|
||||
ReferenceItem specRef=entryBlock.getSpecReferenceBlock();
|
||||
SpecStringPool specStringPool=getSpecStringPool();
|
||||
specStringPool.addReference(specRef);
|
||||
}
|
||||
private void updateEntryGroup(EntryBlock entryBlock){
|
||||
int resId=entryBlock.getResourceId();
|
||||
EntryGroup group=mEntriesGroup.get(resId);
|
||||
@ -178,6 +215,7 @@ public class PackageBlock extends BaseChunk {
|
||||
}
|
||||
group.add(entryBlock);
|
||||
}
|
||||
|
||||
public List<EntryBlock> listEntries(byte typeId, int entryId){
|
||||
List<EntryBlock> results=new ArrayList<>();
|
||||
for(SpecTypePair pair:listSpecTypePair(typeId)){
|
||||
@ -194,7 +232,7 @@ public class PackageBlock extends BaseChunk {
|
||||
}
|
||||
return results;
|
||||
}
|
||||
public List<SpecTypePair> listAllSpecTypePair(){
|
||||
public Collection<SpecTypePair> listAllSpecTypePair(){
|
||||
return getSpecTypePairArray().listItems();
|
||||
}
|
||||
|
||||
@ -203,7 +241,7 @@ public class PackageBlock extends BaseChunk {
|
||||
mKeyStrings.set(pos);
|
||||
}
|
||||
public void onEntryAdded(EntryBlock entryBlock){
|
||||
updateEntryGroup(entryBlock);
|
||||
updateEntry(entryBlock);
|
||||
}
|
||||
@Override
|
||||
public void onChunkLoaded() {
|
||||
|
@ -7,6 +7,7 @@ import com.reandroid.lib.arsc.value.EntryBlock;
|
||||
import com.reandroid.lib.arsc.value.ResConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class TypeBlock extends BaseTypeBlock {
|
||||
@ -27,6 +28,12 @@ public class TypeBlock extends BaseTypeBlock {
|
||||
addChild(mEntryOffsets);
|
||||
addChild(mEntryArray);
|
||||
}
|
||||
public EntryBlock getOrCreateEntry(short entryId){
|
||||
return getEntryBlockArray().getOrCreate(entryId);
|
||||
}
|
||||
public EntryBlock getEntry(short entryId){
|
||||
return getEntryBlockArray().getEntry(entryId);
|
||||
}
|
||||
public ResConfig getResConfig(){
|
||||
return mResConfig;
|
||||
}
|
||||
@ -36,15 +43,12 @@ public class TypeBlock extends BaseTypeBlock {
|
||||
public List<EntryBlock> listEntries(){
|
||||
return listEntries(false);
|
||||
}
|
||||
public List<EntryBlock> listEntries(boolean includeNull){
|
||||
public List<EntryBlock> listEntries(boolean skipNullBlock){
|
||||
List<EntryBlock> results=new ArrayList<>();
|
||||
for(EntryBlock entryBlock:mEntryArray.listItems()){
|
||||
if(!includeNull){
|
||||
if(entryBlock.isNull()){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
results.add(entryBlock);
|
||||
Iterator<EntryBlock> itr = mEntryArray.iterator(skipNullBlock);
|
||||
while (itr.hasNext()){
|
||||
EntryBlock block=itr.next();
|
||||
results.add(block);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ import com.reandroid.lib.arsc.value.ResConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class SpecTypePair extends BlockContainer<Block> {
|
||||
@ -32,6 +34,18 @@ public class SpecTypePair extends BlockContainer<Block> {
|
||||
public SpecTypePair(){
|
||||
this(new SpecBlock(), new TypeBlockArray());
|
||||
}
|
||||
public EntryBlock getOrCreateEntry(short entryId, String qualifiers){
|
||||
return getTypeBlockArray().getOrCreateEntry(entryId, qualifiers);
|
||||
}
|
||||
public EntryBlock getEntry(short entryId, String qualifiers){
|
||||
return getTypeBlockArray().getEntry(entryId, qualifiers);
|
||||
}
|
||||
public TypeBlock getOrCreateTypeBlock(String qualifiers){
|
||||
return getTypeBlockArray().getOrCreate(qualifiers);
|
||||
}
|
||||
public TypeBlock getTypeBlock(String qualifiers){
|
||||
return getTypeBlockArray().getTypeBlock(qualifiers);
|
||||
}
|
||||
public List<ResConfig> listResConfig(){
|
||||
return mTypeBlockArray.listResConfig();
|
||||
}
|
||||
@ -60,7 +74,9 @@ public class SpecTypePair extends BlockContainer<Block> {
|
||||
}
|
||||
public List<EntryBlock> listEntries(int entryId){
|
||||
List<EntryBlock> results=new ArrayList<>();
|
||||
for(TypeBlock typeBlock:listTypeBlocks()){
|
||||
Iterator<TypeBlock> itr = mTypeBlockArray.iterator(true);
|
||||
while (itr.hasNext()){
|
||||
TypeBlock typeBlock=itr.next();
|
||||
EntryBlock entryBlock=typeBlock.getEntryBlock(entryId);
|
||||
if(entryBlock==null||entryBlock.isNull()){
|
||||
continue;
|
||||
@ -69,7 +85,7 @@ public class SpecTypePair extends BlockContainer<Block> {
|
||||
}
|
||||
return results;
|
||||
}
|
||||
public List<TypeBlock> listTypeBlocks(){
|
||||
public Collection<TypeBlock> listTypeBlocks(){
|
||||
return mTypeBlockArray.listItems();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.reandroid.lib.arsc.item;
|
||||
|
||||
|
||||
public class IntegerItem extends BlockItem {
|
||||
public class IntegerItem extends BlockItem implements ReferenceItem{
|
||||
private int mCache;
|
||||
public IntegerItem(){
|
||||
super(4);
|
||||
@ -10,6 +10,7 @@ public class IntegerItem extends BlockItem {
|
||||
this();
|
||||
set(val);
|
||||
}
|
||||
@Override
|
||||
public void set(int val){
|
||||
if(val==mCache){
|
||||
return;
|
||||
@ -21,6 +22,7 @@ public class IntegerItem extends BlockItem {
|
||||
bts[1]= (byte) (val >>> 8 & 0xff);
|
||||
bts[0]= (byte) (val & 0xff);
|
||||
}
|
||||
@Override
|
||||
public int get(){
|
||||
return mCache;
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
package com.reandroid.lib.arsc.item;
|
||||
|
||||
public interface ReferenceItem {
|
||||
void set(int val);
|
||||
int get();
|
||||
}
|
@ -11,13 +11,46 @@ import java.nio.CharBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class StringItem extends BlockItem {
|
||||
private String mCache;
|
||||
private boolean mUtf8;
|
||||
private final List<ReferenceItem> mReferencedList;
|
||||
public StringItem(boolean utf8) {
|
||||
super(0);
|
||||
this.mUtf8=utf8;
|
||||
this.mReferencedList=new ArrayList<>();
|
||||
}
|
||||
public void removeReference(IntegerItem ref){
|
||||
mReferencedList.remove(ref);
|
||||
}
|
||||
public List<ReferenceItem> getReferencedList(){
|
||||
return mReferencedList;
|
||||
}
|
||||
public void addReference(ReferenceItem ref){
|
||||
if(ref!=null){
|
||||
mReferencedList.add(ref);
|
||||
}
|
||||
}
|
||||
public void addReference(Collection<ReferenceItem> refList){
|
||||
if(refList==null){
|
||||
return;
|
||||
}
|
||||
for(ReferenceItem ref:refList){
|
||||
addReference(ref);
|
||||
}
|
||||
}
|
||||
private void reUpdateReferences(int newIndex){
|
||||
for(ReferenceItem ref:mReferencedList){
|
||||
ref.set(newIndex);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onIndexChanged(int oldIndex, int newIndex){
|
||||
reUpdateReferences(newIndex);
|
||||
}
|
||||
public String getHtml(){
|
||||
String str=get();
|
||||
|
@ -1,7 +1,14 @@
|
||||
package com.reandroid.lib.arsc.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TableString extends StringItem {
|
||||
public TableString(boolean utf8) {
|
||||
super(utf8);
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
List<ReferenceItem> refList = getReferencedList();
|
||||
return "USED BY="+refList.size()+"{"+super.toString()+"}";
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import com.reandroid.lib.arsc.io.BlockReader;
|
||||
import com.reandroid.lib.arsc.item.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -64,6 +65,25 @@ public abstract class BaseStringPool<T extends StringItem> extends BaseChunk imp
|
||||
mUniqueMap=new HashMap<>();
|
||||
|
||||
}
|
||||
|
||||
public void addReference(ReferenceItem ref){
|
||||
if(ref==null){
|
||||
return;
|
||||
}
|
||||
T item=get(ref.get());
|
||||
if(item!=null){
|
||||
item.addReference(ref);
|
||||
}
|
||||
}
|
||||
public void addReferences(Collection<ReferenceItem> referenceList){
|
||||
if(referenceList==null){
|
||||
return;
|
||||
}
|
||||
for(ReferenceItem ref:referenceList){
|
||||
addReference(ref);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(String str){
|
||||
return mUniqueMap.containsKey(str);
|
||||
}
|
||||
|
@ -4,12 +4,14 @@ import com.reandroid.lib.arsc.array.StringArray;
|
||||
import com.reandroid.lib.arsc.array.TableStringArray;
|
||||
import com.reandroid.lib.arsc.item.IntegerArray;
|
||||
import com.reandroid.lib.arsc.item.IntegerItem;
|
||||
import com.reandroid.lib.arsc.item.ReferenceItem;
|
||||
import com.reandroid.lib.arsc.item.TableString;
|
||||
|
||||
public class TableStringPool extends BaseStringPool<TableString> {
|
||||
public TableStringPool(boolean is_utf8) {
|
||||
super(is_utf8);
|
||||
}
|
||||
|
||||
@Override
|
||||
StringArray<TableString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
return new TableStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||
|
@ -2,15 +2,17 @@ package com.reandroid.lib.arsc.value;
|
||||
|
||||
import com.reandroid.lib.arsc.base.Block;
|
||||
import com.reandroid.lib.arsc.item.BlockItem;
|
||||
import com.reandroid.lib.arsc.item.IntegerItem;
|
||||
import com.reandroid.lib.arsc.item.ReferenceItem;
|
||||
|
||||
public abstract class BaseResValue extends BlockItem {
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseResValue extends BlockItem {
|
||||
BaseResValue(int bytesLength){
|
||||
super(bytesLength);
|
||||
}
|
||||
|
||||
public ValueType getValueType(){
|
||||
return ValueType.valueOf(getType());
|
||||
}
|
||||
|
||||
public EntryBlock getEntryBlock(){
|
||||
Block parent=getParent();
|
||||
while(parent!=null){
|
||||
@ -22,24 +24,7 @@ public abstract class BaseResValue extends BlockItem {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setType(ValueType valueType){
|
||||
byte type=0;
|
||||
if(valueType!=null){
|
||||
type=valueType.getByte();
|
||||
}
|
||||
setType(type);
|
||||
}
|
||||
|
||||
abstract void setHeaderSize(short size);
|
||||
abstract short getHeaderSize();
|
||||
|
||||
abstract void setReserved(byte reserved);
|
||||
abstract byte getReserved();
|
||||
|
||||
public abstract void setType(byte type);
|
||||
public abstract byte getType();
|
||||
public abstract int getData();
|
||||
public abstract void setData(int data);
|
||||
|
||||
@Override
|
||||
public void onBytesChanged() {
|
||||
|
@ -0,0 +1,49 @@
|
||||
package com.reandroid.lib.arsc.value;
|
||||
|
||||
import com.reandroid.lib.arsc.item.ReferenceItem;
|
||||
|
||||
public abstract class BaseResValueItem extends BaseResValue implements ResValueItem {
|
||||
|
||||
private ReferenceItem mReferenceItem;
|
||||
BaseResValueItem(int bytesLength) {
|
||||
super(bytesLength);
|
||||
}
|
||||
public ReferenceItem getTableStringReference(){
|
||||
if(getValueType()!=ValueType.STRING){
|
||||
return null;
|
||||
}
|
||||
if(mReferenceItem==null){
|
||||
mReferenceItem=createReferenceItem();
|
||||
}
|
||||
return mReferenceItem;
|
||||
}
|
||||
private ReferenceItem createReferenceItem(){
|
||||
return new ReferenceItem() {
|
||||
@Override
|
||||
public void set(int val) {
|
||||
if(getValueType()==ValueType.STRING){
|
||||
BaseResValueItem.this.setData(val);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int get() {
|
||||
if(getValueType()==ValueType.STRING){
|
||||
return BaseResValueItem.this.getData();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ValueType getValueType(){
|
||||
return ValueType.valueOf(getType());
|
||||
}
|
||||
@Override
|
||||
public void setType(ValueType valueType){
|
||||
byte type=0;
|
||||
if(valueType!=null){
|
||||
type=valueType.getByte();
|
||||
}
|
||||
setType(type);
|
||||
}
|
||||
}
|
@ -5,15 +5,14 @@ import com.reandroid.lib.arsc.base.BlockCounter;
|
||||
import com.reandroid.lib.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.lib.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.lib.arsc.io.BlockReader;
|
||||
import com.reandroid.lib.arsc.item.IntegerItem;
|
||||
import com.reandroid.lib.arsc.item.ShortItem;
|
||||
import com.reandroid.lib.arsc.item.SpecString;
|
||||
import com.reandroid.lib.arsc.item.TypeString;
|
||||
import com.reandroid.lib.arsc.item.*;
|
||||
import com.reandroid.lib.arsc.pool.SpecStringPool;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EntryBlock extends Block {
|
||||
private ShortItem mHeaderSize;
|
||||
@ -25,12 +24,35 @@ public class EntryBlock extends Block {
|
||||
super();
|
||||
}
|
||||
|
||||
public List<ReferenceItem> getTableStringReferences(){
|
||||
if(isNull()){
|
||||
return null;
|
||||
}
|
||||
List<ReferenceItem> results=null;
|
||||
BaseResValue resValue=getResValue();
|
||||
if(resValue instanceof ResValueInt){
|
||||
ResValueInt resValueInt=(ResValueInt)resValue;
|
||||
ReferenceItem ref=resValueInt.getTableStringReference();
|
||||
if(ref!=null){
|
||||
results=new ArrayList<>();
|
||||
results.add(ref);
|
||||
}
|
||||
}else if(resValue instanceof ResValueBag){
|
||||
ResValueBag resValueBag=(ResValueBag)resValue;
|
||||
results=resValueBag.getTableStringReferences();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public short getFlags(){
|
||||
return mFlags.get();
|
||||
}
|
||||
public void setFlags(short sh){
|
||||
mFlags.set(sh);
|
||||
}
|
||||
public IntegerItem getSpecReferenceBlock(){
|
||||
return mSpecReference;
|
||||
}
|
||||
public int getSpecReference(){
|
||||
return mSpecReference.get();
|
||||
}
|
||||
@ -41,6 +63,20 @@ public class EntryBlock extends Block {
|
||||
return mResValue;
|
||||
}
|
||||
public void setResValue(BaseResValue resValue){
|
||||
if(resValue==mResValue){
|
||||
return;
|
||||
}
|
||||
setResValueInternal(resValue);
|
||||
if(resValue==null){
|
||||
setNull(true);
|
||||
}else {
|
||||
setNull(false);
|
||||
boolean is_complex=(resValue instanceof ResValueBag);
|
||||
setFlagComplex(is_complex);
|
||||
updatePackage();
|
||||
}
|
||||
}
|
||||
private void setResValueInternal(BaseResValue resValue){
|
||||
if(resValue==mResValue){
|
||||
return;
|
||||
}
|
||||
@ -52,6 +88,9 @@ public class EntryBlock extends Block {
|
||||
mResValue.setIndex(-1);
|
||||
mResValue.setParent(null);
|
||||
}
|
||||
if(resValue!=null){
|
||||
setNull(false);
|
||||
}
|
||||
mResValue=resValue;
|
||||
}
|
||||
|
||||
@ -62,7 +101,6 @@ public class EntryBlock extends Block {
|
||||
setFlags(FLAG_INT);
|
||||
}
|
||||
refreshHeaderSize();
|
||||
refreshResValue();
|
||||
}
|
||||
|
||||
public ResConfig getResConfig(){
|
||||
@ -217,7 +255,7 @@ public class EntryBlock extends Block {
|
||||
}else {
|
||||
resValue=new ResValueInt();
|
||||
}
|
||||
setResValue(resValue);
|
||||
setResValueInternal(resValue);
|
||||
}
|
||||
|
||||
private boolean isFlagsComplex(){
|
||||
|
@ -106,7 +106,7 @@ public class ResConfig extends BlockArray<Block> implements BlockLoad {
|
||||
return new Block[len];
|
||||
}
|
||||
|
||||
public void parseName(String name){
|
||||
public void parseQualifiers(String name){
|
||||
ResConfigHelper.parseQualifiers(this, name);
|
||||
mQualifiers=null;
|
||||
}
|
||||
@ -488,6 +488,21 @@ public class ResConfig extends BlockArray<Block> implements BlockLoad {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEqualQualifiers(String qualifiers){
|
||||
if(qualifiers==null){
|
||||
qualifiers="";
|
||||
}
|
||||
qualifiers=ResConfigHelper.sortQualifiers(qualifiers);
|
||||
return getQualifiers().equals(qualifiers);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o){
|
||||
if(o instanceof ResConfig){
|
||||
ResConfig config=(ResConfig)o;
|
||||
return getQualifiers().equals(config.getQualifiers());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
String q=getQualifiers();
|
||||
|
@ -5,9 +5,11 @@ import com.reandroid.lib.arsc.base.Block;
|
||||
import com.reandroid.lib.arsc.base.BlockCounter;
|
||||
import com.reandroid.lib.arsc.io.BlockReader;
|
||||
import com.reandroid.lib.arsc.item.IntegerItem;
|
||||
import com.reandroid.lib.arsc.item.ReferenceItem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ResValueBag extends BaseResValue {
|
||||
@ -28,6 +30,20 @@ public class ResValueBag extends BaseResValue {
|
||||
mResValueBagItemArray.setParent(this);
|
||||
mResValueBagItemArray.setIndex(2);
|
||||
}
|
||||
public List<ReferenceItem> getTableStringReferences(){
|
||||
List<ReferenceItem> results=null;
|
||||
for(ResValueBagItem bagItem:getResValueBagItemArray().listItems()){
|
||||
ReferenceItem ref=bagItem.getTableStringReference();
|
||||
if(ref==null){
|
||||
continue;
|
||||
}
|
||||
if(results==null){
|
||||
results=new ArrayList<>();
|
||||
}
|
||||
results.add(ref);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
public ResValueBagItemArray getResValueBagItemArray(){
|
||||
return mResValueBagItemArray;
|
||||
}
|
||||
@ -122,44 +138,5 @@ public class ResValueBag extends BaseResValue {
|
||||
}
|
||||
|
||||
|
||||
// NOT Applicable
|
||||
@Override
|
||||
void setHeaderSize(short size) {
|
||||
}
|
||||
// NOT Applicable
|
||||
@Override
|
||||
short getHeaderSize() {
|
||||
return HEADER_COMPLEX;
|
||||
}
|
||||
// NOT Applicable
|
||||
@Override
|
||||
void setReserved(byte reserved) {
|
||||
}
|
||||
// NOT Applicable
|
||||
@Override
|
||||
byte getReserved() {
|
||||
return 0;
|
||||
}
|
||||
// NOT Applicable
|
||||
@Override
|
||||
public void setType(byte type) {
|
||||
}
|
||||
|
||||
// NOT Applicable
|
||||
@Override
|
||||
public byte getType() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOT Applicable
|
||||
@Override
|
||||
public int getData() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOT Applicable
|
||||
@Override
|
||||
public void setData(int data) { }
|
||||
|
||||
private final static short HEADER_COMPLEX=0x0010;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.reandroid.lib.arsc.value;
|
||||
|
||||
public class ResValueBagItem extends BaseResValue {
|
||||
public class ResValueBagItem extends BaseResValueItem{
|
||||
|
||||
public ResValueBagItem() {
|
||||
super(BYTES_COUNT);
|
||||
@ -8,19 +8,19 @@ public class ResValueBagItem extends BaseResValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
void setHeaderSize(short size) {
|
||||
public void setHeaderSize(short size) {
|
||||
setShort(OFFSET_SIZE, size);
|
||||
}
|
||||
@Override
|
||||
short getHeaderSize() {
|
||||
public short getHeaderSize() {
|
||||
return getShort(OFFSET_SIZE);
|
||||
}
|
||||
@Override
|
||||
void setReserved(byte reserved) {
|
||||
public void setReserved(byte reserved) {
|
||||
setByte(OFFSET_RESERVED, reserved);
|
||||
}
|
||||
@Override
|
||||
byte getReserved() {
|
||||
public byte getReserved() {
|
||||
return getByte(OFFSET_RESERVED);
|
||||
}
|
||||
|
||||
@ -32,6 +32,14 @@ public class ResValueBagItem extends BaseResValue {
|
||||
return getInt(OFFSET_ID);
|
||||
}
|
||||
@Override
|
||||
public void setType(ValueType valueType){
|
||||
byte type=0;
|
||||
if(valueType!=null){
|
||||
type=valueType.getByte();
|
||||
}
|
||||
setType(type);
|
||||
}
|
||||
@Override
|
||||
public void setType(byte type){
|
||||
setByte(OFFSET_TYPE, type);
|
||||
}
|
||||
|
@ -1,29 +1,30 @@
|
||||
package com.reandroid.lib.arsc.value;
|
||||
|
||||
import com.reandroid.lib.arsc.io.BlockReader;
|
||||
import com.reandroid.lib.arsc.item.ReferenceItem;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ResValueInt extends BaseResValue {
|
||||
public class ResValueInt extends BaseResValueItem {
|
||||
public ResValueInt() {
|
||||
super(BYTES_COUNT);
|
||||
setHeaderSize(BYTES_SIZE);
|
||||
}
|
||||
@Override
|
||||
void setHeaderSize(short size) {
|
||||
public void setHeaderSize(short size) {
|
||||
setShort(OFFSET_SIZE, size);
|
||||
}
|
||||
@Override
|
||||
short getHeaderSize() {
|
||||
public short getHeaderSize() {
|
||||
return getShort(OFFSET_SIZE);
|
||||
}
|
||||
@Override
|
||||
void setReserved(byte reserved) {
|
||||
public void setReserved(byte reserved) {
|
||||
setByte(OFFSET_RESERVED, reserved);
|
||||
}
|
||||
@Override
|
||||
byte getReserved() {
|
||||
public byte getReserved() {
|
||||
return getByte(OFFSET_RESERVED);
|
||||
}
|
||||
@Override
|
||||
|
16
src/main/java/com/reandroid/lib/arsc/value/ResValueItem.java
Normal file
16
src/main/java/com/reandroid/lib/arsc/value/ResValueItem.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.reandroid.lib.arsc.value;
|
||||
|
||||
public interface ResValueItem {
|
||||
void setHeaderSize(short size);
|
||||
short getHeaderSize();
|
||||
|
||||
void setReserved(byte reserved);
|
||||
byte getReserved();
|
||||
|
||||
void setType(byte type);
|
||||
void setType(ValueType valueType);
|
||||
byte getType();
|
||||
|
||||
int getData();
|
||||
void setData(int data);
|
||||
}
|
Reference in New Issue
Block a user