mirror of
https://github.com/revanced/Apktool.git
synced 2025-02-03 07:37:32 +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.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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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>();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -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;
|
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"};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user