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 176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#ifndef AAPT_BINARY_RESOURCE_PARSER_H 186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#define AAPT_BINARY_RESOURCE_PARSER_H 196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 20ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <string> 21ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "android-base/macros.h" 23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "androidfw/ResourceTypes.h" 24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "ResourceTable.h" 266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "ResourceValues.h" 276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "Source.h" 281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "process/IResourceTableConsumer.h" 291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h" 301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt { 326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct SymbolTable_entry; 346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/* 366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Parses a binary resource table (resources.arsc) and adds the entries 376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * to a ResourceTable. This is different than the libandroidfw ResTable 386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * in that it scans the table from top to bottom and doesn't require 396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * support for random access. It is also able to parse non-runtime 406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * chunks and types. 416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiclass BinaryResourceParser { 43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski /* 45cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Creates a parser, which will read `len` bytes from `data`, and 46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * add any resources parsed to `table`. `source` is for logging purposes. 47cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski */ 48d0f492db038c6210c1138865d816bfb134376538Adam Lesinski BinaryResourceParser(IAaptContext* context, ResourceTable* table, const Source& source, 49d0f492db038c6210c1138865d816bfb134376538Adam Lesinski const void* data, size_t data_len, io::IFileCollection* files = nullptr); 50cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 51cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski /* 52cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Parses the binary resource table and returns true if successful. 53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski */ 54ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool Parse(); 55cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 56cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private: 57ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski DISALLOW_COPY_AND_ASSIGN(BinaryResourceParser); 58ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 59ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool ParseTable(const android::ResChunk_header* chunk); 60ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool ParsePackage(const android::ResChunk_header* chunk); 61ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool ParseTypeSpec(const android::ResChunk_header* chunk); 62ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool ParseType(const ResourceTablePackage* package, 63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const android::ResChunk_header* chunk); 64ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski bool ParseLibrary(const android::ResChunk_header* chunk); 65cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 66d0f492db038c6210c1138865d816bfb134376538Adam Lesinski std::unique_ptr<Item> ParseValue(const ResourceNameRef& name, const ConfigDescription& config, 67d0f492db038c6210c1138865d816bfb134376538Adam Lesinski const android::Res_value& value); 68cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 69ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<Value> ParseMapEntry(const ResourceNameRef& name, 70cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const ConfigDescription& config, 71cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const android::ResTable_map_entry* map); 72cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 73ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<Style> ParseStyle(const ResourceNameRef& name, 74cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const ConfigDescription& config, 75cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const android::ResTable_map_entry* map); 76cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 77ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<Attribute> ParseAttr(const ResourceNameRef& name, 78cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const ConfigDescription& config, 79cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const android::ResTable_map_entry* map); 80cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 81ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<Array> ParseArray(const ResourceNameRef& name, 82cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const ConfigDescription& config, 83cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const android::ResTable_map_entry* map); 84cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 85ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<Plural> ParsePlural(const ResourceNameRef& name, 86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const ConfigDescription& config, 87e78fd617ec60139a973a01925fa7adad31febb39Adam Lesinski const android::ResTable_map_entry* map); 886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 89cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski /** 90cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * If the mapEntry is a special type that denotes meta data (source, comment), 91cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * then it is 92cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * read and added to the Value. 93cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Returns true if the mapEntry was meta data. 94cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski */ 95ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool CollectMetaData(const android::ResTable_map& map_entry, Value* value); 966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 97ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski IAaptContext* context_; 98ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ResourceTable* table_; 99769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski 100ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const Source source_; 1016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 102ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const void* data_; 103ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const size_t data_len_; 104d0f492db038c6210c1138865d816bfb134376538Adam Lesinski 105d0f492db038c6210c1138865d816bfb134376538Adam Lesinski // Optional file collection from which to create io::IFile objects. 106d0f492db038c6210c1138865d816bfb134376538Adam Lesinski io::IFileCollection* files_; 1076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 108cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // The standard value string pool for resource values. 109ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski android::ResStringPool value_pool_; 1106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 111cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // The string pool that holds the names of the types defined 112cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // in this table. 113ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski android::ResStringPool type_pool_; 1146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 115cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // The string pool that holds the names of the entries defined 116cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // in this table. 117ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski android::ResStringPool key_pool_; 1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 119cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // A mapping of resource ID to resource name. When we finish parsing 120cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // we use this to convert all resource IDs to symbolic references. 121ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::map<ResourceId, ResourceName> id_index_; 1226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}; 1236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 124cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace aapt 1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace android { 1276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 1296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Iterator functionality for ResTable_map_entry. 1306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 1316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline const ResTable_map* begin(const ResTable_map_entry* map) { 133cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return (const ResTable_map*)((const uint8_t*)map + 134ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski aapt::util::DeviceToHost32(map->size)); 1356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline const ResTable_map* end(const ResTable_map_entry* map) { 138ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return begin(map) + aapt::util::DeviceToHost32(map->count); 1396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace android 1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 143cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif // AAPT_BINARY_RESOURCE_PARSER_H 144