1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
/*
* 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_RESOURCE_PARSER_H
#define AAPT_RESOURCE_PARSER_H
#include "ConfigDescription.h"
#include "Logger.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "StringPiece.h"
#include "StringPool.h"
#include "XmlPullParser.h"
#include <istream>
#include <memory>
namespace aapt {
/*
* Parses an XML file for resources and adds them to a ResourceTable.
*/
class ResourceParser {
public:
/*
* Extracts the package, type, and name from a string of the format:
*
* [package:]type/name
*
* where the package can be empty. Validation must be performed on each
* individual extracted piece to verify that the pieces are valid.
*/
static void extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
StringPiece16* outType, StringPiece16* outEntry);
/*
* Returns true if the string was parsed as a reference (@[+][package:]type/name), with
* `outReference` set to the parsed reference.
*
* If '+' was present in the reference, `outCreate` is set to true.
* If '*' was present in the reference, `outPrivate` is set to true.
*/
static bool tryParseReference(const StringPiece16& str, ResourceNameRef* outReference,
bool* outCreate, bool* outPrivate);
/*
* Returns true if the string was parsed as an attribute reference (?[package:]type/name),
* with `outReference` set to the parsed reference.
*/
static bool tryParseAttributeReference(const StringPiece16& str,
ResourceNameRef* outReference);
/*
* Returns true if the string `str` was parsed as a valid reference to a style.
* The format for a style parent is slightly more flexible than a normal reference:
*
* @[package:]style/<entry> or
* ?[package:]style/<entry> or
* <package>:[style/]<entry>
*/
static bool parseStyleParentReference(const StringPiece16& str, Reference* outReference,
std::string* outError);
/*
* Returns a Reference object if the string was parsed as a resource or attribute reference,
* ( @[+][package:]type/name | ?[package:]type/name ) setting outCreate to true if
* the '+' was present in the string.
*/
static std::unique_ptr<Reference> tryParseReference(const StringPiece16& str,
bool* outCreate);
/*
* Returns a BinaryPrimitve object representing @null or @empty if the string was parsed
* as one.
*/
static std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece16& str);
/*
* Returns a BinaryPrimitve object representing a color if the string was parsed
* as one.
*/
static std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece16& str);
/*
* Returns a BinaryPrimitve object representing a boolean if the string was parsed
* as one.
*/
static std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece16& str);
/*
* Returns a BinaryPrimitve object representing an integer if the string was parsed
* as one.
*/
static std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece16& str);
/*
* Returns a BinaryPrimitve object representing a floating point number
* (float, dimension, etc) if the string was parsed as one.
*/
static std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece16& str);
/*
* Returns a BinaryPrimitve object representing an enum symbol if the string was parsed
* as one.
*/
static std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute& enumAttr,
const StringPiece16& str);
/*
* Returns a BinaryPrimitve object representing a flag symbol if the string was parsed
* as one.
*/
static std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute& enumAttr,
const StringPiece16& str);
/*
* Try to convert a string to an Item for the given attribute. The attribute will
* restrict what values the string can be converted to.
* The callback function onCreateReference is called when the parsed item is a
* reference to an ID that must be created (@+id/foo).
*/
static std::unique_ptr<Item> parseItemForAttribute(
const StringPiece16& value, const Attribute& attr,
std::function<void(const ResourceName&)> onCreateReference = {});
static std::unique_ptr<Item> parseItemForAttribute(
const StringPiece16& value, uint32_t typeMask,
std::function<void(const ResourceName&)> onCreateReference = {});
static uint32_t androidTypeToAttributeTypeMask(uint16_t type);
ResourceParser(const std::shared_ptr<ResourceTable>& table, const Source& source,
const ConfigDescription& config, const std::shared_ptr<XmlPullParser>& parser);
ResourceParser(const ResourceParser&) = delete; // No copy.
bool parse();
private:
/*
* Parses the XML subtree as a StyleString (flattened XML representation for strings
* with formatting). If successful, `outStyleString`
* contains the escaped and whitespace trimmed text, while `outRawString`
* contains the unescaped text. Returns true on success.
*/
bool flattenXmlSubtree(XmlPullParser* parser, std::u16string* outRawString,\
StyleString* outStyleString);
/*
* Parses the XML subtree and converts it to an Item. The type of Item that can be
* parsed is denoted by the `typeMask`. If `allowRawValue` is true and the subtree
* can not be parsed as a regular Item, then a RawString is returned. Otherwise
* this returns nullptr.
*/
std::unique_ptr<Item> parseXml(XmlPullParser* parser, uint32_t typeMask, bool allowRawValue);
bool parseResources(XmlPullParser* parser);
bool parseString(XmlPullParser* parser, const ResourceNameRef& resourceName);
bool parseColor(XmlPullParser* parser, const ResourceNameRef& resourceName);
bool parsePrimitive(XmlPullParser* parser, const ResourceNameRef& resourceName);
bool parsePublic(XmlPullParser* parser, const StringPiece16& name);
bool parseAttr(XmlPullParser* parser, const ResourceNameRef& resourceName);
std::unique_ptr<Attribute> parseAttrImpl(XmlPullParser* parser,
ResourceName* resourceName,
bool weak);
bool parseEnumOrFlagItem(XmlPullParser* parser, const StringPiece16& tag,
Attribute::Symbol* outSymbol);
bool parseStyle(XmlPullParser* parser, const ResourceNameRef& resourceName);
bool parseUntypedItem(XmlPullParser* parser, Style& style);
bool parseDeclareStyleable(XmlPullParser* parser, const ResourceNameRef& resourceName);
bool parseArray(XmlPullParser* parser, const ResourceNameRef& resourceName, uint32_t typeMask);
bool parsePlural(XmlPullParser* parser, const ResourceNameRef& resourceName);
std::shared_ptr<ResourceTable> mTable;
Source mSource;
ConfigDescription mConfig;
SourceLogger mLogger;
std::shared_ptr<XmlPullParser> mParser;
};
} // namespace aapt
#endif // AAPT_RESOURCE_PARSER_H
|