mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-30 06:14:25 +02:00
V1.0.6
This commit is contained in:
parent
2e29f7a7bb
commit
9d8421b0c7
@ -2,7 +2,7 @@
|
|||||||
apply plugin: 'java-library'
|
apply plugin: 'java-library'
|
||||||
|
|
||||||
group 'com.reandroid.lib.arsc'
|
group 'com.reandroid.lib.arsc'
|
||||||
version '1.0.5'
|
version '1.0.6'
|
||||||
|
|
||||||
java {
|
java {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
@ -114,5 +114,4 @@ public class ApkUtil {
|
|||||||
public static final String DEF_MODULE_NAME="base";
|
public static final String DEF_MODULE_NAME="base";
|
||||||
public static final String NAME_value_type="value_type";
|
public static final String NAME_value_type="value_type";
|
||||||
public static final String NAME_data="data";
|
public static final String NAME_data="data";
|
||||||
public static final String NAME_is_array="is_array";
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import com.reandroid.lib.arsc.chunk.PackageBlock;
|
|||||||
import com.reandroid.lib.arsc.chunk.TableBlock;
|
import com.reandroid.lib.arsc.chunk.TableBlock;
|
||||||
import com.reandroid.lib.arsc.pool.SpecStringPool;
|
import com.reandroid.lib.arsc.pool.SpecStringPool;
|
||||||
import com.reandroid.lib.arsc.pool.TableStringPool;
|
import com.reandroid.lib.arsc.pool.TableStringPool;
|
||||||
|
import com.reandroid.lib.arsc.value.EntryBlock;
|
||||||
import com.reandroid.lib.arsc.value.ValueType;
|
import com.reandroid.lib.arsc.value.ValueType;
|
||||||
import com.reandroid.lib.json.JSONArray;
|
import com.reandroid.lib.json.JSONArray;
|
||||||
import com.reandroid.lib.json.JSONException;
|
import com.reandroid.lib.json.JSONException;
|
||||||
@ -74,8 +75,8 @@ public class StringPoolBuilder {
|
|||||||
return mSpecNameMap.get(pkgId);
|
return mSpecNameMap.get(pkgId);
|
||||||
}
|
}
|
||||||
private void scan(JSONObject jsonObject){
|
private void scan(JSONObject jsonObject){
|
||||||
if(jsonObject.has(ApkUtil.NAME_is_array)){
|
if(jsonObject.has(EntryBlock.NAME_entry_name)){
|
||||||
addSpecName(jsonObject.optString("name"));
|
addSpecName(jsonObject.optString(EntryBlock.NAME_entry_name));
|
||||||
}
|
}
|
||||||
if(jsonObject.has(ApkUtil.NAME_value_type)){
|
if(jsonObject.has(ApkUtil.NAME_value_type)){
|
||||||
if(ValueType.STRING.name().equals(jsonObject.getString(ApkUtil.NAME_value_type))){
|
if(ValueType.STRING.name().equals(jsonObject.getString(ApkUtil.NAME_value_type))){
|
||||||
|
@ -49,6 +49,7 @@ public class TableBlockJsonBuilder {
|
|||||||
for(File typeFile:typeFileList){
|
for(File typeFile:typeFileList){
|
||||||
loadType(pkg, typeFile);
|
loadType(pkg, typeFile);
|
||||||
}
|
}
|
||||||
|
pkg.sortTypes();
|
||||||
}
|
}
|
||||||
private void loadType(PackageBlock packageBlock, File typeJsonFile) throws IOException{
|
private void loadType(PackageBlock packageBlock, File typeJsonFile) throws IOException{
|
||||||
FileInputStream inputStream=new FileInputStream(typeJsonFile);
|
FileInputStream inputStream=new FileInputStream(typeJsonFile);
|
||||||
|
@ -11,11 +11,18 @@ import com.reandroid.lib.json.JSONObject;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class SpecTypePairArray extends BlockArray<SpecTypePair> implements JSONConvert<JSONArray> {
|
public class SpecTypePairArray extends BlockArray<SpecTypePair>
|
||||||
|
implements JSONConvert<JSONArray>, Comparator<SpecTypePair> {
|
||||||
public SpecTypePairArray(){
|
public SpecTypePairArray(){
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sort(){
|
||||||
|
for(SpecTypePair specTypePair:listItems()){
|
||||||
|
specTypePair.sortTypes();
|
||||||
|
}
|
||||||
|
sort(this);
|
||||||
|
}
|
||||||
public void removeEmptyPairs(){
|
public void removeEmptyPairs(){
|
||||||
List<SpecTypePair> allPairs=new ArrayList<>(listItems());
|
List<SpecTypePair> allPairs=new ArrayList<>(listItems());
|
||||||
boolean foundEmpty=false;
|
boolean foundEmpty=false;
|
||||||
@ -219,4 +226,8 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair> implements JSONC
|
|||||||
specTypePair.fromJson(jsonObject);
|
specTypePair.fromJson(jsonObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public int compare(SpecTypePair typePair1, SpecTypePair typePair2) {
|
||||||
|
return typePair1.compareTo(typePair2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,18 @@ import com.reandroid.lib.json.JSONObject;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.AbstractList;
|
import java.util.AbstractList;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TypeBlockArray extends BlockArray<TypeBlock> implements JSONConvert<JSONArray> {
|
public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||||
|
implements JSONConvert<JSONArray>, Comparator<TypeBlock> {
|
||||||
private byte mTypeId;
|
private byte mTypeId;
|
||||||
public TypeBlockArray(){
|
public TypeBlockArray(){
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
public void sort(){
|
||||||
|
sort(this);
|
||||||
|
}
|
||||||
public void removeEmptyBlocks(){
|
public void removeEmptyBlocks(){
|
||||||
List<TypeBlock> allTypes=new ArrayList<>(listItems());
|
List<TypeBlock> allTypes=new ArrayList<>(listItems());
|
||||||
boolean foundEmpty=false;
|
boolean foundEmpty=false;
|
||||||
@ -272,4 +277,8 @@ public class TypeBlockArray extends BlockArray<TypeBlock> implements JSONConvert
|
|||||||
typeBlock.fromJson(jsonObject);
|
typeBlock.fromJson(jsonObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public int compare(TypeBlock typeBlock1, TypeBlock typeBlock2) {
|
||||||
|
return typeBlock1.compareTo(typeBlock2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,9 @@ public class PackageBlock extends BaseChunk implements BlockLoad, JSONConvert<JS
|
|||||||
addChild(mPackageLastBlocks);
|
addChild(mPackageLastBlocks);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public void sortTypes(){
|
||||||
|
getSpecTypePairArray().sort();
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onBlockLoaded(BlockReader reader, Block sender) throws IOException {
|
public void onBlockLoaded(BlockReader reader, Block sender) throws IOException {
|
||||||
if(sender==mPackageId){
|
if(sender==mPackageId){
|
||||||
|
@ -15,7 +15,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TypeBlock extends BaseTypeBlock implements JSONConvert<JSONObject> {
|
public class TypeBlock extends BaseTypeBlock
|
||||||
|
implements JSONConvert<JSONObject>, Comparable<TypeBlock> {
|
||||||
private final IntegerItem mEntriesStart;
|
private final IntegerItem mEntriesStart;
|
||||||
private final ResConfig mResConfig;
|
private final ResConfig mResConfig;
|
||||||
private final IntegerArray mEntryOffsets;
|
private final IntegerArray mEntryOffsets;
|
||||||
@ -138,6 +139,15 @@ public class TypeBlock extends BaseTypeBlock implements JSONConvert<JSONObject>
|
|||||||
getResConfig().fromJson(json.getJSONObject("config"));
|
getResConfig().fromJson(json.getJSONObject("config"));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
public int compareTo(TypeBlock typeBlock) {
|
||||||
|
int id1=getTypeId();
|
||||||
|
int id2=typeBlock.getTypeId();
|
||||||
|
if(id1!=id2){
|
||||||
|
return Integer.compare(id1, id2);
|
||||||
|
}
|
||||||
|
return getResConfig().compareTo(typeBlock.getResConfig());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
StringBuilder builder=new StringBuilder();
|
StringBuilder builder=new StringBuilder();
|
||||||
builder.append(getResConfig().toString());
|
builder.append(getResConfig().toString());
|
||||||
|
@ -21,7 +21,8 @@ import java.util.Collection;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SpecTypePair extends BlockContainer<Block> implements JSONConvert<JSONObject> {
|
public class SpecTypePair extends BlockContainer<Block>
|
||||||
|
implements JSONConvert<JSONObject> , Comparable<SpecTypePair>{
|
||||||
private final Block[] mChildes;
|
private final Block[] mChildes;
|
||||||
private final SpecBlock mSpecBlock;
|
private final SpecBlock mSpecBlock;
|
||||||
private final TypeBlockArray mTypeBlockArray;
|
private final TypeBlockArray mTypeBlockArray;
|
||||||
@ -37,6 +38,9 @@ public class SpecTypePair extends BlockContainer<Block> implements JSONConvert<J
|
|||||||
public SpecTypePair(){
|
public SpecTypePair(){
|
||||||
this(new SpecBlock(), new TypeBlockArray());
|
this(new SpecBlock(), new TypeBlockArray());
|
||||||
}
|
}
|
||||||
|
public void sortTypes(){
|
||||||
|
getTypeBlockArray().sort();
|
||||||
|
}
|
||||||
public void removeEmptyTypeBlocks(){
|
public void removeEmptyTypeBlocks(){
|
||||||
getTypeBlockArray().removeEmptyBlocks();
|
getTypeBlockArray().removeEmptyBlocks();
|
||||||
}
|
}
|
||||||
@ -155,4 +159,23 @@ public class SpecTypePair extends BlockContainer<Block> implements JSONConvert<J
|
|||||||
getSpecBlock().setTypeId((byte) json.getInt("id"));
|
getSpecBlock().setTypeId((byte) json.getInt("id"));
|
||||||
getTypeBlockArray().fromJson(json.getJSONArray("types"));
|
getTypeBlockArray().fromJson(json.getJSONArray("types"));
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public int compareTo(SpecTypePair specTypePair) {
|
||||||
|
return Integer.compare(getTypeId(), specTypePair.getTypeId());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
StringBuilder builder=new StringBuilder();
|
||||||
|
builder.append(String.format("0x%02x", getTypeId()));
|
||||||
|
builder.append(" (");
|
||||||
|
TypeString ts = getTypeString();
|
||||||
|
if(ts!=null){
|
||||||
|
builder.append(ts.get());
|
||||||
|
}else {
|
||||||
|
builder.append("null");
|
||||||
|
}
|
||||||
|
builder.append(") config count=");
|
||||||
|
builder.append(getTypeBlockArray().childesCount());
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,8 +227,42 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
|||||||
removeTableReferences();
|
removeTableReferences();
|
||||||
removeSpecReferences();
|
removeSpecReferences();
|
||||||
}
|
}
|
||||||
private void setEntryTypeFlag(byte b){
|
public void setEntryTypeBag(boolean b){
|
||||||
mFlagEntryType.set(b);
|
int val=mFlagEntryType.get();
|
||||||
|
if(b){
|
||||||
|
val=val|0x1;
|
||||||
|
}else {
|
||||||
|
val=val&0xFE;
|
||||||
|
}
|
||||||
|
mFlagEntryType.set((byte) val);
|
||||||
|
refreshHeaderSize();
|
||||||
|
}
|
||||||
|
public boolean isEntryTypeBag(){
|
||||||
|
return ((mFlagEntryType.get() & 0x1) != 0);
|
||||||
|
}
|
||||||
|
public void setEntryTypeShared(boolean b){
|
||||||
|
int val=mFlagEntryType.get();
|
||||||
|
if(b){
|
||||||
|
val=val|0x2;
|
||||||
|
}else {
|
||||||
|
val=val&0xFD;
|
||||||
|
}
|
||||||
|
mFlagEntryType.set((byte) val);
|
||||||
|
}
|
||||||
|
public boolean isEntryTypeShared(){
|
||||||
|
return (mFlagEntryType.get() & 0x2) !=0;
|
||||||
|
}
|
||||||
|
public void setEntryTypePublic(boolean b){
|
||||||
|
int val=mFlagEntryType.get();
|
||||||
|
if(b){
|
||||||
|
val=val|0x4;
|
||||||
|
}else {
|
||||||
|
val=val&0xFB;
|
||||||
|
}
|
||||||
|
mFlagEntryType.set((byte) val);
|
||||||
|
}
|
||||||
|
public boolean isEntryTypePublic(){
|
||||||
|
return (mFlagEntryType.get() & 0x4) !=0;
|
||||||
}
|
}
|
||||||
private void setByteFlagsB(byte b){
|
private void setByteFlagsB(byte b){
|
||||||
mByteFlagsB.set(b);
|
mByteFlagsB.set(b);
|
||||||
@ -283,19 +317,6 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
|||||||
mResValue=resValue;
|
mResValue=resValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEntryTypeBag(boolean is_complex){
|
|
||||||
if(is_complex){
|
|
||||||
if(!isEntryTypeBag()){
|
|
||||||
setEntryTypeFlag(FLAG_VALUE_BAG);
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
if(isEntryTypeBag()){
|
|
||||||
setEntryTypeFlag(FLAG_VALUE_INT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
refreshHeaderSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResConfig getResConfig(){
|
public ResConfig getResConfig(){
|
||||||
TypeBlock typeBlock=getTypeBlock();
|
TypeBlock typeBlock=getTypeBlock();
|
||||||
if(typeBlock!=null){
|
if(typeBlock!=null){
|
||||||
@ -488,9 +509,9 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
|||||||
}
|
}
|
||||||
private void refreshHeaderSize(){
|
private void refreshHeaderSize(){
|
||||||
if(isEntryTypeBag()){
|
if(isEntryTypeBag()){
|
||||||
mHeaderSize.set(HEADER_COMPLEX);
|
mHeaderSize.set(HEADER_SIZE_BAG);
|
||||||
}else {
|
}else {
|
||||||
mHeaderSize.set(HEADER_INT);
|
mHeaderSize.set(HEADER_SIZE_INT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void createResValue(){
|
private void createResValue(){
|
||||||
@ -505,9 +526,6 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
|||||||
}
|
}
|
||||||
setResValueInternal(resValue);
|
setResValueInternal(resValue);
|
||||||
}
|
}
|
||||||
private boolean isEntryTypeBag(){
|
|
||||||
return ((mFlagEntryType.get() & FLAG_BAG_ENTRY) != 0);
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public void setNull(boolean is_null){
|
public void setNull(boolean is_null){
|
||||||
if(is_null){
|
if(is_null){
|
||||||
@ -635,8 +653,16 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JSONObject jsonObject=new JSONObject();
|
JSONObject jsonObject=new JSONObject();
|
||||||
jsonObject.put(NAME_name, getSpecString().get());
|
jsonObject.put(NAME_entry_name, getSpecString().get());
|
||||||
jsonObject.put(NAME_is_array, isEntryTypeBag());
|
if(isEntryTypeBag()){
|
||||||
|
jsonObject.put(NAME_is_bag, true);
|
||||||
|
}
|
||||||
|
if(isEntryTypePublic()){
|
||||||
|
jsonObject.put(NAME_is_public, true);
|
||||||
|
}
|
||||||
|
if(isEntryTypeShared()){
|
||||||
|
jsonObject.put(NAME_is_shared, true);
|
||||||
|
}
|
||||||
jsonObject.put(NAME_value, getResValue().toJson());
|
jsonObject.put(NAME_value, getResValue().toJson());
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
}
|
}
|
||||||
@ -647,13 +673,15 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BaseResValue baseResValue;
|
BaseResValue baseResValue;
|
||||||
if(json.getBoolean(NAME_is_array)){
|
if(json.optBoolean(NAME_is_bag, false)){
|
||||||
baseResValue=new ResValueBag();
|
baseResValue=new ResValueBag();
|
||||||
}else {
|
}else {
|
||||||
baseResValue=new ResValueInt();
|
baseResValue=new ResValueInt();
|
||||||
}
|
}
|
||||||
setResValue(baseResValue);
|
setResValue(baseResValue);
|
||||||
setName(json.getString(NAME_name));
|
setEntryTypeShared(json.optBoolean(NAME_is_shared, false));
|
||||||
|
setEntryTypePublic(json.optBoolean(NAME_is_public, false));
|
||||||
|
setName(json.getString(NAME_entry_name));
|
||||||
baseResValue.fromJson(json.getJSONObject(NAME_value));
|
baseResValue.fromJson(json.getJSONObject(NAME_value));
|
||||||
mResValue.onDataLoaded();
|
mResValue.onDataLoaded();
|
||||||
}
|
}
|
||||||
@ -708,16 +736,13 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static byte FLAG_BAG_ENTRY = 0x01;
|
private final static short HEADER_SIZE_BAG = 0x0010;
|
||||||
|
private final static short HEADER_SIZE_INT = 0x0008;
|
||||||
|
|
||||||
private final static byte FLAG_VALUE_BAG = 0x0001;
|
public static final String NAME_entry_name ="entry_name";
|
||||||
private final static byte FLAG_VALUE_INT = 0x00;
|
private static final String NAME_is_bag="is_bag";
|
||||||
|
private static final String NAME_is_shared="is_shared";
|
||||||
private final static short HEADER_COMPLEX=0x0010;
|
private static final String NAME_is_public="is_public";
|
||||||
private final static short HEADER_INT=0x0008;
|
|
||||||
|
|
||||||
private static final String NAME_name="name";
|
|
||||||
private static final String NAME_is_array="is_array";
|
|
||||||
private static final String NAME_value="value";
|
private static final String NAME_value="value";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ import com.reandroid.lib.json.JSONObject;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class ResConfig extends FixedBlockContainer implements BlockLoad, JSONConvert<JSONObject> {
|
public class ResConfig extends FixedBlockContainer
|
||||||
|
implements BlockLoad, JSONConvert<JSONObject>, Comparable<ResConfig> {
|
||||||
|
|
||||||
private final IntegerItem configSize;
|
private final IntegerItem configSize;
|
||||||
private final ByteArray mValuesContainer;
|
private final ByteArray mValuesContainer;
|
||||||
@ -781,6 +782,10 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad, JSONCon
|
|||||||
}
|
}
|
||||||
return "["+q+"]";
|
return "["+q+"]";
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public int compareTo(ResConfig resConfig) {
|
||||||
|
return getQualifiers().compareTo(resConfig.getQualifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static char[] unpackLanguageOrRegion(byte b0, byte b1, char base){
|
private static char[] unpackLanguageOrRegion(byte b0, byte b1, char base){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user