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