mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-05-01 14:44:27 +02:00
Minor bug fix
This commit is contained in:
parent
c288c50c89
commit
5826eb8a47
@ -15,7 +15,6 @@
|
||||
*/
|
||||
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.IntegerItem;
|
||||
import com.reandroid.lib.arsc.value.BaseResValue;
|
||||
@ -56,12 +55,27 @@ public class EntryBlockArray extends OffsetBlockArray<EntryBlock> implements JSO
|
||||
public EntryBlock newInstance() {
|
||||
return new EntryBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntryBlock[] newInstance(int 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
|
||||
public JSONArray toJson() {
|
||||
JSONArray jsonArray=new JSONArray();
|
||||
|
@ -254,6 +254,27 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
|
||||
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
|
||||
public int compare(SpecTypePair typePair1, SpecTypePair typePair2) {
|
||||
return typePair1.compareTo(typePair2);
|
||||
|
@ -302,6 +302,21 @@ public class TypeBlockArray extends BlockArray<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
|
||||
public int compare(TypeBlock typeBlock1, TypeBlock typeBlock2) {
|
||||
return typeBlock1.compareTo(typeBlock2);
|
||||
|
@ -47,8 +47,7 @@ public abstract class Block {
|
||||
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{
|
||||
if(isNull()){
|
||||
|
@ -323,6 +323,14 @@ public class PackageBlock extends BaseChunk
|
||||
getLibraryBlock().merge(packageBlock.getLibraryBlock());
|
||||
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
|
||||
public int compareTo(PackageBlock pkg) {
|
||||
return Integer.compare(getId(), pkg.getId());
|
||||
|
@ -190,6 +190,14 @@ public class TypeBlock extends BaseTypeBlock
|
||||
}
|
||||
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
|
||||
public String toString(){
|
||||
StringBuilder builder=new StringBuilder();
|
||||
|
@ -15,8 +15,6 @@
|
||||
*/
|
||||
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 java.io.File;
|
||||
@ -76,10 +74,10 @@ public class AndroidManifestBlock extends ResXmlBlock{
|
||||
List<ResXmlElement> permissionList = manifestElement.listElements(TAG_uses_permission);
|
||||
for(ResXmlElement permission:permissionList){
|
||||
ResXmlAttribute nameAttr = permission.searchAttributeByResourceId(ID_name);
|
||||
if(nameAttr==null){
|
||||
if(nameAttr==null||nameAttr.getValueType()!=ValueType.STRING){
|
||||
continue;
|
||||
}
|
||||
String val=nameAttr.getValueString();
|
||||
String val=nameAttr.getValueAsString();
|
||||
if(val!=null){
|
||||
results.add(val);
|
||||
}
|
||||
@ -94,10 +92,10 @@ public class AndroidManifestBlock extends ResXmlBlock{
|
||||
List<ResXmlElement> permissionList = manifestElement.listElements(TAG_uses_permission);
|
||||
for(ResXmlElement permission:permissionList){
|
||||
ResXmlAttribute nameAttr = permission.searchAttributeByResourceId(ID_name);
|
||||
if(nameAttr==null){
|
||||
if(nameAttr==null || nameAttr.getValueType()!=ValueType.STRING){
|
||||
continue;
|
||||
}
|
||||
String val=nameAttr.getValueString();
|
||||
String val=nameAttr.getValueAsString();
|
||||
if(val==null){
|
||||
continue;
|
||||
}
|
||||
@ -112,87 +110,93 @@ public class AndroidManifestBlock extends ResXmlBlock{
|
||||
if(manifestElement==null){
|
||||
return null;
|
||||
}
|
||||
ResXmlElement exist=getUsesPermission(permissionName);
|
||||
ResXmlElement exist = getUsesPermission(permissionName);
|
||||
if(exist!=null){
|
||||
return exist;
|
||||
}
|
||||
ResXmlElement result=manifestElement.createChildElement(TAG_uses_permission);
|
||||
ResXmlElement result = manifestElement.createChildElement(TAG_uses_permission);
|
||||
ResXmlAttribute attr = result.createAndroidAttribute(NAME_name, ID_name);
|
||||
attr.setValueAsString(permissionName);
|
||||
return result;
|
||||
}
|
||||
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){
|
||||
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(){
|
||||
return getManifestAttributeInt(NAME_compileSdkVersion);
|
||||
return getManifestAttributeInt(ID_compileSdkVersion);
|
||||
}
|
||||
public boolean setCompileSdkVersion(int val){
|
||||
return setManifestAttributeInt(ID_compileSdkVersion, val);
|
||||
}
|
||||
public String getCompileSdkVersionCodename(){
|
||||
return getManifestAttributeString(NAME_compileSdkVersionCodename);
|
||||
return getManifestAttributeString(ID_compileSdkVersionCodename);
|
||||
}
|
||||
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(){
|
||||
return getManifestAttributeInt(NAME_versionCode);
|
||||
return getManifestAttributeInt(ID_versionCode);
|
||||
}
|
||||
public boolean setVersionCode(int val){
|
||||
return setManifestAttributeInt(NAME_versionCode, val);
|
||||
return setManifestAttributeInt(ID_versionCode, val);
|
||||
}
|
||||
public String getVersionName(){
|
||||
return getManifestAttributeString(NAME_versionName);
|
||||
return getManifestAttributeString(ID_versionName);
|
||||
}
|
||||
public boolean setVersionName(String packageName){
|
||||
return setManifestAttributeString(NAME_versionName, packageName);
|
||||
return setManifestAttributeString(ID_versionName, packageName);
|
||||
}
|
||||
private String getManifestAttributeString(String name){
|
||||
ResXmlElement manifestElement=getManifestElement();
|
||||
if(manifestElement==null){
|
||||
private String getManifestAttributeString(int resourceId){
|
||||
ResXmlElement manifest=getManifestElement();
|
||||
if(manifest==null){
|
||||
return null;
|
||||
}
|
||||
ResXmlAttribute attribute= manifestElement.searchAttributeByName(name);
|
||||
if(attribute==null){
|
||||
ResXmlAttribute attribute = manifest.searchAttributeByResourceId(resourceId);
|
||||
if(attribute==null || attribute.getValueType()!=ValueType.STRING){
|
||||
return null;
|
||||
}
|
||||
int raw=attribute.getRawValue();
|
||||
ResXmlStringPool pool = getStringPool();
|
||||
ResXmlString resXmlString = pool.get(raw);
|
||||
if(resXmlString==null){
|
||||
return null;
|
||||
}
|
||||
return resXmlString.getHtml();
|
||||
return attribute.getValueAsString();
|
||||
}
|
||||
private boolean setManifestAttributeString(int resId, String value){
|
||||
private boolean setManifestAttributeString(int resourceId, String value){
|
||||
ResXmlElement manifestElement=getManifestElement();
|
||||
if(manifestElement==null){
|
||||
return false;
|
||||
}
|
||||
ResXmlAttribute attribute= manifestElement.searchAttributeByResourceId(resId);
|
||||
ResXmlAttribute attribute = manifestElement.searchAttributeByResourceId(resourceId);
|
||||
if(attribute==null){
|
||||
return false;
|
||||
}
|
||||
attribute.setValueType(ValueType.STRING);
|
||||
ResXmlString resXmlString=attribute.setValueString(value);
|
||||
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;
|
||||
attribute.setValueAsString(value);
|
||||
return true;
|
||||
}
|
||||
private boolean setManifestAttributeInt(int resId, int value){
|
||||
ResXmlElement manifestElement=getManifestElement();
|
||||
@ -203,32 +207,16 @@ public class AndroidManifestBlock extends ResXmlBlock{
|
||||
if(attribute==null){
|
||||
return false;
|
||||
}
|
||||
attribute.setValueType(ValueType.INT_DEC);
|
||||
attribute.setValueString(String.valueOf(value));
|
||||
attribute.setRawValue(value);
|
||||
attribute.setValueAsIntegerDec(value);
|
||||
return true;
|
||||
}
|
||||
private boolean setManifestAttributeInt(String name, int value){
|
||||
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){
|
||||
private Integer getManifestAttributeInt(int resourceId){
|
||||
ResXmlElement manifestElement=getManifestElement();
|
||||
if(manifestElement==null){
|
||||
return null;
|
||||
}
|
||||
ResXmlAttribute attribute= manifestElement.searchAttributeByName(name);
|
||||
if(attribute==null){
|
||||
ResXmlAttribute attribute= manifestElement.searchAttributeByResourceId(resourceId);
|
||||
if(attribute==null || attribute.getValueType()!=ValueType.INT_DEC){
|
||||
return null;
|
||||
}
|
||||
return attribute.getRawValue();
|
||||
@ -324,6 +312,8 @@ public class AndroidManifestBlock extends ResXmlBlock{
|
||||
public static final String NAME_name = "name";
|
||||
public static final String NAME_extractNativeLibs = "extractNativeLibs";
|
||||
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_compileSdkVersion = 0x01010572;
|
||||
@ -334,6 +324,10 @@ public class AndroidManifestBlock extends ResXmlBlock{
|
||||
public static final int ID_screenOrientation = 0x0101001e;
|
||||
public static final int ID_extractNativeLibs = 0x010104ea;
|
||||
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";
|
||||
|
||||
|
@ -178,22 +178,10 @@ import java.util.Set;
|
||||
}
|
||||
return xmlElement.getStartNamespaceByUriRef(getNamespaceReference());
|
||||
}
|
||||
@Deprecated
|
||||
public String getValueString(){
|
||||
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(){
|
||||
return getResourceId(getNameReference());
|
||||
}
|
||||
@ -313,8 +301,8 @@ import java.util.Set;
|
||||
setRawValue(ref);
|
||||
setValueStringReference(-1);
|
||||
}
|
||||
public void setValueAsInteger(int val){
|
||||
setValueType(ValueType.FIRST_INT);
|
||||
public void setValueAsIntegerDec(int val){
|
||||
setValueType(ValueType.INT_DEC);
|
||||
setRawValue(val);
|
||||
setValueStringReference(-1);
|
||||
}
|
||||
@ -362,18 +350,6 @@ import java.util.Set;
|
||||
setRawValue(val);
|
||||
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
|
||||
public int compareTo(ResXmlAttribute other) {
|
||||
int id1=getNameResourceID();
|
||||
@ -473,7 +449,7 @@ import java.util.Set;
|
||||
}
|
||||
static final String NAME_id = "id";
|
||||
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_data= "data";
|
||||
}
|
||||
|
@ -88,6 +88,21 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
mSpecBlock.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(){
|
||||
return mSpecBlock;
|
||||
}
|
||||
@ -118,7 +133,7 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
return results;
|
||||
}
|
||||
public Collection<TypeBlock> listTypeBlocks(){
|
||||
return mTypeBlockArray.listItems();
|
||||
return getTypeBlockArray().listItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -29,7 +29,8 @@ public abstract class BlockItem extends Block {
|
||||
super();
|
||||
mBytes=new byte[bytesLength];
|
||||
}
|
||||
public abstract void onBytesChanged();
|
||||
protected void onBytesChanged(){
|
||||
}
|
||||
protected byte[] getBytesInternal() {
|
||||
return mBytes;
|
||||
}
|
||||
|
@ -149,10 +149,6 @@ public class ByteArray extends BlockItem {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBytesChanged() {
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return "size="+size();
|
||||
|
@ -44,9 +44,6 @@ public class ByteItem extends BlockItem {
|
||||
return getBytesInternal()[0];
|
||||
}
|
||||
@Override
|
||||
public void onBytesChanged() {
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return String.valueOf(get());
|
||||
}
|
||||
|
@ -49,18 +49,16 @@ public class IntegerArray extends BlockItem {
|
||||
}
|
||||
}
|
||||
public final List<Integer> toList(){
|
||||
List<Integer> results=new AbstractList<Integer>() {
|
||||
return new AbstractList<Integer>() {
|
||||
@Override
|
||||
public Integer get(int i) {
|
||||
return IntegerArray.this.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return IntegerArray.this.size();
|
||||
}
|
||||
};
|
||||
return results;
|
||||
}
|
||||
public final int[] toArray(){
|
||||
int s=size();
|
||||
@ -112,8 +110,4 @@ public class IntegerArray extends BlockItem {
|
||||
bts[i+1]= (byte) (value >>> 8 & 0xff);
|
||||
bts[i]= (byte) (value & 0xff);
|
||||
}
|
||||
@Override
|
||||
public void onBytesChanged() {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -41,11 +41,9 @@ public class IntegerItem extends BlockItem implements ReferenceItem{
|
||||
public int get(){
|
||||
return mCache;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onBytesChanged() {
|
||||
protected void onBytesChanged() {
|
||||
// To save cpu usage, better to calculate once only when bytes changed
|
||||
mCache=readIntBytes();
|
||||
}
|
||||
private int readIntBytes(){
|
||||
|
@ -38,7 +38,8 @@ public class ShortItem extends BlockItem {
|
||||
return mCache;
|
||||
}
|
||||
@Override
|
||||
public void onBytesChanged() {
|
||||
protected void onBytesChanged() {
|
||||
// To save cpu usage, better to calculate once only when bytes changed
|
||||
mCache=readShortBytes();
|
||||
}
|
||||
private short readShortBytes(){
|
||||
|
@ -118,12 +118,11 @@ public class StringItem extends BlockItem implements JSONConvert<JSONObject> {
|
||||
mUtf8=utf8;
|
||||
onBytesChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBytesChanged() {
|
||||
protected void onBytesChanged() {
|
||||
// To save cpu/memory usage, better to decode once only when bytes changed
|
||||
mCache=decodeString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReadBytes(BlockReader reader) throws IOException {
|
||||
if(reader.available()<4){
|
||||
|
@ -254,9 +254,6 @@ public class StyleItem extends IntegerArray implements JSONConvert<JSONObject> {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public void onBytesChanged() {
|
||||
}
|
||||
@Override
|
||||
public void setNull(boolean is_null){
|
||||
if(!is_null){
|
||||
return;
|
||||
|
@ -16,11 +16,19 @@
|
||||
package com.reandroid.lib.arsc.item;
|
||||
|
||||
|
||||
public class TypeString extends StringItem {
|
||||
import com.reandroid.lib.arsc.base.Block;
|
||||
import com.reandroid.lib.arsc.pool.TypeStringPool;
|
||||
|
||||
public class TypeString extends StringItem {
|
||||
public TypeString(boolean utf8) {
|
||||
super(utf8);
|
||||
}
|
||||
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);
|
||||
}
|
||||
@Override
|
||||
@ -28,4 +36,14 @@ public class TypeString extends StringItem {
|
||||
// Type don't have style unless to obfuscate/confuse other decompilers
|
||||
return null;
|
||||
}
|
||||
private TypeStringPool getTypeStringPool(){
|
||||
Block parent=this;
|
||||
while (parent!=null){
|
||||
if(parent instanceof TypeStringPool){
|
||||
return (TypeStringPool) parent;
|
||||
}
|
||||
parent=parent.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -144,6 +144,9 @@ public abstract class BaseStringPool<T extends StringItem> extends BaseChunk imp
|
||||
public List<T> listUnusedStrings(){
|
||||
return getStringsArray().listUnusedStrings();
|
||||
}
|
||||
public Collection<T> listStrings(){
|
||||
return getStringsArray().listItems();
|
||||
}
|
||||
public StyleArray getStyleArray(){
|
||||
return mArrayStyles;
|
||||
}
|
||||
@ -195,7 +198,7 @@ public abstract class BaseStringPool<T extends StringItem> extends BaseChunk imp
|
||||
public final StringGroup<T> get(String str){
|
||||
return mUniqueMap.get(str);
|
||||
}
|
||||
public final T getOrCreate(String str){
|
||||
public T getOrCreate(String str){
|
||||
StringGroup<T> group=getOrCreateGroup(str);
|
||||
T[] items=group.getItems();
|
||||
if(items.length==0){
|
||||
|
@ -17,20 +17,44 @@ package com.reandroid.lib.arsc.pool;
|
||||
|
||||
import com.reandroid.lib.arsc.array.StringArray;
|
||||
import com.reandroid.lib.arsc.array.TypeStringArray;
|
||||
import com.reandroid.lib.arsc.header.HeaderBlock;
|
||||
import com.reandroid.lib.arsc.io.BlockReader;
|
||||
import com.reandroid.lib.arsc.chunk.TypeBlock;
|
||||
import com.reandroid.lib.arsc.group.StringGroup;
|
||||
import com.reandroid.lib.arsc.item.IntegerArray;
|
||||
import com.reandroid.lib.arsc.item.IntegerItem;
|
||||
import com.reandroid.lib.arsc.item.TypeString;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TypeStringPool extends BaseStringPool<TypeString> {
|
||||
private final IntegerItem mTypeIdOffset;
|
||||
public TypeStringPool(boolean is_utf8, IntegerItem typeIdOffset) {
|
||||
super(is_utf8);
|
||||
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){
|
||||
int index=id-mTypeIdOffset.get()-1;
|
||||
return super.get(index);
|
||||
@ -42,6 +66,19 @@ public class TypeStringPool extends BaseStringPool<TypeString> {
|
||||
typeString.set(typeName);
|
||||
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
|
||||
StringArray<TypeString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
return new TypeStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||
|
@ -39,9 +39,92 @@ public class FrameworkTable extends TableBlock {
|
||||
private String mFrameworkTitle;
|
||||
private String mFrameworkName;
|
||||
private String mFrameworkVersion;
|
||||
private Map<String, Map<String, EntryGroup>> mNameGroupMap;
|
||||
private final Object mMapLock=new Object();
|
||||
public FrameworkTable(){
|
||||
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(){
|
||||
if(mFrameworkTitle==null){
|
||||
mFrameworkTitle=loadProperty(PROP_TITLE);
|
||||
|
@ -66,10 +66,6 @@ public abstract class BaseResValue extends BlockItem implements JSONConvert<JSON
|
||||
return;
|
||||
}
|
||||
entryBlock.addTableReference(ref);
|
||||
}
|
||||
@Override
|
||||
public void onBytesChanged() {
|
||||
|
||||
}
|
||||
void onDataLoaded() {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user