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;
|
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();
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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()){
|
||||||
|
@ -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());
|
||||||
|
@ -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();
|
||||||
|
@ -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";
|
||||||
|
|
||||||
|
@ -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";
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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(){
|
||||||
|
@ -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(){
|
||||||
|
@ -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){
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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){
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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() {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user