merge and convert resource spec

This commit is contained in:
REAndroid 2023-03-03 08:01:01 -05:00
parent 21c9d4e6bb
commit dc911e861e
7 changed files with 110 additions and 15 deletions

View File

@ -89,12 +89,13 @@ public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<J
public JSONArray toJson() { public JSONArray toJson() {
JSONArray jsonArray=new JSONArray(); JSONArray jsonArray=new JSONArray();
int index=0; int index=0;
String name_id = Entry.NAME_id;
for(Entry entry :listItems()){ for(Entry entry :listItems()){
JSONObject childObject = entry.toJson(); JSONObject childObject = entry.toJson();
if(childObject==null){ if(childObject==null){
continue; continue;
} }
childObject.put(NAME_id, entry.getIndex()); childObject.put(name_id, entry.getId());
jsonArray.put(index, childObject); jsonArray.put(index, childObject);
index++; index++;
} }
@ -105,12 +106,13 @@ public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<J
clearChildes(); clearChildes();
int length=json.length(); int length=json.length();
ensureSize(length); ensureSize(length);
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.getJSONObject(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 =get(id);
entry.fromJson(jsonObject); entry.fromJson(jsonObject);
@ -128,10 +130,10 @@ public class EntryArray extends OffsetBlockArray<Entry> implements JSONConvert<J
Entry existingBlock = get(comingBlock.getIndex()); Entry existingBlock = get(comingBlock.getIndex());
existingBlock.merge(comingBlock); existingBlock.merge(comingBlock);
} }
refreshCountAndStart();
} }
@Override @Override
public String toString(){ public String toString(){
return getClass().getSimpleName()+": size="+childesCount(); return getClass().getSimpleName()+": size="+childesCount();
} }
private static final String NAME_id="id";
} }

View File

@ -16,6 +16,7 @@
package com.reandroid.arsc.array; package com.reandroid.arsc.array;
import com.reandroid.arsc.base.BlockArray; import com.reandroid.arsc.base.BlockArray;
import com.reandroid.arsc.chunk.SpecBlock;
import com.reandroid.arsc.chunk.TypeBlock; import com.reandroid.arsc.chunk.TypeBlock;
import com.reandroid.arsc.container.SpecTypePair; import com.reandroid.arsc.container.SpecTypePair;
import com.reandroid.arsc.value.Entry; import com.reandroid.arsc.value.Entry;
@ -232,10 +233,11 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
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);
SpecTypePair specTypePair=get(i); int id = jsonObject.getJSONObject(SpecBlock.NAME_spec)
.getInt(TypeBlock.NAME_id);
SpecTypePair specTypePair = getOrCreate((byte) id);
specTypePair.fromJson(jsonObject); specTypePair.fromJson(jsonObject);
} }
} }

View File

@ -73,6 +73,13 @@
protected void onChunkRefreshed() { protected void onChunkRefreshed() {
specFlagsArray.refresh(); specFlagsArray.refresh();
} }
public void merge(SpecBlock specBlock){
if(specBlock == null || specBlock==this){
return;
}
this.getSpecFlagsArray().merge(specBlock.getSpecFlagsArray());
}
@Override @Override
public String toString(){ public String toString(){
StringBuilder builder=new StringBuilder(); StringBuilder builder=new StringBuilder();
@ -89,11 +96,17 @@
public JSONObject toJson() { public JSONObject toJson() {
JSONObject jsonObject=new JSONObject(); JSONObject jsonObject=new JSONObject();
jsonObject.put(TypeBlock.NAME_id, getId()); jsonObject.put(TypeBlock.NAME_id, getId());
jsonObject.put(NAME_spec_flags, getSpecFlagsArray().toJson());
return jsonObject; return jsonObject;
} }
@Override @Override
public void fromJson(JSONObject json) { public void fromJson(JSONObject json) {
setId(json.getInt(TypeBlock.NAME_id)); setId(json.getInt(TypeBlock.NAME_id));
getSpecFlagsArray().fromJson(json.optJSONArray(NAME_spec_flags));
} }
public static final String NAME_spec = "spec";
public static final String NAME_spec_flags = "spec_flags";
public static final String NAME_flag = "flag";
} }

View File

@ -196,14 +196,14 @@ public class SpecTypePair extends BlockContainer<Block>
@Override @Override
public JSONObject toJson() { public JSONObject toJson() {
JSONObject jsonObject=new JSONObject(); JSONObject jsonObject=new JSONObject();
jsonObject.put("id", getSpecBlock().getId()); jsonObject.put(SpecBlock.NAME_spec, getSpecBlock().toJson());
jsonObject.put("types", getTypeBlockArray().toJson()); jsonObject.put(NAME_types, getTypeBlockArray().toJson());
return jsonObject; return jsonObject;
} }
@Override @Override
public void fromJson(JSONObject json) { public void fromJson(JSONObject json) {
getSpecBlock().setTypeId((byte) json.getInt("id")); getSpecBlock().fromJson(json.getJSONObject(SpecBlock.NAME_spec));
getTypeBlockArray().fromJson(json.getJSONArray("types")); getTypeBlockArray().fromJson(json.getJSONArray(NAME_types));
} }
public void merge(SpecTypePair typePair){ public void merge(SpecTypePair typePair){
if(typePair==null||typePair==this){ if(typePair==null||typePair==this){
@ -213,6 +213,7 @@ public class SpecTypePair extends BlockContainer<Block>
throw new IllegalArgumentException("Can not merge different id types: " throw new IllegalArgumentException("Can not merge different id types: "
+getTypeId()+"!="+typePair.getTypeId()); +getTypeId()+"!="+typePair.getTypeId());
} }
getSpecBlock().merge(typePair.getSpecBlock());
getTypeBlockArray().merge(typePair.getTypeBlockArray()); getTypeBlockArray().merge(typePair.getTypeBlockArray());
} }
@Override @Override
@ -234,4 +235,6 @@ public class SpecTypePair extends BlockContainer<Block>
builder.append(getTypeBlockArray().childesCount()); builder.append(getTypeBlockArray().childesCount());
return builder.toString(); return builder.toString();
} }
public static final String NAME_types = "types";
} }

View File

@ -124,4 +124,8 @@ public class IntegerArray extends BlockItem {
bts[i+1]= (byte) (value >>> 8 & 0xff); bts[i+1]= (byte) (value >>> 8 & 0xff);
bts[i]= (byte) (value & 0xff); bts[i]= (byte) (value & 0xff);
} }
@Override
public String toString(){
return "size="+size();
}
} }

View File

@ -16,12 +16,17 @@
package com.reandroid.arsc.item; package com.reandroid.arsc.item;
import com.reandroid.arsc.base.Block; import com.reandroid.arsc.base.Block;
import com.reandroid.arsc.chunk.SpecBlock;
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.value.Entry;
import com.reandroid.json.JSONArray;
import com.reandroid.json.JSONConvert;
import com.reandroid.json.JSONObject;
import java.io.IOException; import java.io.IOException;
public class SpecFlagsArray extends IntegerArray implements BlockLoad { public class SpecFlagsArray extends IntegerArray implements BlockLoad, JSONConvert<JSONArray> {
private final IntegerItem entryCount; private final IntegerItem entryCount;
public SpecFlagsArray(IntegerItem entryCount) { public SpecFlagsArray(IntegerItem entryCount) {
super(); super();
@ -30,11 +35,14 @@ public class SpecFlagsArray extends IntegerArray implements BlockLoad {
setBlockLoad(this); setBlockLoad(this);
} }
public void set(int entryId, int value){ public void set(int entryId, int value){
entryId = 0xffff & entryId; setFlag(entryId, value);
ensureArraySize(entryId);
super.put(entryId, value);
refresh(); refresh();
} }
private void setFlag(int id, int flag){
id = 0xffff & id;
ensureArraySize(id+1);
super.put(id, flag);
}
@Override @Override
public Integer get(int entryId){ public Integer get(int entryId){
entryId = 0xffff & entryId; entryId = 0xffff & entryId;
@ -49,4 +57,65 @@ public class SpecFlagsArray extends IntegerArray implements BlockLoad {
public void refresh(){ public void refresh(){
entryCount.set(size()); entryCount.set(size());
} }
public void merge(SpecFlagsArray specFlagsArray){
if(specFlagsArray == null || specFlagsArray==this){
return;
}
this.ensureArraySize(specFlagsArray.size());
int[] comingValues = specFlagsArray.toArray();
int[] existValues = this.toArray();
for(int i=0; i<comingValues.length; i++){
int valueComing = comingValues[i];
if(valueComing == 0){
continue;
}
int value = existValues[i] | valueComing;
put(i, value);
}
refresh();
}
@Override
public JSONArray toJson() {
JSONArray jsonArray = new JSONArray();
int[] flagValues = toArray();
for(int i=0; i<flagValues.length; i++){
int value = flagValues[i];
if(value==0){
continue;
}
JSONObject jsonObject = new JSONObject();
jsonObject.put(Entry.NAME_id, i);
jsonObject.put(SpecBlock.NAME_flag, value);
jsonArray.put(jsonObject);
}
if(jsonArray.length()==0){
return null;
}
return jsonArray;
}
@Override
public void fromJson(JSONArray json) {
if(json==null || json.length()==0){
setSize(0);
refresh();
return;
}
int length = json.length();
length = length-1;
// to minimise calling new array creation during ensureSize,
// start from last entry
flagFromJson(json.getJSONObject(length));
for(int i=0;i<length;i++){
flagFromJson(json.getJSONObject(i));
}
refresh();
}
private void flagFromJson(JSONObject jsonObject){
int id = jsonObject.getInt(Entry.NAME_id);
int flag = jsonObject.getInt(SpecBlock.NAME_flag);
setFlag(id, flag);
}
} }

View File

@ -424,4 +424,6 @@
builder.append(name); builder.append(name);
return builder.toString(); return builder.toString();
} }
public static final String NAME_id = "id";
} }