diff options
author | 2016-02-13 06:28:06 +0000 | |
---|---|---|
committer | 2016-02-13 06:28:06 +0000 | |
commit | 923e6342fbf40fb3d6d5fe02ae4821e58e43ff52 (patch) | |
tree | 3df3c693d5e62563f96ab431260c37c57db2d551 /tools/aapt2/ResourceTable.cpp | |
parent | f4ff39c92be840d5f53c42cb02cef6b03a1ca70f (diff) | |
parent | e4bb9eb5af5b0899dc0921d5580220b20e15bd5a (diff) |
Merge "AAPT2: Introduce notion of 'product' to ResourceTable" into nyc-dev
Diffstat (limited to 'tools/aapt2/ResourceTable.cpp')
-rw-r--r-- | tools/aapt2/ResourceTable.cpp | 128 |
1 files changed, 103 insertions, 25 deletions
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp index 8a3d047f6e8d..3e73be4dbc54 100644 --- a/tools/aapt2/ResourceTable.cpp +++ b/tools/aapt2/ResourceTable.cpp @@ -19,8 +19,6 @@ #include "ResourceTable.h" #include "ResourceValues.h" #include "ValueVisitor.h" - -#include "util/Comparators.h" #include "util/Util.h" #include <algorithm> @@ -124,6 +122,73 @@ ResourceEntry* ResourceTableType::findOrCreateEntry(const StringPiece16& name) { return entries.emplace(iter, new ResourceEntry(name))->get(); } +ResourceConfigValue* ResourceEntry::findValue(const ConfigDescription& config) { + return findValue(config, StringPiece()); +} + +struct ConfigKey { + const ConfigDescription* config; + const StringPiece& product; +}; + +bool ltConfigKeyRef(const std::unique_ptr<ResourceConfigValue>& lhs, const ConfigKey& rhs) { + int cmp = lhs->config.compare(*rhs.config); + if (cmp == 0) { + cmp = StringPiece(lhs->product).compare(rhs.product); + } + return cmp < 0; +} + +ResourceConfigValue* ResourceEntry::findValue(const ConfigDescription& config, + const StringPiece& product) { + auto iter = std::lower_bound(values.begin(), values.end(), + ConfigKey{ &config, product }, ltConfigKeyRef); + if (iter != values.end()) { + ResourceConfigValue* value = iter->get(); + if (value->config == config && StringPiece(value->product) == product) { + return value; + } + } + return nullptr; +} + +ResourceConfigValue* ResourceEntry::findOrCreateValue(const ConfigDescription& config, + const StringPiece& product) { + auto iter = std::lower_bound(values.begin(), values.end(), + ConfigKey{ &config, product }, ltConfigKeyRef); + if (iter != values.end()) { + ResourceConfigValue* value = iter->get(); + if (value->config == config && StringPiece(value->product) == product) { + return value; + } + } + ResourceConfigValue* newValue = values.insert( + iter, util::make_unique<ResourceConfigValue>(config, product))->get(); + return newValue; +} + +std::vector<ResourceConfigValue*> ResourceEntry::findAllValues(const ConfigDescription& config) { + std::vector<ResourceConfigValue*> results; + + auto iter = values.begin(); + for (; iter != values.end(); ++iter) { + ResourceConfigValue* value = iter->get(); + if (value->config == config) { + results.push_back(value); + ++iter; + break; + } + } + + for (; iter != values.end(); ++iter) { + ResourceConfigValue* value = iter->get(); + if (value->config == config) { + results.push_back(value); + } + } + return results; +} + /** * The default handler for collisions. A return value of -1 means keep the * existing value, 0 means fail, and +1 means take the incoming value. @@ -188,56 +253,69 @@ int ResourceTable::resolveValueCollision(Value* existing, Value* incoming) { static constexpr const char16_t* kValidNameChars = u"._-"; static constexpr const char16_t* kValidNameMangledChars = u"._-$"; -bool ResourceTable::addResource(const ResourceNameRef& name, const ConfigDescription& config, - std::unique_ptr<Value> value, IDiagnostics* diag) { - return addResourceImpl(name, {}, config, std::move(value), kValidNameChars, +bool ResourceTable::addResource(const ResourceNameRef& name, + const ConfigDescription& config, + const StringPiece& product, + std::unique_ptr<Value> value, + IDiagnostics* diag) { + return addResourceImpl(name, {}, config, product, std::move(value), kValidNameChars, resolveValueCollision, diag); } -bool ResourceTable::addResource(const ResourceNameRef& name, const ResourceId resId, - const ConfigDescription& config, std::unique_ptr<Value> value, +bool ResourceTable::addResource(const ResourceNameRef& name, + const ResourceId resId, + const ConfigDescription& config, + const StringPiece& product, + std::unique_ptr<Value> value, IDiagnostics* diag) { - return addResourceImpl(name, resId, config, std::move(value), kValidNameChars, + return addResourceImpl(name, resId, config, product, std::move(value), kValidNameChars, resolveValueCollision, diag); } -bool ResourceTable::addFileReference(const ResourceNameRef& name, const ConfigDescription& config, - const Source& source, const StringPiece16& path, +bool ResourceTable::addFileReference(const ResourceNameRef& name, + const ConfigDescription& config, + const Source& source, + const StringPiece16& path, IDiagnostics* diag) { return addFileReference(name, config, source, path, resolveValueCollision, diag); } -bool ResourceTable::addFileReference(const ResourceNameRef& name, const ConfigDescription& config, - const Source& source, const StringPiece16& path, +bool ResourceTable::addFileReference(const ResourceNameRef& name, + const ConfigDescription& config, + const Source& source, + const StringPiece16& path, std::function<int(Value*,Value*)> conflictResolver, IDiagnostics* diag) { std::unique_ptr<FileReference> fileRef = util::make_unique<FileReference>( stringPool.makeRef(path)); fileRef->setSource(source); - return addResourceImpl(name, ResourceId{}, config, std::move(fileRef), kValidNameChars, - conflictResolver, diag); + return addResourceImpl(name, ResourceId{}, config, StringPiece{}, std::move(fileRef), + kValidNameChars, conflictResolver, diag); } bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config, + const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag) { - return addResourceImpl(name, ResourceId{}, config, std::move(value), kValidNameMangledChars, - resolveValueCollision, diag); + return addResourceImpl(name, ResourceId{}, config, product, std::move(value), + kValidNameMangledChars, resolveValueCollision, diag); } bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name, const ResourceId id, const ConfigDescription& config, + const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag) { - return addResourceImpl(name, id, config, std::move(value), kValidNameMangledChars, + return addResourceImpl(name, id, config, product, std::move(value), kValidNameMangledChars, resolveValueCollision, diag); } bool ResourceTable::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, @@ -298,21 +376,21 @@ bool ResourceTable::addResourceImpl(const ResourceNameRef& name, return false; } - const auto endIter = entry->values.end(); - auto iter = std::lower_bound(entry->values.begin(), endIter, config, cmp::lessThanConfig); - if (iter == endIter || iter->config != config) { - // This resource did not exist before, add it. - entry->values.insert(iter, ResourceConfigValue{ config, std::move(value) }); + ResourceConfigValue* configValue = entry->findOrCreateValue(config, product); + if (!configValue->value) { + // Resource does not exist, add it now. + configValue->value = std::move(value); + } else { - int collisionResult = conflictResolver(iter->value.get(), value.get()); + int collisionResult = conflictResolver(configValue->value.get(), value.get()); if (collisionResult > 0) { // Take the incoming value. - iter->value = std::move(value); + configValue->value = std::move(value); } else if (collisionResult == 0) { diag->error(DiagMessage(value->getSource()) << "duplicate value for resource '" << name << "' " << "with config '" << config << "'"); - diag->error(DiagMessage(iter->value->getSource()) + diag->error(DiagMessage(configValue->value->getSource()) << "resource previously defined here"); return false; } |