make accessible SpecFlag

This commit is contained in:
REAndroid 2023-03-08 14:46:41 -05:00
parent c2da1c776d
commit cd819c1d0d
9 changed files with 215 additions and 7 deletions

View File

@ -16,7 +16,6 @@
package com.reandroid.arsc.chunk; package com.reandroid.arsc.chunk;
import com.reandroid.arsc.array.TypeBlockArray; import com.reandroid.arsc.array.TypeBlockArray;
import com.reandroid.arsc.base.Block;
import com.reandroid.arsc.container.SpecTypePair; import com.reandroid.arsc.container.SpecTypePair;
import com.reandroid.arsc.header.SpecHeader; import com.reandroid.arsc.header.SpecHeader;
import com.reandroid.arsc.item.*; import com.reandroid.arsc.item.*;
@ -33,6 +32,9 @@
this.specFlagsArray = new SpecFlagsArray(header.getEntryCount()); this.specFlagsArray = new SpecFlagsArray(header.getEntryCount());
addChild(specFlagsArray); addChild(specFlagsArray);
} }
public SpecFlag getSpecFlag(int id){
return getSpecFlagsArray().getFlag(id);
}
public SpecFlagsArray getSpecFlagsArray(){ public SpecFlagsArray getSpecFlagsArray(){
return specFlagsArray; return specFlagsArray;
} }
@ -106,6 +108,50 @@
getSpecFlagsArray().fromJson(json.optJSONArray(NAME_spec_flags)); getSpecFlagsArray().fromJson(json.optJSONArray(NAME_spec_flags));
} }
public enum Flag{
SPEC_PUBLIC((byte) 0x40),
SPEC_STAGED_API((byte) 0x20);
private final byte flag;
Flag(byte flag) {
this.flag = flag;
}
public byte getFlag() {
return flag;
}
public static boolean isPublic(byte flag){
return (SPEC_PUBLIC.flag & flag) == SPEC_PUBLIC.flag;
}
public static boolean isStagedApi(byte flag){
return (SPEC_STAGED_API.flag & flag) == SPEC_STAGED_API.flag;
}
public static String toString(byte flagValue){
StringBuilder builder = new StringBuilder();
boolean appendOnce = false;
int sum = 0;
int flagValueInt = flagValue & 0xff;
for(Flag flag:values()){
int flagInt = flag.flag & 0xff;
if((flagInt & flagValueInt) != flagInt){
continue;
}
if(appendOnce){
builder.append('|');
}
builder.append(flag);
appendOnce = true;
sum = sum | flagInt;
}
if(sum != flagValueInt){
if(appendOnce){
builder.append('|');
}
builder.append(String.format("0x%02x", flagValueInt));
}
return builder.toString();
}
}
public static final String NAME_spec = "spec"; public static final String NAME_spec = "spec";
public static final String NAME_spec_flags = "spec_flags"; public static final String NAME_spec_flags = "spec_flags";
public static final String NAME_flag = "flag"; public static final String NAME_flag = "flag";

View File

@ -25,7 +25,6 @@ import com.reandroid.arsc.item.*;
import com.reandroid.arsc.pool.TypeStringPool; import com.reandroid.arsc.pool.TypeStringPool;
import com.reandroid.arsc.value.Entry; import com.reandroid.arsc.value.Entry;
import com.reandroid.arsc.value.ResConfig; import com.reandroid.arsc.value.ResConfig;
import com.reandroid.arsc.value.ValueType;
import com.reandroid.json.JSONConvert; import com.reandroid.json.JSONConvert;
import com.reandroid.json.JSONObject; import com.reandroid.json.JSONObject;

View File

@ -303,12 +303,15 @@
return null; return null;
} }
public ResXmlIDMap getResXmlIDMap(){ public ResXmlIDMap getResXmlIDMap(){
ResXmlDocument resXmlDocument = getParentInstance(ResXmlDocument.class); ResXmlDocument resXmlDocument = getParentDocument();
if(resXmlDocument!=null){ if(resXmlDocument!=null){
return resXmlDocument.getResXmlIDMap(); return resXmlDocument.getResXmlIDMap();
} }
return null; return null;
} }
public ResXmlDocument getParentDocument(){
return getParentInstance(ResXmlDocument.class);
}
public int getDepth(){ public int getDepth(){
return mDepth; return mDepth;

View File

@ -15,7 +15,6 @@
*/ */
package com.reandroid.arsc.chunk.xml; package com.reandroid.arsc.chunk.xml;
import com.reandroid.arsc.base.Block;
import com.reandroid.arsc.chunk.ChunkType; import com.reandroid.arsc.chunk.ChunkType;
import com.reandroid.arsc.array.ResXmlIDArray; import com.reandroid.arsc.array.ResXmlIDArray;
import com.reandroid.arsc.chunk.Chunk; import com.reandroid.arsc.chunk.Chunk;

View File

@ -70,7 +70,6 @@ public class TypeHeader extends HeaderBlock{
+", flags=" + getFlags().toHex() +", flags=" + getFlags().toHex()
+", count=" + getCount() +", count=" + getCount()
+", entriesStart=" + getEntriesStart() +", entriesStart=" + getEntriesStart()
+", config=" + getConfig() +", config=" + getConfig() + '}';
+", flags=" + getFlags().toHex() + '}';
} }
} }

View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2022 github.com/REAndroid
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.reandroid.arsc.item;
import java.util.Objects;
public class IndirectItem<T extends BlockItem> {
private final T blockItem;
private final int offset;
public IndirectItem(T blockItem, int offset){
this.blockItem = blockItem;
this.offset = offset;
}
public T getBlockItem() {
return blockItem;
}
public int getOffset() {
return offset;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
IndirectItem<?> other = (IndirectItem<?>) obj;
return this.getOffset() == other.getOffset() && this.getBlockItem() == other.getBlockItem();
}
@Override
public int hashCode(){
return Objects.hash(this.getOffset(), this.getBlockItem());
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2022 github.com/REAndroid
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.reandroid.arsc.item;
import com.reandroid.arsc.chunk.SpecBlock;
public class SpecFlag extends IndirectItem<SpecFlagsArray> {
public SpecFlag(SpecFlagsArray specFlagsArray, int offset) {
super(specFlagsArray, offset);
}
public byte getFlagByte(){
return getBlockItem().getBytesInternal()[getOffset() + OFFSET_FLAG];
}
public void setFlagByte(byte flag){
getBlockItem().getBytesInternal()[getOffset() + OFFSET_FLAG] = flag;
}
public void addFlagByte(byte flag){
flag = (byte) ((getFlagByte() & 0xff) | (flag & 0xff));
setFlagByte(flag);
}
public void addFlag(SpecBlock.Flag flag){
addFlagByte(flag.getFlag());
}
public void setPublic(){
addFlag(SpecBlock.Flag.SPEC_PUBLIC);
}
public boolean isPublic(){
return SpecBlock.Flag.isPublic(getFlagByte());
}
public int getInteger(){
return BlockItem.getInteger(this.getBlockItem().getBytesInternal(), this.getOffset());
}
public void setInteger(int value){
if(value == getInteger()){
return;
}
BlockItem.putInteger(this.getBlockItem().getBytesInternal(), this.getOffset(), value);
this.getBlockItem().onBytesChanged();
}
@Override
public String toString(){
byte flag = getFlagByte();
if(flag != 0){
return SpecBlock.Flag.toString(getFlagByte());
}
int val = getInteger();
if(val != 0){
return String.format("0x%08x", val);
}
return "";
}
private static final int OFFSET_FLAG = 3;
}

View File

@ -25,15 +25,37 @@ import com.reandroid.json.JSONConvert;
import com.reandroid.json.JSONObject; import com.reandroid.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.util.AbstractList;
public class SpecFlagsArray extends IntegerArray implements BlockLoad, JSONConvert<JSONArray> { public class SpecFlagsArray extends IntegerArray implements BlockLoad, JSONConvert<JSONArray> {
private final IntegerItem entryCount; private final IntegerItem entryCount;
private AbstractList<SpecFlag> specFlagList;
public SpecFlagsArray(IntegerItem entryCount) { public SpecFlagsArray(IntegerItem entryCount) {
super(); super();
this.entryCount = entryCount; this.entryCount = entryCount;
this.entryCount.setBlockLoad(this); this.entryCount.setBlockLoad(this);
setBlockLoad(this); setBlockLoad(this);
} }
public AbstractList<SpecFlag> listSpecFlags(){
if(specFlagList==null){
specFlagList = new AbstractList<SpecFlag>() {
@Override
public SpecFlag get(int i) {
return SpecFlagsArray.this.getFlag(i);
}
@Override
public int size() {
return SpecFlagsArray.this.size();
}
};
}
return specFlagList;
}
public SpecFlag getFlag(int id){
int offset = id & 0xffff;
offset = offset * 4;
return new SpecFlag(this, offset);
}
public void set(int entryId, int value){ public void set(int entryId, int value){
setFlag(entryId, value); setFlag(entryId, value);
refresh(); refresh();

View File

@ -18,8 +18,10 @@
import com.reandroid.arsc.base.Block; import com.reandroid.arsc.base.Block;
import com.reandroid.arsc.base.BlockCounter; import com.reandroid.arsc.base.BlockCounter;
import com.reandroid.arsc.chunk.PackageBlock; import com.reandroid.arsc.chunk.PackageBlock;
import com.reandroid.arsc.chunk.SpecBlock;
import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.chunk.TableBlock;
import com.reandroid.arsc.chunk.TypeBlock; import com.reandroid.arsc.chunk.TypeBlock;
import com.reandroid.arsc.container.SpecTypePair;
import com.reandroid.arsc.group.EntryGroup; import com.reandroid.arsc.group.EntryGroup;
import com.reandroid.arsc.io.BlockReader; import com.reandroid.arsc.io.BlockReader;
import com.reandroid.arsc.item.*; import com.reandroid.arsc.item.*;
@ -37,6 +39,13 @@
super(); super();
} }
public SpecFlag getSpecFlag(){
SpecBlock specBlock = getSpecBlock();
if(specBlock == null){
return null;
}
return specBlock.getSpecFlag(getId());
}
public void ensureComplex(boolean isComplex){ public void ensureComplex(boolean isComplex){
ensureTableEntry(isComplex); ensureTableEntry(isComplex);
} }
@ -161,7 +170,17 @@
} }
return null; return null;
} }
public SpecBlock getSpecBlock(){
TypeBlock typeBlock = getTypeBlock();
if(typeBlock == null){
return null;
}
SpecTypePair specTypePair = typeBlock.getParentSpecTypePair();
if(specTypePair==null){
return null;
}
return specTypePair.getSpecBlock();
}
public TypeBlock getTypeBlock(){ public TypeBlock getTypeBlock(){
return getParent(TypeBlock.class); return getParent(TypeBlock.class);
} }
@ -394,6 +413,11 @@
builder.append(resConfig); builder.append(resConfig);
builder.append(' '); builder.append(' ');
} }
SpecFlag specFlag = getSpecFlag();
if(specFlag!=null){
builder.append(specFlag);
builder.append(' ');
}
if(isNull()){ if(isNull()){
builder.append("NULL"); builder.append("NULL");
return builder.toString(); return builder.toString();