This commit is contained in:
REAndroid 2022-11-27 10:19:31 -05:00
parent bf310c0cac
commit 3dbd9a1e2c
4 changed files with 353 additions and 42 deletions

View File

@ -142,4 +142,47 @@ public class ByteArray extends BlockItem {
public String toString(){
return "size="+size();
}
public static byte[] trimTrailZeros(byte[] bts){
if(bts==null){
return new byte[0];
}
int len=0;
for(int i=0;i<bts.length;i++){
if(bts[i]!=0){
len=i+1;
}
}
byte[] result=new byte[len];
if(result.length>0){
System.arraycopy(bts, 0, result, 0, result.length);
}
return result;
}
public static boolean equals(byte[] bts1, byte[] bts2){
if(bts1==bts2){
return true;
}
if(bts1==null || bts1.length==0){
return bts2==null || bts2.length==0;
}
if(bts2==null || bts2.length==0){
return false;
}
if(bts1.length!=bts2.length){
return false;
}
for(int i=0;i<bts1.length;i++){
if(bts1[i]!=bts2[i]){
return false;
}
}
return true;
}
public static boolean equalsIgnoreTrailZero(byte[] bts1, byte[] bts2){
if(bts1==bts2){
return true;
}
return equals(trimTrailZeros(bts1), trimTrailZeros(bts2));
}
}

View File

@ -27,6 +27,90 @@ public class EntryBlock extends Block{
super();
}
public ResValueInt setValueAsBoolean(boolean val){
ResValueInt resValueInt;
BaseResValue res = getResValue();
if(res instanceof ResValueInt){
resValueInt=(ResValueInt) res;
}else {
resValueInt=new ResValueInt();
setResValue(resValueInt);
}
resValueInt.setType(ValueType.INT_BOOLEAN);
resValueInt.setData(val?0xffffffff:0);
return resValueInt;
}
public ResValueInt setValueAsInteger(int val){
ResValueInt resValueInt;
BaseResValue res = getResValue();
if(res instanceof ResValueInt){
resValueInt=(ResValueInt) res;
}else {
resValueInt=new ResValueInt();
setResValue(resValueInt);
}
resValueInt.setType(ValueType.INT_DEC);
resValueInt.setData(val);
return resValueInt;
}
public ResValueInt setValueAsReference(int resId){
ResValueInt resValueInt;
BaseResValue res = getResValue();
if(res instanceof ResValueInt){
resValueInt=(ResValueInt) res;
}else {
resValueInt=new ResValueInt();
setResValue(resValueInt);
}
resValueInt.setType(ValueType.REFERENCE);
resValueInt.setData(resId);
return resValueInt;
}
public ResValueInt setValueAsString(String str){
TableStringPool stringPool=getTableStringPool();
if(stringPool==null){
throw new IllegalArgumentException("TableStringPool = null, EntryBlock not added to parent TableBlock");
}
TableString tableString = stringPool.getOrCreate(str);
ResValueInt resValueInt;
BaseResValue res = getResValue();
if(res instanceof ResValueInt){
resValueInt=(ResValueInt) res;
}else {
resValueInt=new ResValueInt();
setResValue(resValueInt);
}
resValueInt.setType(ValueType.STRING);
resValueInt.setData(tableString.getIndex());
return resValueInt;
}
public String getValueAsString(){
TableStringPool stringPool=getTableStringPool();
if(stringPool==null){
return null;
}
BaseResValue res = getResValue();
if(!(res instanceof ResValueInt)){
return null;
}
ResValueInt resValueInt=(ResValueInt)res;
TableString tableString= stringPool.get(resValueInt.getData());
if(tableString==null){
return null;
}
return tableString.getHtml();
}
private TableStringPool getTableStringPool(){
PackageBlock pkg=getPackageBlock();
if(pkg==null){
return null;
}
TableBlock table = pkg.getTableBlock();
if(table==null){
return null;
}
return table.getTableStringPool();
}
public boolean isDefault(){
TypeBlock typeBlock=getTypeBlock();
if(typeBlock!=null){
@ -329,8 +413,6 @@ public class EntryBlock extends Block{
}
return null;
}
private void unlockEntry(){
if(mUnLocked){
return;
@ -375,16 +457,6 @@ public class EntryBlock extends Block{
mResValue=null;
}
}
private void refreshResValue(){
if(mResValue==null){
return;
}
if(isFlagsComplex()==(mResValue instanceof ResValueBag)){
return;
}
removeResValue();
createResValue();
}
private void refreshHeaderSize(){
if(isFlagsComplex()){
mHeaderSize.set(HEADER_COMPLEX);
@ -404,11 +476,9 @@ public class EntryBlock extends Block{
}
setResValueInternal(resValue);
}
private boolean isFlagsComplex(){
return ((mFlags.get() & FLAG_COMPLEX_MASK) != 0);
}
@Override
public void setNull(boolean is_null){
if(is_null){

View File

@ -8,6 +8,8 @@ import com.reandroid.lib.arsc.item.ByteArray;
import com.reandroid.lib.arsc.item.IntegerItem;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
public class ResConfig extends FixedBlockContainer implements BlockLoad {
@ -47,12 +49,14 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
mQualifiers=null;
}
public void setConfigSize(int size){
if(size != SIZE_28
if( size != SIZE_16
&& size != SIZE_28
&& size != SIZE_32
&& size != SIZE_36
&& size != SIZE_48
&& size != SIZE_56
&& size != SIZE_64){
&& size != SIZE_64
){
throw new IllegalArgumentException("Invalid config size = " + size);
}
this.configSize.set(size);
@ -63,28 +67,93 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
public int getConfigSize(){
return this.configSize.get();
}
public boolean trimToSize(int size){
int current=getConfigSize();
if(current==size){
return true;
}
if( size != SIZE_16
&& size != SIZE_28
&& size != SIZE_32
&& size != SIZE_36
&& size != SIZE_48
&& size != SIZE_56
&& size != SIZE_64
){
return false;
}
if(current<size){
setConfigSize(size);
return true;
}
int offset=size-4;
int len=current-4-offset;
byte[] bts=mValuesContainer.getByteArray(offset, len);
if(!isNull(bts)){
return false;
}
setConfigSize(size);
return true;
}
public void setMcc(short sh){
if(getConfigSize()<SIZE_16){
if(sh==0){
return;
}
throw new IllegalArgumentException("Can not set mcc for config size="+getConfigSize());
}
mValuesContainer.putShort(OFFSET_mcc, sh);
}
public short getMcc(){
if(getConfigSize()<SIZE_16){
return 0;
}
return mValuesContainer.getShort(OFFSET_mcc);
}
public void setMnc(short sh){
if(getConfigSize()<SIZE_16){
if(sh==0){
return;
}
throw new IllegalArgumentException("Can not set mnc for config size="+getConfigSize());
}
mValuesContainer.putShort(OFFSET_mnc, sh);
}
public short getMnc(){
if(getConfigSize()<SIZE_16){
return 0;
}
return mValuesContainer.getShort(OFFSET_mnc);
}
public void setLanguageIn0(byte b){
if(getConfigSize()<SIZE_16){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set languageIn0 for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_languageIn0, b);
}
public byte getLanguageIn0(){
if(getConfigSize()<SIZE_16){
return 0;
}
return mValuesContainer.get(OFFSET_languageIn0);
}
public void setLanguageIn1(byte b){
if(getConfigSize()<SIZE_16){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set languageIn1 for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_languageIn1, b);
}
public byte getLanguageIn1(){
if(getConfigSize()<SIZE_16){
return 0;
}
return mValuesContainer.get(OFFSET_languageIn1);
}
public char[] getLanguage(){
@ -103,15 +172,33 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
setLanguageIn1(bts[1]);
}
public void setCountryIn0(byte b){
if(getConfigSize()<SIZE_16){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set countryIn0 for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_countryIn0, b);
}
public byte getCountryIn0(){
if(getConfigSize()<SIZE_16){
return 0;
}
return mValuesContainer.get(OFFSET_countryIn0);
}
public void setCountryIn1(byte b){
if(getConfigSize()<SIZE_16){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set countryIn1 for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_countryIn1, b);
}
public byte getCountryIn1(){
if(getConfigSize()<SIZE_16){
return 0;
}
return mValuesContainer.get(OFFSET_countryIn1);
}
public char[] getRegion(){
@ -130,57 +217,138 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
setCountryIn1(bts[1]);
}
public void setOrientation(byte b){
if(getConfigSize()<SIZE_16){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set orientation for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_orientation, b);
}
public byte getOrientation(){
if(getConfigSize()<SIZE_16){
return 0;
}
return mValuesContainer.get(OFFSET_orientation);
}
public void setTouchscreen(byte b){
if(getConfigSize()<SIZE_16){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set touchscreen for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_touchscreen, b);
}
public byte getTouchscreen(){
if(getConfigSize()<SIZE_16){
return 0;
}
return mValuesContainer.get(OFFSET_touchscreen);
}
public void setDensity(short sh){
if(getConfigSize()<SIZE_16){
if(sh==0){
return;
}
throw new IllegalArgumentException("Can not set density for config size="+getConfigSize());
}
mValuesContainer.putShort(OFFSET_density, sh);
}
public short getDensity(){
if(getConfigSize()<SIZE_16){
return 0;
}
return mValuesContainer.getShort(OFFSET_density);
}
public void setKeyboard(byte b){
if(getConfigSize()<SIZE_28){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set keyboard for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_keyboard, b);
}
public byte getKeyboard(){
if(getConfigSize()<SIZE_28){
return 0;
}
return mValuesContainer.get(OFFSET_keyboard);
}
public void setNavigation(byte b){
if(getConfigSize()<SIZE_28){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set navigation for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_navigation, b);
}
public byte getNavigation(){
if(getConfigSize()<SIZE_28){
return 0;
}
return mValuesContainer.get(OFFSET_navigation);
}
public void setInputFlags(byte b){
if(getConfigSize()<SIZE_28){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set inputFlags for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_inputFlags, b);
}
public byte getInputFlags(){
if(getConfigSize()<SIZE_28){
return 0;
}
return mValuesContainer.get(OFFSET_inputFlags);
}
public void setInputPad0(byte b){
if(getConfigSize()<SIZE_28){
if(b==0){
return;
}
throw new IllegalArgumentException("Can not set inputPad0 for config size="+getConfigSize());
}
mValuesContainer.put(OFFSET_inputPad0, b);
}
public byte setInputPad0(){
public byte getInputPad0(){
if(getConfigSize()<SIZE_28){
return 0;
}
return mValuesContainer.get(OFFSET_inputPad0);
}
public void setScreenWidth(short sh){
if(getConfigSize()<SIZE_28){
if(sh==0){
return;
}
throw new IllegalArgumentException("Can not set screenWidth for config size="+getConfigSize());
}
mValuesContainer.putShort(OFFSET_screenWidth, sh);
}
public short getScreenWidth(){
if(getConfigSize()<SIZE_28){
return 0;
}
return mValuesContainer.getShort(OFFSET_screenWidth);
}
public void setScreenHeight(short sh){
if(getConfigSize()<SIZE_28){
if(sh==0){
return;
}
throw new IllegalArgumentException("Can not set screenHeight for config size="+getConfigSize());
}
mValuesContainer.putShort(OFFSET_screenHeight, sh);
}
public short getScreenHeight(){
if(getConfigSize()<SIZE_28){
return 0;
}
return mValuesContainer.getShort(OFFSET_screenHeight);
}
public void setScreenSize(short w, short h){
@ -188,15 +356,33 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
this.setScreenHeight(h);
}
public void setSdkVersion(short sh){
if(getConfigSize()<SIZE_28){
if(sh==0){
return;
}
throw new IllegalArgumentException("Can not set sdkVersion for config size="+getConfigSize());
}
mValuesContainer.putShort(OFFSET_sdkVersion, sh);
}
public short getSdkVersion(){
if(getConfigSize()<SIZE_28){
return 0;
}
return mValuesContainer.getShort(OFFSET_sdkVersion);
}
public void setMinorVersion(short sh){
if(getConfigSize()<SIZE_28){
if(sh==0){
return;
}
throw new IllegalArgumentException("Can not set minorVersion for config size="+getConfigSize());
}
mValuesContainer.putShort(OFFSET_minorVersion, sh);
}
public short getMinorVersion(){
if(getConfigSize()<SIZE_28){
return 0;
}
return mValuesContainer.getShort(OFFSET_minorVersion);
}
public void setScreenLayout(byte b){
@ -347,18 +533,17 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
return mValuesContainer.get(OFFSET_colorMode);
}
private void valuesChanged(int val, int old){
if(val==old){
return;
}
valuesChanged();
}
private void valuesChanged(){
mQualifiers=null;
}
public String getQualifiers(){
if(mQualifiers==null){
try{
mQualifiers = ResConfigHelper.toQualifier(this).trim();
}catch (Exception ex){
mQualifiers = "";
}
}
return mQualifiers;
}
@ -374,13 +559,26 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
return ResConfigHelper.decodeLocale(this);
}
public boolean isDefault(){
return getQualifiers().length()==0;
return isNull(mValuesContainer.getBytes());
}
@Override
public boolean equals(Object o){
if(o instanceof ResConfig){
ResConfig config=(ResConfig)o;
return getQualifiers().equals(config.getQualifiers());
public int hashCode(){
byte[] bts = ByteArray.trimTrailZeros(mValuesContainer.getBytes());
return Arrays.hashCode(bts);
}
@Override
public boolean equals(Object obj){
if(obj==this){
return true;
}
if(obj==null){
return false;
}
if(obj instanceof ResConfig){
ResConfig other = (ResConfig)obj;
byte[] bts1 = mValuesContainer.getBytes();
byte[] bts2 = other.mValuesContainer.getBytes();
return ByteArray.equalsIgnoreTrailZero(bts1, bts2);
}
return false;
}
@ -509,12 +707,13 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
return result;
}
private static final int SIZE_28 = 28;
private static final int SIZE_32 = 32;
private static final int SIZE_36 = 36;
private static final int SIZE_48 = 48;
private static final int SIZE_56 = 56;
private static final int SIZE_64 = 64;
public static final int SIZE_16 = 16;
public static final int SIZE_28 = 28;
public static final int SIZE_32 = 32;
public static final int SIZE_36 = 36;
public static final int SIZE_48 = 48;
public static final int SIZE_56 = 56;
public static final int SIZE_64 = 64;
private static final int OFFSET_mcc = 0;
private static final int OFFSET_mnc = 2;
@ -525,6 +724,7 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
private static final int OFFSET_orientation = 8;
private static final int OFFSET_touchscreen = 9;
private static final int OFFSET_density = 10;
//SIZE=16
private static final int OFFSET_keyboard = 12;
private static final int OFFSET_navigation = 13;
private static final int OFFSET_inputFlags = 14;

View File

@ -9,7 +9,7 @@ import java.util.regex.Pattern;
public class ResConfigHelper {
public static ResConfig fromQualifiers(String qualifiers){
ResConfig result=new ResConfig();
result.setConfigSize(64);
result.setConfigSize(ResConfig.SIZE_64);
parseQualifiers(result, qualifiers);
return result;
}
@ -52,15 +52,13 @@ public class ResConfigHelper {
if(isNull(split)){
return qualifiers;
}
int len=split.length;
Set<String> qSet=new HashSet<>();
for(int i=0; i<len;i++){
List<String> qList=new ArrayList<>();
for(int i=0;i<split.length;i++){
String q=split[i];
if(q!=null){
qSet.add(q);
if(q!=null && !qList.contains(q)){
qList.add(q);
}
}
List<String> qList=new ArrayList<>(qSet);
Comparator<String> cmp=new Comparator<String>() {
@Override
public int compare(String s1, String s2) {