mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-30 06:14:25 +02:00
full implementation of SPARSE type entries
This commit is contained in:
parent
c239585091
commit
21569db1f3
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.reandroid.arsc.array;
|
||||
|
||||
import com.reandroid.arsc.item.IntegerArray;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.value.Entry;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
@ -26,9 +25,32 @@ import java.util.Iterator;
|
||||
|
||||
|
||||
public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<JSONArray> {
|
||||
public EntryArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart){
|
||||
public EntryArray(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart){
|
||||
super(offsets, itemCount, itemStart);
|
||||
}
|
||||
public int getHighestEntryId(){
|
||||
if(isSparse()){
|
||||
return ((SparseOffsetsArray) getOffsetArray()).getHighestId();
|
||||
}
|
||||
return childesCount();
|
||||
}
|
||||
public int getEntryId(int index){
|
||||
OffsetArray offsetArray = getOffsetArray();
|
||||
if(offsetArray instanceof SparseOffsetsArray){
|
||||
return ((SparseOffsetsArray) offsetArray).getIdx(index);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
public int getEntryIndex(int entryId){
|
||||
OffsetArray offsetArray = getOffsetArray();
|
||||
if(offsetArray instanceof SparseOffsetsArray){
|
||||
return ((SparseOffsetsArray) offsetArray).indexOf(entryId);
|
||||
}
|
||||
return entryId;
|
||||
}
|
||||
public boolean isSparse(){
|
||||
return super.getOffsetArray() instanceof SparseOffsetsArray;
|
||||
}
|
||||
public void destroy(){
|
||||
for(Entry entry:listItems()){
|
||||
if(entry!=null){
|
||||
@ -47,26 +69,41 @@ public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<J
|
||||
public boolean isEmpty(){
|
||||
return !iterator(true).hasNext();
|
||||
}
|
||||
public void setEntry(short entryId, Entry entry){
|
||||
setItem(0xffff & entryId, entry);
|
||||
}
|
||||
|
||||
public Entry getOrCreate(short entryId){
|
||||
int id = 0xffff & entryId;
|
||||
Entry entry =get(id);
|
||||
Entry entry = getEntry(id);
|
||||
if(entry != null){
|
||||
return entry;
|
||||
}
|
||||
int count=id+1;
|
||||
ensureSize(count);
|
||||
refreshCount();
|
||||
return get(id);
|
||||
boolean sparse = isSparse();
|
||||
int count;
|
||||
if(sparse){
|
||||
count = childesCount() + 1;
|
||||
}else {
|
||||
count = id + 1;
|
||||
}
|
||||
public Entry get(short entryId){
|
||||
int index = 0xffff & entryId;
|
||||
ensureSize(count);
|
||||
if(!sparse){
|
||||
refreshCount();
|
||||
return super.get(id);
|
||||
}
|
||||
SparseOffsetsArray offsetsArray = (SparseOffsetsArray) getOffsetArray();
|
||||
offsetsArray.ensureArraySize(count);
|
||||
int index = count - 1;
|
||||
offsetsArray.setIdx(index, id);
|
||||
refreshCount();
|
||||
return super.get(index);
|
||||
}
|
||||
public Entry get(short entryId){
|
||||
return getEntry(entryId);
|
||||
}
|
||||
public Entry getEntry(short entryId){
|
||||
return get(0xffff & entryId);
|
||||
return getEntry(0xffff & entryId);
|
||||
}
|
||||
public Entry getEntry(int entryId){
|
||||
int index = getEntryIndex(entryId);
|
||||
return super.get(index);
|
||||
}
|
||||
@Override
|
||||
public Entry newInstance() {
|
||||
@ -98,7 +135,7 @@ public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<J
|
||||
JSONArray jsonArray=new JSONArray();
|
||||
int index=0;
|
||||
String name_id = Entry.NAME_id;
|
||||
for(Entry entry :listItems()){
|
||||
for(Entry entry : listItems(true)){
|
||||
JSONObject childObject = entry.toJson();
|
||||
if(childObject==null){
|
||||
continue;
|
||||
@ -112,33 +149,74 @@ public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<J
|
||||
@Override
|
||||
public void fromJson(JSONArray json) {
|
||||
clearChildes();
|
||||
if(isSparse()){
|
||||
fromJsonSparse(json);
|
||||
}else {
|
||||
fromJsonNonSparse(json);
|
||||
}
|
||||
refreshCountAndStart();
|
||||
}
|
||||
private void fromJsonNonSparse(JSONArray json){
|
||||
int length=json.length();
|
||||
ensureSize(length);
|
||||
String name_id = Entry.NAME_id;
|
||||
for(int i=0;i<length;i++){
|
||||
JSONObject jsonObject= json.getJSONObject(i);
|
||||
JSONObject jsonObject = json.optJSONObject(i);
|
||||
if(jsonObject==null){
|
||||
continue;
|
||||
}
|
||||
int id = jsonObject.getInt(name_id);
|
||||
ensureSize(id + 1);
|
||||
Entry entry =get(id);
|
||||
Entry entry = super.get(id);
|
||||
entry.fromJson(jsonObject);
|
||||
}
|
||||
}
|
||||
private void fromJsonSparse(JSONArray json){
|
||||
SparseOffsetsArray offsetsArray = (SparseOffsetsArray) getOffsetArray();
|
||||
offsetsArray.setSize(0);
|
||||
int length = json.length();
|
||||
ensureSize(length);
|
||||
offsetsArray.setSize(length);
|
||||
String name_id = Entry.NAME_id;
|
||||
for(int i=0;i<length;i++){
|
||||
JSONObject jsonObject = json.optJSONObject(i);
|
||||
if(jsonObject==null){
|
||||
offsetsArray.setIdx(i , OffsetArray.NO_ENTRY);
|
||||
continue;
|
||||
}
|
||||
int id = jsonObject.getInt(name_id);
|
||||
Entry entry = super.get(i);
|
||||
offsetsArray.setIdx(i, id);
|
||||
entry.fromJson(jsonObject);
|
||||
}
|
||||
refreshCountAndStart();
|
||||
}
|
||||
public void merge(EntryArray entryArray){
|
||||
if(entryArray ==null|| entryArray == this|| entryArray.isEmpty()){
|
||||
return;
|
||||
}
|
||||
if(isSparse()){
|
||||
mergeSparse(entryArray);
|
||||
}else {
|
||||
mergeNonSparse(entryArray);
|
||||
}
|
||||
refreshCountAndStart();
|
||||
}
|
||||
private void mergeSparse(EntryArray entryArray){
|
||||
Iterator<Entry> itr = entryArray.iterator(true);
|
||||
while (itr.hasNext()){
|
||||
Entry comingBlock = itr.next();
|
||||
Entry existingBlock = getOrCreate((short) comingBlock.getId());
|
||||
existingBlock.merge(comingBlock);
|
||||
}
|
||||
}
|
||||
private void mergeNonSparse(EntryArray entryArray){
|
||||
ensureSize(entryArray.childesCount());
|
||||
Iterator<Entry> itr = entryArray.iterator(true);
|
||||
while (itr.hasNext()){
|
||||
Entry comingBlock = itr.next();
|
||||
Entry existingBlock = get(comingBlock.getIndex());
|
||||
Entry existingBlock = super.get(comingBlock.getIndex());
|
||||
existingBlock.merge(comingBlock);
|
||||
}
|
||||
refreshCountAndStart();
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
|
40
src/main/java/com/reandroid/arsc/array/OffsetArray.java
Normal file
40
src/main/java/com/reandroid/arsc/array/OffsetArray.java
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.array;
|
||||
|
||||
import com.reandroid.arsc.item.IntegerArray;
|
||||
|
||||
public class OffsetArray extends IntegerArray {
|
||||
public OffsetArray(){
|
||||
super();
|
||||
}
|
||||
public int getOffset(int i){
|
||||
return super.getAt(i);
|
||||
}
|
||||
public void setOffset(int index, int value){
|
||||
super.put(index, value);
|
||||
}
|
||||
public int[] getOffsets(){
|
||||
int length = size();
|
||||
int[] result = new int[length];
|
||||
for(int i=0;i<length;i++){
|
||||
result[i] = getOffset(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static final int NO_ENTRY = 0xFFFFFFFF;
|
||||
}
|
@ -22,7 +22,6 @@ import com.reandroid.arsc.base.BlockCounter;
|
||||
import com.reandroid.arsc.io.BlockLoad;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.item.ByteArray;
|
||||
import com.reandroid.arsc.item.IntegerArray;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
|
||||
|
||||
@ -30,12 +29,12 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> implements BlockLoad {
|
||||
private final IntegerArray mOffsets;
|
||||
private final OffsetArray mOffsets;
|
||||
private final IntegerItem mItemStart;
|
||||
private final IntegerItem mItemCount;
|
||||
private final ByteArray mEnd4Block;
|
||||
private byte mEnd4Type;
|
||||
public OffsetBlockArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart){
|
||||
public OffsetBlockArray(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart){
|
||||
super();
|
||||
this.mOffsets=offsets;
|
||||
this.mItemCount=itemCount;
|
||||
@ -43,6 +42,9 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
|
||||
this.mEnd4Block=new ByteArray();
|
||||
mItemCount.setBlockLoad(this);
|
||||
}
|
||||
OffsetArray getOffsetArray(){
|
||||
return mOffsets;
|
||||
}
|
||||
void setEndBytes(byte b){
|
||||
this.mEnd4Type=b;
|
||||
this.mEnd4Block.fill(b);
|
||||
@ -91,7 +93,8 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
|
||||
@Override
|
||||
protected void onRefreshed() {
|
||||
int count=childesCount();
|
||||
mOffsets.setSize(count);
|
||||
OffsetArray offsetArray = this.mOffsets;
|
||||
offsetArray.setSize(count);
|
||||
T[] childes=getChildes();
|
||||
int sum=0;
|
||||
if(childes!=null){
|
||||
@ -105,7 +108,7 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
|
||||
offset=sum;
|
||||
sum+=item.countBytes();
|
||||
}
|
||||
mOffsets.put(i, offset);
|
||||
offsetArray.setOffset(i, offset);
|
||||
}
|
||||
}
|
||||
refreshCount();
|
||||
@ -167,7 +170,7 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
|
||||
if(childes==null||childes.length==0){
|
||||
return;
|
||||
}
|
||||
int[] offsetArray=mOffsets.toArray();
|
||||
int[] offsetArray=mOffsets.getOffsets();
|
||||
int max=childes.length;
|
||||
int start=mItemStart.get();
|
||||
reader.seek(start);
|
||||
|
@ -25,7 +25,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ResXmlStringArray extends StringArray<ResXmlString> {
|
||||
public ResXmlStringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
public ResXmlStringArray(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
super(offsets, itemCount, itemStart, is_utf8);
|
||||
}
|
||||
@Override
|
||||
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.array;
|
||||
|
||||
public class SparseOffsetsArray extends OffsetArray{
|
||||
public SparseOffsetsArray(){
|
||||
super();
|
||||
}
|
||||
public int getHighestId(){
|
||||
int result = NO_ENTRY;
|
||||
int size = size();
|
||||
for(int i=0; i<size;i++){
|
||||
int id = getIdx(i);
|
||||
if(id > result){
|
||||
result = id;
|
||||
}
|
||||
}
|
||||
if(result == NO_ENTRY){
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public int indexOf(int idx){
|
||||
int size = super.size();
|
||||
for(int i=0; i<size; i++){
|
||||
if(idx == getIdx(i)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return NO_ENTRY;
|
||||
}
|
||||
public int getIdx(int i){
|
||||
int value = super.getAt(i);
|
||||
if(value != NO_ENTRY) {
|
||||
value = value & 0xffff;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
public void setIdx(int index, int idx){
|
||||
int value;
|
||||
if(idx == NO_ENTRY){
|
||||
value = idx;
|
||||
}else {
|
||||
int offset = getAt(index) & 0xffff0000;
|
||||
idx = idx & 0xffff;
|
||||
value = offset | idx;
|
||||
}
|
||||
super.put(index, value);
|
||||
}
|
||||
@Override
|
||||
public int getOffset(int i){
|
||||
int value = super.getAt(i);
|
||||
if(value == NO_ENTRY){
|
||||
return value;
|
||||
}
|
||||
value = (value >>> 16) & 0xffff;
|
||||
return value * 4;
|
||||
}
|
||||
@Override
|
||||
public void setOffset(int index, int offset){
|
||||
int value;
|
||||
if(offset == NO_ENTRY){
|
||||
value = 0;
|
||||
}else {
|
||||
int idx = getAt(0);
|
||||
idx = idx & 0xffff;
|
||||
offset = offset & 0xffff;
|
||||
offset = offset / 4;
|
||||
offset = offset << 16;
|
||||
value = offset | idx;
|
||||
}
|
||||
super.put(index, value);
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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.array;
|
||||
|
||||
import com.reandroid.arsc.base.BlockArray;
|
||||
import com.reandroid.arsc.chunk.SparseTypeBlock;
|
||||
|
||||
public class SparseTypeBlockArray extends BlockArray<SparseTypeBlock> {
|
||||
@Override
|
||||
public SparseTypeBlock[] newInstance(int len) {
|
||||
return new SparseTypeBlock[len];
|
||||
}
|
||||
@Override
|
||||
public SparseTypeBlock newInstance() {
|
||||
return new SparseTypeBlock();
|
||||
}
|
||||
@Override
|
||||
protected void onRefreshed() {
|
||||
}
|
||||
public void merge(SparseTypeBlockArray sparse){
|
||||
if(sparse == null || sparse == this){
|
||||
return;
|
||||
}
|
||||
addAll(sparse.getChildes());
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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.array;
|
||||
|
||||
import com.reandroid.arsc.base.BlockArray;
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.value.SparseTypeEntry;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SparseTypeEntryArray extends BlockArray<SparseTypeEntry> {
|
||||
@Override
|
||||
public SparseTypeEntry[] newInstance(int len) {
|
||||
return new SparseTypeEntry[len];
|
||||
}
|
||||
@Override
|
||||
public SparseTypeEntry newInstance() {
|
||||
return new SparseTypeEntry();
|
||||
}
|
||||
@Override
|
||||
protected void onRefreshed() {
|
||||
}
|
||||
@Override
|
||||
public void onReadBytes(BlockReader reader) throws IOException {
|
||||
int count = reader.available() / 4;
|
||||
setChildesCount(count);
|
||||
super.onReadBytes(reader);
|
||||
}
|
||||
}
|
@ -15,12 +15,11 @@
|
||||
*/
|
||||
package com.reandroid.arsc.array;
|
||||
|
||||
import com.reandroid.arsc.item.IntegerArray;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.item.SpecString;
|
||||
|
||||
public class SpecStringArray extends StringArray<SpecString> {
|
||||
public SpecStringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
public SpecStringArray(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
super(offsets, itemCount, itemStart, is_utf8);
|
||||
}
|
||||
@Override
|
||||
|
@ -115,25 +115,9 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public byte getTypeId(){
|
||||
SpecTypePair[] items=getChildes();
|
||||
if(items==null){
|
||||
return 0;
|
||||
}
|
||||
int max=items.length;
|
||||
for(int i=0;i<max;i++){
|
||||
SpecTypePair pair=items[i];
|
||||
if(pair!=null){
|
||||
return pair.getTypeId();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public SpecTypePair newInstance() {
|
||||
SpecTypePair pair=new SpecTypePair();
|
||||
pair.setTypeId(getTypeId());
|
||||
return pair;
|
||||
return new SpecTypePair();
|
||||
}
|
||||
@Override
|
||||
public SpecTypePair[] newInstance(int len) {
|
||||
@ -147,7 +131,7 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
|
||||
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()){
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.reandroid.arsc.array;
|
||||
|
||||
import com.reandroid.arsc.item.IntegerArray;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.item.StringItem;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
@ -29,7 +28,7 @@ import java.util.List;
|
||||
public abstract class StringArray<T extends StringItem> extends OffsetBlockArray<T> implements JSONConvert<JSONArray> {
|
||||
private boolean mUtf8;
|
||||
|
||||
public StringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
public StringArray(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
super(offsets, itemCount, itemStart);
|
||||
this.mUtf8=is_utf8;
|
||||
setEndBytes((byte)0x00);
|
||||
|
@ -17,7 +17,6 @@ package com.reandroid.arsc.array;
|
||||
|
||||
import com.reandroid.arsc.io.BlockReader;
|
||||
import com.reandroid.arsc.item.ByteArray;
|
||||
import com.reandroid.arsc.item.IntegerArray;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.item.StyleItem;
|
||||
import com.reandroid.json.JSONConvert;
|
||||
@ -26,7 +25,7 @@ import com.reandroid.json.JSONArray;
|
||||
import java.io.IOException;
|
||||
|
||||
public class StyleArray extends OffsetBlockArray<StyleItem> implements JSONConvert<JSONArray> {
|
||||
public StyleArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart) {
|
||||
public StyleArray(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart) {
|
||||
super(offsets, itemCount, itemStart);
|
||||
setEndBytes(END_BYTE);
|
||||
}
|
||||
|
@ -15,12 +15,11 @@
|
||||
*/
|
||||
package com.reandroid.arsc.array;
|
||||
|
||||
import com.reandroid.arsc.item.IntegerArray;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.item.TableString;
|
||||
|
||||
public class TableStringArray extends StringArray<TableString> {
|
||||
public TableStringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
public TableStringArray(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
super(offsets, itemCount, itemStart, is_utf8);
|
||||
}
|
||||
@Override
|
||||
|
@ -95,12 +95,15 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
return typeBlock.getEntry(entryId);
|
||||
}
|
||||
public TypeBlock getOrCreate(ResConfig resConfig){
|
||||
TypeBlock typeBlock=getTypeBlock(resConfig);
|
||||
return getOrCreate(resConfig, false);
|
||||
}
|
||||
public TypeBlock getOrCreate(ResConfig resConfig, boolean sparse){
|
||||
TypeBlock typeBlock = getTypeBlock(resConfig, sparse);
|
||||
if(typeBlock != null){
|
||||
return typeBlock;
|
||||
}
|
||||
byte id = getTypeId();
|
||||
typeBlock=createNext();
|
||||
typeBlock = createNext(sparse);
|
||||
typeBlock.setTypeId(id);
|
||||
ResConfig config = typeBlock.getResConfig();
|
||||
config.copyFrom(resConfig);
|
||||
@ -131,6 +134,9 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
return null;
|
||||
}
|
||||
public TypeBlock getTypeBlock(ResConfig config){
|
||||
return getTypeBlock(config, false);
|
||||
}
|
||||
public TypeBlock getTypeBlock(ResConfig config, boolean sparse){
|
||||
if(config==null){
|
||||
return null;
|
||||
}
|
||||
@ -138,11 +144,14 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
if(items == null){
|
||||
return null;
|
||||
}
|
||||
int max=items.length;
|
||||
for(int i=0;i<max;i++){
|
||||
TypeBlock block=items[i];
|
||||
if(config.equals(block.getResConfig())){
|
||||
return block;
|
||||
int length = items.length;
|
||||
for(int i = 0; i < length; i++){
|
||||
TypeBlock typeBlock = items[i];
|
||||
if(typeBlock == null || sparse != typeBlock.isSparse()){
|
||||
continue;
|
||||
}
|
||||
if(config.equals(typeBlock.getResConfig())){
|
||||
return typeBlock;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -204,12 +213,9 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
};
|
||||
}
|
||||
private SpecBlock getSpecBlock(){
|
||||
Block parent=getParent();
|
||||
while(parent!=null){
|
||||
if(parent instanceof SpecTypePair){
|
||||
return ((SpecTypePair) parent).getSpecBlock();
|
||||
}
|
||||
parent=parent.getParent();
|
||||
SpecTypePair parent = getParent(SpecTypePair.class);
|
||||
if(parent != null){
|
||||
return parent.getSpecBlock();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -224,7 +230,7 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
@Override
|
||||
public TypeBlock newInstance() {
|
||||
byte id = getTypeId();
|
||||
TypeBlock typeBlock=new TypeBlock();
|
||||
TypeBlock typeBlock = new TypeBlock(false);
|
||||
typeBlock.setTypeId(id);
|
||||
return typeBlock;
|
||||
}
|
||||
@ -232,6 +238,13 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
public TypeBlock[] newInstance(int len) {
|
||||
return new TypeBlock[len];
|
||||
}
|
||||
public TypeBlock createNext(boolean sparse){
|
||||
byte id = getTypeId();
|
||||
TypeBlock typeBlock = new TypeBlock(sparse);
|
||||
typeBlock.setTypeId(id);
|
||||
add(typeBlock);
|
||||
return typeBlock;
|
||||
}
|
||||
@Override
|
||||
protected void onRefreshed() {
|
||||
|
||||
@ -265,18 +278,20 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
public int getHighestEntryCount(){
|
||||
int result=0;
|
||||
for(TypeBlock typeBlock:getChildes()){
|
||||
int count=typeBlock.getEntryArray().childesCount();
|
||||
if(count>result){
|
||||
result=count;
|
||||
int high = typeBlock.getEntryArray().getHighestEntryId();
|
||||
if(high > result){
|
||||
result = high;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public void setEntryCount(int count){
|
||||
for(TypeBlock typeBlock:getChildes()){
|
||||
if(!typeBlock.isSparse()){
|
||||
typeBlock.setEntryCount(count);
|
||||
}
|
||||
}
|
||||
}
|
||||
public TypeString getTypeString(){
|
||||
for(TypeBlock typeBlock:getChildes()){
|
||||
TypeString typeString=typeBlock.getTypeString();
|
||||
@ -306,10 +321,10 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
return;
|
||||
}
|
||||
int length = json.length();
|
||||
ensureSize(length);
|
||||
for(int i = 0; i < length; i++){
|
||||
JSONObject jsonObject = json.getJSONObject(i);
|
||||
TypeBlock typeBlock=get(i);
|
||||
TypeBlock typeBlock = createNext(
|
||||
jsonObject.optBoolean(TypeBlock.NAME_is_sparse, false));
|
||||
typeBlock.fromJson(jsonObject);
|
||||
}
|
||||
}
|
||||
@ -318,8 +333,9 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
||||
return;
|
||||
}
|
||||
for(TypeBlock typeBlock:typeBlockArray.listItems()){
|
||||
TypeBlock block=getOrCreate(typeBlock.getResConfig());
|
||||
block.merge(typeBlock);
|
||||
TypeBlock exist = getOrCreate(
|
||||
typeBlock.getResConfig(), typeBlock.isSparse());
|
||||
exist.merge(typeBlock);
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
@ -15,13 +15,12 @@
|
||||
*/
|
||||
package com.reandroid.arsc.array;
|
||||
|
||||
import com.reandroid.arsc.item.IntegerArray;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.item.TypeString;
|
||||
|
||||
public class TypeStringArray extends StringArray<TypeString> {
|
||||
private int lastCreateIndex;
|
||||
public TypeStringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
public TypeStringArray(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
super(offsets, itemCount, itemStart, is_utf8);
|
||||
}
|
||||
@Override
|
||||
|
@ -83,10 +83,13 @@ public abstract class BlockArray<T extends Block> extends BlockContainer<T> impl
|
||||
return results;
|
||||
}
|
||||
public Collection<T> listItems(){
|
||||
return listItems(false);
|
||||
}
|
||||
public Collection<T> listItems(boolean skipNullBlocks){
|
||||
return new AbstractCollection<T>() {
|
||||
@Override
|
||||
public Iterator<T> iterator(){
|
||||
return BlockArray.this.iterator();
|
||||
return BlockArray.this.iterator(skipNullBlocks);
|
||||
}
|
||||
@Override
|
||||
public boolean contains(Object o){
|
||||
@ -277,12 +280,15 @@ public abstract class BlockArray<T extends Block> extends BlockContainer<T> impl
|
||||
}
|
||||
int len=items.length;
|
||||
for(int i=0;i<len;i++){
|
||||
if(block==items[i]){
|
||||
if(isEqual(items[i], block)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected boolean isEqual(T item, Object obj){
|
||||
return obj == item;
|
||||
}
|
||||
public void remove(Collection<T> blockList){
|
||||
T[] items=elementData;
|
||||
if(items==null || items.length==0){
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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.chunk;
|
||||
|
||||
import com.reandroid.arsc.array.SparseTypeEntryArray;
|
||||
import com.reandroid.arsc.header.TypeHeader;
|
||||
import com.reandroid.arsc.value.SparseTypeEntry;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class SparseTypeBlock extends Chunk<TypeHeader>{
|
||||
private final SparseTypeEntryArray entryArray;
|
||||
public SparseTypeBlock() {
|
||||
super(new TypeHeader(), 1);
|
||||
entryArray = new SparseTypeEntryArray();
|
||||
addChild(entryArray);
|
||||
getHeaderBlock().setSparse(true);
|
||||
}
|
||||
public Collection<SparseTypeEntry> listEntries(){
|
||||
return getEntryArray().listItems();
|
||||
}
|
||||
public SparseTypeEntryArray getEntryArray() {
|
||||
return entryArray;
|
||||
}
|
||||
@Override
|
||||
protected void onChunkRefreshed() {
|
||||
getHeaderBlock().setSparse(true);
|
||||
}
|
||||
}
|
@ -16,6 +16,8 @@
|
||||
package com.reandroid.arsc.chunk;
|
||||
|
||||
import com.reandroid.arsc.array.EntryArray;
|
||||
import com.reandroid.arsc.array.OffsetArray;
|
||||
import com.reandroid.arsc.array.SparseOffsetsArray;
|
||||
import com.reandroid.arsc.base.Block;
|
||||
import com.reandroid.arsc.container.SpecTypePair;
|
||||
import com.reandroid.arsc.header.TypeHeader;
|
||||
@ -39,11 +41,16 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
|
||||
private final EntryArray mEntryArray;
|
||||
private TypeString mTypeString;
|
||||
public TypeBlock() {
|
||||
super(new TypeHeader(), 2);
|
||||
public TypeBlock(boolean sparse) {
|
||||
super(new TypeHeader(sparse), 2);
|
||||
TypeHeader header = getHeaderBlock();
|
||||
|
||||
IntegerArray entryOffsets = new IntegerArray();
|
||||
OffsetArray entryOffsets;
|
||||
if(sparse){
|
||||
entryOffsets = new SparseOffsetsArray();
|
||||
}else {
|
||||
entryOffsets = new OffsetArray();
|
||||
}
|
||||
this.mEntryArray = new EntryArray(entryOffsets,
|
||||
header.getCount(), header.getEntriesStart());
|
||||
|
||||
@ -52,6 +59,9 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
addChild(entryOffsets);
|
||||
addChild(mEntryArray);
|
||||
}
|
||||
public boolean isSparse(){
|
||||
return getHeaderBlock().isSparse();
|
||||
}
|
||||
public void destroy(){
|
||||
getEntryArray().destroy();
|
||||
setId(0);
|
||||
@ -243,6 +253,9 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
@Override
|
||||
public JSONObject toJson() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
if(isSparse()){
|
||||
jsonObject.put(NAME_is_sparse, true);
|
||||
}
|
||||
jsonObject.put(NAME_id, getId());
|
||||
jsonObject.put(NAME_name, getTypeName());
|
||||
jsonObject.put(NAME_config, getResConfig().toJson());
|
||||
@ -279,7 +292,11 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
if(id1 != id2){
|
||||
return Integer.compare(id1, id2);
|
||||
}
|
||||
return getResConfig().compareTo(typeBlock.getResConfig());
|
||||
String q1 = (isSparse() ? "1" : "0")
|
||||
+ getResConfig().getQualifiers();
|
||||
String q2 = (typeBlock.isSparse() ? "1" : "0")
|
||||
+ typeBlock.getResConfig().getQualifiers();
|
||||
return q1.compareTo(q2);
|
||||
}
|
||||
/**
|
||||
* It is allowed to have duplicate entry name therefore it is not recommend to use this.
|
||||
@ -311,4 +328,5 @@ public class TypeBlock extends Chunk<TypeHeader>
|
||||
public static final String NAME_config = "config";
|
||||
public static final String NAME_id = "id";
|
||||
public static final String NAME_entries = "entries";
|
||||
public static final String NAME_is_sparse = "is_sparse";
|
||||
}
|
||||
|
@ -117,13 +117,10 @@ public class PackageBody extends FixedBlockContainer {
|
||||
TypeHeader typeHeader = reader.readTypeHeader();
|
||||
SpecTypePair specTypePair = mSpecTypePairArray.getOrCreate(typeHeader.getId().get());
|
||||
if(typeHeader.isSparse()){
|
||||
SparseTypeBlock sparseTypeBlock = specTypePair
|
||||
.getSparseTypeBlockArray().createNext();
|
||||
sparseTypeBlock.readBytes(reader);
|
||||
}else {
|
||||
TypeBlock typeBlock = specTypePair.getTypeBlockArray().createNext();
|
||||
typeBlock.readBytes(reader);
|
||||
String junk = "";
|
||||
}
|
||||
TypeBlock typeBlock = specTypePair.getTypeBlockArray().createNext(typeHeader.isSparse());
|
||||
typeBlock.readBytes(reader);
|
||||
}
|
||||
private void readLibraryBlock(BlockReader reader) throws IOException{
|
||||
LibraryBlock libraryBlock=new LibraryBlock();
|
||||
|
@ -16,7 +16,6 @@
|
||||
package com.reandroid.arsc.container;
|
||||
|
||||
import com.reandroid.arsc.array.EntryArray;
|
||||
import com.reandroid.arsc.array.SparseTypeBlockArray;
|
||||
import com.reandroid.arsc.chunk.*;
|
||||
import com.reandroid.arsc.array.TypeBlockArray;
|
||||
import com.reandroid.arsc.base.Block;
|
||||
@ -39,31 +38,23 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
private final Block[] mChildes;
|
||||
private final SpecBlock mSpecBlock;
|
||||
private final TypeBlockArray mTypeBlockArray;
|
||||
private final SparseTypeBlockArray sparseTypeBlockArray;
|
||||
|
||||
public SpecTypePair(SpecBlock specBlock, TypeBlockArray typeBlockArray){
|
||||
this.mSpecBlock = specBlock;
|
||||
this.mTypeBlockArray = typeBlockArray;
|
||||
this.sparseTypeBlockArray = new SparseTypeBlockArray();
|
||||
|
||||
this.mChildes=new Block[]{specBlock, typeBlockArray, sparseTypeBlockArray};
|
||||
mSpecBlock.setIndex(0);
|
||||
mTypeBlockArray.setIndex(1);
|
||||
sparseTypeBlockArray.setIndex(2);
|
||||
mSpecBlock.setParent(this);
|
||||
mTypeBlockArray.setParent(this);
|
||||
sparseTypeBlockArray.setParent(this);
|
||||
this.mChildes = new Block[]{specBlock, typeBlockArray};
|
||||
|
||||
specBlock.setIndex(0);
|
||||
typeBlockArray.setIndex(1);
|
||||
|
||||
specBlock.setParent(this);
|
||||
typeBlockArray.setParent(this);
|
||||
}
|
||||
public SpecTypePair(){
|
||||
this(new SpecBlock(), new TypeBlockArray());
|
||||
}
|
||||
|
||||
public SparseTypeBlockArray getSparseTypeBlockArray() {
|
||||
return sparseTypeBlockArray;
|
||||
}
|
||||
public Collection<SparseTypeBlock> listSparseTypeBlock(){
|
||||
return sparseTypeBlockArray.listItems();
|
||||
}
|
||||
|
||||
public Map<Integer, EntryGroup> createEntryGroups(){
|
||||
Map<Integer, EntryGroup> map = new HashMap<>();
|
||||
for(TypeBlock typeBlock:listTypeBlocks()){
|
||||
@ -233,12 +224,8 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
}
|
||||
private void readTypeBlock(BlockReader reader) throws IOException {
|
||||
TypeHeader typeHeader = reader.readTypeHeader();
|
||||
if(typeHeader.isSparse()){
|
||||
SparseTypeBlock sparseTypeBlock = sparseTypeBlockArray.createNext();
|
||||
sparseTypeBlock.readBytes(reader);
|
||||
return;
|
||||
}
|
||||
mTypeBlockArray.readBytes(reader);
|
||||
TypeBlock typeBlock = mTypeBlockArray.createNext(typeHeader.isSparse());
|
||||
typeBlock.readBytes(reader);
|
||||
}
|
||||
private void readUnexpectedNonSpecBlock(BlockReader reader, HeaderBlock headerBlock) throws IOException{
|
||||
throw new IOException("Unexpected block: "+headerBlock.toString()+", Should be: "+ChunkType.SPEC);
|
||||
@ -281,7 +268,6 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
}
|
||||
getSpecBlock().merge(typePair.getSpecBlock());
|
||||
getTypeBlockArray().merge(typePair.getTypeBlockArray());
|
||||
getSparseTypeBlockArray().merge(typePair.getSparseTypeBlockArray());
|
||||
}
|
||||
@Override
|
||||
public int compareTo(SpecTypePair specTypePair) {
|
||||
@ -304,4 +290,5 @@ public class SpecTypePair extends BlockContainer<Block>
|
||||
}
|
||||
|
||||
public static final String NAME_types = "types";
|
||||
public static final String NAME_sparse_types = "sparse_types";
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class TypeHeader extends HeaderBlock{
|
||||
private final IntegerItem count;
|
||||
private final IntegerItem entriesStart;
|
||||
private final ResConfig config;
|
||||
public TypeHeader() {
|
||||
public TypeHeader(boolean sparse) {
|
||||
super(ChunkType.TYPE.ID);
|
||||
this.id = new ByteItem();
|
||||
this.flags = new ByteItem();
|
||||
@ -42,6 +42,7 @@ public class TypeHeader extends HeaderBlock{
|
||||
addChild(count);
|
||||
addChild(entriesStart);
|
||||
addChild(config);
|
||||
setSparse(sparse);
|
||||
}
|
||||
public boolean isSparse(){
|
||||
return (getFlags().get() & FLAG_SPARSE) == FLAG_SPARSE;
|
||||
|
@ -69,7 +69,7 @@ import java.io.*;
|
||||
return specHeader;
|
||||
}
|
||||
public TypeHeader readTypeHeader() throws IOException{
|
||||
TypeHeader typeHeader = new TypeHeader();
|
||||
TypeHeader typeHeader = new TypeHeader(false);
|
||||
if(available() < typeHeader.getMinimumSize()){
|
||||
return null;
|
||||
}
|
||||
|
@ -113,6 +113,14 @@ public class IntegerArray extends BlockItem {
|
||||
(bts[i+2] & 0xff) << 16 |
|
||||
(bts[i+3] & 0xff) << 24;
|
||||
}
|
||||
public int getAt(int index){
|
||||
int i=index*4;
|
||||
byte[] bts = getBytesInternal();
|
||||
return bts[i] & 0xff |
|
||||
(bts[i+1] & 0xff) << 8 |
|
||||
(bts[i+2] & 0xff) << 16 |
|
||||
(bts[i+3] & 0xff) << 24;
|
||||
}
|
||||
public final int size(){
|
||||
return getBytesLength()/4;
|
||||
}
|
||||
|
@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.reandroid.arsc.pool;
|
||||
|
||||
import com.reandroid.arsc.array.ResXmlIDArray;
|
||||
import com.reandroid.arsc.array.StringArray;
|
||||
import com.reandroid.arsc.array.ResXmlStringArray;
|
||||
import com.reandroid.arsc.array.StyleArray;
|
||||
import com.reandroid.arsc.array.*;
|
||||
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||
import com.reandroid.arsc.chunk.xml.ResXmlIDMap;
|
||||
import com.reandroid.arsc.group.StringGroup;
|
||||
@ -55,7 +52,7 @@ import java.util.Objects;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
StringArray<ResXmlString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
StringArray<ResXmlString> newInstance(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
return new ResXmlStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||
}
|
||||
public ResXmlString getOrCreate(String str){
|
||||
|
@ -15,11 +15,10 @@
|
||||
*/
|
||||
package com.reandroid.arsc.pool;
|
||||
|
||||
import com.reandroid.arsc.array.OffsetArray;
|
||||
import com.reandroid.arsc.array.SpecStringArray;
|
||||
import com.reandroid.arsc.array.StringArray;
|
||||
import com.reandroid.arsc.base.Block;
|
||||
import com.reandroid.arsc.chunk.PackageBlock;
|
||||
import com.reandroid.arsc.item.IntegerArray;
|
||||
import com.reandroid.arsc.item.IntegerItem;
|
||||
import com.reandroid.arsc.item.SpecString;
|
||||
|
||||
@ -29,7 +28,7 @@ public class SpecStringPool extends StringPool<SpecString> {
|
||||
}
|
||||
|
||||
@Override
|
||||
StringArray<SpecString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
StringArray<SpecString> newInstance(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
return new SpecStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||
}
|
||||
public PackageBlock getPackageBlock(){
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.reandroid.arsc.pool;
|
||||
|
||||
import com.reandroid.arsc.array.OffsetArray;
|
||||
import com.reandroid.arsc.array.StringArray;
|
||||
import com.reandroid.arsc.array.StyleArray;
|
||||
import com.reandroid.arsc.base.Block;
|
||||
@ -40,8 +41,8 @@ package com.reandroid.arsc.pool;
|
||||
StringPool(boolean is_utf8){
|
||||
super(new StringPoolHeader(), 4);
|
||||
|
||||
IntegerArray offsetStrings = new IntegerArray();
|
||||
IntegerArray offsetStyles = new IntegerArray();
|
||||
OffsetArray offsetStrings = new OffsetArray();
|
||||
OffsetArray offsetStyles = new OffsetArray();
|
||||
|
||||
StringPoolHeader header = getHeaderBlock();
|
||||
|
||||
@ -278,7 +279,7 @@ package com.reandroid.arsc.pool;
|
||||
getHeaderBlock().setSorted(sorted);
|
||||
}
|
||||
|
||||
abstract StringArray<T> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8);
|
||||
abstract StringArray<T> newInstance(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8);
|
||||
@Override
|
||||
protected void onChunkRefreshed() {
|
||||
mArrayStrings.refreshCountAndStart();
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.reandroid.arsc.pool;
|
||||
|
||||
import com.reandroid.arsc.array.OffsetArray;
|
||||
import com.reandroid.arsc.array.StringArray;
|
||||
import com.reandroid.arsc.array.TableStringArray;
|
||||
import com.reandroid.arsc.chunk.ChunkType;
|
||||
@ -35,7 +36,7 @@ import java.io.InputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
StringArray<TableString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
StringArray<TableString> newInstance(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
return new TableStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||
}
|
||||
public void merge(TableStringPool stringPool){
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.reandroid.arsc.pool;
|
||||
|
||||
import com.reandroid.arsc.array.OffsetArray;
|
||||
import com.reandroid.arsc.array.StringArray;
|
||||
import com.reandroid.arsc.array.TypeStringArray;
|
||||
import com.reandroid.arsc.chunk.TypeBlock;
|
||||
@ -80,7 +81,7 @@ public class TypeStringPool extends StringPool<TypeString> {
|
||||
return group.get(0);
|
||||
}
|
||||
@Override
|
||||
StringArray<TypeString> newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
StringArray<TypeString> newInstance(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) {
|
||||
return new TypeStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.reandroid.arsc.value;
|
||||
|
||||
import com.reandroid.arsc.array.EntryArray;
|
||||
import com.reandroid.arsc.array.ResValueMapArray;
|
||||
import com.reandroid.arsc.base.Block;
|
||||
import com.reandroid.arsc.base.BlockCounter;
|
||||
@ -65,7 +66,12 @@
|
||||
ensureTableEntry(isComplex);
|
||||
}
|
||||
public int getId(){
|
||||
return getIndex();
|
||||
int id = getIndex();
|
||||
EntryArray entryArray = getParentInstance(EntryArray.class);
|
||||
if(entryArray != null){
|
||||
id = entryArray.getEntryId(id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
public String getName(){
|
||||
SpecString specString = getSpecString();
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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.value;
|
||||
|
||||
import com.reandroid.arsc.item.BlockItem;
|
||||
|
||||
public class SparseTypeEntry extends BlockItem {
|
||||
public SparseTypeEntry() {
|
||||
super(4);
|
||||
}
|
||||
public int getIdx(){
|
||||
return getShort(getBytesInternal(), 0) & 0xffff;
|
||||
}
|
||||
public void setIdx(int idx){
|
||||
putShort(getBytesInternal(), 0, (short) idx);
|
||||
}
|
||||
public int getOffset(){
|
||||
return getShort(getBytesInternal(), 2) & 0xffff;
|
||||
}
|
||||
public void setOffset(int offset){
|
||||
putShort(getBytesInternal(), 2, (short) offset);
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return "idx=" + getIdx() + ", offset=" + getOffset();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user