mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-05-04 16:14:24 +02:00
fix merge error
This commit is contained in:
parent
eb805b7979
commit
0206c73908
@ -64,10 +64,10 @@ package com.reandroid.apk.xmlencoder;
|
||||
public InputSource encodeFileEntry(File resFile){
|
||||
String type = EncodeUtil.getTypeNameFromResFile(resFile);
|
||||
PackageBlock packageBlock = materials.getCurrentPackage();
|
||||
byte typeId=packageBlock
|
||||
int typeId=packageBlock
|
||||
.getTypeStringPool().idOf(type);
|
||||
String qualifiers = EncodeUtil.getQualifiersFromResFile(resFile);
|
||||
TypeBlock typeBlock = packageBlock.getOrCreateTypeBlock(typeId, qualifiers);
|
||||
TypeBlock typeBlock = packageBlock.getOrCreateTypeBlock((byte)typeId, qualifiers);
|
||||
String name = EncodeUtil.getEntryNameFromResFile(resFile);
|
||||
int resourceId=materials.resolveLocalResourceId(type, name);
|
||||
|
||||
|
@ -92,7 +92,7 @@ class XMLValuesEncoder {
|
||||
private TypeBlock getTypeBlock(String type, String qualifiers){
|
||||
PackageBlock packageBlock = getMaterials().getCurrentPackage();
|
||||
TypeStringPool typeStringPool = packageBlock.getTypeStringPool();
|
||||
byte typeId = typeStringPool.idOf(type);
|
||||
byte typeId = (byte) typeStringPool.idOf(type);
|
||||
SpecTypePair specTypePair
|
||||
= packageBlock.getSpecTypePairArray().getOrCreate(typeId);
|
||||
int highest = specTypePair.getHighestEntryCount();
|
||||
|
@ -122,25 +122,9 @@ public class EntryBlockArray extends OffsetBlockArray<EntryBlock> implements JSO
|
||||
while (itr.hasNext()){
|
||||
EntryBlock comingBlock=itr.next();
|
||||
EntryBlock existingBlock=get(comingBlock.getIndex());
|
||||
if(shouldMerge(existingBlock, comingBlock)){
|
||||
existingBlock.merge(comingBlock);
|
||||
}
|
||||
existingBlock.merge(comingBlock);
|
||||
}
|
||||
}
|
||||
private boolean shouldMerge(EntryBlock exist, EntryBlock coming){
|
||||
if(exist.isNull()){
|
||||
return true;
|
||||
}
|
||||
if(coming.isNull()){
|
||||
return false;
|
||||
}
|
||||
BaseResValue resVal = coming.getResValue();
|
||||
if(resVal instanceof ResValueInt){
|
||||
ValueType valueType=((ResValueInt)resVal).getValueType();
|
||||
return valueType!=ValueType.INT_BOOLEAN;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return getClass().getSimpleName()+": size="+childesCount();
|
||||
|
@ -102,10 +102,6 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
|
||||
if(item==null || item.isNull()){
|
||||
offset=-1;
|
||||
}else {
|
||||
// slow but accurate
|
||||
//offset=countUpTo(item);
|
||||
|
||||
// fast but fails for duplicate items
|
||||
offset=sum;
|
||||
sum+=item.countBytes();
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
|
||||
if(pair==null){
|
||||
continue;
|
||||
}
|
||||
int id=pair.getTypeIdInt();
|
||||
int id=pair.getId();
|
||||
if(!firstFound){
|
||||
result=id;
|
||||
}
|
||||
@ -204,7 +204,7 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
|
||||
if(pair==null){
|
||||
continue;
|
||||
}
|
||||
int id=pair.getTypeIdInt();
|
||||
int id=pair.getId();
|
||||
if(id>result){
|
||||
result=id;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.reandroid.arsc.base.Block;
|
||||
import com.reandroid.arsc.base.BlockArray;
|
||||
import com.reandroid.arsc.chunk.SpecBlock;
|
||||
import com.reandroid.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.arsc.container.SpecTypePair;
|
||||
import com.reandroid.arsc.header.HeaderBlock;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.item.TypeString;
|
||||
@ -142,16 +143,12 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
}
|
||||
}
|
||||
public byte getTypeId(){
|
||||
if(mTypeId != 0){
|
||||
return mTypeId;
|
||||
}
|
||||
SpecBlock specBlock=getSpecBlock();
|
||||
if(specBlock!=null){
|
||||
byte id=specBlock.getTypeId();
|
||||
if(id!=0){
|
||||
mTypeId=id;
|
||||
return id;
|
||||
}
|
||||
return specBlock.getTypeId();
|
||||
}
|
||||
if(mTypeId != 0){
|
||||
return mTypeId;
|
||||
}
|
||||
TypeBlock[] allChildes=getChildes();
|
||||
if(allChildes==null){
|
||||
@ -192,8 +189,8 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
private SpecBlock getSpecBlock(){
|
||||
Block parent=getParent();
|
||||
while(parent!=null){
|
||||
if(parent instanceof SpecBlock){
|
||||
return (SpecBlock)parent;
|
||||
if(parent instanceof SpecTypePair){
|
||||
return ((SpecTypePair) parent).getSpecBlock();
|
||||
}
|
||||
parent=parent.getParent();
|
||||
}
|
||||
|
7
src/main/java/com/reandroid/arsc/chunk/MainChunk.java
Normal file
7
src/main/java/com/reandroid/arsc/chunk/MainChunk.java
Normal file
@ -0,0 +1,7 @@
|
||||
package com.reandroid.arsc.chunk;
|
||||
|
||||
import com.reandroid.arsc.pool.StringPool;
|
||||
|
||||
public interface MainChunk {
|
||||
public StringPool<?> getStringPool();
|
||||
}
|
@ -30,6 +30,7 @@ package com.reandroid.arsc.chunk;
|
||||
import com.reandroid.arsc.pool.TypeStringPool;
|
||||
import com.reandroid.arsc.value.EntryBlock;
|
||||
import com.reandroid.arsc.value.LibraryInfo;
|
||||
import com.reandroid.arsc.value.ResConfig;
|
||||
import com.reandroid.arsc.value.StagedAliasEntry;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONObject;
|
||||
@ -51,7 +52,7 @@ package com.reandroid.arsc.chunk;
|
||||
super(new PackageHeader(), 3);
|
||||
PackageHeader header = getHeaderBlock();
|
||||
|
||||
this.mTypeStringPool=new TypeStringPool(false, header.getTypeIdOffset());
|
||||
this.mTypeStringPool=new TypeStringPool(false, header.getTypeIdOffsetItem());
|
||||
this.mSpecStringPool=new SpecStringPool(true);
|
||||
|
||||
this.mBody = new PackageBody();
|
||||
@ -62,6 +63,34 @@ package com.reandroid.arsc.chunk;
|
||||
addChild(mSpecStringPool);
|
||||
addChild(mBody);
|
||||
}
|
||||
public EntryBlock getOrCreate(String qualifiers, String type, String name){
|
||||
ResConfig resConfig = new ResConfig();
|
||||
resConfig.parseQualifiers(qualifiers);
|
||||
return getOrCreate(resConfig, type, name);
|
||||
}
|
||||
public EntryBlock getOrCreate(ResConfig resConfig, String type, String name){
|
||||
SpecTypePair specTypePair = getOrCreateSpecType(type);
|
||||
TypeBlock typeBlock = specTypePair.getOrCreateTypeBlock(resConfig);
|
||||
return typeBlock.getOrCreateEntry(name);
|
||||
}
|
||||
public SpecTypePair getOrCreateSpecType(String type){
|
||||
int last = 0;
|
||||
for(SpecTypePair specTypePair:listAllSpecTypePair()){
|
||||
if(type.equals(specTypePair.getTypeName())){
|
||||
return specTypePair;
|
||||
}
|
||||
int id = specTypePair.getId();
|
||||
if(id>last){
|
||||
last=id;
|
||||
}
|
||||
}
|
||||
last++;
|
||||
getTypeStringPool().getOrCreate(last, type);
|
||||
return getSpecTypePairArray().getOrCreate((byte) last);
|
||||
}
|
||||
public int getTypeIdOffset(){
|
||||
return getHeaderBlock().getTypeIdOffset();
|
||||
}
|
||||
public BlockList<UnknownChunk> getUnknownChunkList(){
|
||||
return mBody.getUnknownChunkList();
|
||||
}
|
||||
@ -270,7 +299,7 @@ package com.reandroid.arsc.chunk;
|
||||
//int largest=getSpecTypePairArray().getHighestTypeId();
|
||||
//int count=getTypeStringPool().countStrings();
|
||||
//getHeaderBlock().getTypeIdOffset().set(count-largest);
|
||||
getHeaderBlock().getTypeIdOffset().set(0);
|
||||
getHeaderBlock().getTypeIdOffsetItem().set(0);
|
||||
}
|
||||
public void onEntryAdded(EntryBlock entryBlock){
|
||||
updateEntry(entryBlock);
|
||||
|
@ -42,14 +42,15 @@
|
||||
public byte getTypeId(){
|
||||
return getHeaderBlock().getId().get();
|
||||
}
|
||||
public int getTypeIdInt(){
|
||||
public int getId(){
|
||||
return getHeaderBlock().getId().unsignedInt();
|
||||
}
|
||||
public void setTypeId(int id){
|
||||
public void setId(int id){
|
||||
setTypeId((byte) (0xff & id));
|
||||
}
|
||||
public void setTypeId(byte id){
|
||||
getHeaderBlock().getId().set(id);
|
||||
getTypeBlockArray().setTypeId(id);
|
||||
}
|
||||
public TypeBlockArray getTypeBlockArray(){
|
||||
SpecTypePair specTypePair=getSpecTypePair();
|
||||
@ -94,12 +95,12 @@
|
||||
@Override
|
||||
public JSONObject toJson() {
|
||||
JSONObject jsonObject=new JSONObject();
|
||||
jsonObject.put(TypeBlock.NAME_id, getTypeIdInt());
|
||||
jsonObject.put(TypeBlock.NAME_id, getId());
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromJson(JSONObject json) {
|
||||
setTypeId(json.getInt(TypeBlock.NAME_id));
|
||||
setId(json.getInt(TypeBlock.NAME_id));
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import com.reandroid.arsc.header.HeaderBlock;
|
||||
import com.reandroid.arsc.header.InfoHeader;
|
||||
import com.reandroid.arsc.header.TableHeader;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.pool.StringPool;
|
||||
import com.reandroid.arsc.pool.TableStringPool;
|
||||
import com.reandroid.arsc.value.StagedAliasEntry;
|
||||
import com.reandroid.common.Frameworks;
|
||||
@ -34,7 +35,8 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class TableBlock extends Chunk<TableHeader> implements JSONConvert<JSONObject> {
|
||||
public class TableBlock extends Chunk<TableHeader>
|
||||
implements MainChunk, JSONConvert<JSONObject> {
|
||||
private final TableStringPool mTableStringPool;
|
||||
private final PackageArray mPackageArray;
|
||||
private final Set<TableBlock> mFrameWorks=new HashSet<>();
|
||||
@ -55,6 +57,10 @@ public class TableBlock extends Chunk<TableHeader> implements JSONConvert<JSONOb
|
||||
public Collection<PackageBlock> listPackages(){
|
||||
return getPackageArray().listItems();
|
||||
}
|
||||
@Override
|
||||
public TableStringPool getStringPool() {
|
||||
return mTableStringPool;
|
||||
}
|
||||
public TableStringPool getTableStringPool(){
|
||||
return mTableStringPool;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import com.reandroid.arsc.item.*;
|
||||
import com.reandroid.arsc.pool.TypeStringPool;
|
||||
import com.reandroid.arsc.value.EntryBlock;
|
||||
import com.reandroid.arsc.value.ResConfig;
|
||||
import com.reandroid.arsc.value.ValueType;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
@ -81,16 +82,16 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
return null;
|
||||
}
|
||||
TypeStringPool typeStringPool=packageBlock.getTypeStringPool();
|
||||
mTypeString=typeStringPool.getById(getTypeIdInt());
|
||||
mTypeString=typeStringPool.getById(getId());
|
||||
return mTypeString;
|
||||
}
|
||||
public byte getTypeId(){
|
||||
return getHeaderBlock().getId().get();
|
||||
}
|
||||
public int getTypeIdInt(){
|
||||
public int getId(){
|
||||
return getHeaderBlock().getId().unsignedInt();
|
||||
}
|
||||
public void setTypeId(int id){
|
||||
public void setId(int id){
|
||||
setTypeId((byte) (0xff & id));
|
||||
}
|
||||
public void setTypeId(byte id){
|
||||
@ -98,7 +99,7 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
}
|
||||
public void setTypeName(String name){
|
||||
TypeStringPool typeStringPool=getTypeStringPool();
|
||||
int id=getTypeIdInt();
|
||||
int id= getId();
|
||||
TypeString typeString=typeStringPool.getById(id);
|
||||
if(typeString==null){
|
||||
typeString=typeStringPool.getOrCreate(id, name);
|
||||
@ -162,6 +163,29 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
}
|
||||
entryBlock.setNull(true);
|
||||
}
|
||||
public EntryBlock getOrCreateEntry(String name){
|
||||
for(EntryBlock entryBlock:getEntryBlockArray().listItems()){
|
||||
if(name.equals(entryBlock.getName())){
|
||||
return entryBlock;
|
||||
}
|
||||
}
|
||||
SpecTypePair specTypePair = getParentSpecTypePair();
|
||||
EntryBlock exist=specTypePair.getAnyEntry(name);
|
||||
int id;
|
||||
if(exist!=null){
|
||||
id=exist.getIndex();
|
||||
}else {
|
||||
id = specTypePair.getHighestEntryCount();
|
||||
}
|
||||
SpecString specString = getPackageBlock()
|
||||
.getSpecStringPool().getOrCreate(name);
|
||||
EntryBlock entryBlock = getOrCreateEntry((short) id);
|
||||
if(entryBlock.isNull()){
|
||||
entryBlock.setValueAsRaw(ValueType.NULL, 0);
|
||||
}
|
||||
entryBlock.setSpecReference(specString.getIndex());
|
||||
return entryBlock;
|
||||
}
|
||||
public EntryBlock getOrCreateEntry(short entryId){
|
||||
return getEntryBlockArray().getOrCreate(entryId);
|
||||
}
|
||||
@ -219,7 +243,7 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
@Override
|
||||
public JSONObject toJson() {
|
||||
JSONObject jsonObject=new JSONObject();
|
||||
jsonObject.put(NAME_id, getTypeIdInt());
|
||||
jsonObject.put(NAME_id, getId());
|
||||
jsonObject.put(NAME_name, getTypeName());
|
||||
jsonObject.put(NAME_config, getResConfig().toJson());
|
||||
jsonObject.put(NAME_entries, getEntryBlockArray().toJson());
|
||||
@ -227,7 +251,7 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
}
|
||||
@Override
|
||||
public void fromJson(JSONObject json) {
|
||||
setTypeId(json.getInt(NAME_id));
|
||||
setId(json.getInt(NAME_id));
|
||||
String name = json.optString(NAME_name);
|
||||
if(name!=null){
|
||||
setTypeName(name);
|
||||
@ -250,8 +274,8 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
}
|
||||
@Override
|
||||
public int compareTo(TypeBlock typeBlock) {
|
||||
int id1=getTypeIdInt();
|
||||
int id2=typeBlock.getTypeIdInt();
|
||||
int id1= getId();
|
||||
int id2=typeBlock.getId();
|
||||
if(id1!=id2){
|
||||
return Integer.compare(id1, id2);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
import com.reandroid.arsc.chunk.Chunk;
|
||||
import com.reandroid.arsc.chunk.ChunkType;
|
||||
import com.reandroid.arsc.chunk.MainChunk;
|
||||
import com.reandroid.arsc.container.SingleBlockContainer;
|
||||
import com.reandroid.arsc.header.HeaderBlock;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
@ -36,7 +37,8 @@
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ResXmlDocument extends Chunk<HeaderBlock> implements JSONConvert<JSONObject> {
|
||||
public class ResXmlDocument extends Chunk<HeaderBlock>
|
||||
implements MainChunk, JSONConvert<JSONObject> {
|
||||
private final ResXmlStringPool mResXmlStringPool;
|
||||
private final ResXmlIDMap mResXmlIDMap;
|
||||
private ResXmlElement mResXmlElement;
|
||||
@ -160,6 +162,7 @@
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public ResXmlStringPool getStringPool(){
|
||||
return mResXmlStringPool;
|
||||
}
|
||||
|
@ -53,6 +53,15 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
public SpecTypePair(){
|
||||
this(new SpecBlock(), new TypeBlockArray());
|
||||
}
|
||||
public EntryBlock getAnyEntry(String name){
|
||||
for(TypeBlock typeBlock:listTypeBlocks()){
|
||||
EntryBlock entryBlock=typeBlock.searchByEntryName(name);
|
||||
if(entryBlock!=null){
|
||||
return entryBlock;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void sortTypes(){
|
||||
getTypeBlockArray().sort();
|
||||
}
|
||||
@ -74,6 +83,9 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
public TypeBlock getOrCreateTypeBlock(String qualifiers){
|
||||
return getTypeBlockArray().getOrCreate(qualifiers);
|
||||
}
|
||||
public TypeBlock getOrCreateTypeBlock(ResConfig resConfig){
|
||||
return getTypeBlockArray().getOrCreate(resConfig);
|
||||
}
|
||||
public TypeBlock getTypeBlock(String qualifiers){
|
||||
return getTypeBlockArray().getTypeBlock(qualifiers);
|
||||
}
|
||||
@ -84,8 +96,8 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
public byte getTypeId(){
|
||||
return mSpecBlock.getTypeId();
|
||||
}
|
||||
public int getTypeIdInt(){
|
||||
return mSpecBlock.getTypeIdInt();
|
||||
public int getId(){
|
||||
return mSpecBlock.getId();
|
||||
}
|
||||
public void setTypeId(byte id){
|
||||
mSpecBlock.setTypeId(id);
|
||||
@ -177,13 +189,17 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
return typeEntryCount;
|
||||
}
|
||||
public TypeString getTypeString(){
|
||||
return getTypeBlockArray().getTypeString();
|
||||
PackageBlock packageBlock = getPackageBlock();
|
||||
if(packageBlock!=null){
|
||||
return packageBlock.getTypeStringPool().getById(getId());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject toJson() {
|
||||
JSONObject jsonObject=new JSONObject();
|
||||
jsonObject.put("id", getSpecBlock().getTypeIdInt());
|
||||
jsonObject.put("id", getSpecBlock().getId());
|
||||
jsonObject.put("types", getTypeBlockArray().toJson());
|
||||
return jsonObject;
|
||||
}
|
||||
@ -204,7 +220,7 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
}
|
||||
@Override
|
||||
public int compareTo(SpecTypePair specTypePair) {
|
||||
return Integer.compare(getTypeIdInt(), specTypePair.getTypeIdInt());
|
||||
return Integer.compare(getId(), specTypePair.getId());
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
|
@ -72,9 +72,19 @@ public class PackageHeader extends HeaderBlock{
|
||||
public IntegerItem getSpecStringPoolCount() {
|
||||
return specStringPoolCount;
|
||||
}
|
||||
public IntegerItem getTypeIdOffset() {
|
||||
public IntegerItem getTypeIdOffsetItem() {
|
||||
return typeIdOffset;
|
||||
}
|
||||
public void setTypeIdOffset(int offset){
|
||||
typeIdOffset.set(offset);
|
||||
typeIdOffsetContainer.setItem(typeIdOffset);
|
||||
}
|
||||
public int getTypeIdOffset() {
|
||||
if(typeIdOffset.getParent()==null){
|
||||
typeIdOffset.set(0);
|
||||
}
|
||||
return typeIdOffset.get();
|
||||
}
|
||||
@Override
|
||||
void onHeaderSizeLoaded(int size){
|
||||
super.onHeaderSizeLoaded(size);
|
||||
|
@ -47,6 +47,16 @@ import java.io.*;
|
||||
public BlockReader(File file) throws IOException {
|
||||
this(loadBuffer(file));
|
||||
}
|
||||
public int readUnsignedShort() throws IOException {
|
||||
return 0x0000ffff & readShort();
|
||||
}
|
||||
public short readShort() throws IOException {
|
||||
int pos = getPosition();
|
||||
byte[] bts = new byte[2];
|
||||
readFully(bts);
|
||||
seek(pos);
|
||||
return toShort(bts, 0);
|
||||
}
|
||||
public InfoHeader readHeaderBlock() throws IOException {
|
||||
InfoHeader infoHeader = new InfoHeader();
|
||||
if(available() < infoHeader.countBytes()){
|
||||
@ -80,6 +90,10 @@ import java.io.*;
|
||||
(bts[offset+2] & 0xff) << 16 |
|
||||
(bts[offset+3] & 0xff) << 24;
|
||||
}
|
||||
private short toShort(byte[] bts, int offset){
|
||||
return (short) (bts[offset] & 0xff |
|
||||
(bts[offset+1] & 0xff) << 8);
|
||||
}
|
||||
public byte[] getBytes(){
|
||||
int len = length();
|
||||
if(this.BUFFER.length == len){
|
||||
|
@ -48,7 +48,7 @@ public abstract class BlockItem extends Block {
|
||||
final void setBytesLength(int length){
|
||||
setBytesLength(length, true);
|
||||
}
|
||||
final void setBytesLength(int length, boolean notify){
|
||||
protected final void setBytesLength(int length, boolean notify){
|
||||
if(length<0){
|
||||
length=0;
|
||||
}
|
||||
@ -122,4 +122,30 @@ public abstract class BlockItem extends Block {
|
||||
super.notifyBlockLoad();
|
||||
return bts.length;
|
||||
}
|
||||
|
||||
protected static int getInteger(byte[] bts, int offset){
|
||||
if((offset+4)>bts.length){
|
||||
return 0;
|
||||
}
|
||||
return bts[offset] & 0xff |
|
||||
(bts[offset+1] & 0xff) << 8 |
|
||||
(bts[offset+2] & 0xff) << 16 |
|
||||
(bts[offset+3] & 0xff) << 24;
|
||||
}
|
||||
protected static short getShort(byte[] bts, int offset){
|
||||
return (short) (bts[offset] & 0xff | (bts[offset+1] & 0xff) << 8);
|
||||
}
|
||||
protected static void putInteger(byte[] bts, int offset, int val){
|
||||
if((offset+4)>bts.length){
|
||||
return;
|
||||
}
|
||||
bts[offset+3]= (byte) (val >>> 24 & 0xff);
|
||||
bts[offset+2]= (byte) (val >>> 16 & 0xff);
|
||||
bts[offset+1]= (byte) (val >>> 8 & 0xff);
|
||||
bts[offset]= (byte) (val & 0xff);
|
||||
}
|
||||
protected static void putShort(byte[] bts, int offset, short val){
|
||||
bts[offset+1]= (byte) (val >>> 8 & 0xff);
|
||||
bts[offset]= (byte) (val & 0xff);
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +105,9 @@ public class ByteArray extends BlockItem {
|
||||
}
|
||||
public final void putInteger(int offset, int val){
|
||||
byte[] bts = getBytesInternal();
|
||||
if((offset+4)>bts.length){
|
||||
return;
|
||||
}
|
||||
bts[offset+3]= (byte) (val >>> 24 & 0xff);
|
||||
bts[offset+2]= (byte) (val >>> 16 & 0xff);
|
||||
bts[offset+1]= (byte) (val >>> 8 & 0xff);
|
||||
@ -112,6 +115,9 @@ public class ByteArray extends BlockItem {
|
||||
}
|
||||
public final int getInteger(int offset){
|
||||
byte[] bts = getBytesInternal();
|
||||
if((offset+4)>bts.length){
|
||||
return 0;
|
||||
}
|
||||
return bts[offset] & 0xff |
|
||||
(bts[offset+1] & 0xff) << 8 |
|
||||
(bts[offset+2] & 0xff) << 16 |
|
||||
|
@ -17,7 +17,7 @@ package com.reandroid.arsc.item;
|
||||
|
||||
import com.reandroid.arsc.base.Block;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.pool.BaseStringPool;
|
||||
import com.reandroid.arsc.pool.StringPool;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONObject;
|
||||
|
||||
@ -212,18 +212,18 @@ public class StringItem extends BlockItem implements JSONConvert<JSONObject> {
|
||||
return styleItem.getSpanInfoList().size()>0;
|
||||
}
|
||||
public StyleItem getStyle(){
|
||||
BaseStringPool<?> stringPool=getStringPool();
|
||||
StringPool<?> stringPool=getStringPool();
|
||||
if(stringPool==null){
|
||||
return null;
|
||||
}
|
||||
int index=getIndex();
|
||||
return stringPool.getStyle(index);
|
||||
}
|
||||
private BaseStringPool<?> getStringPool(){
|
||||
private StringPool<?> getStringPool(){
|
||||
Block parent=getParent();
|
||||
while (parent!=null){
|
||||
if(parent instanceof BaseStringPool){
|
||||
return (BaseStringPool<?>)parent;
|
||||
if(parent instanceof StringPool){
|
||||
return (StringPool<?>)parent;
|
||||
}
|
||||
parent=parent.getParent();
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ package com.reandroid.arsc.item;
|
||||
import com.reandroid.arsc.base.Block;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.model.StyleSpanInfo;
|
||||
import com.reandroid.arsc.pool.BaseStringPool;
|
||||
import com.reandroid.arsc.pool.StringPool;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
import com.reandroid.json.JSONArray;
|
||||
import com.reandroid.json.JSONObject;
|
||||
@ -64,7 +64,7 @@ public class StyleItem extends IntegerArray implements JSONConvert<JSONObject> {
|
||||
super.put(i, val);
|
||||
}
|
||||
public void addStylePiece(String tag, int firstChar, int lastChar){
|
||||
BaseStringPool<?> stringPool = getStringPool();
|
||||
StringPool<?> stringPool = getStringPool();
|
||||
if(stringPool==null){
|
||||
throw new IllegalArgumentException("Null string pool, must be added to parent StyleArray first");
|
||||
}
|
||||
@ -188,7 +188,7 @@ public class StyleItem extends IntegerArray implements JSONConvert<JSONObject> {
|
||||
return mSpanInfoList;
|
||||
}
|
||||
private String getStringFromPool(int ref){
|
||||
BaseStringPool<?> stringPool = getStringPool();
|
||||
StringPool<?> stringPool = getStringPool();
|
||||
if(stringPool==null){
|
||||
return null;
|
||||
}
|
||||
@ -198,11 +198,11 @@ public class StyleItem extends IntegerArray implements JSONConvert<JSONObject> {
|
||||
}
|
||||
return stringItem.get();
|
||||
}
|
||||
private BaseStringPool<?> getStringPool(){
|
||||
private StringPool<?> getStringPool(){
|
||||
Block parent=getParent();
|
||||
while (parent!=null){
|
||||
if(parent instanceof BaseStringPool){
|
||||
return (BaseStringPool<?>)parent;
|
||||
if(parent instanceof StringPool){
|
||||
return (StringPool<?>)parent;
|
||||
}
|
||||
parent=parent.getParent();
|
||||
}
|
||||
@ -310,7 +310,7 @@ public class StyleItem extends IntegerArray implements JSONConvert<JSONObject> {
|
||||
public void addSpanInfo(String tag, int first, int last){
|
||||
int index=getStylePieceCount();
|
||||
setStylePieceCount(index+1);
|
||||
BaseStringPool<?> stringPool = getStringPool();
|
||||
StringPool<?> stringPool = getStringPool();
|
||||
if(stringPool==null){
|
||||
throw new IllegalArgumentException("Null string pool, must be added to parent StyleArray first");
|
||||
}
|
||||
|
@ -23,13 +23,13 @@ package com.reandroid.arsc.item;
|
||||
public TypeString(boolean utf8) {
|
||||
super(utf8);
|
||||
}
|
||||
public byte getId(){
|
||||
public int getId(){
|
||||
TypeStringPool stringPool=getTypeStringPool();
|
||||
if(stringPool!=null){
|
||||
return stringPool.idOf(this);
|
||||
}
|
||||
// Should not reach here , this means it not added to string pool
|
||||
return (byte) (getIndex()+1);
|
||||
return getIndex()+1;
|
||||
}
|
||||
@Override
|
||||
public StyleItem getStyle(){
|
||||
|
@ -475,7 +475,7 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
||||
return 0;
|
||||
}
|
||||
int pkgId=packageBlock.getId();
|
||||
int typeId=typeBlock.getTypeIdInt();
|
||||
int typeId=typeBlock.getId();
|
||||
int entryId=getIndex();
|
||||
return ((pkgId << 24) | (typeId << 16) | entryId);
|
||||
}
|
||||
@ -607,7 +607,7 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
||||
if(isNull()){
|
||||
return;
|
||||
}
|
||||
counter.addCount(countBytes());
|
||||
//counter.addCount(countBytes());
|
||||
entryHeader.onCountUpTo(counter);
|
||||
mSpecReference.onCountUpTo(counter);
|
||||
mResValue.onCountUpTo(counter);
|
||||
@ -712,7 +712,7 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
||||
mResValue.onDataLoaded();
|
||||
}
|
||||
public void merge(EntryBlock entryBlock){
|
||||
if(entryBlock==null||entryBlock==this||entryBlock.isNull()){
|
||||
if(!shouldMerge(entryBlock)){
|
||||
return;
|
||||
}
|
||||
String name=entryBlock.getName();
|
||||
@ -736,6 +736,27 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
||||
setPublic(entryBlock.isPublic());
|
||||
setWeak(entryBlock.isWeak());
|
||||
}
|
||||
private boolean shouldMerge(EntryBlock coming){
|
||||
if(coming == null || coming == this || coming.isNull()){
|
||||
return false;
|
||||
}
|
||||
if(this.isNull()){
|
||||
return true;
|
||||
}
|
||||
BaseResValue value = this.getResValue();
|
||||
if(value instanceof ResValueInt){
|
||||
ValueType valueType = ((ResValueInt)value).getValueType();
|
||||
if(valueType==null || valueType==ValueType.NULL){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
value = coming.getResValue();
|
||||
if(value instanceof ResValueInt){
|
||||
ValueType valueType = ((ResValueInt)value).getValueType();
|
||||
return valueType!=null && valueType != ValueType.NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private ResValueBag getOrCreateResValueBag(){
|
||||
if(mResValue instanceof ResValueBag){
|
||||
return (ResValueBag) mResValue;
|
||||
|
@ -166,7 +166,7 @@ public class ResValueBag extends BaseResValue {
|
||||
refreshCount();
|
||||
}
|
||||
public void merge(ResValueBag resValueBag){
|
||||
if(resValueBag==null||resValueBag==this){
|
||||
if(resValueBag==null || resValueBag==this || resValueBag.getCount()==0){
|
||||
return;
|
||||
}
|
||||
setParentId(resValueBag.getParentId());
|
||||
|
@ -228,6 +228,8 @@ public class ResValueBagItem extends BaseResValueItem{
|
||||
}else {
|
||||
builder.append("Unknown");
|
||||
}
|
||||
builder.append(" size=").append(getHeaderSize());
|
||||
builder.append(" bytes=").append(countBytes());
|
||||
builder.append('(');
|
||||
builder.append(String.format("0x%02x", getType()));
|
||||
builder.append(") id=");
|
||||
|
Loading…
x
Reference in New Issue
Block a user