diff options
Diffstat (limited to 'tools/aapt/XMLNode.cpp')
-rw-r--r-- | tools/aapt/XMLNode.cpp | 43 |
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", |