mirror of
https://github.com/revanced/Apktool.git
synced 2025-02-02 23:27:41 +01:00
Rewrited bags factoring mechanisms.
This commit is contained in:
parent
024b369a6e
commit
5c27cba88a
@ -19,20 +19,30 @@ package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import brut.util.Duo;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResArrayValue extends ResBagValue implements ResXmlSerializable {
|
||||
public ResArrayValue(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
super(parent, items);
|
||||
ResArrayValue(ResReferenceValue parent,
|
||||
Duo<Integer, ResScalarValue>[] items) {
|
||||
super(parent);
|
||||
|
||||
mItems = new ResScalarValue[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
mItems[i] = items[i].m2;
|
||||
}
|
||||
}
|
||||
|
||||
public ResArrayValue(ResReferenceValue parent, ResScalarValue[] items) {
|
||||
super(parent);
|
||||
mItems = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
String type = getType();
|
||||
@ -40,26 +50,29 @@ public class ResArrayValue extends ResBagValue implements ResXmlSerializable {
|
||||
|
||||
serializer.startTag(null, type);
|
||||
serializer.attribute(null, "name", res.getResSpec().getName());
|
||||
for (ResScalarValue item : mItems.values()) {
|
||||
for (int i = 0; i < mItems.length; i++) {
|
||||
serializer.startTag(null, "item");
|
||||
serializer.text(item.toResXmlFormat());
|
||||
serializer.text(mItems[i].toResXmlFormat());
|
||||
serializer.endTag(null, "item");
|
||||
}
|
||||
serializer.endTag(null, type);
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
if (mItems.size() == 0) {
|
||||
String type = mItems[0].getType();
|
||||
if (! "string".equals(type) && ! "integer".equals(type)) {
|
||||
return null;
|
||||
}
|
||||
Iterator<ResScalarValue> it = mItems.values().iterator();
|
||||
String type = it.next().getType();
|
||||
while (it.hasNext()) {
|
||||
String itemType = it.next().getType();
|
||||
if (! type.equals(itemType)) {
|
||||
for (int i = 1; i < mItems.length; i++) {
|
||||
if (! type.equals(mItems[i].getType())) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private final ResScalarValue[] mItems;
|
||||
|
||||
|
||||
public static final int BAG_KEY_ARRAY_START = 0x02000000;
|
||||
}
|
||||
|
@ -19,20 +19,21 @@ package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import brut.util.Duo;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResAttr extends ResBagValue implements ResXmlSerializable {
|
||||
private final int mType;
|
||||
|
||||
public ResAttr(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items, int type) {
|
||||
super(parent, items);
|
||||
ResAttr(ResReferenceValue parentVal, int type, Integer min, Integer max,
|
||||
Boolean l10n) {
|
||||
super(parentVal);
|
||||
mType = type;
|
||||
mMin = min;
|
||||
mMax = max;
|
||||
mL10n = l10n;
|
||||
}
|
||||
|
||||
public String convertToResXmlFormat(ResScalarValue value)
|
||||
@ -40,6 +41,7 @@ public class ResAttr extends ResBagValue implements ResXmlSerializable {
|
||||
return value.toResXmlFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
String type = getTypeAsString();
|
||||
@ -49,10 +51,66 @@ public class ResAttr extends ResBagValue implements ResXmlSerializable {
|
||||
if (type != null) {
|
||||
serializer.attribute(null, "format", type);
|
||||
}
|
||||
if (mMin != null) {
|
||||
serializer.attribute(null, "min", mMin.toString());
|
||||
}
|
||||
if (mMax != null) {
|
||||
serializer.attribute(null, "max", mMax.toString());
|
||||
}
|
||||
if (mL10n != null && mL10n) {
|
||||
serializer.attribute(null, "localization", "suggested");
|
||||
}
|
||||
serializeBody(serializer, res);
|
||||
serializer.endTag(null, "attr");
|
||||
}
|
||||
|
||||
|
||||
public static ResAttr factory(ResReferenceValue parent,
|
||||
Duo<Integer, ResScalarValue>[] items, ResValueFactory factory)
|
||||
throws AndrolibException {
|
||||
|
||||
int type = ((ResIntValue) items[0].m2).getValue();
|
||||
int scalarType = type & 0xffff;
|
||||
Integer min = null, max = null;
|
||||
Boolean l10n = null;
|
||||
int i;
|
||||
for (i = 1; i < items.length; i++) {
|
||||
switch (items[i].m1) {
|
||||
case BAG_KEY_ATTR_MIN:
|
||||
min = ((ResIntValue) items[i].m2).getValue();
|
||||
continue;
|
||||
case BAG_KEY_ATTR_MAX:
|
||||
max = ((ResIntValue) items[i].m2).getValue();
|
||||
continue;
|
||||
case BAG_KEY_ATTR_L10N:
|
||||
l10n = ((ResIntValue) items[i].m2).getValue() != 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == items.length) {
|
||||
return new ResAttr(parent, scalarType, min, max, l10n);
|
||||
}
|
||||
Duo<ResReferenceValue, ResIntValue>[] attrItems =
|
||||
new Duo[items.length - i];
|
||||
int j = 0;
|
||||
for (; i < items.length; i++) {
|
||||
attrItems[j++] = new Duo<ResReferenceValue, ResIntValue>(
|
||||
factory.newReference(items[i].m1), (ResIntValue) items[i].m2);
|
||||
}
|
||||
switch (type & 0xff0000) {
|
||||
case TYPE_ENUM:
|
||||
return new ResEnumAttr(
|
||||
parent, scalarType, min, max, l10n, attrItems);
|
||||
case TYPE_FLAGS:
|
||||
return new ResFlagsAttr(
|
||||
parent, scalarType, min, max, l10n, attrItems);
|
||||
}
|
||||
|
||||
throw new AndrolibException("Could not decode attr value");
|
||||
}
|
||||
|
||||
protected void serializeBody(XmlSerializer serializer, ResResource res)
|
||||
throws AndrolibException, IOException {}
|
||||
|
||||
@ -88,6 +146,17 @@ public class ResAttr extends ResBagValue implements ResXmlSerializable {
|
||||
return s.substring(1);
|
||||
}
|
||||
|
||||
private final int mType;
|
||||
private final Integer mMin;
|
||||
private final Integer mMax;
|
||||
private final Boolean mL10n;
|
||||
|
||||
|
||||
public static final int BAG_KEY_ATTR_TYPE = 0x01000000;
|
||||
private static final int BAG_KEY_ATTR_MIN = 0x01000001;
|
||||
private static final int BAG_KEY_ATTR_MAX = 0x01000002;
|
||||
private static final int BAG_KEY_ATTR_L10N = 0x01000003;
|
||||
|
||||
private final static int TYPE_REFERENCE = 0x01;
|
||||
private final static int TYPE_STRING = 0x02;
|
||||
private final static int TYPE_INT = 0x04;
|
||||
@ -97,4 +166,7 @@ public class ResAttr extends ResBagValue implements ResXmlSerializable {
|
||||
private final static int TYPE_DIMEN = 0x40;
|
||||
private final static int TYPE_FRACTION = 0x80;
|
||||
private final static int TYPE_ANY_STRING = 0xee;
|
||||
|
||||
private static final int TYPE_ENUM = 0x00010000;
|
||||
private static final int TYPE_FLAGS = 0x00020000;
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* 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.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResAttrFactory {
|
||||
static ResAttr factory(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
int type = ((ResIntValue) items.values().iterator().next()).getValue();
|
||||
|
||||
int attrType = type & 0x0000ffff;
|
||||
switch (type & 0x00ff0000) {
|
||||
case TYPE_ENUM:
|
||||
return new ResEnumAttr(parent, items, attrType);
|
||||
case TYPE_SET:
|
||||
return new ResSetAttr(parent, items, attrType);
|
||||
}
|
||||
return new ResAttr(parent, items, attrType);
|
||||
}
|
||||
|
||||
private final static int TYPE_ENUM = 0x00010000;
|
||||
private final static int TYPE_SET = 0x00020000;
|
||||
}
|
@ -17,26 +17,32 @@
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResBagValue extends ResValue {
|
||||
public class ResBagValue extends ResValue implements ResXmlSerializable {
|
||||
protected final ResReferenceValue mParent;
|
||||
protected final Map<ResReferenceValue, ResScalarValue> mItems;
|
||||
|
||||
public ResBagValue(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
public ResBagValue(ResReferenceValue parent) {
|
||||
this.mParent = parent;
|
||||
this.mItems = items;
|
||||
}
|
||||
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
serializer.startTag(null, "item");
|
||||
serializer.attribute(null, "type",
|
||||
res.getResSpec().getType().getName());
|
||||
serializer.attribute(null, "name", res.getResSpec().getName());
|
||||
serializer.endTag(null, "item");
|
||||
}
|
||||
|
||||
public ResReferenceValue getParent() {
|
||||
return mParent;
|
||||
}
|
||||
|
||||
public Map<ResReferenceValue, ResScalarValue> getItems() {
|
||||
return mItems;
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,10 @@ package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import brut.util.Duo;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
@ -27,17 +30,22 @@ import org.xmlpull.v1.XmlSerializer;
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResEnumAttr extends ResMapAttr {
|
||||
public ResEnumAttr(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items, int type) {
|
||||
super(parent, items, type);
|
||||
public class ResEnumAttr extends ResAttr {
|
||||
ResEnumAttr(ResReferenceValue parent, int type, Integer min, Integer max,
|
||||
Boolean l10n, Duo<ResReferenceValue, ResIntValue>[] items) {
|
||||
super(parent, type, min, max, l10n);
|
||||
|
||||
mItems = new LinkedHashMap<Integer, ResReferenceValue>();
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
mItems.put(items[i].m2.getValue(), items[i].m1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToResXmlFormat(ResScalarValue value)
|
||||
throws AndrolibException {
|
||||
if (value instanceof ResIntValue) {
|
||||
String ret = getItemsMap().get(((ResIntValue) value).getValue());
|
||||
String ret = decodeValue(((ResIntValue) value).getValue());
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
@ -48,11 +56,28 @@ public class ResEnumAttr extends ResMapAttr {
|
||||
@Override
|
||||
protected void serializeBody(XmlSerializer serializer, ResResource res)
|
||||
throws AndrolibException, IOException {
|
||||
for (Entry<Integer, String> entry : getItemsMap().entrySet()) {
|
||||
for (int intVal : mItems.keySet()) {
|
||||
serializer.startTag(null, "enum");
|
||||
serializer.attribute(null, "name", entry.getValue());
|
||||
serializer.attribute(null, "value", String.valueOf(entry.getKey()));
|
||||
serializer.attribute(null, "name", decodeValue(intVal));
|
||||
serializer.attribute(null, "value", String.valueOf(intVal));
|
||||
serializer.endTag(null, "enum");
|
||||
}
|
||||
}
|
||||
|
||||
private String decodeValue(int value) throws AndrolibException {
|
||||
String value2 = mItemsCache.get(value);
|
||||
if (value2 == null) {
|
||||
ResReferenceValue ref = mItems.get(value);
|
||||
if (ref != null) {
|
||||
value2 = ref.getReferent().getName();
|
||||
mItemsCache.put(value, value2);
|
||||
}
|
||||
}
|
||||
return value2;
|
||||
}
|
||||
|
||||
|
||||
private final Map<Integer, ResReferenceValue> mItems;
|
||||
private final Map<Integer, String> mItemsCache =
|
||||
new HashMap<Integer, String>();
|
||||
}
|
||||
|
@ -19,18 +19,21 @@ package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import brut.util.Duo;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResSetAttr extends ResMapAttr {
|
||||
public ResSetAttr(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items, int type) {
|
||||
super(parent, items, type);
|
||||
public class ResFlagsAttr extends ResAttr {
|
||||
ResFlagsAttr(ResReferenceValue parent, int type, Integer min, Integer max, Boolean l10n, Duo<ResReferenceValue, ResIntValue>[] items) {
|
||||
super(parent, type, min, max, l10n);
|
||||
|
||||
mItems = new FlagItem[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
mItems[i] = new FlagItem(items[i].m1, items[i].m2.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,14 +44,15 @@ public class ResSetAttr extends ResMapAttr {
|
||||
}
|
||||
int intVal = ((ResIntValue) value).getValue();
|
||||
String strVal = "";
|
||||
for (Entry<Integer, String> entry : getItemsMap().entrySet()) {
|
||||
int flag = entry.getKey();
|
||||
if ((intVal & flag) == flag) {
|
||||
strVal += "|" + entry.getValue();
|
||||
for (int i = 0; i < mItems.length; i++) {
|
||||
FlagItem item = mItems[i];
|
||||
|
||||
if ((intVal & item.flag) == item.flag) {
|
||||
strVal += "|" + item.getValue();
|
||||
}
|
||||
}
|
||||
if (strVal.isEmpty()) {
|
||||
return "";
|
||||
return strVal;
|
||||
}
|
||||
return strVal.substring(1);
|
||||
}
|
||||
@ -56,12 +60,36 @@ public class ResSetAttr extends ResMapAttr {
|
||||
@Override
|
||||
protected void serializeBody(XmlSerializer serializer, ResResource res)
|
||||
throws AndrolibException, IOException {
|
||||
for (Entry<Integer, String> entry : getItemsMap().entrySet()) {
|
||||
for (int i = 0; i < mItems.length; i++) {
|
||||
FlagItem item = mItems[i];
|
||||
|
||||
serializer.startTag(null, "flag");
|
||||
serializer.attribute(null, "name", entry.getValue());
|
||||
serializer.attribute(null, "name", item.getValue());
|
||||
serializer.attribute(null, "value",
|
||||
String.format("0x%08x", entry.getKey()));
|
||||
String.format("0x%08x", item.flag));
|
||||
serializer.endTag(null, "flag");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final FlagItem[] mItems;
|
||||
|
||||
|
||||
private static class FlagItem {
|
||||
public final ResReferenceValue ref;
|
||||
public final int flag;
|
||||
public String value;
|
||||
|
||||
public FlagItem(ResReferenceValue ref, int flag) {
|
||||
this.ref = ref;
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public String getValue() throws AndrolibException {
|
||||
if (value == null) {
|
||||
value = ref.getReferent().getName();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* 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.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public abstract class ResMapAttr extends ResAttr {
|
||||
private Map<Integer, String> mMap;
|
||||
|
||||
public ResMapAttr(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items, int type) {
|
||||
super(parent, items, type);
|
||||
}
|
||||
|
||||
protected Map<Integer, String> getItemsMap() throws AndrolibException {
|
||||
if (mMap == null) {
|
||||
loadItemsMap();
|
||||
}
|
||||
return mMap;
|
||||
}
|
||||
|
||||
private void loadItemsMap() throws AndrolibException {
|
||||
mMap = new LinkedHashMap<Integer, String>();
|
||||
Iterator<Entry<ResReferenceValue, ResScalarValue>> it =
|
||||
mItems.entrySet().iterator();
|
||||
it.next();
|
||||
|
||||
while (it.hasNext()) {
|
||||
Entry<ResReferenceValue, ResScalarValue> entry = it.next();
|
||||
// TODO
|
||||
if (entry.getKey().getValue() < 0x01010000) {
|
||||
continue;
|
||||
}
|
||||
mMap.put(
|
||||
((ResIntValue) entry.getValue()).getValue(),
|
||||
entry.getKey().getReferent().getName());
|
||||
}
|
||||
}
|
||||
}
|
@ -18,21 +18,29 @@
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.AndrolibResources;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import brut.util.Duo;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResPluralsValue extends ResBagValue implements ResXmlSerializable {
|
||||
public ResPluralsValue(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
super(parent, items);
|
||||
ResPluralsValue(ResReferenceValue parent,
|
||||
Duo<Integer, ResScalarValue>[] items) {
|
||||
super(parent);
|
||||
|
||||
mItems = new String[6];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
mItems[items[i].m1 - BAG_KEY_PLURALS_START] =
|
||||
((ResStringValue) items[i].m2).getValue();
|
||||
}
|
||||
}
|
||||
|
||||
public ResPluralsValue(ResReferenceValue parent, String[] items) {
|
||||
super(parent);
|
||||
mItems = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -40,37 +48,25 @@ public class ResPluralsValue extends ResBagValue implements ResXmlSerializable {
|
||||
throws IOException, AndrolibException {
|
||||
serializer.startTag(null, "plurals");
|
||||
serializer.attribute(null, "name", res.getResSpec().getName());
|
||||
for (Entry<String, String> entry : getPluralsMap().entrySet()) {
|
||||
for (int i = 0; i < mItems.length; i++) {
|
||||
String item = mItems[i];
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
serializer.startTag(null, "item");
|
||||
serializer.attribute(null, "quantity", entry.getKey());
|
||||
serializer.text(entry.getValue());
|
||||
serializer.attribute(null, "quantity", QUANTITY_MAP[i]);
|
||||
serializer.text(item);
|
||||
serializer.endTag(null, "item");
|
||||
}
|
||||
serializer.endTag(null, "plurals");
|
||||
}
|
||||
|
||||
private Map<String, String> getPluralsMap() {
|
||||
Map<String, String> plurals = new LinkedHashMap<String, String>();
|
||||
for (Entry<ResReferenceValue, ResScalarValue> entry
|
||||
: mItems.entrySet()) {
|
||||
String quantity = getQuantityMap()[
|
||||
(entry.getKey().getValue() & 0xffff) - 4];
|
||||
if (quantity != null) {
|
||||
String value = ((ResStringValue) entry.getValue()).getValue();
|
||||
plurals.put(quantity, AndrolibResources.escapeForResXml(value));
|
||||
|
||||
}
|
||||
}
|
||||
return plurals;
|
||||
}
|
||||
|
||||
private static String[] getQuantityMap() {
|
||||
if (quantityMap == null) {
|
||||
quantityMap = new String[]
|
||||
{"other", "zero", "one", "two", "few", "many"};
|
||||
}
|
||||
return quantityMap;
|
||||
}
|
||||
private final String[] mItems;
|
||||
|
||||
private static String[] quantityMap;
|
||||
|
||||
public static final int BAG_KEY_PLURALS_START = 0x01000004;
|
||||
public static final int BAG_KEY_PLURALS_END = 0x01000009;
|
||||
private static final String[] QUANTITY_MAP =
|
||||
new String[] {"other", "zero", "one", "two", "few", "many"};
|
||||
}
|
||||
|
@ -20,20 +20,26 @@ package brut.androlib.res.data.value;
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResSpec;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import brut.util.Duo;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResStyleValue extends ResBagValue implements ResXmlSerializable {
|
||||
public ResStyleValue(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
super(parent, items);
|
||||
ResStyleValue(ResReferenceValue parent,
|
||||
Duo<Integer, ResScalarValue>[] items, ResValueFactory factory) {
|
||||
super(parent);
|
||||
|
||||
mItems = new Duo[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
mItems[i] = new Duo<ResReferenceValue, ResScalarValue>(
|
||||
factory.newReference(items[i].m1), items[i].m2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
serializer.startTag(null, "style");
|
||||
@ -41,11 +47,10 @@ public class ResStyleValue extends ResBagValue implements ResXmlSerializable {
|
||||
if (! mParent.isNull()) {
|
||||
serializer.attribute(null, "parent", mParent.toResXmlFormat());
|
||||
}
|
||||
for (Entry<ResReferenceValue, ResScalarValue> entry
|
||||
: mItems.entrySet()) {
|
||||
ResResSpec spec = entry.getKey().getReferent();
|
||||
for (int i = 0; i < mItems.length; i++) {
|
||||
ResResSpec spec = mItems[i].m1.getReferent();
|
||||
ResAttr attr = (ResAttr) spec.getDefaultResource().getValue();
|
||||
String value = attr.convertToResXmlFormat(entry.getValue());
|
||||
String value = attr.convertToResXmlFormat(mItems[i].m2);
|
||||
|
||||
if (value == null) {
|
||||
continue;
|
||||
@ -59,4 +64,7 @@ public class ResStyleValue extends ResBagValue implements ResXmlSerializable {
|
||||
}
|
||||
serializer.endTag(null, "style");
|
||||
}
|
||||
|
||||
|
||||
private final Duo<ResReferenceValue, ResScalarValue>[] mItems;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ package brut.androlib.res.data.value;
|
||||
import android.util.TypedValue;
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResPackage;
|
||||
import brut.util.Duo;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -68,23 +69,25 @@ public class ResValueFactory {
|
||||
return new ResStringValue(value);
|
||||
}
|
||||
|
||||
public ResBagValue bagFactory(String type, int parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
public ResBagValue bagFactory(int parent,
|
||||
Duo<Integer, ResScalarValue>[] items) throws AndrolibException {
|
||||
ResReferenceValue parentVal = newReference(parent);
|
||||
|
||||
if ("array".equals(type)) {
|
||||
if (items.length == 0) {
|
||||
return new ResBagValue(parentVal);
|
||||
}
|
||||
int key = items[0].m1;
|
||||
if (key == ResAttr.BAG_KEY_ATTR_TYPE) {
|
||||
return ResAttr.factory(parentVal, items, this);
|
||||
}
|
||||
if (key == ResArrayValue.BAG_KEY_ARRAY_START) {
|
||||
return new ResArrayValue(parentVal, items);
|
||||
}
|
||||
if ("style".equals(type)) {
|
||||
return new ResStyleValue(parentVal, items);
|
||||
}
|
||||
if ("plurals".equals(type)) {
|
||||
if (key >= ResPluralsValue.BAG_KEY_PLURALS_START
|
||||
&& key <= ResPluralsValue.BAG_KEY_PLURALS_END) {
|
||||
return new ResPluralsValue(parentVal, items);
|
||||
}
|
||||
if ("attr".equals(type)) {
|
||||
return ResAttrFactory.factory(parentVal, items);
|
||||
}
|
||||
return new ResBagValue(parentVal, items);
|
||||
return new ResStyleValue(parentVal, items, this);
|
||||
}
|
||||
|
||||
public ResReferenceValue newReference(int resID) {
|
||||
|
@ -20,6 +20,7 @@ import android.util.TypedValue;
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.*;
|
||||
import brut.androlib.res.data.value.*;
|
||||
import brut.util.Duo;
|
||||
import brut.util.ExtDataInput;
|
||||
import com.mindprod.ledatastream.LEDataInputStream;
|
||||
import java.io.*;
|
||||
@ -160,15 +161,13 @@ public class ARSCDecoder {
|
||||
int count = mIn.readInt();
|
||||
|
||||
ResValueFactory factory = mPkg.getValueFactory();
|
||||
Map<ResReferenceValue, ResScalarValue> items =
|
||||
new LinkedHashMap<ResReferenceValue, ResScalarValue>();
|
||||
Duo<Integer, ResScalarValue>[] items = new Duo[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
items.put(
|
||||
factory.newReference(mIn.readInt()),
|
||||
(ResScalarValue) readValue());
|
||||
items[i] = new Duo<Integer, ResScalarValue>(
|
||||
mIn.readInt(), (ResScalarValue) readValue());
|
||||
}
|
||||
|
||||
return factory.bagFactory(mType.getName(), parent, items);
|
||||
return factory.bagFactory(parent, items);
|
||||
}
|
||||
|
||||
private ResValue readValue() throws IOException, AndrolibException {
|
||||
|
Loading…
x
Reference in New Issue
Block a user