317 lines
9.9 KiB
C++
317 lines
9.9 KiB
C++
/*
|
|
* 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_TABLE_H
|
|
#define AAPT_RESOURCE_TABLE_H
|
|
|
|
#include "ConfigDescription.h"
|
|
#include "Diagnostics.h"
|
|
#include "Resource.h"
|
|
#include "ResourceValues.h"
|
|
#include "Source.h"
|
|
#include "StringPool.h"
|
|
#include "io/File.h"
|
|
|
|
#include <android-base/macros.h>
|
|
#include <functional>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <tuple>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
namespace aapt {
|
|
|
|
enum class SymbolState {
|
|
kUndefined,
|
|
kPublic,
|
|
kPrivate
|
|
};
|
|
|
|
/**
|
|
* The Public status of a resource.
|
|
*/
|
|
struct Symbol {
|
|
SymbolState state = SymbolState::kUndefined;
|
|
Source source;
|
|
std::u16string comment;
|
|
};
|
|
|
|
class ResourceConfigValue {
|
|
public:
|
|
/**
|
|
* The configuration for which this value is defined.
|
|
*/
|
|
const ConfigDescription config;
|
|
|
|
/**
|
|
* The product for which this value is defined.
|
|
*/
|
|
const std::string product;
|
|
|
|
/**
|
|
* The actual Value.
|
|
*/
|
|
std::unique_ptr<Value> value;
|
|
|
|
ResourceConfigValue(const ConfigDescription& config, const StringPiece& product) :
|
|
config(config), product(product.toString()) { }
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue);
|
|
};
|
|
|
|
/**
|
|
* Represents a resource entry, which may have
|
|
* varying values for each defined configuration.
|
|
*/
|
|
class ResourceEntry {
|
|
public:
|
|
/**
|
|
* The name of the resource. Immutable, as
|
|
* this determines the order of this resource
|
|
* when doing lookups.
|
|
*/
|
|
const std::u16string name;
|
|
|
|
/**
|
|
* The entry ID for this resource.
|
|
*/
|
|
Maybe<uint16_t> id;
|
|
|
|
/**
|
|
* Whether this resource is public (and must maintain the same entry ID across builds).
|
|
*/
|
|
Symbol symbolStatus;
|
|
|
|
/**
|
|
* The resource's values for each configuration.
|
|
*/
|
|
std::vector<std::unique_ptr<ResourceConfigValue>> values;
|
|
|
|
explicit ResourceEntry(const StringPiece16& name) : name(name.toString()) { }
|
|
|
|
ResourceConfigValue* findValue(const ConfigDescription& config);
|
|
ResourceConfigValue* findValue(const ConfigDescription& config, const StringPiece& product);
|
|
ResourceConfigValue* findOrCreateValue(const ConfigDescription& config,
|
|
const StringPiece& product);
|
|
std::vector<ResourceConfigValue*> findAllValues(const ConfigDescription& config);
|
|
std::vector<ResourceConfigValue*> findValuesIf(
|
|
const std::function<bool(ResourceConfigValue*)>& f);
|
|
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(ResourceEntry);
|
|
};
|
|
|
|
/**
|
|
* Represents a resource type, which holds entries defined
|
|
* for this type.
|
|
*/
|
|
class ResourceTableType {
|
|
public:
|
|
/**
|
|
* The logical type of resource (string, drawable, layout, etc.).
|
|
*/
|
|
const ResourceType type;
|
|
|
|
/**
|
|
* The type ID for this resource.
|
|
*/
|
|
Maybe<uint8_t> id;
|
|
|
|
/**
|
|
* Whether this type is public (and must maintain the same
|
|
* type ID across builds).
|
|
*/
|
|
Symbol symbolStatus;
|
|
|
|
/**
|
|
* List of resources for this type.
|
|
*/
|
|
std::vector<std::unique_ptr<ResourceEntry>> entries;
|
|
|
|
explicit ResourceTableType(const ResourceType type) : type(type) { }
|
|
|
|
ResourceEntry* findEntry(const StringPiece16& name);
|
|
ResourceEntry* findOrCreateEntry(const StringPiece16& name);
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
|
|
};
|
|
|
|
enum class PackageType {
|
|
System,
|
|
Vendor,
|
|
App,
|
|
Dynamic
|
|
};
|
|
|
|
class ResourceTablePackage {
|
|
public:
|
|
PackageType type = PackageType::App;
|
|
Maybe<uint8_t> id;
|
|
std::u16string name;
|
|
|
|
std::vector<std::unique_ptr<ResourceTableType>> types;
|
|
|
|
ResourceTablePackage() = default;
|
|
ResourceTableType* findType(ResourceType type);
|
|
ResourceTableType* findOrCreateType(const ResourceType type);
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
|
|
};
|
|
|
|
/**
|
|
* The container and index for all resources defined for an app. This gets
|
|
* flattened into a binary resource table (resources.arsc).
|
|
*/
|
|
class ResourceTable {
|
|
public:
|
|
ResourceTable() = default;
|
|
|
|
/**
|
|
* When a collision of resources occurs, this method decides which value to keep.
|
|
* Returns -1 if the existing value should be chosen.
|
|
* Returns 0 if the collision can not be resolved (error).
|
|
* Returns 1 if the incoming value should be chosen.
|
|
*/
|
|
static int resolveValueCollision(Value* existing, Value* incoming);
|
|
|
|
bool addResource(const ResourceNameRef& name,
|
|
const ConfigDescription& config,
|
|
const StringPiece& product,
|
|
std::unique_ptr<Value> value,
|
|
IDiagnostics* diag);
|
|
|
|
bool addResource(const ResourceNameRef& name,
|
|
const ResourceId& resId,
|
|
const ConfigDescription& config,
|
|
const StringPiece& product,
|
|
std::unique_ptr<Value> value,
|
|
IDiagnostics* diag);
|
|
|
|
bool addFileReference(const ResourceNameRef& name,
|
|
const ConfigDescription& config,
|
|
const Source& source,
|
|
const StringPiece16& path,
|
|
IDiagnostics* diag);
|
|
|
|
bool addFileReferenceAllowMangled(const ResourceNameRef& name,
|
|
const ConfigDescription& config,
|
|
const Source& source,
|
|
const StringPiece16& path,
|
|
io::IFile* file,
|
|
IDiagnostics* diag);
|
|
|
|
/**
|
|
* Same as addResource, but doesn't verify the validity of the name. This is used
|
|
* when loading resources from an existing binary resource table that may have mangled
|
|
* names.
|
|
*/
|
|
bool addResourceAllowMangled(const ResourceNameRef& name,
|
|
const ConfigDescription& config,
|
|
const StringPiece& product,
|
|
std::unique_ptr<Value> value,
|
|
IDiagnostics* diag);
|
|
|
|
bool addResourceAllowMangled(const ResourceNameRef& name,
|
|
const ResourceId& id,
|
|
const ConfigDescription& config,
|
|
const StringPiece& product,
|
|
std::unique_ptr<Value> value,
|
|
IDiagnostics* diag);
|
|
|
|
bool setSymbolState(const ResourceNameRef& name,
|
|
const ResourceId& resId,
|
|
const Symbol& symbol,
|
|
IDiagnostics* diag);
|
|
|
|
bool setSymbolStateAllowMangled(const ResourceNameRef& name,
|
|
const ResourceId& resId,
|
|
const Symbol& symbol,
|
|
IDiagnostics* diag);
|
|
|
|
struct SearchResult {
|
|
ResourceTablePackage* package;
|
|
ResourceTableType* type;
|
|
ResourceEntry* entry;
|
|
};
|
|
|
|
Maybe<SearchResult> findResource(const ResourceNameRef& name);
|
|
|
|
/**
|
|
* The string pool used by this resource table. Values that reference strings must use
|
|
* this pool to create their strings.
|
|
*
|
|
* NOTE: `stringPool` must come before `packages` so that it is destroyed after.
|
|
* When `string pool` references are destroyed (as they will be when `packages`
|
|
* is destroyed), they decrement a refCount, which would cause invalid
|
|
* memory access if the pool was already destroyed.
|
|
*/
|
|
StringPool stringPool;
|
|
|
|
/**
|
|
* The list of packages in this table, sorted alphabetically by package name.
|
|
*/
|
|
std::vector<std::unique_ptr<ResourceTablePackage>> packages;
|
|
|
|
/**
|
|
* Returns the package struct with the given name, or nullptr if such a package does not
|
|
* exist. The empty string is a valid package and typically is used to represent the
|
|
* 'current' package before it is known to the ResourceTable.
|
|
*/
|
|
ResourceTablePackage* findPackage(const StringPiece16& name);
|
|
|
|
ResourceTablePackage* findPackageById(uint8_t id);
|
|
|
|
ResourceTablePackage* createPackage(const StringPiece16& name, Maybe<uint8_t> id = {});
|
|
|
|
private:
|
|
ResourceTablePackage* findOrCreatePackage(const StringPiece16& name);
|
|
|
|
bool addFileReferenceImpl(const ResourceNameRef& name,
|
|
const ConfigDescription& config,
|
|
const Source& source,
|
|
const StringPiece16& path,
|
|
io::IFile* file,
|
|
const char16_t* validChars,
|
|
IDiagnostics* diag);
|
|
|
|
bool addResourceImpl(const ResourceNameRef& name,
|
|
const ResourceId& resId,
|
|
const ConfigDescription& config,
|
|
const StringPiece& product,
|
|
std::unique_ptr<Value> value,
|
|
const char16_t* validChars,
|
|
std::function<int(Value*,Value*)> conflictResolver,
|
|
IDiagnostics* diag);
|
|
|
|
bool setSymbolStateImpl(const ResourceNameRef& name,
|
|
const ResourceId& resId,
|
|
const Symbol& symbol,
|
|
const char16_t* validChars,
|
|
IDiagnostics* diag);
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ResourceTable);
|
|
};
|
|
|
|
} // namespace aapt
|
|
|
|
#endif // AAPT_RESOURCE_TABLE_H
|