Rewrited bags factoring mechanisms.

This commit is contained in:
Ryszard Wiśniewski 2010-04-02 13:46:26 +02:00
parent 024b369a6e
commit 5c27cba88a
11 changed files with 258 additions and 211 deletions

View File

@ -19,20 +19,30 @@ package brut.androlib.res.data.value;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.res.data.ResResource; import brut.androlib.res.data.ResResource;
import brut.util.Duo;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
/** /**
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public class ResArrayValue extends ResBagValue implements ResXmlSerializable { public class ResArrayValue extends ResBagValue implements ResXmlSerializable {
public ResArrayValue(ResReferenceValue parent, ResArrayValue(ResReferenceValue parent,
Map<ResReferenceValue, ResScalarValue> items) { Duo<Integer, ResScalarValue>[] items) {
super(parent, 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) public void serializeToXml(XmlSerializer serializer, ResResource res)
throws IOException, AndrolibException { throws IOException, AndrolibException {
String type = getType(); String type = getType();
@ -40,26 +50,29 @@ public class ResArrayValue extends ResBagValue implements ResXmlSerializable {
serializer.startTag(null, type); serializer.startTag(null, type);
serializer.attribute(null, "name", res.getResSpec().getName()); 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.startTag(null, "item");
serializer.text(item.toResXmlFormat()); serializer.text(mItems[i].toResXmlFormat());
serializer.endTag(null, "item"); serializer.endTag(null, "item");
} }
serializer.endTag(null, type); serializer.endTag(null, type);
} }
public String getType() { public String getType() {
if (mItems.size() == 0) { String type = mItems[0].getType();
if (! "string".equals(type) && ! "integer".equals(type)) {
return null; return null;
} }
Iterator<ResScalarValue> it = mItems.values().iterator(); for (int i = 1; i < mItems.length; i++) {
String type = it.next().getType(); if (! type.equals(mItems[i].getType())) {
while (it.hasNext()) {
String itemType = it.next().getType();
if (! type.equals(itemType)) {
return null; return null;
} }
} }
return type; return type;
} }
private final ResScalarValue[] mItems;
public static final int BAG_KEY_ARRAY_START = 0x02000000;
} }

View File

@ -19,20 +19,21 @@ package brut.androlib.res.data.value;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.res.data.ResResource; import brut.androlib.res.data.ResResource;
import brut.util.Duo;
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
/** /**
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public class ResAttr extends ResBagValue implements ResXmlSerializable { public class ResAttr extends ResBagValue implements ResXmlSerializable {
private final int mType; ResAttr(ResReferenceValue parentVal, int type, Integer min, Integer max,
Boolean l10n) {
public ResAttr(ResReferenceValue parent, super(parentVal);
Map<ResReferenceValue, ResScalarValue> items, int type) {
super(parent, items);
mType = type; mType = type;
mMin = min;
mMax = max;
mL10n = l10n;
} }
public String convertToResXmlFormat(ResScalarValue value) public String convertToResXmlFormat(ResScalarValue value)
@ -40,6 +41,7 @@ public class ResAttr extends ResBagValue implements ResXmlSerializable {
return value.toResXmlFormat(); return value.toResXmlFormat();
} }
@Override
public void serializeToXml(XmlSerializer serializer, ResResource res) public void serializeToXml(XmlSerializer serializer, ResResource res)
throws IOException, AndrolibException { throws IOException, AndrolibException {
String type = getTypeAsString(); String type = getTypeAsString();
@ -49,10 +51,66 @@ public class ResAttr extends ResBagValue implements ResXmlSerializable {
if (type != null) { if (type != null) {
serializer.attribute(null, "format", type); 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); serializeBody(serializer, res);
serializer.endTag(null, "attr"); 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) protected void serializeBody(XmlSerializer serializer, ResResource res)
throws AndrolibException, IOException {} throws AndrolibException, IOException {}
@ -88,6 +146,17 @@ public class ResAttr extends ResBagValue implements ResXmlSerializable {
return s.substring(1); 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_REFERENCE = 0x01;
private final static int TYPE_STRING = 0x02; private final static int TYPE_STRING = 0x02;
private final static int TYPE_INT = 0x04; 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_DIMEN = 0x40;
private final static int TYPE_FRACTION = 0x80; private final static int TYPE_FRACTION = 0x80;
private final static int TYPE_ANY_STRING = 0xee; private final static int TYPE_ANY_STRING = 0xee;
private static final int TYPE_ENUM = 0x00010000;
private static final int TYPE_FLAGS = 0x00020000;
} }

View File

@ -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;
}

View File

@ -17,26 +17,32 @@
package brut.androlib.res.data.value; 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 java.util.Map;
import org.xmlpull.v1.XmlSerializer;
/** /**
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @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 ResReferenceValue mParent;
protected final Map<ResReferenceValue, ResScalarValue> mItems;
public ResBagValue(ResReferenceValue parent, public ResBagValue(ResReferenceValue parent) {
Map<ResReferenceValue, ResScalarValue> items) {
this.mParent = 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() { public ResReferenceValue getParent() {
return mParent; return mParent;
} }
public Map<ResReferenceValue, ResScalarValue> getItems() {
return mItems;
}
} }

View File

@ -19,7 +19,10 @@ package brut.androlib.res.data.value;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.res.data.ResResource; import brut.androlib.res.data.ResResource;
import brut.util.Duo;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
@ -27,17 +30,22 @@ import org.xmlpull.v1.XmlSerializer;
/** /**
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public class ResEnumAttr extends ResMapAttr { public class ResEnumAttr extends ResAttr {
public ResEnumAttr(ResReferenceValue parent, ResEnumAttr(ResReferenceValue parent, int type, Integer min, Integer max,
Map<ResReferenceValue, ResScalarValue> items, int type) { Boolean l10n, Duo<ResReferenceValue, ResIntValue>[] items) {
super(parent, items, type); 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 @Override
public String convertToResXmlFormat(ResScalarValue value) public String convertToResXmlFormat(ResScalarValue value)
throws AndrolibException { throws AndrolibException {
if (value instanceof ResIntValue) { if (value instanceof ResIntValue) {
String ret = getItemsMap().get(((ResIntValue) value).getValue()); String ret = decodeValue(((ResIntValue) value).getValue());
if (ret != null) { if (ret != null) {
return ret; return ret;
} }
@ -48,11 +56,28 @@ public class ResEnumAttr extends ResMapAttr {
@Override @Override
protected void serializeBody(XmlSerializer serializer, ResResource res) protected void serializeBody(XmlSerializer serializer, ResResource res)
throws AndrolibException, IOException { throws AndrolibException, IOException {
for (Entry<Integer, String> entry : getItemsMap().entrySet()) { for (int intVal : mItems.keySet()) {
serializer.startTag(null, "enum"); serializer.startTag(null, "enum");
serializer.attribute(null, "name", entry.getValue()); serializer.attribute(null, "name", decodeValue(intVal));
serializer.attribute(null, "value", String.valueOf(entry.getKey())); serializer.attribute(null, "value", String.valueOf(intVal));
serializer.endTag(null, "enum"); 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>();
} }

View File

@ -19,18 +19,21 @@ package brut.androlib.res.data.value;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.res.data.ResResource; import brut.androlib.res.data.ResResource;
import brut.util.Duo;
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
/** /**
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public class ResSetAttr extends ResMapAttr { public class ResFlagsAttr extends ResAttr {
public ResSetAttr(ResReferenceValue parent, ResFlagsAttr(ResReferenceValue parent, int type, Integer min, Integer max, Boolean l10n, Duo<ResReferenceValue, ResIntValue>[] items) {
Map<ResReferenceValue, ResScalarValue> items, int type) { super(parent, type, min, max, l10n);
super(parent, items, type);
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 @Override
@ -41,14 +44,15 @@ public class ResSetAttr extends ResMapAttr {
} }
int intVal = ((ResIntValue) value).getValue(); int intVal = ((ResIntValue) value).getValue();
String strVal = ""; String strVal = "";
for (Entry<Integer, String> entry : getItemsMap().entrySet()) { for (int i = 0; i < mItems.length; i++) {
int flag = entry.getKey(); FlagItem item = mItems[i];
if ((intVal & flag) == flag) {
strVal += "|" + entry.getValue(); if ((intVal & item.flag) == item.flag) {
strVal += "|" + item.getValue();
} }
} }
if (strVal.isEmpty()) { if (strVal.isEmpty()) {
return ""; return strVal;
} }
return strVal.substring(1); return strVal.substring(1);
} }
@ -56,12 +60,36 @@ public class ResSetAttr extends ResMapAttr {
@Override @Override
protected void serializeBody(XmlSerializer serializer, ResResource res) protected void serializeBody(XmlSerializer serializer, ResResource res)
throws AndrolibException, IOException { 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.startTag(null, "flag");
serializer.attribute(null, "name", entry.getValue()); serializer.attribute(null, "name", item.getValue());
serializer.attribute(null, "value", serializer.attribute(null, "value",
String.format("0x%08x", entry.getKey())); String.format("0x%08x", item.flag));
serializer.endTag(null, "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;
}
}
} }

View File

@ -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());
}
}
}

View File

@ -18,21 +18,29 @@
package brut.androlib.res.data.value; package brut.androlib.res.data.value;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.res.AndrolibResources;
import brut.androlib.res.data.ResResource; import brut.androlib.res.data.ResResource;
import brut.util.Duo;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
/** /**
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public class ResPluralsValue extends ResBagValue implements ResXmlSerializable { public class ResPluralsValue extends ResBagValue implements ResXmlSerializable {
public ResPluralsValue(ResReferenceValue parent, ResPluralsValue(ResReferenceValue parent,
Map<ResReferenceValue, ResScalarValue> items) { Duo<Integer, ResScalarValue>[] items) {
super(parent, 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 @Override
@ -40,37 +48,25 @@ public class ResPluralsValue extends ResBagValue implements ResXmlSerializable {
throws IOException, AndrolibException { throws IOException, AndrolibException {
serializer.startTag(null, "plurals"); serializer.startTag(null, "plurals");
serializer.attribute(null, "name", res.getResSpec().getName()); 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.startTag(null, "item");
serializer.attribute(null, "quantity", entry.getKey()); serializer.attribute(null, "quantity", QUANTITY_MAP[i]);
serializer.text(entry.getValue()); serializer.text(item);
serializer.endTag(null, "item"); serializer.endTag(null, "item");
} }
serializer.endTag(null, "plurals"); 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));
} private final String[] mItems;
}
return plurals;
}
private static String[] getQuantityMap() {
if (quantityMap == null) {
quantityMap = new String[]
{"other", "zero", "one", "two", "few", "many"};
}
return quantityMap;
}
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"};
} }

View File

@ -20,20 +20,26 @@ package brut.androlib.res.data.value;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.res.data.ResResSpec; import brut.androlib.res.data.ResResSpec;
import brut.androlib.res.data.ResResource; import brut.androlib.res.data.ResResource;
import brut.util.Duo;
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
/** /**
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public class ResStyleValue extends ResBagValue implements ResXmlSerializable { public class ResStyleValue extends ResBagValue implements ResXmlSerializable {
public ResStyleValue(ResReferenceValue parent, ResStyleValue(ResReferenceValue parent,
Map<ResReferenceValue, ResScalarValue> items) { Duo<Integer, ResScalarValue>[] items, ResValueFactory factory) {
super(parent, items); 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) public void serializeToXml(XmlSerializer serializer, ResResource res)
throws IOException, AndrolibException { throws IOException, AndrolibException {
serializer.startTag(null, "style"); serializer.startTag(null, "style");
@ -41,11 +47,10 @@ public class ResStyleValue extends ResBagValue implements ResXmlSerializable {
if (! mParent.isNull()) { if (! mParent.isNull()) {
serializer.attribute(null, "parent", mParent.toResXmlFormat()); serializer.attribute(null, "parent", mParent.toResXmlFormat());
} }
for (Entry<ResReferenceValue, ResScalarValue> entry for (int i = 0; i < mItems.length; i++) {
: mItems.entrySet()) { ResResSpec spec = mItems[i].m1.getReferent();
ResResSpec spec = entry.getKey().getReferent();
ResAttr attr = (ResAttr) spec.getDefaultResource().getValue(); ResAttr attr = (ResAttr) spec.getDefaultResource().getValue();
String value = attr.convertToResXmlFormat(entry.getValue()); String value = attr.convertToResXmlFormat(mItems[i].m2);
if (value == null) { if (value == null) {
continue; continue;
@ -59,4 +64,7 @@ public class ResStyleValue extends ResBagValue implements ResXmlSerializable {
} }
serializer.endTag(null, "style"); serializer.endTag(null, "style");
} }
private final Duo<ResReferenceValue, ResScalarValue>[] mItems;
} }

View File

@ -20,6 +20,7 @@ package brut.androlib.res.data.value;
import android.util.TypedValue; import android.util.TypedValue;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.res.data.ResPackage; import brut.androlib.res.data.ResPackage;
import brut.util.Duo;
import java.util.Map; import java.util.Map;
/** /**
@ -68,23 +69,25 @@ public class ResValueFactory {
return new ResStringValue(value); return new ResStringValue(value);
} }
public ResBagValue bagFactory(String type, int parent, public ResBagValue bagFactory(int parent,
Map<ResReferenceValue, ResScalarValue> items) { Duo<Integer, ResScalarValue>[] items) throws AndrolibException {
ResReferenceValue parentVal = newReference(parent); 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); return new ResArrayValue(parentVal, items);
} }
if ("style".equals(type)) { if (key >= ResPluralsValue.BAG_KEY_PLURALS_START
return new ResStyleValue(parentVal, items); && key <= ResPluralsValue.BAG_KEY_PLURALS_END) {
}
if ("plurals".equals(type)) {
return new ResPluralsValue(parentVal, items); return new ResPluralsValue(parentVal, items);
} }
if ("attr".equals(type)) { return new ResStyleValue(parentVal, items, this);
return ResAttrFactory.factory(parentVal, items);
}
return new ResBagValue(parentVal, items);
} }
public ResReferenceValue newReference(int resID) { public ResReferenceValue newReference(int resID) {

View File

@ -20,6 +20,7 @@ import android.util.TypedValue;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.res.data.*; import brut.androlib.res.data.*;
import brut.androlib.res.data.value.*; import brut.androlib.res.data.value.*;
import brut.util.Duo;
import brut.util.ExtDataInput; import brut.util.ExtDataInput;
import com.mindprod.ledatastream.LEDataInputStream; import com.mindprod.ledatastream.LEDataInputStream;
import java.io.*; import java.io.*;
@ -160,15 +161,13 @@ public class ARSCDecoder {
int count = mIn.readInt(); int count = mIn.readInt();
ResValueFactory factory = mPkg.getValueFactory(); ResValueFactory factory = mPkg.getValueFactory();
Map<ResReferenceValue, ResScalarValue> items = Duo<Integer, ResScalarValue>[] items = new Duo[count];
new LinkedHashMap<ResReferenceValue, ResScalarValue>();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
items.put( items[i] = new Duo<Integer, ResScalarValue>(
factory.newReference(mIn.readInt()), mIn.readInt(), (ResScalarValue) readValue());
(ResScalarValue) readValue());
} }
return factory.bagFactory(mType.getName(), parent, items); return factory.bagFactory(parent, items);
} }
private ResValue readValue() throws IOException, AndrolibException { private ResValue readValue() throws IOException, AndrolibException {