From 3a5e7087a87f8da622e9aa1dc87c742f22f57c8c Mon Sep 17 00:00:00 2001 From: REAndroid Date: Tue, 9 May 2023 12:49:13 +0200 Subject: [PATCH] better complex entry structure --- .../com/reandroid/apk/FrameworkOptimizer.java | 4 +- .../apk/xmldecoder/BagDecoderAttr.java | 33 ++- .../apk/xmldecoder/BagDecoderPlural.java | 9 +- .../arsc/array/CompoundItemArray.java | 113 ++++++++ .../arsc/array/ResValueMapArray.java | 67 +---- .../reandroid/arsc/decoder/ValueDecoder.java | 6 +- .../reandroid/arsc/value/AttributeType.java | 80 ++++++ .../arsc/value/AttributeTypeFormat.java | 251 ++++++++++++++++++ .../reandroid/arsc/value/CompoundEntry.java | 114 ++++++++ .../java/com/reandroid/arsc/value/Entry.java | 2 +- .../arsc/value/ResTableMapEntry.java | 79 +----- .../com/reandroid/arsc/value/ResValueMap.java | 16 ++ 12 files changed, 613 insertions(+), 161 deletions(-) create mode 100644 src/main/java/com/reandroid/arsc/array/CompoundItemArray.java create mode 100644 src/main/java/com/reandroid/arsc/value/AttributeType.java create mode 100644 src/main/java/com/reandroid/arsc/value/AttributeTypeFormat.java create mode 100644 src/main/java/com/reandroid/arsc/value/CompoundEntry.java diff --git a/src/main/java/com/reandroid/apk/FrameworkOptimizer.java b/src/main/java/com/reandroid/apk/FrameworkOptimizer.java index 26719fd..a02f7cc 100644 --- a/src/main/java/com/reandroid/apk/FrameworkOptimizer.java +++ b/src/main/java/com/reandroid/apk/FrameworkOptimizer.java @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2022 github.com/REAndroid * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -258,7 +258,7 @@ import java.util.zip.ZipEntry; return false; } TableEntry tableEntry = entry.getTableEntry(); - if(tableEntry instanceof ResTableMapEntry){ + if(tableEntry instanceof CompoundEntry){ return false; } if(!(tableEntry instanceof ResTableEntry)){ diff --git a/src/main/java/com/reandroid/apk/xmldecoder/BagDecoderAttr.java b/src/main/java/com/reandroid/apk/xmldecoder/BagDecoderAttr.java index c143e46..1e402aa 100644 --- a/src/main/java/com/reandroid/apk/xmldecoder/BagDecoderAttr.java +++ b/src/main/java/com/reandroid/apk/xmldecoder/BagDecoderAttr.java @@ -16,10 +16,9 @@ package com.reandroid.apk.xmldecoder; import com.reandroid.apk.XmlHelper; +import com.reandroid.arsc.array.CompoundItemArray; import com.reandroid.arsc.util.HexUtil; -import com.reandroid.arsc.value.Entry; -import com.reandroid.arsc.value.ResTableMapEntry; -import com.reandroid.arsc.value.ValueType; +import com.reandroid.arsc.value.*; import com.reandroid.arsc.value.attribute.AttributeBag; import com.reandroid.arsc.value.attribute.AttributeBagItem; import com.reandroid.common.EntryStore; @@ -39,16 +38,18 @@ class BagDecoderAttr extends BagDecoder{ writer.startTag(tag); writer.attribute("name", entry.getName()); AttributeBag attributeBag = AttributeBag.create(mapEntry.getValue()); - writeParentAttributes(writer, attributeBag); + writeParentAttributes(writer, mapEntry.getValue()); + ResValueMap formatsMap = mapEntry.getByType(AttributeType.FORMATS); + + boolean is_flag = AttributeTypeFormat.FLAG.matches(formatsMap.getData()); - boolean is_flag = attributeBag.isFlag(); String childTag = is_flag ? "flag" : "enum"; AttributeBagItem[] bagItems = attributeBag.getBagItems(); EntryStore entryStore = getEntryStore(); - for(int i=0;i< bagItems.length;i++){ + for(int i = 0; i < bagItems.length; i++){ AttributeBagItem item = bagItems[i]; if(item.isType()){ continue; @@ -63,7 +64,7 @@ class BagDecoderAttr extends BagDecoder{ if(item.getBagItem().getValueType() == ValueType.INT_HEX){ value = HexUtil.toHex8(rawVal); }else { - value = String.valueOf(rawVal); + value = Integer.toString(rawVal); } writer.text(value); @@ -72,6 +73,24 @@ class BagDecoderAttr extends BagDecoder{ return writer.endTag(tag); } + private void writeParentAttributes(EntryWriter writer, CompoundItemArray itemArray) throws IOException { + String formats = AttributeTypeFormat.toString(itemArray.getFormats()); + if(formats!=null){ + writer.attribute(AttributeType.FORMATS.getName(), formats); + } + ResValueMap item = itemArray.getByType(AttributeType.MIN); + if(item != null){ + writer.attribute(AttributeType.MIN.getName(), Integer.toString(item.getData())); + } + item = itemArray.getByType(AttributeType.MAX); + if(item != null){ + writer.attribute(AttributeType.MAX.getName(), Integer.toString(item.getData())); + } + item = itemArray.getByType(AttributeType.L10N);; + if(item != null){ + writer.attribute(AttributeType.L10N.getName(), Integer.toString(item.getData())); + } + } private void writeParentAttributes(EntryWriter writer, AttributeBag attributeBag) throws IOException { String formats= attributeBag.decodeValueType(); if(formats!=null){ diff --git a/src/main/java/com/reandroid/apk/xmldecoder/BagDecoderPlural.java b/src/main/java/com/reandroid/apk/xmldecoder/BagDecoderPlural.java index 11ea1e1..2831589 100644 --- a/src/main/java/com/reandroid/apk/xmldecoder/BagDecoderPlural.java +++ b/src/main/java/com/reandroid/apk/xmldecoder/BagDecoderPlural.java @@ -17,11 +17,9 @@ package com.reandroid.apk.xmldecoder; import com.reandroid.apk.XmlHelper; import com.reandroid.arsc.chunk.PackageBlock; -import com.reandroid.arsc.decoder.ValueDecoder; import com.reandroid.arsc.value.*; import com.reandroid.arsc.value.plurals.PluralsQuantity; import com.reandroid.common.EntryStore; -import com.reandroid.xml.XMLElement; import java.io.IOException; @@ -46,12 +44,11 @@ class BagDecoderPlural extends BagDecoder{ writer.enableIndent(true); writer.startTag(childTag); - PluralsQuantity quantity = - PluralsQuantity.valueOf((short) (valueMap.getName() & 0xffff)); - if(quantity == null){ + AttributeType quantity = valueMap.getAttributeType(); + if(quantity == null || !quantity.isPlural()){ throw new IOException("Unknown plural quantity: " + valueMap); } - writer.attribute("quantity", quantity.toString()); + writer.attribute("quantity", quantity.getName()); writeText(writer, packageBlock, valueMap); diff --git a/src/main/java/com/reandroid/arsc/array/CompoundItemArray.java b/src/main/java/com/reandroid/arsc/array/CompoundItemArray.java new file mode 100644 index 0000000..c09fc20 --- /dev/null +++ b/src/main/java/com/reandroid/arsc/array/CompoundItemArray.java @@ -0,0 +1,113 @@ +/* + * 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.value.AttributeType; +import com.reandroid.arsc.value.AttributeTypeFormat; +import com.reandroid.arsc.value.ResValueMap; +import com.reandroid.json.JSONConvert; +import com.reandroid.json.JSONArray; + +public abstract class CompoundItemArray extends BlockArray implements JSONConvert { + public CompoundItemArray(){ + super(); + } + public AttributeTypeFormat[] getFormats(){ + ResValueMap formatsMap = getByType(AttributeType.FORMATS); + if(formatsMap != null){ + return AttributeTypeFormat.valuesOf(formatsMap.getData()); + } + return null; + } + public boolean containsType(AttributeType attributeType){ + for(T valueMap : getChildes()){ + if(attributeType == valueMap.getAttributeType()){ + return true; + } + } + return false; + } + public T getByType(AttributeType attributeType){ + if(attributeType == null){ + return null; + } + for(T valueMap : getChildes()){ + if(attributeType == valueMap.getAttributeType()){ + return valueMap; + } + } + return null; + } + public T getByName(int name){ + for(T resValueMap : getChildes()){ + if(resValueMap != null && name == resValueMap.getName()){ + return resValueMap; + } + } + return null; + } + @Override + protected void onRefreshed() { + } + public void onRemoved(){ + for(T resValueMap : getChildes()){ + resValueMap.onRemoved(); + } + } + @Override + public void clearChildes(){ + this.onRemoved(); + super.clearChildes(); + } + @Override + public JSONArray toJson() { + JSONArray jsonArray=new JSONArray(); + if(isNull()){ + return jsonArray; + } + T[] childes = getChildes(); + for(int i = 0; i < childes.length; i++){ + jsonArray.put(i, childes[i].toJson()); + } + return jsonArray; + } + @Override + public void fromJson(JSONArray json){ + clearChildes(); + if(json==null){ + return; + } + int count=json.length(); + ensureSize(count); + for(int i=0;i mapArray){ + if(mapArray == null || mapArray == this){ + return; + } + clearChildes(); + int count = mapArray.childesCount(); + ensureSize(count); + for(int i=0;i implements JSONConvert { +public class ResValueMapArray extends CompoundItemArray { public ResValueMapArray(){ super(); } - - public ResValueMap getByName(int name){ - for(ResValueMap resValueMap:listItems()){ - if(resValueMap != null &&name == resValueMap.getName()){ - return resValueMap; - } - } - return null; - } @Override public ResValueMap newInstance() { return new ResValueMap(); @@ -42,55 +30,4 @@ public class ResValueMapArray extends BlockArray implements JSONCon public ResValueMap[] newInstance(int len) { return new ResValueMap[len]; } - - @Override - protected void onRefreshed() { - } - public void onRemoved(){ - for(ResValueMap resValueMap:listItems()){ - resValueMap.onRemoved(); - } - } - @Override - public void clearChildes(){ - this.onRemoved(); - super.clearChildes(); - } - @Override - public JSONArray toJson() { - JSONArray jsonArray=new JSONArray(); - if(isNull()){ - return jsonArray; - } - ResValueMap[] childes = getChildes(); - for(int i=0;i tableEntry = entry.getTableEntry(); - if(tableEntry == null || (tableEntry instanceof ResTableMapEntry)){ + if(tableEntry == null || (tableEntry instanceof CompoundEntry)){ return null; } - ResValue resValue =(ResValue) tableEntry.getValue(); - int resourceId= resValue.getData(); + ResValue resValue = (ResValue) tableEntry.getValue(); + int resourceId = resValue.getData(); ValueType valueType= resValue.getValueType(); return buildReferenceValue(store, entry, valueType, resourceId); } diff --git a/src/main/java/com/reandroid/arsc/value/AttributeType.java b/src/main/java/com/reandroid/arsc/value/AttributeType.java new file mode 100644 index 0000000..6682ab8 --- /dev/null +++ b/src/main/java/com/reandroid/arsc/value/AttributeType.java @@ -0,0 +1,80 @@ +/* + * 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; + +public enum AttributeType { + + FORMATS(0x01000000), + MIN(0x01000001), + MAX(0x01000002), + L10N(0x01000003), + + OTHER(0x01000004), + ZERO(0x01000005), + ONE(0x01000006), + TWO(0x01000007), + FEW(0x01000008), + MANY(0x01000009); + + private final int id; + AttributeType(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public boolean isPlural(){ + int i = id & 0xffff; + return i>=4 && i<=9; + } + + public String getName(){ + return name().toLowerCase(); + } + @Override + public String toString(){ + return getName(); + } + + public static AttributeType valueOf(int value){ + for(AttributeType type:VALUES){ + if(type.getId() == value){ + return type; + } + } + return null; + } + + public static AttributeType fromName(String name){ + if(name == null){ + return null; + } + name = name.toUpperCase(); + if("FORMAT".equals(name)){ + return FORMATS; + } + for(AttributeType type:VALUES){ + if(name.equals(type.name())){ + return type; + } + } + return null; + } + + private static final AttributeType[] VALUES = values(); +} diff --git a/src/main/java/com/reandroid/arsc/value/AttributeTypeFormat.java b/src/main/java/com/reandroid/arsc/value/AttributeTypeFormat.java new file mode 100644 index 0000000..92e8ea4 --- /dev/null +++ b/src/main/java/com/reandroid/arsc/value/AttributeTypeFormat.java @@ -0,0 +1,251 @@ +/* + * 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; + +public enum AttributeTypeFormat { + + REFERENCE(1<<0, + new ValueType[]{ + ValueType.REFERENCE, + ValueType.ATTRIBUTE, + ValueType.DYNAMIC_REFERENCE, + ValueType.DYNAMIC_ATTRIBUTE, + ValueType.NULL, + }), + STRING(1<<1, new ValueType[]{ + ValueType.STRING + }), + INTEGER(1<<2, new ValueType[]{ + ValueType.INT_DEC, + ValueType.INT_HEX + }), + BOOL(1<<3, new ValueType[]{ + ValueType.INT_BOOLEAN + }), + COLOR(1<<4, new ValueType[]{ + ValueType.INT_COLOR_RGB4, + ValueType.INT_COLOR_ARGB4, + ValueType.INT_COLOR_RGB8, + ValueType.INT_COLOR_ARGB8 + }), + FLOAT(1<<5, new ValueType[]{ + ValueType.FLOAT + }), + DIMENSION(1<<6, new ValueType[]{ + ValueType.DIMENSION + }), + FRACTION(1<<7, new ValueType[]{ + ValueType.FRACTION + }), + ANY(0x0000FFFF, ValueType.values().clone()), + + ENUM(1<<16, new ValueType[]{ + ValueType.INT_DEC, + ValueType.INT_HEX + }), + FLAG(1<<17, new ValueType[]{ + ValueType.INT_HEX, + ValueType.INT_DEC + }); + + private final int mask; + private final ValueType[] valueTypes; + + AttributeTypeFormat(int mask, ValueType[] valueTypes) { + this.mask = mask; + this.valueTypes = valueTypes; + } + + public int getMask() { + return mask; + } + public boolean matches(int value){ + int mask = this.mask; + return (value & mask) == mask; + } + + public ValueType[] getValueTypes() { + return valueTypes.clone(); + } + public boolean contains(ValueType valueType){ + ValueType[] valueTypes = this.valueTypes; + for(int i = 0; i < valueTypes.length; i++){ + if(valueType == valueTypes[i]){ + return true; + } + } + return false; + } + public String getName(){ + return name().toLowerCase(); + } + @Override + public String toString(){ + StringBuilder builder = new StringBuilder(); + builder.append(getName()); + builder.append('{'); + ValueType[] valueTypes = this.valueTypes; + for(int i = 0; i < valueTypes.length; i++){ + if(i != 0){ + builder.append(','); + } + builder.append(valueTypes[i]); + } + builder.append('}'); + return builder.toString(); + } + + public static String toString(int typeValue){ + return toString(valuesOf(typeValue)); + } + public static String toString(AttributeTypeFormat[] typeValues){ + if(typeValues == null || typeValues.length == 0){ + return null; + } + StringBuilder builder = new StringBuilder(); + + boolean appendOnce = false; + int appendedTypes = 0; + for(AttributeTypeFormat typeValue : typeValues){ + if(typeValue == ENUM || typeValue == FLAG){ + continue; + } + if(typeValue == AttributeTypeFormat.ANY){ + return AttributeTypeFormat.ANY.getName(); + } + int mask = typeValue.getMask(); + if((appendedTypes & mask) == mask){ + continue; + } + if(appendOnce){ + builder.append('|'); + } + builder.append(typeValue.getName()); + appendOnce = true; + appendedTypes = appendedTypes | mask; + } + return builder.toString(); + } + public static int sum(AttributeTypeFormat[] typeValues){ + if(typeValues == null){ + return 0; + } + int result = 0; + for(AttributeTypeFormat typeValue:typeValues){ + if(typeValue==null){ + continue; + } + result |= typeValue.getMask(); + } + return result; + } + + public static AttributeTypeFormat[] valuesOf(int value){ + AttributeTypeFormat[] tmp = new AttributeTypeFormat[VALUES.length]; + int length = 0; + for(AttributeTypeFormat typeValue : VALUES){ + int mask = typeValue.getMask(); + if(mask == value){ + return new AttributeTypeFormat[]{typeValue}; + } + if(typeValue == ANY){ + continue; + } + if((value & mask) == mask){ + tmp[length] = typeValue; + length++; + } + } + if(length == 0){ + return null; + } + AttributeTypeFormat[] results = new AttributeTypeFormat[length]; + System.arraycopy(tmp, 0, results, 0, length); + return results; + } + public static AttributeTypeFormat[] valuesOf(String valuesString){ + if(valuesString == null){ + return null; + } + valuesString = valuesString.trim(); + String[] valueNames = valuesString.split("\\s*\\|\\s*"); + AttributeTypeFormat[] tmp = new AttributeTypeFormat[VALUES.length]; + int length = 0; + for(String name:valueNames){ + AttributeTypeFormat typeValue = fromName(name); + if(typeValue!=null){ + tmp[length] = typeValue; + length++; + } + } + if(length == 0){ + return null; + } + AttributeTypeFormat[] results = new AttributeTypeFormat[length]; + System.arraycopy(tmp, 0, results, 0, length); + return results; + } + public static AttributeTypeFormat valueOf(int mask){ + for(AttributeTypeFormat typeValue:VALUES){ + if(typeValue.getMask() == mask){ + return typeValue; + } + } + return null; + } + public static AttributeTypeFormat typeOf(int mask){ + for(AttributeTypeFormat typeValue:TYPES){ + if(typeValue.matches(mask)){ + return typeValue; + } + } + return null; + } + public static AttributeTypeFormat fromName(String name){ + if(name==null){ + return null; + } + name = name.trim().toUpperCase(); + for(AttributeTypeFormat typeValue:VALUES){ + if(name.equals(typeValue.name())){ + return typeValue; + } + } + for(AttributeTypeFormat typeValue:TYPES){ + if(name.equals(typeValue.name())){ + return typeValue; + } + } + return null; + } + + private static final AttributeTypeFormat[] VALUES = new AttributeTypeFormat[]{ + REFERENCE, + STRING, + INTEGER, + BOOL, + COLOR, + FLOAT, + DIMENSION, + FRACTION, + ANY + }; + + private static final AttributeTypeFormat[] TYPES = new AttributeTypeFormat[]{ + ENUM, + FLAG + }; +} diff --git a/src/main/java/com/reandroid/arsc/value/CompoundEntry.java b/src/main/java/com/reandroid/arsc/value/CompoundEntry.java new file mode 100644 index 0000000..0b08781 --- /dev/null +++ b/src/main/java/com/reandroid/arsc/value/CompoundEntry.java @@ -0,0 +1,114 @@ +/* + * 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.array.CompoundItemArray; +import com.reandroid.arsc.pool.TableStringPool; +import com.reandroid.json.JSONObject; + +public abstract class CompoundEntry> extends TableEntry { + public CompoundEntry(ARRAY mapArray){ + super(new EntryHeaderMap(), mapArray); + } + // Valid for type attr + public AttributeTypeFormat[] getAttributeTypeFormats(){ + ITEM item = getByType(AttributeType.FORMATS); + if(item != null){ + return item.getAttributeTypeFormats(); + } + return null; + } + public boolean containsType(AttributeType attributeType){ + return getValue().containsType(attributeType); + } + public ITEM getByType(AttributeType attributeType){ + return getValue().getByType(attributeType); + } + public void refresh(){ + getHeader().setValuesCount(getValue().childesCount()); + } + public ITEM[] listResValueMap(){ + return getValue().getChildes(); + } + public int getParentId(){ + return getHeader().getParentId(); + } + public void setParentId(int parentId){ + getHeader().setParentId(parentId); + } + public int getValuesCount(){ + return getHeader().getValuesCount(); + } + public void setValuesCount(int valuesCount){ + getHeader().setValuesCount(valuesCount); + getValue().setChildesCount(valuesCount); + } + @Override + void linkTableStringsInternal(TableStringPool tableStringPool){ + for(ITEM item : listResValueMap()){ + item.linkTableStrings(tableStringPool); + } + } + @Override + void onHeaderLoaded(ValueHeader valueHeader){ + getValue().setChildesCount(getValuesCount()); + } + + @Override + void onRemoved(){ + getHeader().onRemoved(); + getValue().onRemoved(); + } + + @Override + public JSONObject toJson() { + JSONObject jsonObject = new JSONObject(); + getHeader().toJson(jsonObject); + jsonObject.put(NAME_values, getValue().toJson()); + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + getHeader().fromJson(json); + getValue().fromJson(json.optJSONArray(NAME_values)); + refresh(); + } + + @Override + public String toString(){ + StringBuilder builder = new StringBuilder(); + builder.append(getHeader()); + ITEM[] valueMaps = listResValueMap(); + int len = valueMaps.length; + int max = len; + if(max>4){ + max = 4; + } + for(int i=0;i0){ + if(max!=len){ + builder.append("\n ..."); + } + builder.append("\n "); + } + return builder.toString(); + } + + public static final String NAME_values = "values"; +} diff --git a/src/main/java/com/reandroid/arsc/value/Entry.java b/src/main/java/com/reandroid/arsc/value/Entry.java index 9ed77b5..5696e31 100755 --- a/src/main/java/com/reandroid/arsc/value/Entry.java +++ b/src/main/java/com/reandroid/arsc/value/Entry.java @@ -302,7 +302,7 @@ public class Entry extends Block implements JSONConvert { } public boolean isComplex(){ - return getTableEntry() instanceof ResTableMapEntry; + return getTableEntry() instanceof CompoundEntry; } public void setTableEntry(TableEntry tableEntry){ if(tableEntry==this.mTableEntry){ diff --git a/src/main/java/com/reandroid/arsc/value/ResTableMapEntry.java b/src/main/java/com/reandroid/arsc/value/ResTableMapEntry.java index 5c63e46..ef3969a 100644 --- a/src/main/java/com/reandroid/arsc/value/ResTableMapEntry.java +++ b/src/main/java/com/reandroid/arsc/value/ResTableMapEntry.java @@ -16,47 +16,10 @@ package com.reandroid.arsc.value; import com.reandroid.arsc.array.ResValueMapArray; -import com.reandroid.arsc.pool.TableStringPool; -import com.reandroid.json.JSONObject; -public class ResTableMapEntry extends TableEntry { +public class ResTableMapEntry extends CompoundEntry { public ResTableMapEntry(){ - super(new EntryHeaderMap(), new ResValueMapArray()); - } - public void refresh(){ - getHeader().setValuesCount(getValue().childesCount()); - } - public ResValueMap[] listResValueMap(){ - return getValue().getChildes(); - } - public int getParentId(){ - return getHeader().getParentId(); - } - public void setParentId(int parentId){ - getHeader().setParentId(parentId); - } - public int getValuesCount(){ - return getHeader().getValuesCount(); - } - public void setValuesCount(int valuesCount){ - getHeader().setValuesCount(valuesCount); - getValue().setChildesCount(valuesCount); - } - @Override - void linkTableStringsInternal(TableStringPool tableStringPool){ - for(ResValueMap resValueMap : listResValueMap()){ - resValueMap.linkTableStrings(tableStringPool); - } - } - @Override - void onHeaderLoaded(ValueHeader valueHeader){ - getValue().setChildesCount(getValuesCount()); - } - - @Override - void onRemoved(){ - getHeader().onRemoved(); - getValue().onRemoved(); + super(new ResValueMapArray()); } @Override boolean shouldMerge(TableEntry tableEntry){ @@ -80,42 +43,4 @@ public class ResTableMapEntry extends TableEntry4){ - max = 4; - } - for(int i=0;i0){ - if(max!=len){ - builder.append("\n ..."); - } - builder.append("\n "); - } - return builder.toString(); - } - - public static final String NAME_values = "values"; } diff --git a/src/main/java/com/reandroid/arsc/value/ResValueMap.java b/src/main/java/com/reandroid/arsc/value/ResValueMap.java index a60400e..9fd6ee3 100755 --- a/src/main/java/com/reandroid/arsc/value/ResValueMap.java +++ b/src/main/java/com/reandroid/arsc/value/ResValueMap.java @@ -26,6 +26,22 @@ public class ResValueMap extends ValueItem implements AttributeValue{ super(12, OFFSET_SIZE); } + public AttributeType getAttributeType(){ + return AttributeType.valueOf(getNameResourceID()); + } + public void setAttributeType(AttributeType attributeType){ + setNameResourceID(attributeType.getId()); + } + public AttributeTypeFormat[] getAttributeTypeFormats(){ + AttributeType attributeType = getAttributeType(); + if(attributeType != AttributeType.FORMATS){ + return null; + } + return AttributeTypeFormat.valuesOf(getData()); + } + public void setAttributeTypeFormats(AttributeTypeFormat[] formats){ + setData(AttributeTypeFormat.sum(formats)); + } public Entry getEntry(){ return getParent(Entry.class); }