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;
|
package com.reandroid.arsc.array;
|
||||||
|
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
import com.reandroid.arsc.item.IntegerItem;
|
||||||
import com.reandroid.arsc.value.Entry;
|
import com.reandroid.arsc.value.Entry;
|
||||||
import com.reandroid.json.JSONConvert;
|
import com.reandroid.json.JSONConvert;
|
||||||
@ -26,9 +25,32 @@ import java.util.Iterator;
|
|||||||
|
|
||||||
|
|
||||||
public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<JSONArray> {
|
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);
|
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(){
|
public void destroy(){
|
||||||
for(Entry entry:listItems()){
|
for(Entry entry:listItems()){
|
||||||
if(entry!=null){
|
if(entry!=null){
|
||||||
@ -47,26 +69,41 @@ public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<J
|
|||||||
public boolean isEmpty(){
|
public boolean isEmpty(){
|
||||||
return !iterator(true).hasNext();
|
return !iterator(true).hasNext();
|
||||||
}
|
}
|
||||||
public void setEntry(short entryId, Entry entry){
|
|
||||||
setItem(0xffff & entryId, entry);
|
|
||||||
}
|
|
||||||
public Entry getOrCreate(short entryId){
|
public Entry getOrCreate(short entryId){
|
||||||
int id = 0xffff & entryId;
|
int id = 0xffff & entryId;
|
||||||
Entry entry =get(id);
|
Entry entry = getEntry(id);
|
||||||
if(entry !=null){
|
if(entry != null){
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
int count=id+1;
|
boolean sparse = isSparse();
|
||||||
|
int count;
|
||||||
|
if(sparse){
|
||||||
|
count = childesCount() + 1;
|
||||||
|
}else {
|
||||||
|
count = id + 1;
|
||||||
|
}
|
||||||
ensureSize(count);
|
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();
|
refreshCount();
|
||||||
return get(id);
|
|
||||||
}
|
|
||||||
public Entry get(short entryId){
|
|
||||||
int index = 0xffff & entryId;
|
|
||||||
return super.get(index);
|
return super.get(index);
|
||||||
}
|
}
|
||||||
|
public Entry get(short entryId){
|
||||||
|
return getEntry(entryId);
|
||||||
|
}
|
||||||
public Entry getEntry(short 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
|
@Override
|
||||||
public Entry newInstance() {
|
public Entry newInstance() {
|
||||||
@ -98,7 +135,7 @@ public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<J
|
|||||||
JSONArray jsonArray=new JSONArray();
|
JSONArray jsonArray=new JSONArray();
|
||||||
int index=0;
|
int index=0;
|
||||||
String name_id = Entry.NAME_id;
|
String name_id = Entry.NAME_id;
|
||||||
for(Entry entry :listItems()){
|
for(Entry entry : listItems(true)){
|
||||||
JSONObject childObject = entry.toJson();
|
JSONObject childObject = entry.toJson();
|
||||||
if(childObject==null){
|
if(childObject==null){
|
||||||
continue;
|
continue;
|
||||||
@ -112,33 +149,74 @@ public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<J
|
|||||||
@Override
|
@Override
|
||||||
public void fromJson(JSONArray json) {
|
public void fromJson(JSONArray json) {
|
||||||
clearChildes();
|
clearChildes();
|
||||||
|
if(isSparse()){
|
||||||
|
fromJsonSparse(json);
|
||||||
|
}else {
|
||||||
|
fromJsonNonSparse(json);
|
||||||
|
}
|
||||||
|
refreshCountAndStart();
|
||||||
|
}
|
||||||
|
private void fromJsonNonSparse(JSONArray json){
|
||||||
int length=json.length();
|
int length=json.length();
|
||||||
ensureSize(length);
|
ensureSize(length);
|
||||||
String name_id = Entry.NAME_id;
|
String name_id = Entry.NAME_id;
|
||||||
for(int i=0;i<length;i++){
|
for(int i=0;i<length;i++){
|
||||||
JSONObject jsonObject= json.getJSONObject(i);
|
JSONObject jsonObject = json.optJSONObject(i);
|
||||||
if(jsonObject==null){
|
if(jsonObject==null){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int id = jsonObject.getInt(name_id);
|
int id = jsonObject.getInt(name_id);
|
||||||
ensureSize(id+1);
|
ensureSize(id + 1);
|
||||||
Entry entry =get(id);
|
Entry entry = super.get(id);
|
||||||
entry.fromJson(jsonObject);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void merge(EntryArray entryArray){
|
||||||
|
if(entryArray ==null|| entryArray == this|| entryArray.isEmpty()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(isSparse()){
|
||||||
|
mergeSparse(entryArray);
|
||||||
|
}else {
|
||||||
|
mergeNonSparse(entryArray);
|
||||||
|
}
|
||||||
refreshCountAndStart();
|
refreshCountAndStart();
|
||||||
}
|
}
|
||||||
public void merge(EntryArray entryArray){
|
private void mergeSparse(EntryArray entryArray){
|
||||||
if(entryArray ==null|| entryArray ==this|| entryArray.isEmpty()){
|
Iterator<Entry> itr = entryArray.iterator(true);
|
||||||
return;
|
while (itr.hasNext()){
|
||||||
|
Entry comingBlock = itr.next();
|
||||||
|
Entry existingBlock = getOrCreate((short) comingBlock.getId());
|
||||||
|
existingBlock.merge(comingBlock);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
private void mergeNonSparse(EntryArray entryArray){
|
||||||
ensureSize(entryArray.childesCount());
|
ensureSize(entryArray.childesCount());
|
||||||
Iterator<Entry> itr = entryArray.iterator(true);
|
Iterator<Entry> itr = entryArray.iterator(true);
|
||||||
while (itr.hasNext()){
|
while (itr.hasNext()){
|
||||||
Entry comingBlock = itr.next();
|
Entry comingBlock = itr.next();
|
||||||
Entry existingBlock = get(comingBlock.getIndex());
|
Entry existingBlock = super.get(comingBlock.getIndex());
|
||||||
existingBlock.merge(comingBlock);
|
existingBlock.merge(comingBlock);
|
||||||
}
|
}
|
||||||
refreshCountAndStart();
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
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;
|
||||||
|
}
|
@ -1,18 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.array;
|
package com.reandroid.arsc.array;
|
||||||
|
|
||||||
|
|
||||||
@ -22,7 +22,6 @@ import com.reandroid.arsc.base.BlockCounter;
|
|||||||
import com.reandroid.arsc.io.BlockLoad;
|
import com.reandroid.arsc.io.BlockLoad;
|
||||||
import com.reandroid.arsc.io.BlockReader;
|
import com.reandroid.arsc.io.BlockReader;
|
||||||
import com.reandroid.arsc.item.ByteArray;
|
import com.reandroid.arsc.item.ByteArray;
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
import com.reandroid.arsc.item.IntegerItem;
|
||||||
|
|
||||||
|
|
||||||
@ -30,12 +29,12 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> implements BlockLoad {
|
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 mItemStart;
|
||||||
private final IntegerItem mItemCount;
|
private final IntegerItem mItemCount;
|
||||||
private final ByteArray mEnd4Block;
|
private final ByteArray mEnd4Block;
|
||||||
private byte mEnd4Type;
|
private byte mEnd4Type;
|
||||||
public OffsetBlockArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart){
|
public OffsetBlockArray(OffsetArray offsets, IntegerItem itemCount, IntegerItem itemStart){
|
||||||
super();
|
super();
|
||||||
this.mOffsets=offsets;
|
this.mOffsets=offsets;
|
||||||
this.mItemCount=itemCount;
|
this.mItemCount=itemCount;
|
||||||
@ -43,6 +42,9 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
|
|||||||
this.mEnd4Block=new ByteArray();
|
this.mEnd4Block=new ByteArray();
|
||||||
mItemCount.setBlockLoad(this);
|
mItemCount.setBlockLoad(this);
|
||||||
}
|
}
|
||||||
|
OffsetArray getOffsetArray(){
|
||||||
|
return mOffsets;
|
||||||
|
}
|
||||||
void setEndBytes(byte b){
|
void setEndBytes(byte b){
|
||||||
this.mEnd4Type=b;
|
this.mEnd4Type=b;
|
||||||
this.mEnd4Block.fill(b);
|
this.mEnd4Block.fill(b);
|
||||||
@ -91,7 +93,8 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
|
|||||||
@Override
|
@Override
|
||||||
protected void onRefreshed() {
|
protected void onRefreshed() {
|
||||||
int count=childesCount();
|
int count=childesCount();
|
||||||
mOffsets.setSize(count);
|
OffsetArray offsetArray = this.mOffsets;
|
||||||
|
offsetArray.setSize(count);
|
||||||
T[] childes=getChildes();
|
T[] childes=getChildes();
|
||||||
int sum=0;
|
int sum=0;
|
||||||
if(childes!=null){
|
if(childes!=null){
|
||||||
@ -105,7 +108,7 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
|
|||||||
offset=sum;
|
offset=sum;
|
||||||
sum+=item.countBytes();
|
sum+=item.countBytes();
|
||||||
}
|
}
|
||||||
mOffsets.put(i, offset);
|
offsetArray.setOffset(i, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
refreshCount();
|
refreshCount();
|
||||||
@ -167,7 +170,7 @@ public abstract class OffsetBlockArray<T extends Block> extends BlockArray<T> im
|
|||||||
if(childes==null||childes.length==0){
|
if(childes==null||childes.length==0){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int[] offsetArray=mOffsets.toArray();
|
int[] offsetArray=mOffsets.getOffsets();
|
||||||
int max=childes.length;
|
int max=childes.length;
|
||||||
int start=mItemStart.get();
|
int start=mItemStart.get();
|
||||||
reader.seek(start);
|
reader.seek(start);
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.array;
|
package com.reandroid.arsc.array;
|
||||||
|
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||||
@ -24,8 +24,8 @@ import com.reandroid.arsc.item.ResXmlString;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ResXmlStringArray extends StringArray<ResXmlString> {
|
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);
|
super(offsets, itemCount, itemStart, is_utf8);
|
||||||
}
|
}
|
||||||
@Override
|
@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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +1,25 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.array;
|
package com.reandroid.arsc.array;
|
||||||
|
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
import com.reandroid.arsc.item.IntegerItem;
|
||||||
import com.reandroid.arsc.item.SpecString;
|
import com.reandroid.arsc.item.SpecString;
|
||||||
|
|
||||||
public class SpecStringArray extends StringArray<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);
|
super(offsets, itemCount, itemStart, is_utf8);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -90,11 +90,11 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
|
|||||||
return pair.getTypeBlockArray().getOrCreate(resConfig);
|
return pair.getTypeBlockArray().getOrCreate(resConfig);
|
||||||
}
|
}
|
||||||
public SpecTypePair getOrCreate(byte typeId){
|
public SpecTypePair getOrCreate(byte typeId){
|
||||||
SpecTypePair pair=getPair(typeId);
|
SpecTypePair pair = getPair(typeId);
|
||||||
if(pair!=null){
|
if(pair!=null){
|
||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
pair=createNext();
|
pair = createNext();
|
||||||
pair.setTypeId(typeId);
|
pair.setTypeId(typeId);
|
||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
@ -115,25 +115,9 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
|
|||||||
}
|
}
|
||||||
return null;
|
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
|
@Override
|
||||||
public SpecTypePair newInstance() {
|
public SpecTypePair newInstance() {
|
||||||
SpecTypePair pair=new SpecTypePair();
|
return new SpecTypePair();
|
||||||
pair.setTypeId(getTypeId());
|
|
||||||
return pair;
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public SpecTypePair[] newInstance(int len) {
|
public SpecTypePair[] newInstance(int len) {
|
||||||
@ -147,7 +131,7 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
|
|||||||
protected void onPreRefreshRefresh(){
|
protected void onPreRefreshRefresh(){
|
||||||
validateEntryCounts();
|
validateEntryCounts();
|
||||||
}
|
}
|
||||||
// For android API < 26, it is required to have equal entry count on all SpecTypePair
|
|
||||||
private void validateEntryCounts(){
|
private void validateEntryCounts(){
|
||||||
Map<Byte, Integer> entryCountMap=mapHighestEntryCount();
|
Map<Byte, Integer> entryCountMap=mapHighestEntryCount();
|
||||||
for(Map.Entry<Byte, Integer> entry:entryCountMap.entrySet()){
|
for(Map.Entry<Byte, Integer> entry:entryCountMap.entrySet()){
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.array;
|
package com.reandroid.arsc.array;
|
||||||
|
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
import com.reandroid.arsc.item.IntegerItem;
|
||||||
import com.reandroid.arsc.item.StringItem;
|
import com.reandroid.arsc.item.StringItem;
|
||||||
import com.reandroid.json.JSONConvert;
|
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> {
|
public abstract class StringArray<T extends StringItem> extends OffsetBlockArray<T> implements JSONConvert<JSONArray> {
|
||||||
private boolean mUtf8;
|
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);
|
super(offsets, itemCount, itemStart);
|
||||||
this.mUtf8=is_utf8;
|
this.mUtf8=is_utf8;
|
||||||
setEndBytes((byte)0x00);
|
setEndBytes((byte)0x00);
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.array;
|
package com.reandroid.arsc.array;
|
||||||
|
|
||||||
import com.reandroid.arsc.io.BlockReader;
|
import com.reandroid.arsc.io.BlockReader;
|
||||||
import com.reandroid.arsc.item.ByteArray;
|
import com.reandroid.arsc.item.ByteArray;
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
import com.reandroid.arsc.item.IntegerItem;
|
||||||
import com.reandroid.arsc.item.StyleItem;
|
import com.reandroid.arsc.item.StyleItem;
|
||||||
import com.reandroid.json.JSONConvert;
|
import com.reandroid.json.JSONConvert;
|
||||||
@ -26,7 +25,7 @@ import com.reandroid.json.JSONArray;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class StyleArray extends OffsetBlockArray<StyleItem> implements JSONConvert<JSONArray> {
|
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);
|
super(offsets, itemCount, itemStart);
|
||||||
setEndBytes(END_BYTE);
|
setEndBytes(END_BYTE);
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.array;
|
package com.reandroid.arsc.array;
|
||||||
|
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
import com.reandroid.arsc.item.IntegerItem;
|
||||||
import com.reandroid.arsc.item.TableString;
|
import com.reandroid.arsc.item.TableString;
|
||||||
|
|
||||||
public class TableStringArray extends StringArray<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);
|
super(offsets, itemCount, itemStart, is_utf8);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -95,14 +95,17 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
|||||||
return typeBlock.getEntry(entryId);
|
return typeBlock.getEntry(entryId);
|
||||||
}
|
}
|
||||||
public TypeBlock getOrCreate(ResConfig resConfig){
|
public TypeBlock getOrCreate(ResConfig resConfig){
|
||||||
TypeBlock typeBlock=getTypeBlock(resConfig);
|
return getOrCreate(resConfig, false);
|
||||||
if(typeBlock!=null){
|
}
|
||||||
|
public TypeBlock getOrCreate(ResConfig resConfig, boolean sparse){
|
||||||
|
TypeBlock typeBlock = getTypeBlock(resConfig, sparse);
|
||||||
|
if(typeBlock != null){
|
||||||
return typeBlock;
|
return typeBlock;
|
||||||
}
|
}
|
||||||
byte id=getTypeId();
|
byte id = getTypeId();
|
||||||
typeBlock=createNext();
|
typeBlock = createNext(sparse);
|
||||||
typeBlock.setTypeId(id);
|
typeBlock.setTypeId(id);
|
||||||
ResConfig config=typeBlock.getResConfig();
|
ResConfig config = typeBlock.getResConfig();
|
||||||
config.copyFrom(resConfig);
|
config.copyFrom(resConfig);
|
||||||
return typeBlock;
|
return typeBlock;
|
||||||
}
|
}
|
||||||
@ -131,18 +134,24 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public TypeBlock getTypeBlock(ResConfig config){
|
public TypeBlock getTypeBlock(ResConfig config){
|
||||||
|
return getTypeBlock(config, false);
|
||||||
|
}
|
||||||
|
public TypeBlock getTypeBlock(ResConfig config, boolean sparse){
|
||||||
if(config==null){
|
if(config==null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
TypeBlock[] items=getChildes();
|
TypeBlock[] items = getChildes();
|
||||||
if(items==null){
|
if(items == null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int max=items.length;
|
int length = items.length;
|
||||||
for(int i=0;i<max;i++){
|
for(int i = 0; i < length; i++){
|
||||||
TypeBlock block=items[i];
|
TypeBlock typeBlock = items[i];
|
||||||
if(config.equals(block.getResConfig())){
|
if(typeBlock == null || sparse != typeBlock.isSparse()){
|
||||||
return block;
|
continue;
|
||||||
|
}
|
||||||
|
if(config.equals(typeBlock.getResConfig())){
|
||||||
|
return typeBlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -204,12 +213,9 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
private SpecBlock getSpecBlock(){
|
private SpecBlock getSpecBlock(){
|
||||||
Block parent=getParent();
|
SpecTypePair parent = getParent(SpecTypePair.class);
|
||||||
while(parent!=null){
|
if(parent != null){
|
||||||
if(parent instanceof SpecTypePair){
|
return parent.getSpecBlock();
|
||||||
return ((SpecTypePair) parent).getSpecBlock();
|
|
||||||
}
|
|
||||||
parent=parent.getParent();
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -223,8 +229,8 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public TypeBlock newInstance() {
|
public TypeBlock newInstance() {
|
||||||
byte id=getTypeId();
|
byte id = getTypeId();
|
||||||
TypeBlock typeBlock=new TypeBlock();
|
TypeBlock typeBlock = new TypeBlock(false);
|
||||||
typeBlock.setTypeId(id);
|
typeBlock.setTypeId(id);
|
||||||
return typeBlock;
|
return typeBlock;
|
||||||
}
|
}
|
||||||
@ -232,6 +238,13 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
|||||||
public TypeBlock[] newInstance(int len) {
|
public TypeBlock[] newInstance(int len) {
|
||||||
return new TypeBlock[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
|
@Override
|
||||||
protected void onRefreshed() {
|
protected void onRefreshed() {
|
||||||
|
|
||||||
@ -265,16 +278,18 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
|||||||
public int getHighestEntryCount(){
|
public int getHighestEntryCount(){
|
||||||
int result=0;
|
int result=0;
|
||||||
for(TypeBlock typeBlock:getChildes()){
|
for(TypeBlock typeBlock:getChildes()){
|
||||||
int count=typeBlock.getEntryArray().childesCount();
|
int high = typeBlock.getEntryArray().getHighestEntryId();
|
||||||
if(count>result){
|
if(high > result){
|
||||||
result=count;
|
result = high;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
public void setEntryCount(int count){
|
public void setEntryCount(int count){
|
||||||
for(TypeBlock typeBlock:getChildes()){
|
for(TypeBlock typeBlock:getChildes()){
|
||||||
typeBlock.setEntryCount(count);
|
if(!typeBlock.isSparse()){
|
||||||
|
typeBlock.setEntryCount(count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public TypeString getTypeString(){
|
public TypeString getTypeString(){
|
||||||
@ -305,21 +320,22 @@ public class TypeBlockArray extends BlockArray<TypeBlock>
|
|||||||
if(json == null){
|
if(json == null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int length= json.length();
|
int length = json.length();
|
||||||
ensureSize(length);
|
for(int i = 0; i < length; i++){
|
||||||
for (int i=0;i<length;i++){
|
JSONObject jsonObject = json.getJSONObject(i);
|
||||||
JSONObject jsonObject=json.getJSONObject(i);
|
TypeBlock typeBlock = createNext(
|
||||||
TypeBlock typeBlock=get(i);
|
jsonObject.optBoolean(TypeBlock.NAME_is_sparse, false));
|
||||||
typeBlock.fromJson(jsonObject);
|
typeBlock.fromJson(jsonObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void merge(TypeBlockArray typeBlockArray){
|
public void merge(TypeBlockArray typeBlockArray){
|
||||||
if(typeBlockArray==null||typeBlockArray==this){
|
if(typeBlockArray == null || typeBlockArray == this){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(TypeBlock typeBlock:typeBlockArray.listItems()){
|
for(TypeBlock typeBlock:typeBlockArray.listItems()){
|
||||||
TypeBlock block=getOrCreate(typeBlock.getResConfig());
|
TypeBlock exist = getOrCreate(
|
||||||
block.merge(typeBlock);
|
typeBlock.getResConfig(), typeBlock.isSparse());
|
||||||
|
exist.merge(typeBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -15,13 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.array;
|
package com.reandroid.arsc.array;
|
||||||
|
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
import com.reandroid.arsc.item.IntegerItem;
|
||||||
import com.reandroid.arsc.item.TypeString;
|
import com.reandroid.arsc.item.TypeString;
|
||||||
|
|
||||||
public class TypeStringArray extends StringArray<TypeString> {
|
public class TypeStringArray extends StringArray<TypeString> {
|
||||||
private int lastCreateIndex;
|
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);
|
super(offsets, itemCount, itemStart, is_utf8);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -83,10 +83,13 @@ public abstract class BlockArray<T extends Block> extends BlockContainer<T> impl
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
public Collection<T> listItems(){
|
public Collection<T> listItems(){
|
||||||
|
return listItems(false);
|
||||||
|
}
|
||||||
|
public Collection<T> listItems(boolean skipNullBlocks){
|
||||||
return new AbstractCollection<T>() {
|
return new AbstractCollection<T>() {
|
||||||
@Override
|
@Override
|
||||||
public Iterator<T> iterator(){
|
public Iterator<T> iterator(){
|
||||||
return BlockArray.this.iterator();
|
return BlockArray.this.iterator(skipNullBlocks);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(Object o){
|
public boolean contains(Object o){
|
||||||
@ -277,12 +280,15 @@ public abstract class BlockArray<T extends Block> extends BlockContainer<T> impl
|
|||||||
}
|
}
|
||||||
int len=items.length;
|
int len=items.length;
|
||||||
for(int i=0;i<len;i++){
|
for(int i=0;i<len;i++){
|
||||||
if(block==items[i]){
|
if(isEqual(items[i], block)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
protected boolean isEqual(T item, Object obj){
|
||||||
|
return obj == item;
|
||||||
|
}
|
||||||
public void remove(Collection<T> blockList){
|
public void remove(Collection<T> blockList){
|
||||||
T[] items=elementData;
|
T[] items=elementData;
|
||||||
if(items==null || items.length==0){
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.chunk;
|
package com.reandroid.arsc.chunk;
|
||||||
|
|
||||||
import com.reandroid.arsc.array.EntryArray;
|
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.base.Block;
|
||||||
import com.reandroid.arsc.container.SpecTypePair;
|
import com.reandroid.arsc.container.SpecTypePair;
|
||||||
import com.reandroid.arsc.header.TypeHeader;
|
import com.reandroid.arsc.header.TypeHeader;
|
||||||
@ -39,11 +41,16 @@ public class TypeBlock extends Chunk<TypeHeader>
|
|||||||
|
|
||||||
private final EntryArray mEntryArray;
|
private final EntryArray mEntryArray;
|
||||||
private TypeString mTypeString;
|
private TypeString mTypeString;
|
||||||
public TypeBlock() {
|
public TypeBlock(boolean sparse) {
|
||||||
super(new TypeHeader(), 2);
|
super(new TypeHeader(sparse), 2);
|
||||||
TypeHeader header = getHeaderBlock();
|
TypeHeader header = getHeaderBlock();
|
||||||
|
|
||||||
IntegerArray entryOffsets = new IntegerArray();
|
OffsetArray entryOffsets;
|
||||||
|
if(sparse){
|
||||||
|
entryOffsets = new SparseOffsetsArray();
|
||||||
|
}else {
|
||||||
|
entryOffsets = new OffsetArray();
|
||||||
|
}
|
||||||
this.mEntryArray = new EntryArray(entryOffsets,
|
this.mEntryArray = new EntryArray(entryOffsets,
|
||||||
header.getCount(), header.getEntriesStart());
|
header.getCount(), header.getEntriesStart());
|
||||||
|
|
||||||
@ -52,6 +59,9 @@ public class TypeBlock extends Chunk<TypeHeader>
|
|||||||
addChild(entryOffsets);
|
addChild(entryOffsets);
|
||||||
addChild(mEntryArray);
|
addChild(mEntryArray);
|
||||||
}
|
}
|
||||||
|
public boolean isSparse(){
|
||||||
|
return getHeaderBlock().isSparse();
|
||||||
|
}
|
||||||
public void destroy(){
|
public void destroy(){
|
||||||
getEntryArray().destroy();
|
getEntryArray().destroy();
|
||||||
setId(0);
|
setId(0);
|
||||||
@ -227,9 +237,9 @@ public class TypeBlock extends Chunk<TypeHeader>
|
|||||||
super.onPreRefreshRefresh();
|
super.onPreRefreshRefresh();
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* method Block.addBytes is inefficient for large size byte array
|
* method Block.addBytes is inefficient for large size byte array
|
||||||
* so let's override here because this block is the largest
|
* so let's override here because this block is the largest
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public byte[] getBytes(){
|
public byte[] getBytes(){
|
||||||
ByteArrayOutputStream os=new ByteArrayOutputStream();
|
ByteArrayOutputStream os=new ByteArrayOutputStream();
|
||||||
@ -242,7 +252,10 @@ public class TypeBlock extends Chunk<TypeHeader>
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public JSONObject toJson() {
|
public JSONObject toJson() {
|
||||||
JSONObject jsonObject=new JSONObject();
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
if(isSparse()){
|
||||||
|
jsonObject.put(NAME_is_sparse, true);
|
||||||
|
}
|
||||||
jsonObject.put(NAME_id, getId());
|
jsonObject.put(NAME_id, getId());
|
||||||
jsonObject.put(NAME_name, getTypeName());
|
jsonObject.put(NAME_name, getTypeName());
|
||||||
jsonObject.put(NAME_config, getResConfig().toJson());
|
jsonObject.put(NAME_config, getResConfig().toJson());
|
||||||
@ -274,12 +287,16 @@ public class TypeBlock extends Chunk<TypeHeader>
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(TypeBlock typeBlock) {
|
public int compareTo(TypeBlock typeBlock) {
|
||||||
int id1= getId();
|
int id1 = getId();
|
||||||
int id2=typeBlock.getId();
|
int id2 = typeBlock.getId();
|
||||||
if(id1!=id2){
|
if(id1 != id2){
|
||||||
return Integer.compare(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.
|
* 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_config = "config";
|
||||||
public static final String NAME_id = "id";
|
public static final String NAME_id = "id";
|
||||||
public static final String NAME_entries = "entries";
|
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();
|
TypeHeader typeHeader = reader.readTypeHeader();
|
||||||
SpecTypePair specTypePair = mSpecTypePairArray.getOrCreate(typeHeader.getId().get());
|
SpecTypePair specTypePair = mSpecTypePairArray.getOrCreate(typeHeader.getId().get());
|
||||||
if(typeHeader.isSparse()){
|
if(typeHeader.isSparse()){
|
||||||
SparseTypeBlock sparseTypeBlock = specTypePair
|
String junk = "";
|
||||||
.getSparseTypeBlockArray().createNext();
|
|
||||||
sparseTypeBlock.readBytes(reader);
|
|
||||||
}else {
|
|
||||||
TypeBlock typeBlock = specTypePair.getTypeBlockArray().createNext();
|
|
||||||
typeBlock.readBytes(reader);
|
|
||||||
}
|
}
|
||||||
|
TypeBlock typeBlock = specTypePair.getTypeBlockArray().createNext(typeHeader.isSparse());
|
||||||
|
typeBlock.readBytes(reader);
|
||||||
}
|
}
|
||||||
private void readLibraryBlock(BlockReader reader) throws IOException{
|
private void readLibraryBlock(BlockReader reader) throws IOException{
|
||||||
LibraryBlock libraryBlock=new LibraryBlock();
|
LibraryBlock libraryBlock=new LibraryBlock();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -16,7 +16,6 @@
|
|||||||
package com.reandroid.arsc.container;
|
package com.reandroid.arsc.container;
|
||||||
|
|
||||||
import com.reandroid.arsc.array.EntryArray;
|
import com.reandroid.arsc.array.EntryArray;
|
||||||
import com.reandroid.arsc.array.SparseTypeBlockArray;
|
|
||||||
import com.reandroid.arsc.chunk.*;
|
import 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.base.Block;
|
||||||
@ -39,31 +38,23 @@ public class SpecTypePair extends BlockContainer<Block>
|
|||||||
private final Block[] mChildes;
|
private final Block[] mChildes;
|
||||||
private final SpecBlock mSpecBlock;
|
private final SpecBlock mSpecBlock;
|
||||||
private final TypeBlockArray mTypeBlockArray;
|
private final TypeBlockArray mTypeBlockArray;
|
||||||
private final SparseTypeBlockArray sparseTypeBlockArray;
|
|
||||||
public SpecTypePair(SpecBlock specBlock, TypeBlockArray typeBlockArray){
|
public SpecTypePair(SpecBlock specBlock, TypeBlockArray typeBlockArray){
|
||||||
this.mSpecBlock = specBlock;
|
this.mSpecBlock = specBlock;
|
||||||
this.mTypeBlockArray = typeBlockArray;
|
this.mTypeBlockArray = typeBlockArray;
|
||||||
this.sparseTypeBlockArray = new SparseTypeBlockArray();
|
|
||||||
|
|
||||||
this.mChildes=new Block[]{specBlock, typeBlockArray, sparseTypeBlockArray};
|
this.mChildes = new Block[]{specBlock, typeBlockArray};
|
||||||
mSpecBlock.setIndex(0);
|
|
||||||
mTypeBlockArray.setIndex(1);
|
specBlock.setIndex(0);
|
||||||
sparseTypeBlockArray.setIndex(2);
|
typeBlockArray.setIndex(1);
|
||||||
mSpecBlock.setParent(this);
|
|
||||||
mTypeBlockArray.setParent(this);
|
specBlock.setParent(this);
|
||||||
sparseTypeBlockArray.setParent(this);
|
typeBlockArray.setParent(this);
|
||||||
}
|
}
|
||||||
public SpecTypePair(){
|
public SpecTypePair(){
|
||||||
this(new SpecBlock(), new TypeBlockArray());
|
this(new SpecBlock(), new TypeBlockArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public SparseTypeBlockArray getSparseTypeBlockArray() {
|
|
||||||
return sparseTypeBlockArray;
|
|
||||||
}
|
|
||||||
public Collection<SparseTypeBlock> listSparseTypeBlock(){
|
|
||||||
return sparseTypeBlockArray.listItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Integer, EntryGroup> createEntryGroups(){
|
public Map<Integer, EntryGroup> createEntryGroups(){
|
||||||
Map<Integer, EntryGroup> map = new HashMap<>();
|
Map<Integer, EntryGroup> map = new HashMap<>();
|
||||||
for(TypeBlock typeBlock:listTypeBlocks()){
|
for(TypeBlock typeBlock:listTypeBlocks()){
|
||||||
@ -233,12 +224,8 @@ public class SpecTypePair extends BlockContainer<Block>
|
|||||||
}
|
}
|
||||||
private void readTypeBlock(BlockReader reader) throws IOException {
|
private void readTypeBlock(BlockReader reader) throws IOException {
|
||||||
TypeHeader typeHeader = reader.readTypeHeader();
|
TypeHeader typeHeader = reader.readTypeHeader();
|
||||||
if(typeHeader.isSparse()){
|
TypeBlock typeBlock = mTypeBlockArray.createNext(typeHeader.isSparse());
|
||||||
SparseTypeBlock sparseTypeBlock = sparseTypeBlockArray.createNext();
|
typeBlock.readBytes(reader);
|
||||||
sparseTypeBlock.readBytes(reader);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mTypeBlockArray.readBytes(reader);
|
|
||||||
}
|
}
|
||||||
private void readUnexpectedNonSpecBlock(BlockReader reader, HeaderBlock headerBlock) throws IOException{
|
private void readUnexpectedNonSpecBlock(BlockReader reader, HeaderBlock headerBlock) throws IOException{
|
||||||
throw new IOException("Unexpected block: "+headerBlock.toString()+", Should be: "+ChunkType.SPEC);
|
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());
|
getSpecBlock().merge(typePair.getSpecBlock());
|
||||||
getTypeBlockArray().merge(typePair.getTypeBlockArray());
|
getTypeBlockArray().merge(typePair.getTypeBlockArray());
|
||||||
getSparseTypeBlockArray().merge(typePair.getSparseTypeBlockArray());
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(SpecTypePair specTypePair) {
|
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_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 count;
|
||||||
private final IntegerItem entriesStart;
|
private final IntegerItem entriesStart;
|
||||||
private final ResConfig config;
|
private final ResConfig config;
|
||||||
public TypeHeader() {
|
public TypeHeader(boolean sparse) {
|
||||||
super(ChunkType.TYPE.ID);
|
super(ChunkType.TYPE.ID);
|
||||||
this.id = new ByteItem();
|
this.id = new ByteItem();
|
||||||
this.flags = new ByteItem();
|
this.flags = new ByteItem();
|
||||||
@ -42,6 +42,7 @@ public class TypeHeader extends HeaderBlock{
|
|||||||
addChild(count);
|
addChild(count);
|
||||||
addChild(entriesStart);
|
addChild(entriesStart);
|
||||||
addChild(config);
|
addChild(config);
|
||||||
|
setSparse(sparse);
|
||||||
}
|
}
|
||||||
public boolean isSparse(){
|
public boolean isSparse(){
|
||||||
return (getFlags().get() & FLAG_SPARSE) == FLAG_SPARSE;
|
return (getFlags().get() & FLAG_SPARSE) == FLAG_SPARSE;
|
||||||
|
@ -69,7 +69,7 @@ import java.io.*;
|
|||||||
return specHeader;
|
return specHeader;
|
||||||
}
|
}
|
||||||
public TypeHeader readTypeHeader() throws IOException{
|
public TypeHeader readTypeHeader() throws IOException{
|
||||||
TypeHeader typeHeader = new TypeHeader();
|
TypeHeader typeHeader = new TypeHeader(false);
|
||||||
if(available() < typeHeader.getMinimumSize()){
|
if(available() < typeHeader.getMinimumSize()){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,14 @@ public class IntegerArray extends BlockItem {
|
|||||||
(bts[i+2] & 0xff) << 16 |
|
(bts[i+2] & 0xff) << 16 |
|
||||||
(bts[i+3] & 0xff) << 24;
|
(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(){
|
public final int size(){
|
||||||
return getBytesLength()/4;
|
return getBytesLength()/4;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.pool;
|
package com.reandroid.arsc.pool;
|
||||||
|
|
||||||
import com.reandroid.arsc.array.ResXmlIDArray;
|
import com.reandroid.arsc.array.*;
|
||||||
import com.reandroid.arsc.array.StringArray;
|
|
||||||
import com.reandroid.arsc.array.ResXmlStringArray;
|
|
||||||
import com.reandroid.arsc.array.StyleArray;
|
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlIDMap;
|
import com.reandroid.arsc.chunk.xml.ResXmlIDMap;
|
||||||
import com.reandroid.arsc.group.StringGroup;
|
import com.reandroid.arsc.group.StringGroup;
|
||||||
@ -26,7 +23,7 @@ import com.reandroid.arsc.item.*;
|
|||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ResXmlStringPool extends StringPool<ResXmlString> {
|
public class ResXmlStringPool extends StringPool<ResXmlString> {
|
||||||
public ResXmlStringPool(boolean is_utf8) {
|
public ResXmlStringPool(boolean is_utf8) {
|
||||||
super(is_utf8);
|
super(is_utf8);
|
||||||
}
|
}
|
||||||
@ -55,7 +52,7 @@ import java.util.Objects;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@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);
|
return new ResXmlStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||||
}
|
}
|
||||||
public ResXmlString getOrCreate(String str){
|
public ResXmlString getOrCreate(String str){
|
||||||
|
@ -1,25 +1,24 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.pool;
|
package com.reandroid.arsc.pool;
|
||||||
|
|
||||||
|
import com.reandroid.arsc.array.OffsetArray;
|
||||||
import com.reandroid.arsc.array.SpecStringArray;
|
import com.reandroid.arsc.array.SpecStringArray;
|
||||||
import com.reandroid.arsc.array.StringArray;
|
import com.reandroid.arsc.array.StringArray;
|
||||||
import com.reandroid.arsc.base.Block;
|
|
||||||
import com.reandroid.arsc.chunk.PackageBlock;
|
import com.reandroid.arsc.chunk.PackageBlock;
|
||||||
import com.reandroid.arsc.item.IntegerArray;
|
|
||||||
import com.reandroid.arsc.item.IntegerItem;
|
import com.reandroid.arsc.item.IntegerItem;
|
||||||
import com.reandroid.arsc.item.SpecString;
|
import com.reandroid.arsc.item.SpecString;
|
||||||
|
|
||||||
@ -29,7 +28,7 @@ public class SpecStringPool extends StringPool<SpecString> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return new SpecStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||||
}
|
}
|
||||||
public PackageBlock getPackageBlock(){
|
public PackageBlock getPackageBlock(){
|
||||||
|
@ -1,37 +1,38 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.pool;
|
package com.reandroid.arsc.pool;
|
||||||
|
|
||||||
import com.reandroid.arsc.array.StringArray;
|
import com.reandroid.arsc.array.OffsetArray;
|
||||||
import com.reandroid.arsc.array.StyleArray;
|
import com.reandroid.arsc.array.StringArray;
|
||||||
import com.reandroid.arsc.base.Block;
|
import com.reandroid.arsc.array.StyleArray;
|
||||||
import com.reandroid.arsc.chunk.Chunk;
|
import com.reandroid.arsc.base.Block;
|
||||||
import com.reandroid.arsc.group.StringGroup;
|
import com.reandroid.arsc.chunk.Chunk;
|
||||||
import com.reandroid.arsc.header.StringPoolHeader;
|
import com.reandroid.arsc.group.StringGroup;
|
||||||
import com.reandroid.arsc.io.BlockLoad;
|
import com.reandroid.arsc.header.StringPoolHeader;
|
||||||
import com.reandroid.arsc.io.BlockReader;
|
import com.reandroid.arsc.io.BlockLoad;
|
||||||
import com.reandroid.arsc.item.*;
|
import com.reandroid.arsc.io.BlockReader;
|
||||||
import com.reandroid.json.JSONArray;
|
import com.reandroid.arsc.item.*;
|
||||||
import com.reandroid.json.JSONConvert;
|
import com.reandroid.json.JSONArray;
|
||||||
|
import com.reandroid.json.JSONConvert;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
public abstract class StringPool<T extends StringItem> extends Chunk<StringPoolHeader> implements BlockLoad, JSONConvert<JSONArray>, Comparator<String> {
|
public abstract class StringPool<T extends StringItem> extends Chunk<StringPoolHeader> implements BlockLoad, JSONConvert<JSONArray>, Comparator<String> {
|
||||||
private final StringArray<T> mArrayStrings;
|
private final StringArray<T> mArrayStrings;
|
||||||
private final StyleArray mArrayStyles;
|
private final StyleArray mArrayStyles;
|
||||||
|
|
||||||
@ -40,8 +41,8 @@ package com.reandroid.arsc.pool;
|
|||||||
StringPool(boolean is_utf8){
|
StringPool(boolean is_utf8){
|
||||||
super(new StringPoolHeader(), 4);
|
super(new StringPoolHeader(), 4);
|
||||||
|
|
||||||
IntegerArray offsetStrings = new IntegerArray();
|
OffsetArray offsetStrings = new OffsetArray();
|
||||||
IntegerArray offsetStyles = new IntegerArray();
|
OffsetArray offsetStyles = new OffsetArray();
|
||||||
|
|
||||||
StringPoolHeader header = getHeaderBlock();
|
StringPoolHeader header = getHeaderBlock();
|
||||||
|
|
||||||
@ -278,7 +279,7 @@ package com.reandroid.arsc.pool;
|
|||||||
getHeaderBlock().setSorted(sorted);
|
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
|
@Override
|
||||||
protected void onChunkRefreshed() {
|
protected void onChunkRefreshed() {
|
||||||
mArrayStrings.refreshCountAndStart();
|
mArrayStrings.refreshCountAndStart();
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.pool;
|
package com.reandroid.arsc.pool;
|
||||||
|
|
||||||
|
import com.reandroid.arsc.array.OffsetArray;
|
||||||
import com.reandroid.arsc.array.StringArray;
|
import com.reandroid.arsc.array.StringArray;
|
||||||
import com.reandroid.arsc.array.TableStringArray;
|
import com.reandroid.arsc.array.TableStringArray;
|
||||||
import com.reandroid.arsc.chunk.ChunkType;
|
import com.reandroid.arsc.chunk.ChunkType;
|
||||||
@ -29,13 +30,13 @@ import com.reandroid.arsc.item.TableString;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class TableStringPool extends StringPool<TableString> {
|
public class TableStringPool extends StringPool<TableString> {
|
||||||
public TableStringPool(boolean is_utf8) {
|
public TableStringPool(boolean is_utf8) {
|
||||||
super(is_utf8);
|
super(is_utf8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return new TableStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||||
}
|
}
|
||||||
public void merge(TableStringPool stringPool){
|
public void merge(TableStringPool stringPool){
|
||||||
@ -58,10 +59,10 @@ import java.io.InputStream;
|
|||||||
refreshUniqueIdMap();
|
refreshUniqueIdMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads string pool only from table block (resources.arsc) without
|
* Loads string pool only from table block (resources.arsc) without
|
||||||
* loading other chunks
|
* loading other chunks
|
||||||
*/
|
*/
|
||||||
public static TableStringPool readFromTable(InputStream inputStream) throws IOException {
|
public static TableStringPool readFromTable(InputStream inputStream) throws IOException {
|
||||||
TableHeader tableHeader = new TableHeader();
|
TableHeader tableHeader = new TableHeader();
|
||||||
tableHeader.readBytes(inputStream);
|
tableHeader.readBytes(inputStream);
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.pool;
|
package com.reandroid.arsc.pool;
|
||||||
|
|
||||||
|
import com.reandroid.arsc.array.OffsetArray;
|
||||||
import com.reandroid.arsc.array.StringArray;
|
import com.reandroid.arsc.array.StringArray;
|
||||||
import com.reandroid.arsc.array.TypeStringArray;
|
import com.reandroid.arsc.array.TypeStringArray;
|
||||||
import com.reandroid.arsc.chunk.TypeBlock;
|
import com.reandroid.arsc.chunk.TypeBlock;
|
||||||
@ -80,7 +81,7 @@ public class TypeStringPool extends StringPool<TypeString> {
|
|||||||
return group.get(0);
|
return group.get(0);
|
||||||
}
|
}
|
||||||
@Override
|
@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);
|
return new TypeStringArray(offsets, itemCount, itemStart, is_utf8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,459 +1,465 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 github.com/REAndroid
|
* Copyright (C) 2022 github.com/REAndroid
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.value;
|
package com.reandroid.arsc.value;
|
||||||
|
|
||||||
import com.reandroid.arsc.array.ResValueMapArray;
|
import com.reandroid.arsc.array.EntryArray;
|
||||||
import com.reandroid.arsc.base.Block;
|
import com.reandroid.arsc.array.ResValueMapArray;
|
||||||
import com.reandroid.arsc.base.BlockCounter;
|
import com.reandroid.arsc.base.Block;
|
||||||
import com.reandroid.arsc.chunk.PackageBlock;
|
import com.reandroid.arsc.base.BlockCounter;
|
||||||
import com.reandroid.arsc.chunk.SpecBlock;
|
import com.reandroid.arsc.chunk.PackageBlock;
|
||||||
import com.reandroid.arsc.chunk.TableBlock;
|
import com.reandroid.arsc.chunk.SpecBlock;
|
||||||
import com.reandroid.arsc.chunk.TypeBlock;
|
import com.reandroid.arsc.chunk.TableBlock;
|
||||||
import com.reandroid.arsc.container.SpecTypePair;
|
import com.reandroid.arsc.chunk.TypeBlock;
|
||||||
import com.reandroid.arsc.group.EntryGroup;
|
import com.reandroid.arsc.container.SpecTypePair;
|
||||||
import com.reandroid.arsc.io.BlockReader;
|
import com.reandroid.arsc.group.EntryGroup;
|
||||||
import com.reandroid.arsc.item.*;
|
import com.reandroid.arsc.io.BlockReader;
|
||||||
import com.reandroid.json.JSONConvert;
|
import com.reandroid.arsc.item.*;
|
||||||
import com.reandroid.json.JSONObject;
|
import com.reandroid.json.JSONConvert;
|
||||||
|
import com.reandroid.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public class Entry extends Block implements JSONConvert<JSONObject> {
|
public class Entry extends Block implements JSONConvert<JSONObject> {
|
||||||
private TableEntry<?, ?> mTableEntry;
|
private TableEntry<?, ?> mTableEntry;
|
||||||
|
|
||||||
public Entry(){
|
public Entry(){
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResValue getResValue(){
|
public ResValue getResValue(){
|
||||||
TableEntry<?, ?> tableEntry = getTableEntry();
|
TableEntry<?, ?> tableEntry = getTableEntry();
|
||||||
if(tableEntry instanceof ResTableEntry){
|
if(tableEntry instanceof ResTableEntry){
|
||||||
return ((ResTableEntry)tableEntry).getValue();
|
return ((ResTableEntry)tableEntry).getValue();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public ResValueMapArray getResValueMapArray(){
|
public ResValueMapArray getResValueMapArray(){
|
||||||
TableEntry<?, ?> tableEntry = getTableEntry();
|
TableEntry<?, ?> tableEntry = getTableEntry();
|
||||||
if(tableEntry instanceof ResTableMapEntry){
|
if(tableEntry instanceof ResTableMapEntry){
|
||||||
return ((ResTableMapEntry)tableEntry).getValue();
|
return ((ResTableMapEntry)tableEntry).getValue();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public SpecFlag getSpecFlag(){
|
public SpecFlag getSpecFlag(){
|
||||||
SpecBlock specBlock = getSpecBlock();
|
SpecBlock specBlock = getSpecBlock();
|
||||||
if(specBlock == null){
|
if(specBlock == null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return specBlock.getSpecFlag(getId());
|
return specBlock.getSpecFlag(getId());
|
||||||
}
|
}
|
||||||
public void ensureComplex(boolean isComplex){
|
public void ensureComplex(boolean isComplex){
|
||||||
ensureTableEntry(isComplex);
|
ensureTableEntry(isComplex);
|
||||||
}
|
}
|
||||||
public int getId(){
|
public int getId(){
|
||||||
return getIndex();
|
int id = getIndex();
|
||||||
}
|
EntryArray entryArray = getParentInstance(EntryArray.class);
|
||||||
public String getName(){
|
if(entryArray != null){
|
||||||
SpecString specString = getSpecString();
|
id = entryArray.getEntryId(id);
|
||||||
if(specString!=null){
|
}
|
||||||
return specString.get();
|
return id;
|
||||||
}
|
}
|
||||||
return null;
|
public String getName(){
|
||||||
}
|
SpecString specString = getSpecString();
|
||||||
public String getTypeName(){
|
if(specString!=null){
|
||||||
TypeBlock typeBlock = getTypeBlock();
|
return specString.get();
|
||||||
if(typeBlock!=null){
|
}
|
||||||
return typeBlock.getTypeName();
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
public String getTypeName(){
|
||||||
}
|
TypeBlock typeBlock = getTypeBlock();
|
||||||
public int getResourceId(){
|
if(typeBlock!=null){
|
||||||
PackageBlock packageBlock = getPackageBlock();
|
return typeBlock.getTypeName();
|
||||||
if(packageBlock==null){
|
}
|
||||||
return 0;
|
return null;
|
||||||
}
|
}
|
||||||
TypeBlock typeBlock = getTypeBlock();
|
public int getResourceId(){
|
||||||
if(typeBlock==null){
|
PackageBlock packageBlock = getPackageBlock();
|
||||||
return 0;
|
if(packageBlock==null){
|
||||||
}
|
return 0;
|
||||||
return (packageBlock.getId()<<24)
|
}
|
||||||
| (typeBlock.getId() << 16)
|
TypeBlock typeBlock = getTypeBlock();
|
||||||
| getId();
|
if(typeBlock==null){
|
||||||
}
|
return 0;
|
||||||
public int getSpecReference(){
|
}
|
||||||
TableEntry<?, ?> tableEntry = getTableEntry();
|
return (packageBlock.getId()<<24)
|
||||||
if(tableEntry == null){
|
| (typeBlock.getId() << 16)
|
||||||
return 0;
|
| getId();
|
||||||
}
|
}
|
||||||
return tableEntry.getHeader().getKey();
|
public int getSpecReference(){
|
||||||
}
|
TableEntry<?, ?> tableEntry = getTableEntry();
|
||||||
public TypeString getTypeString(){
|
if(tableEntry == null){
|
||||||
TypeBlock typeBlock = getTypeBlock();
|
return 0;
|
||||||
if(typeBlock!=null){
|
}
|
||||||
return typeBlock.getTypeString();
|
return tableEntry.getHeader().getKey();
|
||||||
}
|
}
|
||||||
return null;
|
public TypeString getTypeString(){
|
||||||
}
|
TypeBlock typeBlock = getTypeBlock();
|
||||||
public boolean isDefault(){
|
if(typeBlock!=null){
|
||||||
ResConfig resConfig = getResConfig();
|
return typeBlock.getTypeString();
|
||||||
if(resConfig!=null){
|
}
|
||||||
return resConfig.isDefault();
|
return null;
|
||||||
}
|
}
|
||||||
return false;
|
public boolean isDefault(){
|
||||||
}
|
ResConfig resConfig = getResConfig();
|
||||||
public void setSpecReference(StringItem specReference){
|
if(resConfig!=null){
|
||||||
TableEntry<?, ?> tableEntry = getTableEntry();
|
return resConfig.isDefault();
|
||||||
if(tableEntry == null){
|
}
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
tableEntry.getHeader().setKey(specReference);
|
public void setSpecReference(StringItem specReference){
|
||||||
}
|
TableEntry<?, ?> tableEntry = getTableEntry();
|
||||||
public void setSpecReference(int ref){
|
if(tableEntry == null){
|
||||||
TableEntry<?, ?> tableEntry = getTableEntry();
|
return;
|
||||||
if(tableEntry == null){
|
}
|
||||||
return;
|
tableEntry.getHeader().setKey(specReference);
|
||||||
}
|
}
|
||||||
tableEntry.getHeader().setKey(ref);
|
public void setSpecReference(int ref){
|
||||||
}
|
TableEntry<?, ?> tableEntry = getTableEntry();
|
||||||
private Entry searchEntry(int resourceId){
|
if(tableEntry == null){
|
||||||
if(resourceId==getResourceId()){
|
return;
|
||||||
return this;
|
}
|
||||||
}
|
tableEntry.getHeader().setKey(ref);
|
||||||
PackageBlock packageBlock= getPackageBlock();
|
}
|
||||||
if(packageBlock==null){
|
private Entry searchEntry(int resourceId){
|
||||||
return null;
|
if(resourceId==getResourceId()){
|
||||||
}
|
return this;
|
||||||
TableBlock tableBlock = packageBlock.getTableBlock();
|
}
|
||||||
if(tableBlock==null){
|
PackageBlock packageBlock= getPackageBlock();
|
||||||
return null;
|
if(packageBlock==null){
|
||||||
}
|
return null;
|
||||||
EntryGroup entryGroup = tableBlock.search(resourceId);
|
}
|
||||||
if(entryGroup!=null){
|
TableBlock tableBlock = packageBlock.getTableBlock();
|
||||||
return entryGroup.pickOne();
|
if(tableBlock==null){
|
||||||
}
|
return null;
|
||||||
return null;
|
}
|
||||||
}
|
EntryGroup entryGroup = tableBlock.search(resourceId);
|
||||||
public ResValue setValueAsRaw(ValueType valueType, int data){
|
if(entryGroup!=null){
|
||||||
TableEntry<?, ?> tableEntry = ensureTableEntry(false);
|
return entryGroup.pickOne();
|
||||||
ResValue resValue = (ResValue) tableEntry.getValue();
|
}
|
||||||
resValue.setTypeAndData(valueType, data);
|
return null;
|
||||||
return resValue;
|
}
|
||||||
}
|
public ResValue setValueAsRaw(ValueType valueType, int data){
|
||||||
public ResValue setValueAsBoolean(boolean val){
|
TableEntry<?, ?> tableEntry = ensureTableEntry(false);
|
||||||
int data = val?0xffffffff:0;
|
ResValue resValue = (ResValue) tableEntry.getValue();
|
||||||
return setValueAsRaw(ValueType.INT_BOOLEAN, data);
|
resValue.setTypeAndData(valueType, data);
|
||||||
}
|
return resValue;
|
||||||
public ResValue setValueAsReference(int resourceId){
|
}
|
||||||
return setValueAsRaw(ValueType.REFERENCE, resourceId);
|
public ResValue setValueAsBoolean(boolean val){
|
||||||
}
|
int data = val?0xffffffff:0;
|
||||||
public ResValue setValueAsString(String str){
|
return setValueAsRaw(ValueType.INT_BOOLEAN, data);
|
||||||
TableEntry<?, ?> tableEntry = ensureTableEntry(false);
|
}
|
||||||
ResValue resValue = (ResValue) tableEntry.getValue();
|
public ResValue setValueAsReference(int resourceId){
|
||||||
resValue.setValueAsString(str);
|
return setValueAsRaw(ValueType.REFERENCE, resourceId);
|
||||||
return resValue;
|
}
|
||||||
}
|
public ResValue setValueAsString(String str){
|
||||||
public SpecString getSpecString(){
|
TableEntry<?, ?> tableEntry = ensureTableEntry(false);
|
||||||
TableEntry<?, ?> tableEntry = getTableEntry();
|
ResValue resValue = (ResValue) tableEntry.getValue();
|
||||||
if(tableEntry == null){
|
resValue.setValueAsString(str);
|
||||||
return null;
|
return resValue;
|
||||||
}
|
}
|
||||||
PackageBlock packageBlock = getPackageBlock();
|
public SpecString getSpecString(){
|
||||||
if(packageBlock == null){
|
TableEntry<?, ?> tableEntry = getTableEntry();
|
||||||
return null;
|
if(tableEntry == null){
|
||||||
}
|
return null;
|
||||||
return packageBlock.getSpecStringPool()
|
}
|
||||||
.get(tableEntry.getHeader().getKey());
|
PackageBlock packageBlock = getPackageBlock();
|
||||||
}
|
if(packageBlock == null){
|
||||||
public ResConfig getResConfig(){
|
return null;
|
||||||
TypeBlock typeBlock = getTypeBlock();
|
}
|
||||||
if(typeBlock!=null){
|
return packageBlock.getSpecStringPool()
|
||||||
return typeBlock.getResConfig();
|
.get(tableEntry.getHeader().getKey());
|
||||||
}
|
}
|
||||||
return null;
|
public ResConfig getResConfig(){
|
||||||
}
|
TypeBlock typeBlock = getTypeBlock();
|
||||||
public SpecBlock getSpecBlock(){
|
if(typeBlock!=null){
|
||||||
TypeBlock typeBlock = getTypeBlock();
|
return typeBlock.getResConfig();
|
||||||
if(typeBlock == null){
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
SpecTypePair specTypePair = typeBlock.getParentSpecTypePair();
|
public SpecBlock getSpecBlock(){
|
||||||
if(specTypePair==null){
|
TypeBlock typeBlock = getTypeBlock();
|
||||||
return null;
|
if(typeBlock == null){
|
||||||
}
|
return null;
|
||||||
return specTypePair.getSpecBlock();
|
}
|
||||||
}
|
SpecTypePair specTypePair = typeBlock.getParentSpecTypePair();
|
||||||
public TypeBlock getTypeBlock(){
|
if(specTypePair==null){
|
||||||
return getParent(TypeBlock.class);
|
return null;
|
||||||
}
|
}
|
||||||
private String getPackageName(){
|
return specTypePair.getSpecBlock();
|
||||||
PackageBlock packageBlock = getPackageBlock();
|
}
|
||||||
if(packageBlock!=null){
|
public TypeBlock getTypeBlock(){
|
||||||
return packageBlock.getName();
|
return getParent(TypeBlock.class);
|
||||||
}
|
}
|
||||||
return null;
|
private String getPackageName(){
|
||||||
}
|
PackageBlock packageBlock = getPackageBlock();
|
||||||
public PackageBlock getPackageBlock(){
|
if(packageBlock!=null){
|
||||||
return getParent(PackageBlock.class);
|
return packageBlock.getName();
|
||||||
}
|
}
|
||||||
private TableEntry<?, ?> ensureTableEntry(boolean is_complex){
|
return null;
|
||||||
TableEntry<?, ?> tableEntry = getTableEntry();
|
}
|
||||||
|
public PackageBlock getPackageBlock(){
|
||||||
|
return getParent(PackageBlock.class);
|
||||||
|
}
|
||||||
|
private TableEntry<?, ?> ensureTableEntry(boolean is_complex){
|
||||||
|
TableEntry<?, ?> tableEntry = getTableEntry();
|
||||||
|
|
||||||
boolean is_correct_type = (is_complex && tableEntry instanceof ResTableMapEntry) || (!is_complex && tableEntry instanceof ResTableEntry);
|
boolean is_correct_type = (is_complex && tableEntry instanceof ResTableMapEntry) || (!is_complex && tableEntry instanceof ResTableEntry);
|
||||||
if (tableEntry == null || !is_correct_type) {
|
if (tableEntry == null || !is_correct_type) {
|
||||||
tableEntry = createTableEntry(is_complex);
|
tableEntry = createTableEntry(is_complex);
|
||||||
setTableEntry(tableEntry);
|
setTableEntry(tableEntry);
|
||||||
}
|
}
|
||||||
return tableEntry;
|
return tableEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TableEntry<?, ?> getTableEntry(){
|
public TableEntry<?, ?> getTableEntry(){
|
||||||
return mTableEntry;
|
return mTableEntry;
|
||||||
}
|
}
|
||||||
public ValueHeader getHeader(){
|
public ValueHeader getHeader(){
|
||||||
TableEntry<?, ?> tableEntry = getTableEntry();
|
TableEntry<?, ?> tableEntry = getTableEntry();
|
||||||
if(tableEntry!=null){
|
if(tableEntry!=null){
|
||||||
return tableEntry.getHeader();
|
return tableEntry.getHeader();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNull(){
|
public boolean isNull(){
|
||||||
return getTableEntry()==null;
|
return getTableEntry()==null;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void setNull(boolean is_null){
|
public void setNull(boolean is_null){
|
||||||
if(is_null){
|
if(is_null){
|
||||||
setTableEntry(null);
|
setTableEntry(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
if(isNull()){
|
if(isNull()){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getTableEntry().getBytes();
|
return getTableEntry().getBytes();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int countBytes() {
|
public int countBytes() {
|
||||||
if(isNull()){
|
if(isNull()){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return getTableEntry().countBytes();
|
return getTableEntry().countBytes();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onCountUpTo(BlockCounter counter) {
|
public void onCountUpTo(BlockCounter counter) {
|
||||||
if(counter.FOUND){
|
if(counter.FOUND){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(counter.END==this){
|
if(counter.END==this){
|
||||||
counter.FOUND=true;
|
counter.FOUND=true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(isNull()){
|
if(isNull()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
counter.addCount(getTableEntry().countBytes());
|
counter.addCount(getTableEntry().countBytes());
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected int onWriteBytes(OutputStream stream) throws IOException {
|
protected int onWriteBytes(OutputStream stream) throws IOException {
|
||||||
if(isNull()){
|
if(isNull()){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return getTableEntry().writeBytes(stream);
|
return getTableEntry().writeBytes(stream);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onReadBytes(BlockReader reader) throws IOException {
|
public void onReadBytes(BlockReader reader) throws IOException {
|
||||||
TableEntry<?, ?> tableEntry = createTableEntry(reader);
|
TableEntry<?, ?> tableEntry = createTableEntry(reader);
|
||||||
setTableEntry(tableEntry);
|
setTableEntry(tableEntry);
|
||||||
tableEntry.readBytes(reader);
|
tableEntry.readBytes(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isComplex(){
|
public boolean isComplex(){
|
||||||
return getTableEntry() instanceof ResTableMapEntry;
|
return getTableEntry() instanceof ResTableMapEntry;
|
||||||
}
|
}
|
||||||
public void setTableEntry(TableEntry<?, ?> tableEntry){
|
public void setTableEntry(TableEntry<?, ?> tableEntry){
|
||||||
if(tableEntry==this.mTableEntry){
|
if(tableEntry==this.mTableEntry){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onTableEntryRemoved();
|
onTableEntryRemoved();
|
||||||
if(tableEntry==null){
|
if(tableEntry==null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tableEntry.setIndex(0);
|
tableEntry.setIndex(0);
|
||||||
tableEntry.setParent(this);
|
tableEntry.setParent(this);
|
||||||
this.mTableEntry = tableEntry;
|
this.mTableEntry = tableEntry;
|
||||||
onTableEntryAdded();
|
onTableEntryAdded();
|
||||||
}
|
}
|
||||||
private void onTableEntryAdded(){
|
private void onTableEntryAdded(){
|
||||||
PackageBlock packageBlock = getPackageBlock();
|
PackageBlock packageBlock = getPackageBlock();
|
||||||
if(packageBlock!=null){
|
if(packageBlock!=null){
|
||||||
packageBlock.onEntryAdded(this);
|
packageBlock.onEntryAdded(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void onTableEntryRemoved(){
|
private void onTableEntryRemoved(){
|
||||||
TableEntry<?, ?> exist = this.mTableEntry;
|
TableEntry<?, ?> exist = this.mTableEntry;
|
||||||
if(exist == null){
|
if(exist == null){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PackageBlock packageBlock = getPackageBlock();
|
PackageBlock packageBlock = getPackageBlock();
|
||||||
if(packageBlock!=null){
|
if(packageBlock!=null){
|
||||||
packageBlock.removeEntryGroup(this);
|
packageBlock.removeEntryGroup(this);
|
||||||
}
|
}
|
||||||
exist.onRemoved();
|
exist.onRemoved();
|
||||||
exist.setIndex(-1);
|
exist.setIndex(-1);
|
||||||
exist.setParent(null);
|
exist.setParent(null);
|
||||||
this.mTableEntry = null;
|
this.mTableEntry = null;
|
||||||
}
|
}
|
||||||
private TableEntry<?, ?> createTableEntry(BlockReader reader) throws IOException {
|
private TableEntry<?, ?> createTableEntry(BlockReader reader) throws IOException {
|
||||||
int startPosition = reader.getPosition();
|
int startPosition = reader.getPosition();
|
||||||
reader.offset(2);
|
reader.offset(2);
|
||||||
boolean is_complex = (0x0001 & reader.readShort()) == 0x0001;
|
boolean is_complex = (0x0001 & reader.readShort()) == 0x0001;
|
||||||
reader.seek(startPosition);
|
reader.seek(startPosition);
|
||||||
return createTableEntry(is_complex);
|
return createTableEntry(is_complex);
|
||||||
}
|
}
|
||||||
private TableEntry<?, ?> createTableEntry(boolean is_complex) {
|
private TableEntry<?, ?> createTableEntry(boolean is_complex) {
|
||||||
if(is_complex){
|
if(is_complex){
|
||||||
return new ResTableMapEntry();
|
return new ResTableMapEntry();
|
||||||
}else {
|
}else {
|
||||||
return new ResTableEntry();
|
return new ResTableEntry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject toJson() {
|
public JSONObject toJson() {
|
||||||
if(isNull()){
|
if(isNull()){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getTableEntry().toJson();
|
return getTableEntry().toJson();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void fromJson(JSONObject json) {
|
public void fromJson(JSONObject json) {
|
||||||
if(json==null){
|
if(json==null){
|
||||||
setNull(true);
|
setNull(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean is_complex = json.optBoolean(ValueHeader.NAME_is_complex, false);
|
boolean is_complex = json.optBoolean(ValueHeader.NAME_is_complex, false);
|
||||||
TableEntry<?, ?> entry = createTableEntry(is_complex);
|
TableEntry<?, ?> entry = createTableEntry(is_complex);
|
||||||
setTableEntry(entry);
|
setTableEntry(entry);
|
||||||
entry.fromJson(json);
|
entry.fromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void merge(Entry entry){
|
public void merge(Entry entry){
|
||||||
if(!shouldMerge(entry)){
|
if(!shouldMerge(entry)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TableEntry<?, ?> tableEntry = entry.getTableEntry();
|
TableEntry<?, ?> tableEntry = entry.getTableEntry();
|
||||||
TableEntry<?, ?> existEntry = ensureTableEntry(tableEntry instanceof ResTableMapEntry);
|
TableEntry<?, ?> existEntry = ensureTableEntry(tableEntry instanceof ResTableMapEntry);
|
||||||
existEntry.merge(tableEntry);
|
existEntry.merge(tableEntry);
|
||||||
}
|
}
|
||||||
private boolean shouldMerge(Entry coming){
|
private boolean shouldMerge(Entry coming){
|
||||||
if(coming == null || coming == this || coming.isNull()){
|
if(coming == null || coming == this || coming.isNull()){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(this.isNull()){
|
if(this.isNull()){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return getTableEntry().shouldMerge(coming.getTableEntry());
|
return getTableEntry().shouldMerge(coming.getTableEntry());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String buildResourceName(int resourceId, char prefix, boolean includeType){
|
public String buildResourceName(int resourceId, char prefix, boolean includeType){
|
||||||
if(resourceId==0){
|
if(resourceId==0){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Entry entry=searchEntry(resourceId);
|
Entry entry=searchEntry(resourceId);
|
||||||
return buildResourceName(entry, prefix, includeType);
|
return buildResourceName(entry, prefix, includeType);
|
||||||
}
|
}
|
||||||
public String buildResourceName(Entry entry, char prefix, boolean includeType){
|
public String buildResourceName(Entry entry, char prefix, boolean includeType){
|
||||||
if(entry==null){
|
if(entry==null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String pkgName=entry.getPackageName();
|
String pkgName=entry.getPackageName();
|
||||||
if(getResourceId()==entry.getResourceId()){
|
if(getResourceId()==entry.getResourceId()){
|
||||||
pkgName=null;
|
pkgName=null;
|
||||||
}else if(pkgName!=null){
|
}else if(pkgName!=null){
|
||||||
if(pkgName.equals(this.getPackageName())){
|
if(pkgName.equals(this.getPackageName())){
|
||||||
pkgName=null;
|
pkgName=null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String type=null;
|
String type=null;
|
||||||
if(includeType){
|
if(includeType){
|
||||||
type=entry.getTypeName();
|
type=entry.getTypeName();
|
||||||
}
|
}
|
||||||
String name=entry.getName();
|
String name=entry.getName();
|
||||||
return buildResourceName(prefix, pkgName, type, name);
|
return buildResourceName(prefix, pkgName, type, name);
|
||||||
}
|
}
|
||||||
public String getResourceName(){
|
public String getResourceName(){
|
||||||
return buildResourceName('@',null, getTypeName(), getName());
|
return buildResourceName('@',null, getTypeName(), getName());
|
||||||
}
|
}
|
||||||
public String getResourceName(char prefix){
|
public String getResourceName(char prefix){
|
||||||
return getResourceName(prefix, false, true);
|
return getResourceName(prefix, false, true);
|
||||||
}
|
}
|
||||||
public String getResourceName(char prefix, boolean includePackage, boolean includeType){
|
public String getResourceName(char prefix, boolean includePackage, boolean includeType){
|
||||||
String pkg=includePackage?getPackageName():null;
|
String pkg=includePackage?getPackageName():null;
|
||||||
String type=includeType?getTypeName():null;
|
String type=includeType?getTypeName():null;
|
||||||
return buildResourceName(prefix,pkg, type, getName());
|
return buildResourceName(prefix,pkg, type, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append(String.format("0x%08x", getResourceId()));
|
builder.append(String.format("0x%08x", getResourceId()));
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
ResConfig resConfig = getResConfig();
|
ResConfig resConfig = getResConfig();
|
||||||
if(resConfig!=null){
|
if(resConfig!=null){
|
||||||
builder.append(resConfig);
|
builder.append(resConfig);
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
}
|
}
|
||||||
SpecFlag specFlag = getSpecFlag();
|
SpecFlag specFlag = getSpecFlag();
|
||||||
if(specFlag!=null){
|
if(specFlag!=null){
|
||||||
builder.append(specFlag);
|
builder.append(specFlag);
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
}
|
}
|
||||||
if(isNull()){
|
if(isNull()){
|
||||||
builder.append("NULL");
|
builder.append("NULL");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
builder.append('@');
|
builder.append('@');
|
||||||
builder.append(getTypeName());
|
builder.append(getTypeName());
|
||||||
builder.append('/');
|
builder.append('/');
|
||||||
builder.append(getName());
|
builder.append(getName());
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String buildResourceName(char prefix, String packageName, String type, String name){
|
public static String buildResourceName(char prefix, String packageName, String type, String name){
|
||||||
if(name==null){
|
if(name==null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
StringBuilder builder=new StringBuilder();
|
StringBuilder builder=new StringBuilder();
|
||||||
if(prefix!=0){
|
if(prefix!=0){
|
||||||
builder.append(prefix);
|
builder.append(prefix);
|
||||||
}
|
}
|
||||||
if(packageName!=null){
|
if(packageName!=null){
|
||||||
builder.append(packageName);
|
builder.append(packageName);
|
||||||
builder.append(':');
|
builder.append(':');
|
||||||
}
|
}
|
||||||
if(type!=null){
|
if(type!=null){
|
||||||
builder.append(type);
|
builder.append(type);
|
||||||
builder.append('/');
|
builder.append('/');
|
||||||
}
|
}
|
||||||
builder.append(name);
|
builder.append(name);
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String NAME_id = "id";
|
public static final String NAME_id = "id";
|
||||||
}
|
}
|
||||||
|
@ -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