summaryrefslogtreecommitdiffstats
path: root/tools/aapt/XMLNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt/XMLNode.cpp')
-rw-r--r--tools/aapt/XMLNode.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index ca3f687..6ab55d5 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -11,6 +11,7 @@
#include <utils/ByteOrder.h>
#include <errno.h>
#include <string.h>
+#include <androidfw/AssetManager.h>
#ifndef HAVE_MS_C_RUNTIME
#define O_BINARY 0
@@ -583,9 +584,51 @@ status_t parseXMLResource(const sp<AaptFile>& file, ResXMLTree* outTree,
return NO_ERROR;
}
+sp<XMLNode> XMLNode::parseFromZip(const sp<AaptFile>& file) {
+ AssetManager assets;
+ int32_t cookie;
+
+ if (!assets.addAssetPath(file->getZipFile(), &cookie)) {
+ fprintf(stderr, "Error: Could not open path %s\n", file->getZipFile().string());
+ return NULL;
+ }
+
+ Asset* asset = assets.openNonAsset(cookie, file->getSourceFile(), Asset::ACCESS_BUFFER);
+ ssize_t len = asset->getLength();
+ const void* buf = asset->getBuffer(false);
+
+ XML_Parser parser = XML_ParserCreateNS(NULL, 1);
+ ParseState state;
+ state.filename = file->getPrintableSource();
+ state.parser = parser;
+ XML_SetUserData(parser, &state);
+ XML_SetElementHandler(parser, startElement, endElement);
+ XML_SetNamespaceDeclHandler(parser, startNamespace, endNamespace);
+ XML_SetCharacterDataHandler(parser, characterData);
+ XML_SetCommentHandler(parser, commentData);
+
+ bool done = true;
+ if (XML_Parse(parser, (char*) buf, len, done) == XML_STATUS_ERROR) {
+ SourcePos(file->getSourceFile(), (int)XML_GetCurrentLineNumber(parser)).error(
+ "Error parsing XML: %s\n", XML_ErrorString(XML_GetErrorCode(parser)));
+ return NULL;
+ }
+ XML_ParserFree(parser);
+ if (state.root == NULL) {
+ SourcePos(file->getSourceFile(), -1).error("No XML data generated when parsing");
+ }
+ return state.root;
+}
+
sp<XMLNode> XMLNode::parse(const sp<AaptFile>& file)
{
char buf[16384];
+
+ //Check for zip first
+ if (file->getZipFile().length() > 0) {
+ return parseFromZip(file);
+ }
+
int fd = open(file->getSourceFile().string(), O_RDONLY | O_BINARY);
if (fd < 0) {
SourcePos(file->getSourceFile(), -1).error("Unable to open file for read: %s",