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