Minor bug fix

This commit is contained in:
REAndroid 2022-12-26 10:37:09 -05:00
parent c288c50c89
commit 5826eb8a47
22 changed files with 306 additions and 136 deletions

View File

@ -15,7 +15,6 @@
*/ */
package com.reandroid.lib.arsc.array; package com.reandroid.lib.arsc.array;
import com.reandroid.lib.arsc.chunk.TypeBlock;
import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerArray;
import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.value.BaseResValue; import com.reandroid.lib.arsc.value.BaseResValue;
@ -56,12 +55,27 @@ public class EntryBlockArray extends OffsetBlockArray<EntryBlock> implements JSO
public EntryBlock newInstance() { public EntryBlock newInstance() {
return new EntryBlock(); return new EntryBlock();
} }
@Override @Override
public EntryBlock[] newInstance(int len) { public EntryBlock[] newInstance(int len) {
return new EntryBlock[len]; return new EntryBlock[len];
} }
/**
* It is allowed to have duplicate entry name therefore it is not recommend to use this.
* Lets depreciate to warn developer
*/
@Deprecated
public EntryBlock searchByEntryName(String entryName){
if(entryName==null){
return null;
}
for(EntryBlock entryBlock:listItems()){
if(entryName.equals(entryBlock.getName())){
return entryBlock;
}
}
return null;
}
@Override @Override
public JSONArray toJson() { public JSONArray toJson() {
JSONArray jsonArray=new JSONArray(); JSONArray jsonArray=new JSONArray();

View File

@ -254,6 +254,27 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
exist.merge(typePair); exist.merge(typePair);
} }
} }
/**
* It is allowed to have duplicate type name therefore it is not recommend to use this.
* Lets depreciate to warn developer
*/
@Deprecated
public SpecTypePair searchByTypeName(String typeName){
if(typeName==null){
return null;
}
SpecTypePair[] childes=getChildes();
if(childes==null){
return null;
}
for(int i=0;i<childes.length;i++){
SpecTypePair specTypePair=childes[i];
if(typeName.equals(specTypePair.getTypeName())){
return specTypePair;
}
}
return null;
}
@Override @Override
public int compare(SpecTypePair typePair1, SpecTypePair typePair2) { public int compare(SpecTypePair typePair1, SpecTypePair typePair2) {
return typePair1.compareTo(typePair2); return typePair1.compareTo(typePair2);

View File

@ -302,6 +302,21 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
block.merge(typeBlock); block.merge(typeBlock);
} }
} }
/**
* It is allowed to have duplicate entry name therefore it is not recommend to use this.
* Lets depreciate to warn developer
*/
@Deprecated
public EntryBlock searchByEntryName(String entryName){
if(entryName==null){
return null;
}
TypeBlock[] childes = getChildes();
if(childes==null || childes.length==0){
return null;
}
return childes[0].searchByEntryName(entryName);
}
@Override @Override
public int compare(TypeBlock typeBlock1, TypeBlock typeBlock2) { public int compare(TypeBlock typeBlock1, TypeBlock typeBlock2) {
return typeBlock1.compareTo(typeBlock2); return typeBlock1.compareTo(typeBlock2);

View File

@ -47,8 +47,7 @@ public abstract class Block {
blockLoad.onBlockLoaded(reader, this); blockLoad.onBlockLoaded(reader, this);
} }
} }
public void onReadBytes(BlockReader reader) throws IOException{ protected void onReadBytes(BlockReader reader) throws IOException{
} }
public final int writeBytes(OutputStream stream) throws IOException{ public final int writeBytes(OutputStream stream) throws IOException{
if(isNull()){ if(isNull()){

View File

@ -323,6 +323,14 @@ public class PackageBlock extends BaseChunk
getLibraryBlock().merge(packageBlock.getLibraryBlock()); getLibraryBlock().merge(packageBlock.getLibraryBlock());
getSpecTypePairArray().merge(packageBlock.getSpecTypePairArray()); getSpecTypePairArray().merge(packageBlock.getSpecTypePairArray());
} }
/**
* It is allowed to have duplicate type name therefore it is not recommend to use this.
* Lets depreciate to warn developer
*/
@Deprecated
public SpecTypePair searchByTypeName(String typeName){
return getSpecTypePairArray().searchByTypeName(typeName);
}
@Override @Override
public int compareTo(PackageBlock pkg) { public int compareTo(PackageBlock pkg) {
return Integer.compare(getId(), pkg.getId()); return Integer.compare(getId(), pkg.getId());

View File

@ -190,6 +190,14 @@ public class TypeBlock extends BaseTypeBlock
} }
return getResConfig().compareTo(typeBlock.getResConfig()); return getResConfig().compareTo(typeBlock.getResConfig());
} }
/**
* It is allowed to have duplicate entry name therefore it is not recommend to use this.
* Lets depreciate to warn developer
*/
@Deprecated
public EntryBlock searchByEntryName(String entryName){
return getEntryBlockArray().searchByEntryName(entryName);
}
@Override @Override
public String toString(){ public String toString(){
StringBuilder builder=new StringBuilder(); StringBuilder builder=new StringBuilder();

View File

@ -15,8 +15,6 @@
*/ */
package com.reandroid.lib.arsc.chunk.xml; package com.reandroid.lib.arsc.chunk.xml;
import com.reandroid.lib.arsc.item.ResXmlString;
import com.reandroid.lib.arsc.pool.ResXmlStringPool;
import com.reandroid.lib.arsc.value.ValueType; import com.reandroid.lib.arsc.value.ValueType;
import java.io.File; import java.io.File;
@ -76,10 +74,10 @@ public class AndroidManifestBlock extends ResXmlBlock{
List<ResXmlElement> permissionList = manifestElement.listElements(TAG_uses_permission); List<ResXmlElement> permissionList = manifestElement.listElements(TAG_uses_permission);
for(ResXmlElement permission:permissionList){ for(ResXmlElement permission:permissionList){
ResXmlAttribute nameAttr = permission.searchAttributeByResourceId(ID_name); ResXmlAttribute nameAttr = permission.searchAttributeByResourceId(ID_name);
if(nameAttr==null){ if(nameAttr==null||nameAttr.getValueType()!=ValueType.STRING){
continue; continue;
} }
String val=nameAttr.getValueString(); String val=nameAttr.getValueAsString();
if(val!=null){ if(val!=null){
results.add(val); results.add(val);
} }
@ -94,10 +92,10 @@ public class AndroidManifestBlock extends ResXmlBlock{
List<ResXmlElement> permissionList = manifestElement.listElements(TAG_uses_permission); List<ResXmlElement> permissionList = manifestElement.listElements(TAG_uses_permission);
for(ResXmlElement permission:permissionList){ for(ResXmlElement permission:permissionList){
ResXmlAttribute nameAttr = permission.searchAttributeByResourceId(ID_name); ResXmlAttribute nameAttr = permission.searchAttributeByResourceId(ID_name);
if(nameAttr==null){ if(nameAttr==null || nameAttr.getValueType()!=ValueType.STRING){
continue; continue;
} }
String val=nameAttr.getValueString(); String val=nameAttr.getValueAsString();
if(val==null){ if(val==null){
continue; continue;
} }
@ -122,77 +120,83 @@ public class AndroidManifestBlock extends ResXmlBlock{
return result; return result;
} }
public String getPackageName(){ public String getPackageName(){
return getManifestAttributeString(NAME_PACKAGE); ResXmlElement manifest=getManifestElement();
if(manifest==null){
return null;
}
ResXmlAttribute attribute = manifest.searchAttributeByName(NAME_PACKAGE);
if(attribute==null || attribute.getValueType()!=ValueType.STRING){
return null;
}
return attribute.getValueAsString();
} }
public boolean setPackageName(String packageName){ public boolean setPackageName(String packageName){
return setManifestAttributeString(NAME_PACKAGE, packageName); ResXmlElement manifestElement=getManifestElement();
if(manifestElement==null){
return false;
}
ResXmlAttribute attribute= manifestElement.searchAttributeByName(NAME_PACKAGE);
if(attribute==null){
return false;
}
attribute.setValueAsString(packageName);
return true;
} }
public Integer getCompileSdkVersion(){ public Integer getCompileSdkVersion(){
return getManifestAttributeInt(NAME_compileSdkVersion); return getManifestAttributeInt(ID_compileSdkVersion);
} }
public boolean setCompileSdkVersion(int val){ public boolean setCompileSdkVersion(int val){
return setManifestAttributeInt(ID_compileSdkVersion, val); return setManifestAttributeInt(ID_compileSdkVersion, val);
} }
public String getCompileSdkVersionCodename(){ public String getCompileSdkVersionCodename(){
return getManifestAttributeString(NAME_compileSdkVersionCodename); return getManifestAttributeString(ID_compileSdkVersionCodename);
} }
public boolean setCompileSdkVersionCodename(String val){ public boolean setCompileSdkVersionCodename(String val){
return setManifestAttributeString(ID_compileSdkVersionCodename, val); ResXmlElement manifest=getManifestElement();
if(manifest==null){
return false;
}
ResXmlAttribute attribute = manifest.searchAttributeByResourceId(ID_compileSdkVersionCodename);
if(attribute==null){
return false;
}
attribute.setValueAsString(val);
return true;
} }
public Integer getVersionCode(){ public Integer getVersionCode(){
return getManifestAttributeInt(NAME_versionCode); return getManifestAttributeInt(ID_versionCode);
} }
public boolean setVersionCode(int val){ public boolean setVersionCode(int val){
return setManifestAttributeInt(NAME_versionCode, val); return setManifestAttributeInt(ID_versionCode, val);
} }
public String getVersionName(){ public String getVersionName(){
return getManifestAttributeString(NAME_versionName); return getManifestAttributeString(ID_versionName);
} }
public boolean setVersionName(String packageName){ public boolean setVersionName(String packageName){
return setManifestAttributeString(NAME_versionName, packageName); return setManifestAttributeString(ID_versionName, packageName);
} }
private String getManifestAttributeString(String name){ private String getManifestAttributeString(int resourceId){
ResXmlElement manifestElement=getManifestElement(); ResXmlElement manifest=getManifestElement();
if(manifestElement==null){ if(manifest==null){
return null; return null;
} }
ResXmlAttribute attribute= manifestElement.searchAttributeByName(name); ResXmlAttribute attribute = manifest.searchAttributeByResourceId(resourceId);
if(attribute==null){ if(attribute==null || attribute.getValueType()!=ValueType.STRING){
return null; return null;
} }
int raw=attribute.getRawValue(); return attribute.getValueAsString();
ResXmlStringPool pool = getStringPool();
ResXmlString resXmlString = pool.get(raw);
if(resXmlString==null){
return null;
} }
return resXmlString.getHtml(); private boolean setManifestAttributeString(int resourceId, String value){
}
private boolean setManifestAttributeString(int resId, String value){
ResXmlElement manifestElement=getManifestElement(); ResXmlElement manifestElement=getManifestElement();
if(manifestElement==null){ if(manifestElement==null){
return false; return false;
} }
ResXmlAttribute attribute= manifestElement.searchAttributeByResourceId(resId); ResXmlAttribute attribute = manifestElement.searchAttributeByResourceId(resourceId);
if(attribute==null){ if(attribute==null){
return false; return false;
} }
attribute.setValueType(ValueType.STRING); attribute.setValueAsString(value);
ResXmlString resXmlString=attribute.setValueString(value); return true;
return resXmlString!=null;
}
private boolean setManifestAttributeString(String name, String value){
ResXmlElement manifestElement=getManifestElement();
if(manifestElement==null){
return false;
}
ResXmlAttribute attribute= manifestElement.searchAttributeByName(name);
if(attribute==null){
return false;
}
attribute.setValueType(ValueType.STRING);
ResXmlString resXmlString=attribute.setValueString(value);
return resXmlString!=null;
} }
private boolean setManifestAttributeInt(int resId, int value){ private boolean setManifestAttributeInt(int resId, int value){
ResXmlElement manifestElement=getManifestElement(); ResXmlElement manifestElement=getManifestElement();
@ -203,32 +207,16 @@ public class AndroidManifestBlock extends ResXmlBlock{
if(attribute==null){ if(attribute==null){
return false; return false;
} }
attribute.setValueType(ValueType.INT_DEC); attribute.setValueAsIntegerDec(value);
attribute.setValueString(String.valueOf(value));
attribute.setRawValue(value);
return true; return true;
} }
private boolean setManifestAttributeInt(String name, int value){ private Integer getManifestAttributeInt(int resourceId){
ResXmlElement manifestElement=getManifestElement();
if(manifestElement==null){
return false;
}
ResXmlAttribute attribute= manifestElement.searchAttributeByName(name);
if(attribute==null){
return false;
}
attribute.setValueType(ValueType.INT_DEC);
attribute.setValueString(String.valueOf(value));
attribute.setRawValue(value);
return true;
}
private Integer getManifestAttributeInt(String name){
ResXmlElement manifestElement=getManifestElement(); ResXmlElement manifestElement=getManifestElement();
if(manifestElement==null){ if(manifestElement==null){
return null; return null;
} }
ResXmlAttribute attribute= manifestElement.searchAttributeByName(name); ResXmlAttribute attribute= manifestElement.searchAttributeByResourceId(resourceId);
if(attribute==null){ if(attribute==null || attribute.getValueType()!=ValueType.INT_DEC){
return null; return null;
} }
return attribute.getRawValue(); return attribute.getRawValue();
@ -324,6 +312,8 @@ public class AndroidManifestBlock extends ResXmlBlock{
public static final String NAME_name = "name"; public static final String NAME_name = "name";
public static final String NAME_extractNativeLibs = "extractNativeLibs"; public static final String NAME_extractNativeLibs = "extractNativeLibs";
public static final String NAME_isSplitRequired = "isSplitRequired"; public static final String NAME_isSplitRequired = "isSplitRequired";
public static final String NAME_value = "value";
public static final String NAME_resource = "resource";
public static final int ID_name = 0x01010003; public static final int ID_name = 0x01010003;
public static final int ID_compileSdkVersion = 0x01010572; public static final int ID_compileSdkVersion = 0x01010572;
@ -334,6 +324,10 @@ public class AndroidManifestBlock extends ResXmlBlock{
public static final int ID_screenOrientation = 0x0101001e; public static final int ID_screenOrientation = 0x0101001e;
public static final int ID_extractNativeLibs = 0x010104ea; public static final int ID_extractNativeLibs = 0x010104ea;
public static final int ID_isSplitRequired = 0x01010591; public static final int ID_isSplitRequired = 0x01010591;
public static final int ID_value = 0x01010024;
public static final int ID_resource = 0x01010025;
public static final int ID_versionCode = 0x0101021b;
public static final int ID_versionName = 0x0101021c;
public static final String VALUE_android_intent_action_MAIN = "android.intent.action.MAIN"; public static final String VALUE_android_intent_action_MAIN = "android.intent.action.MAIN";

View File

@ -178,22 +178,10 @@ import java.util.Set;
} }
return xmlElement.getStartNamespaceByUriRef(getNamespaceReference()); return xmlElement.getStartNamespaceByUriRef(getNamespaceReference());
} }
@Deprecated
public String getValueString(){ public String getValueString(){
return getString(getValueStringReference()); return getString(getValueStringReference());
} }
ResXmlString setValueString(String str){
ResXmlString resXmlString=getOrCreateResXmlString(str);
if(resXmlString==null){
return null;
}
int ref=resXmlString.getIndex();
setValueStringReference(ref);
if(getValueType()==ValueType.STRING){
setRawValue(ref);
setValueStringReference(ref);
}
return resXmlString;
}
public int getNameResourceID(){ public int getNameResourceID(){
return getResourceId(getNameReference()); return getResourceId(getNameReference());
} }
@ -313,8 +301,8 @@ import java.util.Set;
setRawValue(ref); setRawValue(ref);
setValueStringReference(-1); setValueStringReference(-1);
} }
public void setValueAsInteger(int val){ public void setValueAsIntegerDec(int val){
setValueType(ValueType.FIRST_INT); setValueType(ValueType.INT_DEC);
setRawValue(val); setRawValue(val);
setValueStringReference(-1); setValueStringReference(-1);
} }
@ -362,18 +350,6 @@ import java.util.Set;
setRawValue(val); setRawValue(val);
setValueStringReference(-1); setValueStringReference(-1);
} }
private String getCompareName(){
int id=getNameResourceID();
StringBuilder builder=new StringBuilder();
if(id!=0){
builder.append("0 ");
builder.append(String.format("%08x", id));
}else {
builder.append("1 ");
builder.append(getName());
}
return builder.toString();
}
@Override @Override
public int compareTo(ResXmlAttribute other) { public int compareTo(ResXmlAttribute other) {
int id1=getNameResourceID(); int id1=getNameResourceID();
@ -473,7 +449,7 @@ import java.util.Set;
} }
static final String NAME_id = "id"; static final String NAME_id = "id";
public static final String NAME_value_type = "value_type"; public static final String NAME_value_type = "value_type";
static final String NAME_name = "name"; public static final String NAME_name = "name";
public static final String NAME_namespace_uri = "namespace_uri"; public static final String NAME_namespace_uri = "namespace_uri";
public static final String NAME_data= "data"; public static final String NAME_data= "data";
} }

View File

@ -88,6 +88,21 @@ public class SpecTypePair extends BlockContainer<Block>
mSpecBlock.setTypeId(id); mSpecBlock.setTypeId(id);
mTypeBlockArray.setTypeId(id); mTypeBlockArray.setTypeId(id);
} }
public String getTypeName(){
TypeString typeString = getTypeString();
if(typeString!=null){
return typeString.get();
}
return null;
}
/**
* It is allowed to have duplicate entry name therefore it is not recommend to use this.
* Lets depreciate to warn developer
*/
@Deprecated
public EntryBlock searchByEntryName(String entryName){
return getTypeBlockArray().searchByEntryName(entryName);
}
public SpecBlock getSpecBlock(){ public SpecBlock getSpecBlock(){
return mSpecBlock; return mSpecBlock;
} }
@ -118,7 +133,7 @@ public class SpecTypePair extends BlockContainer<Block>
return results; return results;
} }
public Collection<TypeBlock> listTypeBlocks(){ public Collection<TypeBlock> listTypeBlocks(){
return mTypeBlockArray.listItems(); return getTypeBlockArray().listItems();
} }
@Override @Override

View File

@ -29,7 +29,8 @@ public abstract class BlockItem extends Block {
super(); super();
mBytes=new byte[bytesLength]; mBytes=new byte[bytesLength];
} }
public abstract void onBytesChanged(); protected void onBytesChanged(){
}
protected byte[] getBytesInternal() { protected byte[] getBytesInternal() {
return mBytes; return mBytes;
} }

View File

@ -149,10 +149,6 @@ public class ByteArray extends BlockItem {
} }
}; };
} }
@Override
public void onBytesChanged() {
}
@Override @Override
public String toString(){ public String toString(){
return "size="+size(); return "size="+size();

View File

@ -44,9 +44,6 @@ public class ByteItem extends BlockItem {
return getBytesInternal()[0]; return getBytesInternal()[0];
} }
@Override @Override
public void onBytesChanged() {
}
@Override
public String toString(){ public String toString(){
return String.valueOf(get()); return String.valueOf(get());
} }

View File

@ -49,18 +49,16 @@ public class IntegerArray extends BlockItem {
} }
} }
public final List<Integer> toList(){ public final List<Integer> toList(){
List<Integer> results=new AbstractList<Integer>() { return new AbstractList<Integer>() {
@Override @Override
public Integer get(int i) { public Integer get(int i) {
return IntegerArray.this.get(i); return IntegerArray.this.get(i);
} }
@Override @Override
public int size() { public int size() {
return IntegerArray.this.size(); return IntegerArray.this.size();
} }
}; };
return results;
} }
public final int[] toArray(){ public final int[] toArray(){
int s=size(); int s=size();
@ -112,8 +110,4 @@ public class IntegerArray extends BlockItem {
bts[i+1]= (byte) (value >>> 8 & 0xff); bts[i+1]= (byte) (value >>> 8 & 0xff);
bts[i]= (byte) (value & 0xff); bts[i]= (byte) (value & 0xff);
} }
@Override
public void onBytesChanged() {
}
} }

View File

@ -41,11 +41,9 @@ public class IntegerItem extends BlockItem implements ReferenceItem{
public int get(){ public int get(){
return mCache; return mCache;
} }
@Override @Override
public void onBytesChanged() { protected void onBytesChanged() {
// To save cpu usage, better to calculate once only when bytes changed
mCache=readIntBytes(); mCache=readIntBytes();
} }
private int readIntBytes(){ private int readIntBytes(){

View File

@ -38,7 +38,8 @@ public class ShortItem extends BlockItem {
return mCache; return mCache;
} }
@Override @Override
public void onBytesChanged() { protected void onBytesChanged() {
// To save cpu usage, better to calculate once only when bytes changed
mCache=readShortBytes(); mCache=readShortBytes();
} }
private short readShortBytes(){ private short readShortBytes(){

View File

@ -118,12 +118,11 @@ public class StringItem extends BlockItem implements JSONConvert<JSONObject> {
mUtf8=utf8; mUtf8=utf8;
onBytesChanged(); onBytesChanged();
} }
@Override @Override
public void onBytesChanged() { protected void onBytesChanged() {
// To save cpu/memory usage, better to decode once only when bytes changed
mCache=decodeString(); mCache=decodeString();
} }
@Override @Override
public void onReadBytes(BlockReader reader) throws IOException { public void onReadBytes(BlockReader reader) throws IOException {
if(reader.available()<4){ if(reader.available()<4){

View File

@ -254,9 +254,6 @@ public class StyleItem extends IntegerArray implements JSONConvert<JSONObject> {
return true; return true;
} }
@Override @Override
public void onBytesChanged() {
}
@Override
public void setNull(boolean is_null){ public void setNull(boolean is_null){
if(!is_null){ if(!is_null){
return; return;

View File

@ -16,11 +16,19 @@
package com.reandroid.lib.arsc.item; package com.reandroid.lib.arsc.item;
import com.reandroid.lib.arsc.base.Block;
import com.reandroid.lib.arsc.pool.TypeStringPool;
public class TypeString extends StringItem { public class TypeString extends StringItem {
public TypeString(boolean utf8) { public TypeString(boolean utf8) {
super(utf8); super(utf8);
} }
public byte getId(){ public byte 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 (byte) (getIndex()+1);
} }
@Override @Override
@ -28,4 +36,14 @@ public class TypeString extends StringItem {
// Type don't have style unless to obfuscate/confuse other decompilers // Type don't have style unless to obfuscate/confuse other decompilers
return null; return null;
} }
private TypeStringPool getTypeStringPool(){
Block parent=this;
while (parent!=null){
if(parent instanceof TypeStringPool){
return (TypeStringPool) parent;
}
parent=parent.getParent();
}
return null;
}
} }

View File

@ -144,6 +144,9 @@ public abstract class BaseStringPool<T extends StringItem> extends BaseChunk imp
public List<T> listUnusedStrings(){ public List<T> listUnusedStrings(){
return getStringsArray().listUnusedStrings(); return getStringsArray().listUnusedStrings();
} }
public Collection<T> listStrings(){
return getStringsArray().listItems();
}
public StyleArray getStyleArray(){ public StyleArray getStyleArray(){
return mArrayStyles; return mArrayStyles;
} }
@ -195,7 +198,7 @@ public abstract class BaseStringPool<T extends StringItem> extends BaseChunk imp
public final StringGroup<T> get(String str){ public final StringGroup<T> get(String str){
return mUniqueMap.get(str); return mUniqueMap.get(str);
} }
public final T getOrCreate(String str){ public T getOrCreate(String str){
StringGroup<T> group=getOrCreateGroup(str); StringGroup<T> group=getOrCreateGroup(str);
T[] items=group.getItems(); T[] items=group.getItems();
if(items.length==0){ if(items.length==0){

View File

@ -17,20 +17,44 @@ package com.reandroid.lib.arsc.pool;
import com.reandroid.lib.arsc.array.StringArray; import com.reandroid.lib.arsc.array.StringArray;
import com.reandroid.lib.arsc.array.TypeStringArray; import com.reandroid.lib.arsc.array.TypeStringArray;
import com.reandroid.lib.arsc.header.HeaderBlock; import com.reandroid.lib.arsc.chunk.TypeBlock;
import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.group.StringGroup;
import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerArray;
import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.item.TypeString; import com.reandroid.lib.arsc.item.TypeString;
import java.io.IOException;
public class TypeStringPool extends BaseStringPool<TypeString> { public class TypeStringPool extends BaseStringPool<TypeString> {
private final IntegerItem mTypeIdOffset; private final IntegerItem mTypeIdOffset;
public TypeStringPool(boolean is_utf8, IntegerItem typeIdOffset) { public TypeStringPool(boolean is_utf8, IntegerItem typeIdOffset) {
super(is_utf8); super(is_utf8);
this.mTypeIdOffset = typeIdOffset; this.mTypeIdOffset = typeIdOffset;
} }
public byte idOf(String typeName){
return idOf(getByName(typeName));
}
/**
* Resolves id of {@link TypeBlock}
* Not recommend to use unless unless you are sure of proper pool
**/
public byte idOf(TypeString typeString){
if(typeString==null){
return 0;
}
return (byte) (typeString.getIndex()+mTypeIdOffset.get()+1);
}
/**
* Searches string entry {@link TypeBlock}
* {@param name} is name of {@link TypeBlock}
* This might not working if duplicate type names are present
**/
public TypeString getByName(String name){
for(TypeString typeString:listStrings()){
if(name.equals(typeString.get())){
return typeString;
}
}
return null;
}
public TypeString getById(int id){ public TypeString getById(int id){
int index=id-mTypeIdOffset.get()-1; int index=id-mTypeIdOffset.get()-1;
return super.get(index); return super.get(index);
@ -42,6 +66,19 @@ public class TypeStringPool extends BaseStringPool<TypeString> {
typeString.set(typeName); typeString.set(typeName);
return typeString; return typeString;
} }
/**
* Use getOrCreate(typeId, typeName)}
**/
@Deprecated
@Override
public final TypeString getOrCreate(String str){
StringGroup<TypeString> group = get(str);
if(group==null||group.size()==0){
throw new IllegalArgumentException("Can not create TypeString (" + str
+") without type id. use getOrCreate(typeId, typeName)");
}
return group.get(0);
}
@Override @Override
StringArray<TypeString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) { StringArray<TypeString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
return new TypeStringArray(offsets, itemCount, itemStart, is_utf8); return new TypeStringArray(offsets, itemCount, itemStart, is_utf8);

View File

@ -39,9 +39,92 @@ public class FrameworkTable extends TableBlock {
private String mFrameworkTitle; private String mFrameworkTitle;
private String mFrameworkName; private String mFrameworkName;
private String mFrameworkVersion; private String mFrameworkVersion;
private Map<String, Map<String, EntryGroup>> mNameGroupMap;
private final Object mMapLock=new Object();
public FrameworkTable(){ public FrameworkTable(){
super(); super();
} }
public int resolveResourceId(String typeName, String entryName){
EntryBlock entryBlock=searchEntryBlock(typeName, entryName);
if(entryBlock!=null){
return entryBlock.getResourceId();
}
return 0;
}
/**
* Loads all resource name map to memory for faster use
* Call this if you plan to search entries frequently
*/
public void loadResourceNameMap(){
synchronized (mMapLock){
if(mNameGroupMap !=null){
return;
}
Map<String, Map<String, EntryGroup>> typeMap=new HashMap<>();
for(PackageBlock packageBlock:listPackages()){
for(EntryGroup group:packageBlock.listEntryGroup()){
String type=group.getTypeName();
Map<String, EntryGroup> groupMap=typeMap.get(type);
if(groupMap==null){
groupMap=new HashMap<>();
typeMap.put(type, groupMap);
}
groupMap.put(group.getSpecName(), group);
}
}
mNameGroupMap = typeMap;
}
}
/**
* Clears resource name map from memory
*/
public void clearResourceNameMap(){
synchronized (mMapLock){
if(mNameGroupMap!=null){
mNameGroupMap.clear();
mNameGroupMap =null;
}
}
}
private boolean hasResourceGroupMap(){
synchronized (mMapLock){
return mNameGroupMap!=null;
}
}
private EntryBlock searchEntryBlockFromMap(String typeName, String entryName){
synchronized (mMapLock){
if(mNameGroupMap ==null){
return null;
}
Map<String, EntryGroup> groupMap = mNameGroupMap.get(typeName);
if(groupMap!=null){
EntryGroup group=groupMap.get(entryName);
if(group!=null){
return group.pickOne();
}
}
return null;
}
}
public EntryBlock searchEntryBlock(String typeName, String entryName){
if(hasResourceGroupMap()){
return searchEntryBlockFromMap(typeName, entryName);
}
return searchEntryBlockFromTable(typeName, entryName);
}
/**
* Since this is framework, we are sure of proper names.
*/
public EntryBlock searchEntryBlockFromTable(String typeName, String entryName){
for(PackageBlock packageBlock:listPackages()){
SpecTypePair specTypePair = packageBlock.searchByTypeName(typeName);
if(specTypePair!=null){
return specTypePair.searchByEntryName(entryName);
}
}
return null;
}
public String getFrameworkTitle(){ public String getFrameworkTitle(){
if(mFrameworkTitle==null){ if(mFrameworkTitle==null){
mFrameworkTitle=loadProperty(PROP_TITLE); mFrameworkTitle=loadProperty(PROP_TITLE);

View File

@ -66,10 +66,6 @@ public abstract class BaseResValue extends BlockItem implements JSONConvert<JSON
return; return;
} }
entryBlock.addTableReference(ref); entryBlock.addTableReference(ref);
}
@Override
public void onBytesChanged() {
} }
void onDataLoaded() { void onDataLoaded() {