This commit is contained in:
REAndroid 2022-11-23 08:04:01 -05:00
parent 6c4d425a79
commit 4fe4657f9f
18 changed files with 120 additions and 52 deletions

View File

@ -2,7 +2,7 @@
apply plugin: 'java-library'
group 'com.reandroid.lib.arsc'
version '1.0.1'
version '1.0.2'
java {
sourceCompatibility JavaVersion.VERSION_1_8

View File

@ -4,8 +4,6 @@ import com.reandroid.lib.arsc.item.IntegerArray;
import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.value.EntryBlock;
import java.util.Iterator;
public class EntryBlockArray extends OffsetBlockArray<EntryBlock> {
public EntryBlockArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart){
@ -22,7 +20,9 @@ public class EntryBlockArray extends OffsetBlockArray<EntryBlock> {
if(entryBlock!=null){
return entryBlock;
}
ensureSize(entryId+1);
int count=entryId+1;
ensureSize(count);
refreshCount();
return get(entryId);
}
public EntryBlock getEntry(short entryId){

View File

@ -105,7 +105,7 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
refreshCount();
refreshStart();
}
private void refreshCount(){
void refreshCount(){
mItemCount.set(childesCount());
}
private void refreshStart(){

View File

@ -5,9 +5,7 @@ import com.reandroid.lib.arsc.chunk.TypeBlock;
import com.reandroid.lib.arsc.container.SpecTypePair;
import com.reandroid.lib.arsc.value.EntryBlock;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.*;
public class SpecTypePairArray extends BlockArray<SpecTypePair> {
public SpecTypePairArray(){
@ -114,4 +112,32 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair> {
protected void onRefreshed() {
}
@Override
protected void onPreRefreshRefresh(){
validateEntryCounts();
}
// For android API < 26, it is required to have equal entry count on all SpecTypePair
private void validateEntryCounts(){
Map<Byte, Integer> entryCountMap=mapHighestEntryCount();
for(Map.Entry<Byte, Integer> entry:entryCountMap.entrySet()){
byte id=entry.getKey();
int count=entry.getValue();
SpecTypePair pair=getPair(id);
pair.getSpecBlock().setEntryCount(count);
pair.getTypeBlockArray().setEntryCount(count);
}
}
private Map<Byte, Integer> mapHighestEntryCount(){
Map<Byte, Integer> results=new HashMap<>();
SpecTypePair[] childes=getChildes();
for (SpecTypePair pair:childes){
int count=pair.getHighestEntryCount();
byte id=pair.getTypeId();
Integer exist=results.get(id);
if(exist==null || count>exist){
results.put(id, count);
}
}
return results;
}
}

View File

@ -9,6 +9,7 @@ import java.util.List;
public abstract class StringArray<T extends StringItem> extends OffsetBlockArray<T>{
private boolean mUtf8;
public StringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
super(offsets, itemCount, itemStart);
this.mUtf8=is_utf8;

View File

@ -7,6 +7,7 @@ import com.reandroid.lib.arsc.chunk.SpecBlock;
import com.reandroid.lib.arsc.chunk.TypeBlock;
import com.reandroid.lib.arsc.header.HeaderBlock;
import com.reandroid.lib.arsc.io.BlockReader;
import com.reandroid.lib.arsc.item.TypeString;
import com.reandroid.lib.arsc.value.EntryBlock;
import com.reandroid.lib.arsc.value.ResConfig;
@ -207,4 +208,28 @@ public class TypeBlockArray extends BlockArray<TypeBlock> {
typeBlock.readBytes(reader);
return reader.getPosition()>pos;
}
public int getHighestEntryCount(){
int result=0;
for(TypeBlock typeBlock:getChildes()){
int count=typeBlock.getEntryCount();
if(count>result){
result=count;
}
}
return result;
}
public void setEntryCount(int count){
for(TypeBlock typeBlock:getChildes()){
typeBlock.setEntryCount(count);
}
}
public TypeString getTypeString(){
for(TypeBlock typeBlock:getChildes()){
TypeString typeString=typeBlock.getTypeString();
if(typeString!=null){
return typeString;
}
}
return null;
}
}

View File

@ -5,12 +5,17 @@ import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.item.TypeString;
public class TypeStringArray extends StringArray<TypeString> {
private int lastCreateIndex;
public TypeStringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
super(offsets, itemCount, itemStart, is_utf8);
}
@Override
public TypeString newInstance() {
return new TypeString(isUtf8());
TypeString typeString=new TypeString(isUtf8());
//create default name
this.lastCreateIndex++;
typeString.set("type-"+lastCreateIndex);
return typeString;
}
@Override
public TypeString[] newInstance(int len) {

View File

@ -157,7 +157,7 @@ public abstract class BlockArray<T extends Block> extends BlockContainer<T> impl
int result=-1;
for(int i=0;i<len;i++){
if(block==items[i]){
result=-1;
result=i;
}
}
return result;

View File

@ -20,12 +20,16 @@ public abstract class BlockContainer<T extends Block> extends Block{
parent=parent.getParent();
}
return result;
}
protected void onPreRefreshRefresh(){
}
protected abstract void onRefreshed();
public final void refresh(){
if(isNull()){
return;
}
onPreRefreshRefresh();
refreshChildes();
onRefreshed();
}
@ -36,7 +40,7 @@ public abstract class BlockContainer<T extends Block> extends Block{
for(int i=0;i<max;i++){
T item=childes[i];
if(item instanceof BlockContainer){
BlockContainer container=(BlockContainer)item;
BlockContainer<?> container=(BlockContainer<?>)item;
container.refresh();
}
}

View File

@ -8,6 +8,7 @@ import com.reandroid.lib.arsc.group.EntryGroup;
import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.item.PackageName;
import com.reandroid.lib.arsc.item.ReferenceItem;
import com.reandroid.lib.arsc.item.TypeString;
import com.reandroid.lib.arsc.pool.SpecStringPool;
import com.reandroid.lib.arsc.pool.TableStringPool;
import com.reandroid.lib.arsc.pool.TypeStringPool;

View File

@ -50,13 +50,6 @@ public class TableBlock extends BaseChunk {
refreshPackageCount();
}
@Override
public int onWriteBytes(OutputStream stream) throws IOException{
int result=super.onWriteBytes(stream);
stream.flush();
stream.close();
return result;
}
public void readBytes(File file) throws IOException{
BlockReader reader=new BlockReader(file);
super.readBytes(reader);
@ -74,7 +67,9 @@ public class TableBlock extends BaseChunk {
dir.mkdirs();
}
OutputStream outputStream=new FileOutputStream(file);
return super.writeBytes(outputStream);
int length = super.writeBytes(outputStream);
outputStream.close();
return length;
}
@Override

View File

@ -107,13 +107,6 @@ public class ResXmlBlock extends BaseChunk {
@Override
protected void onChunkRefreshed() {
}
@Override
public int onWriteBytes(OutputStream stream) throws IOException{
int result=super.onWriteBytes(stream);
stream.flush();
stream.close();
return result;
}
public void readBytes(File file) throws IOException{
BlockReader reader=new BlockReader(file);
@ -132,7 +125,9 @@ public class ResXmlBlock extends BaseChunk {
dir.mkdirs();
}
OutputStream outputStream=new FileOutputStream(file);
return super.writeBytes(outputStream);
int length = super.writeBytes(outputStream);
outputStream.close();
return length;
}
public static boolean isResXmlBlock(File file){

View File

@ -9,6 +9,7 @@ import com.reandroid.lib.arsc.chunk.SpecBlock;
import com.reandroid.lib.arsc.chunk.TypeBlock;
import com.reandroid.lib.arsc.header.HeaderBlock;
import com.reandroid.lib.arsc.io.BlockReader;
import com.reandroid.lib.arsc.item.TypeString;
import com.reandroid.lib.arsc.value.EntryBlock;
import com.reandroid.lib.arsc.value.ResConfig;
@ -128,5 +129,15 @@ public class SpecTypePair extends BlockContainer<Block> {
private void readUnexpectedNonSpecBlock(BlockReader reader, HeaderBlock headerBlock) throws IOException{
throw new IOException("Unexpected block: "+headerBlock.toString()+", Should be: "+ChunkType.SPEC);
}
public int getHighestEntryCount(){
int specEntryCount=getSpecBlock().getEntryCount();
int typeEntryCount=getTypeBlockArray().getHighestEntryCount();
if(specEntryCount>typeEntryCount){
return specEntryCount;
}
return typeEntryCount;
}
public TypeString getTypeString(){
return getTypeBlockArray().getTypeString();
}
}

View File

@ -306,7 +306,9 @@ public class BlockReader extends InputStream {
private static byte[] loadBuffer(File file) throws IOException {
FileInputStream in=new FileInputStream(file);
return loadBuffer(in);
byte[] result = loadBuffer(in);
in.close();
return result;
}
private static byte[] loadBuffer(InputStream in) throws IOException {
byte[] result=new byte[0];

View File

@ -2,6 +2,7 @@ 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.group.StringGroup;
import com.reandroid.lib.arsc.item.IntegerArray;
import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.item.TypeString;
@ -13,6 +14,12 @@ public class TypeStringPool extends BaseStringPool<TypeString> {
public TypeString getById(int id){
return super.get(id-1);
}
public TypeString getOrCreate(int typeId, String typeName){
getStringsArray().ensureSize(typeId);
TypeString typeString=getById(typeId);
typeString.set(typeName);
return typeString;
}
@Override
StringArray<TypeString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
return new TypeStringArray(offsets, itemCount, itemStart, is_utf8);

View File

@ -1,22 +1,14 @@
package com.reandroid.lib.arsc.value;
import com.reandroid.lib.arsc.base.Block;
import com.reandroid.lib.arsc.chunk.PackageBlock;
import com.reandroid.lib.arsc.chunk.TableBlock;
import com.reandroid.lib.arsc.item.BlockItem;
import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.item.ReferenceItem;
import com.reandroid.lib.arsc.pool.SpecStringPool;
import com.reandroid.lib.arsc.pool.TableStringPool;
import java.util.List;
public abstract class BaseResValue extends BlockItem {
BaseResValue(int bytesLength){
super(bytesLength);
}
public EntryBlock getEntryBlock(){
Block parent=getParent();
while(parent!=null){
@ -27,7 +19,6 @@ public abstract class BaseResValue extends BlockItem {
}
return null;
}
boolean removeSpecReference(ReferenceItem ref){
EntryBlock entryBlock=getEntryBlock();
if(entryBlock==null){
@ -56,15 +47,10 @@ public abstract class BaseResValue extends BlockItem {
}
entryBlock.addTableReference(ref);
}
@Override
public void onBytesChanged() {
}
int getInt(int offset){
byte[] bts = getBytesInternal();
return bts[offset] & 0xff |
@ -83,7 +69,6 @@ public abstract class BaseResValue extends BlockItem {
bts[offset]= (byte) (val & 0xff);
onBytesChanged();
}
void setShort(int offset, short val){
if(val==getShort(offset)){
return;

View File

@ -17,7 +17,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class EntryBlock extends Block {
public class EntryBlock extends Block{
private ShortItem mHeaderSize;
private ShortItem mFlags;
private IntegerItem mSpecReference;
@ -189,9 +189,13 @@ public class EntryBlock extends Block {
public void setFlagComplex(boolean is_complex){
if(is_complex){
setFlags(FLAG_COMPLEX);
if(!isFlagsComplex()){
setFlags(FLAG_COMPLEX);
}
}else {
setFlags(FLAG_INT);
if(isFlagsComplex()){
setFlags(FLAG_INT);
}
}
refreshHeaderSize();
}
@ -437,7 +441,14 @@ public class EntryBlock extends Block {
if(isNull()){
return 0;
}
return 8+mResValue.countBytes();
/*
mHeaderSize -> 2 bytes
mFlags -> 2 bytes
mSpecReference -> 4 bytes
-------
Total = 8 bytes, thus this value is always fixed no need to re-count
*/
return 8 + mResValue.countBytes();
}
@Override
public void onCountUpTo(BlockCounter counter) {
@ -514,6 +525,7 @@ public class EntryBlock extends Block {
updatePackage();
updateSpecRef();
}
@Override
public String toString(){
StringBuilder builder=new StringBuilder();
builder.append(getClass().getSimpleName());
@ -566,9 +578,10 @@ public class EntryBlock extends Block {
private final static short FLAG_COMPLEX_MASK = 0x0001;
private final static short FLAG_COMPLEX = 0x0003;
private final static short FLAG_INT = 0x0002;
private final static short FLAG_COMPLEX = 0x0001;
private final static short FLAG_INT = 0x0000;
private final static short HEADER_COMPLEX=0x0010;
private final static short HEADER_INT=0x0008;
}

View File

@ -2,8 +2,6 @@ package com.reandroid.lib.arsc.value;
import com.reandroid.lib.arsc.decoder.ValueDecoder;
import com.reandroid.lib.arsc.io.BlockReader;
import com.reandroid.lib.arsc.item.ReferenceItem;
import java.io.IOException;