1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "AppInfo.h" 18 #include "Logger.h" 19 #include "ManifestParser.h" 20 #include "Source.h" 21 #include "XmlPullParser.h" 22 23 #include <string> 24 25 namespace aapt { 26 27 bool ManifestParser::parse(const Source& source, std::shared_ptr<XmlPullParser> parser, 28 AppInfo* outInfo) { 29 SourceLogger logger = { source }; 30 31 int depth = 0; 32 while (XmlPullParser::isGoodEvent(parser->next())) { 33 XmlPullParser::Event event = parser->getEvent(); 34 if (event == XmlPullParser::Event::kEndElement) { 35 depth--; 36 continue; 37 } else if (event != XmlPullParser::Event::kStartElement) { 38 continue; 39 } 40 41 depth++; 42 43 const std::u16string& element = parser->getElementName(); 44 if (depth == 1) { 45 if (element == u"manifest") { 46 if (!parseManifest(logger, parser, outInfo)) { 47 return false; 48 } 49 } else { 50 logger.error() 51 << "unexpected top-level element '" 52 << element 53 << "'." 54 << std::endl; 55 return false; 56 } 57 } else { 58 XmlPullParser::skipCurrentElement(parser.get()); 59 } 60 } 61 62 if (parser->getEvent() == XmlPullParser::Event::kBadDocument) { 63 logger.error(parser->getLineNumber()) 64 << "failed to parse manifest: " 65 << parser->getLastError() 66 << "." 67 << std::endl; 68 return false; 69 } 70 return true; 71 } 72 73 bool ManifestParser::parseManifest(SourceLogger& logger, std::shared_ptr<XmlPullParser> parser, 74 AppInfo* outInfo) { 75 auto attrIter = parser->findAttribute(u"", u"package"); 76 if (attrIter == parser->endAttributes() || attrIter->value.empty()) { 77 logger.error() << "no 'package' attribute found for element <manifest>." << std::endl; 78 return false; 79 } 80 outInfo->package = attrIter->value; 81 return true; 82 } 83 84 } // namespace aapt 85