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