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_FORMAT_BINARY_RESOURCEPARSER_H 18 #define AAPT_FORMAT_BINARY_RESOURCEPARSER_H 19 20 #include <string> 21 22 #include "android-base/macros.h" 23 #include "androidfw/ConfigDescription.h" 24 #include "androidfw/ResourceTypes.h" 25 26 #include "ResourceTable.h" 27 #include "ResourceValues.h" 28 #include "Source.h" 29 #include "process/IResourceTableConsumer.h" 30 #include "util/Util.h" 31 32 namespace aapt { 33 34 struct SymbolTable_entry; 35 36 // Parses a binary resource table (resources.arsc) and adds the entries to a ResourceTable. 37 // This is different than the libandroidfw ResTable in that it scans the table from top to bottom 38 // and doesn't require support for random access. 39 class BinaryResourceParser { 40 public: 41 // Creates a parser, which will read `len` bytes from `data`, and add any resources parsed to 42 // `table`. `source` is for logging purposes. 43 BinaryResourceParser(IDiagnostics* diag, ResourceTable* table, const Source& source, 44 const void* data, size_t data_len, io::IFileCollection* files = nullptr); 45 46 // Parses the binary resource table and returns true if successful. 47 bool Parse(); 48 49 private: 50 DISALLOW_COPY_AND_ASSIGN(BinaryResourceParser); 51 52 bool ParseTable(const android::ResChunk_header* chunk); 53 bool ParsePackage(const android::ResChunk_header* chunk); 54 bool ParseTypeSpec(const ResourceTablePackage* package, const android::ResChunk_header* chunk); 55 bool ParseType(const ResourceTablePackage* package, const android::ResChunk_header* chunk); 56 bool ParseLibrary(const android::ResChunk_header* chunk); 57 bool ParseOverlayable(const android::ResChunk_header* chunk); 58 59 std::unique_ptr<Item> ParseValue(const ResourceNameRef& name, 60 const android::ConfigDescription& config, 61 const android::Res_value& value); 62 63 std::unique_ptr<Value> ParseMapEntry(const ResourceNameRef& name, 64 const android::ConfigDescription& config, 65 const android::ResTable_map_entry* map); 66 67 std::unique_ptr<Style> ParseStyle(const ResourceNameRef& name, 68 const android::ConfigDescription& config, 69 const android::ResTable_map_entry* map); 70 71 std::unique_ptr<Attribute> ParseAttr(const ResourceNameRef& name, 72 const android::ConfigDescription& config, 73 const android::ResTable_map_entry* map); 74 75 std::unique_ptr<Array> ParseArray(const ResourceNameRef& name, 76 const android::ConfigDescription& config, 77 const android::ResTable_map_entry* map); 78 79 std::unique_ptr<Plural> ParsePlural(const ResourceNameRef& name, 80 const android::ConfigDescription& config, 81 const android::ResTable_map_entry* map); 82 83 /** 84 * If the mapEntry is a special type that denotes meta data (source, comment), 85 * then it is 86 * read and added to the Value. 87 * Returns true if the mapEntry was meta data. 88 */ 89 bool CollectMetaData(const android::ResTable_map& map_entry, Value* value); 90 91 IDiagnostics* diag_; 92 ResourceTable* table_; 93 94 const Source source_; 95 96 const void* data_; 97 const size_t data_len_; 98 99 // Optional file collection from which to create io::IFile objects. 100 io::IFileCollection* files_; 101 102 // The standard value string pool for resource values. 103 android::ResStringPool value_pool_; 104 105 // The string pool that holds the names of the types defined 106 // in this table. 107 android::ResStringPool type_pool_; 108 109 // The string pool that holds the names of the entries defined 110 // in this table. 111 android::ResStringPool key_pool_; 112 113 // A mapping of resource ID to resource name. When we finish parsing 114 // we use this to convert all resource IDs to symbolic references. 115 std::map<ResourceId, ResourceName> id_index_; 116 117 // A mapping of resource ID to type spec flags. 118 std::unordered_map<ResourceId, uint32_t> entry_type_spec_flags_; 119 }; 120 121 } // namespace aapt 122 123 namespace android { 124 125 // Iterator functionality for ResTable_map_entry. 126 127 inline const ResTable_map* begin(const ResTable_map_entry* map) { 128 return (const ResTable_map*)((const uint8_t*)map + ::aapt::util::DeviceToHost32(map->size)); 129 } 130 131 inline const ResTable_map* end(const ResTable_map_entry* map) { 132 return begin(map) + aapt::util::DeviceToHost32(map->count); 133 } 134 135 } // namespace android 136 137 #endif // AAPT_FORMAT_BINARY_RESOURCEPARSER_H 138