mirror of
https://github.com/revanced/Apktool.git
synced 2024-12-12 05:47:46 +01:00
Fixing the mess-ups that was apktool v1.4.8 :(
This commit is contained in:
parent
b5a476bb1b
commit
97451619b8
@ -149,10 +149,9 @@ final public class AndrolibResources {
|
|||||||
inApk = apkFile.getDirectory();
|
inApk = apkFile.getDirectory();
|
||||||
out = new FileDirectory(outDir);
|
out = new FileDirectory(outDir);
|
||||||
|
|
||||||
LOGGER.info("Decoding AndroidManifest.xml with resources...");
|
fileDecoder.decode(
|
||||||
|
inApk, "AndroidManifest.xml", out, "AndroidManifest.xml",
|
||||||
fileDecoder.decodeManifest(
|
"xml");
|
||||||
inApk, "AndroidManifest.xml", out, "AndroidManifest.xml");
|
|
||||||
|
|
||||||
if (inApk.containsDir("res")) {
|
if (inApk.containsDir("res")) {
|
||||||
in = inApk.getDir("res");
|
in = inApk.getDir("res");
|
||||||
|
@ -51,15 +51,7 @@ public class ResPluralsValue extends ResBagValue implements ResValuesXmlSerializ
|
|||||||
}
|
}
|
||||||
serializer.startTag(null, "item");
|
serializer.startTag(null, "item");
|
||||||
serializer.attribute(null, "quantity", QUANTITY_MAP[i]);
|
serializer.attribute(null, "quantity", QUANTITY_MAP[i]);
|
||||||
|
serializer.text(item.encodeAsResXmlValue());
|
||||||
String rawValue = item.encodeAsResXmlValueExt();
|
|
||||||
//AAPT don`t parse formatted for item tag(only for string and string-array tag),
|
|
||||||
// so adding "formatted='fasle'" is useless.
|
|
||||||
/*if (ResXmlEncoders.hasMultipleNonPositionalSubstitutions(rawValue)) {
|
|
||||||
serializer.attribute(null, "formatted", "false");
|
|
||||||
}*/
|
|
||||||
serializer.text(rawValue);
|
|
||||||
|
|
||||||
serializer.endTag(null, "item");
|
serializer.endTag(null, "item");
|
||||||
}
|
}
|
||||||
serializer.endTag(null, "plurals");
|
serializer.endTag(null, "plurals");
|
||||||
|
@ -52,7 +52,7 @@ public abstract class ResScalarValue extends ResValue
|
|||||||
if (mRawValue != null) {
|
if (mRawValue != null) {
|
||||||
return mRawValue;
|
return mRawValue;
|
||||||
}
|
}
|
||||||
return encodeAsResXml();
|
return encodeAsResXmlValueExt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String encodeAsResXmlValueExt() throws AndrolibException {
|
public String encodeAsResXmlValueExt() throws AndrolibException {
|
||||||
@ -60,7 +60,7 @@ public abstract class ResScalarValue extends ResValue
|
|||||||
if (rawValue != null) {
|
if (rawValue != null) {
|
||||||
if (ResXmlEncoders.hasMultipleNonPositionalSubstitutions(rawValue)) {
|
if (ResXmlEncoders.hasMultipleNonPositionalSubstitutions(rawValue)) {
|
||||||
int count = 1;
|
int count = 1;
|
||||||
StringBuffer result = new StringBuffer();
|
StringBuilder result = new StringBuilder();
|
||||||
String tmp1[] = rawValue.split("%%", -1);
|
String tmp1[] = rawValue.split("%%", -1);
|
||||||
int tmp1_sz = tmp1.length;
|
int tmp1_sz = tmp1.length;
|
||||||
for(int i=0;i<tmp1_sz;i++) {
|
for(int i=0;i<tmp1_sz;i++) {
|
||||||
|
@ -247,13 +247,13 @@ public class ARSCDecoder {
|
|||||||
byte keyboard = mIn.readByte();
|
byte keyboard = mIn.readByte();
|
||||||
byte navigation = mIn.readByte();
|
byte navigation = mIn.readByte();
|
||||||
byte inputFlags = mIn.readByte();
|
byte inputFlags = mIn.readByte();
|
||||||
/*inputPad0*/ mIn.skipBytes(1);
|
mIn.skipBytes(1);
|
||||||
|
|
||||||
short screenWidth = mIn.readShort();
|
short screenWidth = mIn.readShort();
|
||||||
short screenHeight = mIn.readShort();
|
short screenHeight = mIn.readShort();
|
||||||
|
|
||||||
short sdkVersion = mIn.readShort();
|
short sdkVersion = mIn.readShort();
|
||||||
/*minorVersion, now must always be 0*/ mIn.skipBytes(2);
|
mIn.skipBytes(2);
|
||||||
|
|
||||||
byte screenLayout = 0;
|
byte screenLayout = 0;
|
||||||
byte uiMode = 0;
|
byte uiMode = 0;
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package brut.androlib.res.decoder;
|
package brut.androlib.res.decoder;
|
||||||
|
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
@ -40,14 +39,13 @@ import java.util.logging.Logger;
|
|||||||
*
|
*
|
||||||
* Binary xml files parser.
|
* Binary xml files parser.
|
||||||
*
|
*
|
||||||
* Parser has only two states:
|
* Parser has only two states: (1) Operational state, which parser obtains after
|
||||||
* (1) Operational state, which parser obtains after first successful call
|
* first successful call to next() and retains until open(), close(), or failed
|
||||||
* to next() and retains until open(), close(), or failed call to next().
|
* call to next(). (2) Closed state, which parser obtains after open(), close(),
|
||||||
* (2) Closed state, which parser obtains after open(), close(), or failed
|
* or failed call to next(). In this state methods return invalid values or
|
||||||
* call to next(). In this state methods return invalid values or throw exceptions.
|
* throw exceptions.
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO: * check all methods in closed state
|
||||||
* * check all methods in closed state
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AXmlResourceParser implements XmlResourceParser {
|
public class AXmlResourceParser implements XmlResourceParser {
|
||||||
@ -319,20 +317,19 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
try {
|
try {
|
||||||
return mAttrDecoder.decode(valueType, valueData,
|
return mAttrDecoder.decode(valueType, valueData,
|
||||||
valueRaw == -1 ? null : ResXmlEncoders.escapeXmlChars(
|
valueRaw == -1 ? null : ResXmlEncoders.escapeXmlChars(
|
||||||
m_strings.getString(valueRaw)),
|
m_strings.getString(valueRaw)),
|
||||||
getAttributeNameResource(index));
|
getAttributeNameResource(index));
|
||||||
} catch (AndrolibException ex) {
|
} catch (AndrolibException ex) {
|
||||||
setFirstError(ex);
|
setFirstError(ex);
|
||||||
LOGGER.log(Level.WARNING, String.format(
|
LOGGER.log(Level.WARNING, String.format(
|
||||||
"Could not decode attr value, using undecoded value " +
|
"Could not decode attr value, using undecoded value "
|
||||||
"instead: ns=%s, name=%s, value=0x%08x",
|
+ "instead: ns=%s, name=%s, value=0x%08x",
|
||||||
getAttributePrefix(index), getAttributeName(index),
|
getAttributePrefix(index), getAttributeName(index),
|
||||||
valueData
|
valueData), ex);
|
||||||
), ex);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (valueType==TypedValue.TYPE_STRING) {
|
if (valueType == TypedValue.TYPE_STRING) {
|
||||||
return m_strings.getString(valueRaw);
|
return ResXmlEncoders.escapeXmlChars(m_strings.getString(valueRaw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,20 +490,16 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
|
|
||||||
///////////////////////////////////////////// implementation
|
///////////////////////////////////////////// implementation
|
||||||
/**
|
/**
|
||||||
* Namespace stack, holds prefix+uri pairs, as well as
|
* Namespace stack, holds prefix+uri pairs, as well as depth information.
|
||||||
* depth information.
|
* All information is stored in one int[] array. Array consists of depth
|
||||||
* All information is stored in one int[] array.
|
* frames: Data=DepthFrame*; DepthFrame=Count+[Prefix+Uri]*+Count;
|
||||||
* Array consists of depth frames:
|
* Count='count of Prefix+Uri pairs'; Yes, count is stored twice, to enable
|
||||||
* Data=DepthFrame*;
|
* bottom-up traversal. increaseDepth adds depth frame, decreaseDepth
|
||||||
* DepthFrame=Count+[Prefix+Uri]*+Count;
|
* removes it. push/pop operations operate only in current depth frame.
|
||||||
* Count='count of Prefix+Uri pairs';
|
* decreaseDepth removes any remaining (not pop'ed) namespace pairs. findXXX
|
||||||
* Yes, count is stored twice, to enable bottom-up traversal.
|
* methods search all depth frames starting from the last namespace pair of
|
||||||
* increaseDepth adds depth frame, decreaseDepth removes it.
|
* current depth frame. All functions that operate with int, use -1 as
|
||||||
* push/pop operations operate only in current depth frame.
|
* 'invalid value'.
|
||||||
* decreaseDepth removes any remaining (not pop'ed) namespace pairs.
|
|
||||||
* findXXX methods search all depth frames starting
|
|
||||||
* from the last namespace pair of current depth frame.
|
|
||||||
* All functions that operate with int, use -1 as 'invalid value'.
|
|
||||||
*
|
*
|
||||||
* !! functions expect 'prefix'+'uri' pairs, not 'uri'+'prefix' !!
|
* !! functions expect 'prefix'+'uri' pairs, not 'uri'+'prefix' !!
|
||||||
*
|
*
|
||||||
@ -764,7 +757,7 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
if (m_event != START_TAG) {
|
if (m_event != START_TAG) {
|
||||||
throw new IndexOutOfBoundsException("Current event is not START_TAG.");
|
throw new IndexOutOfBoundsException("Current event is not START_TAG.");
|
||||||
}
|
}
|
||||||
int offset = index * ATTRIBUTE_LENGHT;
|
int offset = index * ATTRIBUTE_LENGHT;
|
||||||
if (offset >= m_attributes.length) {
|
if (offset >= m_attributes.length) {
|
||||||
throw new IndexOutOfBoundsException("Invalid attribute index (" + index + ").");
|
throw new IndexOutOfBoundsException("Invalid attribute index (" + index + ").");
|
||||||
}
|
}
|
||||||
@ -806,7 +799,9 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
// Delayed initialization.
|
// Delayed initialization.
|
||||||
if (m_strings == null) {
|
if (m_strings == null) {
|
||||||
m_reader.skipCheckInt(CHUNK_AXML_FILE);
|
m_reader.skipCheckInt(CHUNK_AXML_FILE);
|
||||||
/*chunkSize*/ m_reader.skipInt();
|
/*
|
||||||
|
* chunkSize
|
||||||
|
*/ m_reader.skipInt();
|
||||||
m_strings = StringBlock.read(m_reader);
|
m_strings = StringBlock.read(m_reader);
|
||||||
m_namespaces.increaseDepth();
|
m_namespaces.increaseDepth();
|
||||||
m_operational = true;
|
m_operational = true;
|
||||||
@ -856,9 +851,13 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Common header.
|
// Common header.
|
||||||
/*chunkSize*/ m_reader.skipInt();
|
/*
|
||||||
|
* chunkSize
|
||||||
|
*/ m_reader.skipInt();
|
||||||
int lineNumber = m_reader.readInt();
|
int lineNumber = m_reader.readInt();
|
||||||
/*0xFFFFFFFF*/ m_reader.skipInt();
|
/*
|
||||||
|
* 0xFFFFFFFF
|
||||||
|
*/ m_reader.skipInt();
|
||||||
|
|
||||||
// Fake START_DOCUMENT event.
|
// Fake START_DOCUMENT event.
|
||||||
if (chunkType == CHUNK_XML_START_TAG && event == -1) {
|
if (chunkType == CHUNK_XML_START_TAG && event == -1) {
|
||||||
@ -874,8 +873,12 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
int uri = m_reader.readInt();
|
int uri = m_reader.readInt();
|
||||||
m_namespaces.push(prefix, uri);
|
m_namespaces.push(prefix, uri);
|
||||||
} else {
|
} else {
|
||||||
/*prefix*/ m_reader.skipInt();
|
/*
|
||||||
/*uri*/ m_reader.skipInt();
|
* prefix
|
||||||
|
*/ m_reader.skipInt();
|
||||||
|
/*
|
||||||
|
* uri
|
||||||
|
*/ m_reader.skipInt();
|
||||||
m_namespaces.pop();
|
m_namespaces.pop();
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -888,7 +891,9 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
if (chunkType == CHUNK_XML_START_TAG) {
|
if (chunkType == CHUNK_XML_START_TAG) {
|
||||||
m_namespaceUri = m_reader.readInt();
|
m_namespaceUri = m_reader.readInt();
|
||||||
m_name = m_reader.readInt();
|
m_name = m_reader.readInt();
|
||||||
/*flags?*/ m_reader.skipInt();
|
/*
|
||||||
|
* flags?
|
||||||
|
*/ m_reader.skipInt();
|
||||||
int attributeCount = m_reader.readInt();
|
int attributeCount = m_reader.readInt();
|
||||||
m_idAttribute = (attributeCount >>> 16) - 1;
|
m_idAttribute = (attributeCount >>> 16) - 1;
|
||||||
attributeCount &= 0xFFFF;
|
attributeCount &= 0xFFFF;
|
||||||
@ -903,7 +908,7 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
m_namespaces.increaseDepth();
|
m_namespaces.increaseDepth();
|
||||||
m_event = START_TAG;
|
m_event = START_TAG;
|
||||||
m_strings.touch(m_name, m_name);
|
m_strings.touch(m_name, m_name);
|
||||||
for(int i = 0; i<attributeCount; i++) {
|
for (int i = 0; i < attributeCount; i++) {
|
||||||
m_strings.touch(m_attributes[ATTRIBUTE_IX_NAME], m_name);
|
m_strings.touch(m_attributes[ATTRIBUTE_IX_NAME], m_name);
|
||||||
m_strings.touch(m_attributes[ATTRIBUTE_IX_VALUE_STRING], m_name);
|
m_strings.touch(m_attributes[ATTRIBUTE_IX_VALUE_STRING], m_name);
|
||||||
}
|
}
|
||||||
@ -922,119 +927,122 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
|
|
||||||
if (chunkType == CHUNK_XML_TEXT) {
|
if (chunkType == CHUNK_XML_TEXT) {
|
||||||
m_name = m_reader.readInt();
|
m_name = m_reader.readInt();
|
||||||
/*?*/ m_reader.skipInt();
|
/*
|
||||||
/*?*/ m_reader.skipInt();
|
* ?
|
||||||
|
*/ m_reader.skipInt();
|
||||||
|
/*
|
||||||
|
* ?
|
||||||
|
*/ m_reader.skipInt();
|
||||||
m_event = TEXT;
|
m_event = TEXT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatArray(int[] array, int min, int max) {
|
private static String formatArray(int[] array, int min, int max) {
|
||||||
if(max > array.length)
|
if (max > array.length) {
|
||||||
max = array.length;
|
max = array.length;
|
||||||
if(min < 0)
|
}
|
||||||
min = 0;
|
if (min < 0) {
|
||||||
StringBuffer sb = new StringBuffer("[");
|
min = 0;
|
||||||
int i = min;
|
}
|
||||||
while(true) {
|
StringBuffer sb = new StringBuffer("[");
|
||||||
sb.append(array[i]);
|
int i = min;
|
||||||
i++;
|
while (true) {
|
||||||
if(i < max) {
|
sb.append(array[i]);
|
||||||
sb.append(", ");
|
i++;
|
||||||
} else {
|
if (i < max) {
|
||||||
sb.append("]");
|
sb.append(", ");
|
||||||
break;
|
} else {
|
||||||
}
|
sb.append("]");
|
||||||
}
|
break;
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean compareAttr(int[] attr1, int[] attr2) {
|
|
||||||
//TODO: sort Attrs
|
|
||||||
/*
|
|
||||||
* ATTRIBUTE_IX_VALUE_TYPE == TYPE_STRING : ATTRIBUTE_IX_VALUE_STRING
|
|
||||||
* : ATTRIBUTE_IX_NAMESPACE_URI
|
|
||||||
* ATTRIBUTE_IX_NAMESPACE_URI : ATTRIBUTE_IX_NAME
|
|
||||||
* id
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
if(attr1[ATTRIBUTE_IX_VALUE_TYPE] == TypedValue.TYPE_STRING &&
|
|
||||||
attr1[ATTRIBUTE_IX_VALUE_TYPE] == attr2[ATTRIBUTE_IX_VALUE_TYPE] &&
|
|
||||||
//(m_strings.touch(attr1[ATTRIBUTE_IX_VALUE_STRING], m_name) ||
|
|
||||||
// m_strings.touch(attr2[ATTRIBUTE_IX_VALUE_STRING], m_name)) &&
|
|
||||||
//m_strings.touch(attr1[ATTRIBUTE_IX_VALUE_STRING], m_name) &&
|
|
||||||
attr1[ATTRIBUTE_IX_VALUE_STRING] != attr2[ATTRIBUTE_IX_VALUE_STRING]) {
|
|
||||||
return (attr1[ATTRIBUTE_IX_VALUE_STRING] < attr2[ATTRIBUTE_IX_VALUE_STRING]);
|
|
||||||
} else if ((attr1[ATTRIBUTE_IX_NAMESPACE_URI] == attr2[ATTRIBUTE_IX_NAMESPACE_URI]) && (attr1[ATTRIBUTE_IX_NAMESPACE_URI] != -1) &&
|
|
||||||
//(m_strings.touch(attr1[ATTRIBUTE_IX_NAME], m_name) ||
|
|
||||||
// m_strings.touch(attr2[ATTRIBUTE_IX_NAME], m_name)) &&
|
|
||||||
//m_strings.touch(attr1[ATTRIBUTE_IX_NAME], m_name) &&
|
|
||||||
(attr1[ATTRIBUTE_IX_NAME] != attr2[ATTRIBUTE_IX_NAME])) {
|
|
||||||
return (attr1[ATTRIBUTE_IX_NAME] < attr2[ATTRIBUTE_IX_NAME]);
|
|
||||||
//} else if (attr1[ATTRIBUTE_IX_NAMESPACE_URI] < attr2[ATTRIBUTE_IX_NAMESPACE_URI]) {
|
|
||||||
// return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sortAttrs() {
|
|
||||||
int attributeCount = m_attributes.length/ATTRIBUTE_LENGHT;
|
|
||||||
int tmp1[][] = new int[attributeCount][];
|
|
||||||
int tmp2[] = null;
|
|
||||||
for (int i = 0; i < attributeCount;i++) {
|
|
||||||
tmp1[i] = new int[ATTRIBUTE_LENGHT+1];
|
|
||||||
for(int j = 0; j < ATTRIBUTE_LENGHT; j++) {
|
|
||||||
tmp1[i][j] = m_attributes[i*ATTRIBUTE_LENGHT+j];
|
|
||||||
}
|
|
||||||
tmp1[i][ATTRIBUTE_LENGHT] = i;
|
|
||||||
if(DBG) {
|
|
||||||
try {
|
|
||||||
if (dbgOut == null) {
|
|
||||||
dbgOut = new BufferedWriter(new FileWriter("C:\\res.log",false));
|
|
||||||
}
|
|
||||||
dbgOut.write("Namespace: " + getAttributeNamespace (i) +
|
|
||||||
", Name: " + getAttributeName (i)+
|
|
||||||
", Value: " + getAttributeValue (i) + ", Array: " +
|
|
||||||
formatArray(tmp1[i], 0, ATTRIBUTE_LENGHT) + "\n");
|
|
||||||
dbgOut.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int j = 1; j < attributeCount;j++) {
|
return sb.toString();
|
||||||
for (int i = 1; i < attributeCount;i++) {
|
}
|
||||||
if(compareAttr(tmp1[i], tmp1[i-1])) {
|
|
||||||
tmp2 = tmp1[i-1];
|
private boolean compareAttr(int[] attr1, int[] attr2) {
|
||||||
tmp1[i-1] = tmp1[i];
|
//TODO: sort Attrs
|
||||||
|
/*
|
||||||
|
* ATTRIBUTE_IX_VALUE_TYPE == TYPE_STRING : ATTRIBUTE_IX_VALUE_STRING :
|
||||||
|
* ATTRIBUTE_IX_NAMESPACE_URI ATTRIBUTE_IX_NAMESPACE_URI :
|
||||||
|
* ATTRIBUTE_IX_NAME id
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (attr1[ATTRIBUTE_IX_VALUE_TYPE] == TypedValue.TYPE_STRING
|
||||||
|
&& attr1[ATTRIBUTE_IX_VALUE_TYPE] == attr2[ATTRIBUTE_IX_VALUE_TYPE]
|
||||||
|
&& //(m_strings.touch(attr1[ATTRIBUTE_IX_VALUE_STRING], m_name) ||
|
||||||
|
// m_strings.touch(attr2[ATTRIBUTE_IX_VALUE_STRING], m_name)) &&
|
||||||
|
//m_strings.touch(attr1[ATTRIBUTE_IX_VALUE_STRING], m_name) &&
|
||||||
|
attr1[ATTRIBUTE_IX_VALUE_STRING] != attr2[ATTRIBUTE_IX_VALUE_STRING]) {
|
||||||
|
return (attr1[ATTRIBUTE_IX_VALUE_STRING] < attr2[ATTRIBUTE_IX_VALUE_STRING]);
|
||||||
|
} else if ((attr1[ATTRIBUTE_IX_NAMESPACE_URI] == attr2[ATTRIBUTE_IX_NAMESPACE_URI]) && (attr1[ATTRIBUTE_IX_NAMESPACE_URI] != -1)
|
||||||
|
&& //(m_strings.touch(attr1[ATTRIBUTE_IX_NAME], m_name) ||
|
||||||
|
// m_strings.touch(attr2[ATTRIBUTE_IX_NAME], m_name)) &&
|
||||||
|
//m_strings.touch(attr1[ATTRIBUTE_IX_NAME], m_name) &&
|
||||||
|
(attr1[ATTRIBUTE_IX_NAME] != attr2[ATTRIBUTE_IX_NAME])) {
|
||||||
|
return (attr1[ATTRIBUTE_IX_NAME] < attr2[ATTRIBUTE_IX_NAME]);
|
||||||
|
//} else if (attr1[ATTRIBUTE_IX_NAMESPACE_URI] < attr2[ATTRIBUTE_IX_NAMESPACE_URI]) {
|
||||||
|
// return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sortAttrs() {
|
||||||
|
int attributeCount = m_attributes.length / ATTRIBUTE_LENGHT;
|
||||||
|
int tmp1[][] = new int[attributeCount][];
|
||||||
|
int tmp2[] = null;
|
||||||
|
for (int i = 0; i < attributeCount; i++) {
|
||||||
|
tmp1[i] = new int[ATTRIBUTE_LENGHT + 1];
|
||||||
|
for (int j = 0; j < ATTRIBUTE_LENGHT; j++) {
|
||||||
|
tmp1[i][j] = m_attributes[i * ATTRIBUTE_LENGHT + j];
|
||||||
|
}
|
||||||
|
tmp1[i][ATTRIBUTE_LENGHT] = i;
|
||||||
|
if (DBG) {
|
||||||
|
try {
|
||||||
|
if (dbgOut == null) {
|
||||||
|
dbgOut = new BufferedWriter(new FileWriter("C:\\res.log", false));
|
||||||
|
}
|
||||||
|
dbgOut.write("Namespace: " + getAttributeNamespace(i)
|
||||||
|
+ ", Name: " + getAttributeName(i)
|
||||||
|
+ ", Value: " + getAttributeValue(i) + ", Array: "
|
||||||
|
+ formatArray(tmp1[i], 0, ATTRIBUTE_LENGHT) + "\n");
|
||||||
|
dbgOut.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = 1; j < attributeCount; j++) {
|
||||||
|
for (int i = 1; i < attributeCount; i++) {
|
||||||
|
if (compareAttr(tmp1[i], tmp1[i - 1])) {
|
||||||
|
tmp2 = tmp1[i - 1];
|
||||||
|
tmp1[i - 1] = tmp1[i];
|
||||||
tmp1[i] = tmp2;
|
tmp1[i] = tmp2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < attributeCount;i++) {
|
for (int i = 0; i < attributeCount; i++) {
|
||||||
for(int j = 0; j < ATTRIBUTE_LENGHT; j++) {
|
for (int j = 0; j < ATTRIBUTE_LENGHT; j++) {
|
||||||
m_attributes[i*ATTRIBUTE_LENGHT+j] = tmp1[i][j];
|
m_attributes[i * ATTRIBUTE_LENGHT + j] = tmp1[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFirstError(AndrolibException error) {
|
private void setFirstError(AndrolibException error) {
|
||||||
if (mFirstError == null) {
|
if (mFirstError == null) {
|
||||||
mFirstError = error;
|
mFirstError = error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////// data
|
/////////////////////////////////// data
|
||||||
/*
|
/*
|
||||||
* All values are essentially indices, e.g. m_name is
|
* All values are essentially indices, e.g. m_name is an index of name in
|
||||||
* an index of name in m_strings.
|
* m_strings.
|
||||||
*/
|
*/
|
||||||
private ExtDataInput m_reader;
|
private ExtDataInput m_reader;
|
||||||
private ResAttrDecoder mAttrDecoder;
|
private ResAttrDecoder mAttrDecoder;
|
||||||
private AndrolibException mFirstError;
|
private AndrolibException mFirstError;
|
||||||
|
|
||||||
private boolean m_operational = false;
|
private boolean m_operational = false;
|
||||||
private StringBlock m_strings;
|
private StringBlock m_strings;
|
||||||
private int[] m_resourceIDs;
|
private int[] m_resourceIDs;
|
||||||
@ -1048,28 +1056,24 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
private int m_idAttribute;
|
private int m_idAttribute;
|
||||||
private int m_classAttribute;
|
private int m_classAttribute;
|
||||||
private int m_styleAttribute;
|
private int m_styleAttribute;
|
||||||
|
|
||||||
private final static Logger LOGGER =
|
private final static Logger LOGGER =
|
||||||
Logger.getLogger(AXmlResourceParser.class.getName());
|
Logger.getLogger(AXmlResourceParser.class.getName());
|
||||||
private static final String E_NOT_SUPPORTED = "Method is not supported.";
|
private static final String E_NOT_SUPPORTED = "Method is not supported.";
|
||||||
private static final int
|
private static final int ATTRIBUTE_IX_NAMESPACE_URI = 0,
|
||||||
ATTRIBUTE_IX_NAMESPACE_URI = 0,
|
ATTRIBUTE_IX_NAME = 1,
|
||||||
ATTRIBUTE_IX_NAME = 1,
|
ATTRIBUTE_IX_VALUE_STRING = 2,
|
||||||
ATTRIBUTE_IX_VALUE_STRING = 2,
|
ATTRIBUTE_IX_VALUE_TYPE = 3,
|
||||||
ATTRIBUTE_IX_VALUE_TYPE = 3,
|
ATTRIBUTE_IX_VALUE_DATA = 4,
|
||||||
ATTRIBUTE_IX_VALUE_DATA = 4,
|
ATTRIBUTE_LENGHT = 5;
|
||||||
ATTRIBUTE_LENGHT = 5;
|
private static final int CHUNK_AXML_FILE = 0x00080003,
|
||||||
|
CHUNK_RESOURCEIDS = 0x00080180,
|
||||||
private static final int
|
CHUNK_XML_FIRST = 0x00100100,
|
||||||
CHUNK_AXML_FILE = 0x00080003,
|
|
||||||
CHUNK_RESOURCEIDS = 0x00080180,
|
|
||||||
CHUNK_XML_FIRST = 0x00100100,
|
|
||||||
CHUNK_XML_START_NAMESPACE = 0x00100100,
|
CHUNK_XML_START_NAMESPACE = 0x00100100,
|
||||||
CHUNK_XML_END_NAMESPACE = 0x00100101,
|
CHUNK_XML_END_NAMESPACE = 0x00100101,
|
||||||
CHUNK_XML_START_TAG = 0x00100102,
|
CHUNK_XML_START_TAG = 0x00100102,
|
||||||
CHUNK_XML_END_TAG = 0x00100103,
|
CHUNK_XML_END_TAG = 0x00100103,
|
||||||
CHUNK_XML_TEXT = 0x00100104,
|
CHUNK_XML_TEXT = 0x00100104,
|
||||||
CHUNK_XML_LAST = 0x00100104;
|
CHUNK_XML_LAST = 0x00100104;
|
||||||
private Writer dbgOut = null;
|
private Writer dbgOut = null;
|
||||||
private final static boolean DBG = false;
|
private final static boolean DBG = false;
|
||||||
}
|
}
|
@ -156,37 +156,24 @@ public final class ResXmlEncoders {
|
|||||||
return out.toString();
|
return out.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static List<Integer> findNonPositionalSubstitutions(String str,
|
||||||
* It searches for "%", but not "%%" nor "%(\d)+\$"
|
|
||||||
*/
|
|
||||||
private static List<Integer> findNonPositionalSubstitutions(String str,
|
|
||||||
int max) {
|
int max) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int pos2 = 0;
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int length = str.length();
|
int length = str.length();
|
||||||
List<Integer> ret = new ArrayList<Integer>();
|
List<Integer> ret = new ArrayList<Integer>();
|
||||||
while((pos2 = (pos = str.indexOf('%', pos2)) + 1) != 0) {
|
while((pos = str.indexOf('%', pos)) != -1) {
|
||||||
if (pos2 == length) {
|
if (pos + 1 == length) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
char c = str.charAt(pos2++);
|
char c = str.charAt(pos + 1);
|
||||||
if (c == '%') {
|
if (c >= 'a' && c <= 'z') {
|
||||||
continue;
|
ret.add(pos);
|
||||||
}
|
if (max != -1 && ++count >= max) {
|
||||||
if (c >= '0' && c <= '9' && pos2 < length) {
|
break;
|
||||||
do {
|
|
||||||
c = str.charAt(pos2++);
|
|
||||||
} while (c >= '0' && c <= '9' && pos2 < length);
|
|
||||||
if (c == '$') {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pos += 2;
|
||||||
ret.add(pos);
|
|
||||||
if (max != -1 && ++count >= max) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user