diff options
author | Adam Lesinski <adamlesinski@google.com> | 2014-11-14 14:48:12 -0800 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2015-04-02 17:02:48 -0700 |
commit | 6f6ceb7e1456698b1f33e04536bfb3227f9fcfcb (patch) | |
tree | 0a1f8e354c4714f162f849b09a5d5da757c6d5b8 /tools/aapt2/XmlPullParser.h | |
parent | 041ca26d028ae314d416cb107721ea7267af6aca (diff) | |
download | frameworks_base-6f6ceb7e1456698b1f33e04536bfb3227f9fcfcb.zip frameworks_base-6f6ceb7e1456698b1f33e04536bfb3227f9fcfcb.tar.gz frameworks_base-6f6ceb7e1456698b1f33e04536bfb3227f9fcfcb.tar.bz2 |
AAPT2
First checking of AAPT2. The individual phases of AAPT2 work, but there
are some missing pieces.
For early testing we are missing:
- Need to properly mark file references and include them in package
- Need to package into zip
Final AAPT for apps we are missing:
- Need to crush PNGs
- Need to parse 9-patches
- Need to validate all of AndroidManifest.xml
- Need to write align method to align resource tables for splits.
Final AAPT for apps + system we are missing:
- Need to handle overlays
- Need to store comments for R file
- Need to handle --shared-lib (dynamic references too).
New AAPT features coming:
- Need to import compiled libraries
- Name mangling
- R file generation for library code
Change-Id: I95f8a63581b81a1f424ae6fb2c373c883b72c18d
Diffstat (limited to 'tools/aapt2/XmlPullParser.h')
-rw-r--r-- | tools/aapt2/XmlPullParser.h | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/tools/aapt2/XmlPullParser.h b/tools/aapt2/XmlPullParser.h new file mode 100644 index 0000000..c667df2 --- /dev/null +++ b/tools/aapt2/XmlPullParser.h @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * 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. + */ + +#ifndef AAPT_XML_PULL_PARSER_H +#define AAPT_XML_PULL_PARSER_H + +#include <algorithm> +#include <ostream> +#include <string> +#include <vector> + +#include "StringPiece.h" + +namespace aapt { + +class XmlPullParser { +public: + enum class Event { + kBadDocument, + kStartDocument, + kEndDocument, + + kStartNamespace, + kEndNamespace, + kStartElement, + kEndElement, + kText, + kComment, + }; + + static void skipCurrentElement(XmlPullParser* parser); + static bool isGoodEvent(Event event); + + virtual ~XmlPullParser() {} + + /** + * Returns the current event that is being processed. + */ + virtual Event getEvent() const = 0; + + virtual const std::string& getLastError() const = 0; + + /** + * Note, unlike XmlPullParser, the first call to next() will return + * StartElement of the first element. + */ + virtual Event next() = 0; + + // + // These are available for all nodes. + // + + virtual const std::u16string& getComment() const = 0; + virtual size_t getLineNumber() const = 0; + virtual size_t getDepth() const = 0; + + /** + * Returns the character data for a Text event. + */ + virtual const std::u16string& getText() const = 0; + + /** + * Namespace prefix is available for StartNamespace and EndNamespace. + */ + virtual const std::u16string& getNamespacePrefix() const = 0; + + /** + * Namespace URI is available for StartNamespace. + */ + virtual const std::u16string& getNamespaceUri() const = 0; + + // + // These are available for StartElement and EndElement. + // + + virtual const std::u16string& getElementNamespace() const = 0; + virtual const std::u16string& getElementName() const = 0; + + // + // Remaining methods are for retrieving information about attributes + // associated with a StartElement. + // + // Attributes must be in sorted order (according to the less than operator + // of struct Attribute). + // + + struct Attribute { + std::u16string namespaceUri; + std::u16string name; + std::u16string value; + + int compare(const Attribute& rhs) const; + bool operator<(const Attribute& rhs) const; + bool operator==(const Attribute& rhs) const; + bool operator!=(const Attribute& rhs) const; + }; + + using const_iterator = std::vector<Attribute>::const_iterator; + + virtual const_iterator beginAttributes() const = 0; + virtual const_iterator endAttributes() const = 0; + virtual size_t getAttributeCount() const = 0; + const_iterator findAttribute(StringPiece16 namespaceUri, StringPiece16 name) const; +}; + +/* + * Automatically reads up to the end tag of the element it was initialized with + * when being destroyed. + */ +class AutoFinishElement { +public: + AutoFinishElement(const std::shared_ptr<XmlPullParser>& parser); + ~AutoFinishElement(); + +private: + std::shared_ptr<XmlPullParser> mParser; + int mDepth; +}; + +// +// Implementation +// + +inline ::std::ostream& operator<<(::std::ostream& out, XmlPullParser::Event event) { + switch (event) { + case XmlPullParser::Event::kBadDocument: return out << "BadDocument"; + case XmlPullParser::Event::kStartDocument: return out << "StartDocument"; + case XmlPullParser::Event::kEndDocument: return out << "EndDocument"; + case XmlPullParser::Event::kStartNamespace: return out << "StartNamespace"; + case XmlPullParser::Event::kEndNamespace: return out << "EndNamespace"; + case XmlPullParser::Event::kStartElement: return out << "StartElement"; + case XmlPullParser::Event::kEndElement: return out << "EndElement"; + case XmlPullParser::Event::kText: return out << "Text"; + case XmlPullParser::Event::kComment: return out << "Comment"; + } + return out; +} + +inline void XmlPullParser::skipCurrentElement(XmlPullParser* parser) { + int depth = 1; + while (depth > 0) { + switch (parser->next()) { + case Event::kEndDocument: + case Event::kBadDocument: + return; + case Event::kStartElement: + depth++; + break; + case Event::kEndElement: + depth--; + break; + default: + break; + } + } +} + +inline bool XmlPullParser::isGoodEvent(XmlPullParser::Event event) { + return event != Event::kBadDocument && event != Event::kEndDocument; +} + +inline int XmlPullParser::Attribute::compare(const Attribute& rhs) const { + int cmp = namespaceUri.compare(rhs.namespaceUri); + if (cmp != 0) return cmp; + return name.compare(rhs.name); +} + +inline bool XmlPullParser::Attribute::operator<(const Attribute& rhs) const { + return compare(rhs) < 0; +} + +inline bool XmlPullParser::Attribute::operator==(const Attribute& rhs) const { + return compare(rhs) == 0; +} + +inline bool XmlPullParser::Attribute::operator!=(const Attribute& rhs) const { + return compare(rhs) != 0; +} + +inline XmlPullParser::const_iterator XmlPullParser::findAttribute(StringPiece16 namespaceUri, + StringPiece16 name) const { + const auto endIter = endAttributes(); + const auto iter = std::lower_bound(beginAttributes(), endIter, + std::pair<StringPiece16, StringPiece16>(namespaceUri, name), + [](const Attribute& attr, const std::pair<StringPiece16, StringPiece16>& rhs) -> bool { + int cmp = attr.namespaceUri.compare(0, attr.namespaceUri.size(), + rhs.first.data(), rhs.first.size()); + if (cmp < 0) return true; + if (cmp > 0) return false; + cmp = attr.name.compare(0, attr.name.size(), rhs.second.data(), rhs.second.size()); + if (cmp < 0) return true; + return false; + } + ); + + if (iter != endIter && namespaceUri == iter->namespaceUri && name == iter->name) { + return iter; + } + return endIter; +} + +inline AutoFinishElement::AutoFinishElement(const std::shared_ptr<XmlPullParser>& parser) : + mParser(parser), mDepth(parser->getDepth()) { +} + +inline AutoFinishElement::~AutoFinishElement() { + int depth; + XmlPullParser::Event event; + while ((depth = mParser->getDepth()) >= mDepth && + XmlPullParser::isGoodEvent(event = mParser->getEvent())) { + if (depth == mDepth && (event == XmlPullParser::Event::kEndElement || + event == XmlPullParser::Event::kEndNamespace)) { + return; + } + mParser->next(); + } +} + +} // namespace aapt + +#endif // AAPT_XML_PULL_PARSER_H |