16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/* 26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project 36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License. 66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at 76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software 116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and 146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License. 156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 17ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <iostream> 18ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <string> 19ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Maybe.h" 211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h" 22467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "xml/XmlPullParser.h" 23467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "xml/XmlUtil.h" 241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 255b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinskiusing ::aapt::io::InputStream; 265b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinskiusing ::android::StringPiece; 27d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski 286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt { 29467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinskinamespace xml { 306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiconstexpr char kXmlNamespaceSep = 1; 326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 335b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam LesinskiXmlPullParser::XmlPullParser(InputStream* in) : in_(in), empty_(), depth_(0) { 34ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser_ = XML_ParserCreateNS(nullptr, kXmlNamespaceSep); 35ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XML_SetUserData(parser_, this); 36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XML_SetElementHandler(parser_, StartElementHandler, EndElementHandler); 37ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XML_SetNamespaceDeclHandler(parser_, StartNamespaceHandler, 38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski EndNamespaceHandler); 39ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XML_SetCharacterDataHandler(parser_, CharacterDataHandler); 40ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XML_SetCommentHandler(parser_, CommentDataHandler); 41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski event_queue_.push(EventData{Event::kStartDocument, 0, depth_++}); 426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 445b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam LesinskiXmlPullParser::~XmlPullParser() { 455b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski XML_ParserFree(parser_); 465b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski} 47ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 48ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiXmlPullParser::Event XmlPullParser::Next() { 49ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const Event currentEvent = event(); 505b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski if (currentEvent == Event::kBadDocument || currentEvent == Event::kEndDocument) { 51ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return currentEvent; 52ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 54ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski event_queue_.pop(); 55ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski while (event_queue_.empty()) { 565b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski const char* buffer = nullptr; 575b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski size_t buffer_size = 0; 585b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski bool done = false; 595b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski if (!in_->Next(reinterpret_cast<const void**>(&buffer), &buffer_size)) { 605b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski if (in_->HadError()) { 615b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski error_ = in_->GetError(); 625b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski event_queue_.push(EventData{Event::kBadDocument}); 635b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski break; 645b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski } 65ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 665b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski done = true; 676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 695b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski if (XML_Parse(parser_, buffer, buffer_size, done) == XML_STATUS_ERROR) { 70ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski error_ = XML_ErrorString(XML_GetErrorCode(parser_)); 71ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski event_queue_.push(EventData{Event::kBadDocument}); 725b54ca2d72c410aa34363b0f3bb0fe1666954aeaAdam Lesinski break; 736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 75ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (done) { 76ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski event_queue_.push(EventData{Event::kEndDocument, 0, 0}); 77ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 78ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 79ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 80ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Event next_event = event(); 81ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 82ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski // Record namespace prefixes and package names so that we can do our own 83ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski // handling of references that use namespace aliases. 84ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (next_event == Event::kStartNamespace || 85ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski next_event == Event::kEndNamespace) { 86ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Maybe<ExtractedPackage> result = 87ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ExtractPackageFromNamespace(namespace_uri()); 88ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (next_event == Event::kStartNamespace) { 89ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (result) { 90ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski package_aliases_.emplace_back( 91ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski PackageDecl{namespace_prefix(), std::move(result.value())}); 92ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 93ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } else { 94ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (result) { 95ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski package_aliases_.pop_back(); 96ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 9724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski } 98ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 9924aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 100ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return next_event; 1016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 103ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiXmlPullParser::Event XmlPullParser::event() const { 104ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().event; 1056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 107ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiconst std::string& XmlPullParser::error() const { return error_; } 1086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 109ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiconst std::string& XmlPullParser::comment() const { 110ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().data1; 1116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 113ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskisize_t XmlPullParser::line_number() const { 114ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().line_number; 1156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 117ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskisize_t XmlPullParser::depth() const { return event_queue_.front().depth; } 1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 119ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiconst std::string& XmlPullParser::text() const { 120ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (event() != Event::kText) { 121ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return empty_; 122ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 123ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().data1; 1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 126ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiconst std::string& XmlPullParser::namespace_prefix() const { 127ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const Event current_event = event(); 128ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (current_event != Event::kStartNamespace && 129ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski current_event != Event::kEndNamespace) { 130ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return empty_; 131ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 132ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().data1; 1336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 135ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiconst std::string& XmlPullParser::namespace_uri() const { 136ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const Event current_event = event(); 137ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (current_event != Event::kStartNamespace && 138ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski current_event != Event::kEndNamespace) { 139ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return empty_; 140ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 141ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().data2; 1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 144ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiMaybe<ExtractedPackage> XmlPullParser::TransformPackageAlias( 145ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const StringPiece& alias, const StringPiece& local_package) const { 146ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (alias.empty()) { 147d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski return ExtractedPackage{local_package.to_string(), false /* private */}; 148ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 149ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 150ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const auto end_iter = package_aliases_.rend(); 151ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski for (auto iter = package_aliases_.rbegin(); iter != end_iter; ++iter) { 152ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (alias == iter->prefix) { 153ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (iter->package.package.empty()) { 154d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski return ExtractedPackage{local_package.to_string(), iter->package.private_namespace}; 155ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 156ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return iter->package; 1571ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 158ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 159ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return {}; 16024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski} 16124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 162ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiconst std::string& XmlPullParser::element_namespace() const { 163ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const Event current_event = event(); 164ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (current_event != Event::kStartElement && 165ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski current_event != Event::kEndElement) { 166ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return empty_; 167ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 168ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().data1; 1696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 171ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiconst std::string& XmlPullParser::element_name() const { 172ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const Event current_event = event(); 173ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (current_event != Event::kStartElement && 174ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski current_event != Event::kEndElement) { 175ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return empty_; 176ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 177ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().data2; 1786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 180ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiXmlPullParser::const_iterator XmlPullParser::begin_attributes() const { 181ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().attributes.begin(); 1826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 184ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiXmlPullParser::const_iterator XmlPullParser::end_attributes() const { 185ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().attributes.end(); 1866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 188ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskisize_t XmlPullParser::attribute_count() const { 189ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (event() != Event::kStartElement) { 190ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return 0; 191ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 192ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return event_queue_.front().attributes.size(); 1936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 1966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Extracts the namespace and name of an expanded element or attribute name. 1976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 198d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskistatic void SplitName(const char* name, std::string* out_ns, std::string* out_name) { 199ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* p = name; 200ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski while (*p != 0 && *p != kXmlNamespaceSep) { 201ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski p++; 202ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 203ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 204ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (*p == 0) { 205d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski out_ns->clear(); 206d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski out_name->assign(name); 207ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } else { 208d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski out_ns->assign(name, (p - name)); 209d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski out_name->assign(p + 1); 210ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 2116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 213ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid XMLCALL XmlPullParser::StartNamespaceHandler(void* user_data, 214ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* prefix, 215ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* uri) { 216ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); 217ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string namespace_uri = uri != nullptr ? uri : std::string(); 218ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->namespace_uris_.push(namespace_uri); 219ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->event_queue_.push( 220ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski EventData{Event::kStartNamespace, 221ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XML_GetCurrentLineNumber(parser->parser_), parser->depth_++, 222ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski prefix != nullptr ? prefix : std::string(), namespace_uri}); 2236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 225ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid XMLCALL XmlPullParser::StartElementHandler(void* user_data, 226ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* name, 227ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char** attrs) { 228ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); 229ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 230ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski EventData data = {Event::kStartElement, 231ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XML_GetCurrentLineNumber(parser->parser_), 232ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->depth_++}; 233d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski SplitName(name, &data.data1, &data.data2); 234ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 235ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski while (*attrs) { 236ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Attribute attribute; 237d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski SplitName(*attrs++, &attribute.namespace_uri, &attribute.name); 238ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski attribute.value = *attrs++; 239ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 240ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski // Insert in sorted order. 241ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski auto iter = std::lower_bound(data.attributes.begin(), data.attributes.end(), 242ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski attribute); 243ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski data.attributes.insert(iter, std::move(attribute)); 244ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 245ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 246ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski // Move the structure into the queue (no copy). 247ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->event_queue_.push(std::move(data)); 2486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 250ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid XMLCALL XmlPullParser::CharacterDataHandler(void* user_data, const char* s, 251ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski int len) { 252ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); 2536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 254d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski parser->event_queue_.push(EventData{Event::kText, XML_GetCurrentLineNumber(parser->parser_), 255d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski parser->depth_, std::string(s, len)}); 2566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 258ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid XMLCALL XmlPullParser::EndElementHandler(void* user_data, 259ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* name) { 260ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); 2616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 262ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski EventData data = {Event::kEndElement, 263ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XML_GetCurrentLineNumber(parser->parser_), 264ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski --(parser->depth_)}; 265d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski SplitName(name, &data.data1, &data.data2); 2666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 267ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski // Move the data into the queue (no copy). 268ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->event_queue_.push(std::move(data)); 2696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 271ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid XMLCALL XmlPullParser::EndNamespaceHandler(void* user_data, 272ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* prefix) { 273ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); 274ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 275ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->event_queue_.push( 276ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski EventData{Event::kEndNamespace, XML_GetCurrentLineNumber(parser->parser_), 277ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski --(parser->depth_), prefix != nullptr ? prefix : std::string(), 278ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->namespace_uris_.top()}); 279ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->namespace_uris_.pop(); 2806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 282ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid XMLCALL XmlPullParser::CommentDataHandler(void* user_data, 283ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* comment) { 284ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); 2856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 286ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->event_queue_.push(EventData{Event::kComment, 287ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XML_GetCurrentLineNumber(parser->parser_), 288ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski parser->depth_, comment}); 2896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 291ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiMaybe<StringPiece> FindAttribute(const XmlPullParser* parser, 292ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const StringPiece& name) { 293ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski auto iter = parser->FindAttribute("", name); 294ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (iter != parser->end_attributes()) { 295ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return StringPiece(util::TrimWhitespace(iter->value)); 296ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 297ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return {}; 298467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski} 299467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski 300ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiMaybe<StringPiece> FindNonEmptyAttribute(const XmlPullParser* parser, 301ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const StringPiece& name) { 302ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski auto iter = parser->FindAttribute("", name); 303ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (iter != parser->end_attributes()) { 304ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski StringPiece trimmed = util::TrimWhitespace(iter->value); 305ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!trimmed.empty()) { 306ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return trimmed; 307467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski } 308ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 309ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return {}; 310467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski} 311467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski 312ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski} // namespace xml 313ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski} // namespace aapt 314