summaryrefslogtreecommitdiff
path: root/tools/aapt2/ResourceTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/ResourceTable.cpp')
-rw-r--r--tools/aapt2/ResourceTable.cpp94
1 files changed, 57 insertions, 37 deletions
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index f9707e41bb3d..bdc6a8c5d4f9 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -35,11 +35,11 @@ static bool lessThanType(const std::unique_ptr<ResourceTableType>& lhs, Resource
template <typename T>
static bool lessThanStructWithName(const std::unique_ptr<T>& lhs,
- const StringPiece16& rhs) {
+ const StringPiece& rhs) {
return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0;
}
-ResourceTablePackage* ResourceTable::findPackage(const StringPiece16& name) {
+ResourceTablePackage* ResourceTable::findPackage(const StringPiece& name) {
const auto last = packages.end();
auto iter = std::lower_bound(packages.begin(), last, name,
lessThanStructWithName<ResourceTablePackage>);
@@ -58,7 +58,7 @@ ResourceTablePackage* ResourceTable::findPackageById(uint8_t id) {
return nullptr;
}
-ResourceTablePackage* ResourceTable::createPackage(const StringPiece16& name, Maybe<uint8_t> id) {
+ResourceTablePackage* ResourceTable::createPackage(const StringPiece& name, Maybe<uint8_t> id) {
ResourceTablePackage* package = findOrCreatePackage(name);
if (id && !package->id) {
package->id = id;
@@ -71,7 +71,7 @@ ResourceTablePackage* ResourceTable::createPackage(const StringPiece16& name, Ma
return package;
}
-ResourceTablePackage* ResourceTable::findOrCreatePackage(const StringPiece16& name) {
+ResourceTablePackage* ResourceTable::findOrCreatePackage(const StringPiece& name) {
const auto last = packages.end();
auto iter = std::lower_bound(packages.begin(), last, name,
lessThanStructWithName<ResourceTablePackage>);
@@ -102,7 +102,7 @@ ResourceTableType* ResourceTablePackage::findOrCreateType(ResourceType type) {
return types.emplace(iter, new ResourceTableType(type))->get();
}
-ResourceEntry* ResourceTableType::findEntry(const StringPiece16& name) {
+ResourceEntry* ResourceTableType::findEntry(const StringPiece& name) {
const auto last = entries.end();
auto iter = std::lower_bound(entries.begin(), last, name,
lessThanStructWithName<ResourceEntry>);
@@ -112,7 +112,7 @@ ResourceEntry* ResourceTableType::findEntry(const StringPiece16& name) {
return nullptr;
}
-ResourceEntry* ResourceTableType::findOrCreateEntry(const StringPiece16& name) {
+ResourceEntry* ResourceTableType::findOrCreateEntry(const StringPiece& name) {
auto last = entries.end();
auto iter = std::lower_bound(entries.begin(), last, name,
lessThanStructWithName<ResourceEntry>);
@@ -201,36 +201,51 @@ std::vector<ResourceConfigValue*> ResourceEntry::findValuesIf(
}
/**
- * 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.
+ * The default handler for collisions.
+ *
+ * Typically, a weak value will be overridden by a strong value. An existing weak
+ * value will not be overridden by an incoming weak value.
+ *
+ * There are some exceptions:
+ *
+ * Attributes: There are two types of Attribute values: USE and DECL.
+ *
+ * USE is anywhere an Attribute is declared without a format, and in a place that would
+ * be legal to declare if the Attribute already existed. This is typically in a
+ * <declare-styleable> tag. Attributes defined in a <declare-styleable> are also weak.
+ *
+ * DECL is an absolute declaration of an Attribute and specifies an explicit format.
+ *
+ * A DECL will override a USE without error. Two DECLs must match in their format for there to be
+ * no error.
*/
-int ResourceTable::resolveValueCollision(Value* existing, Value* incoming) {
+ResourceTable::CollisionResult ResourceTable::resolveValueCollision(
+ Value* existing, Value* incoming) {
Attribute* existingAttr = valueCast<Attribute>(existing);
Attribute* incomingAttr = valueCast<Attribute>(incoming);
-
if (!incomingAttr) {
if (incoming->isWeak()) {
// We're trying to add a weak resource but a resource
// already exists. Keep the existing.
- return -1;
+ return CollisionResult::kKeepOriginal;
} else if (existing->isWeak()) {
// Override the weak resource with the new strong resource.
- return 1;
+ return CollisionResult::kTakeNew;
}
// The existing and incoming values are strong, this is an error
// if the values are not both attributes.
- return 0;
+ return CollisionResult::kConflict;
}
if (!existingAttr) {
if (existing->isWeak()) {
// The existing value is not an attribute and it is weak,
// so take the incoming attribute value.
- return 1;
+ return CollisionResult::kTakeNew;
}
// The existing value is not an attribute and it is strong,
// so the incoming attribute value is an error.
- return 0;
+ return CollisionResult::kConflict;
}
assert(incomingAttr && existingAttr);
@@ -245,24 +260,24 @@ int ResourceTable::resolveValueCollision(Value* existing, Value* incoming) {
// The two attributes are both DECLs, but they are plain attributes
// with the same formats.
// Keep the strongest one.
- return existingAttr->isWeak() ? 1 : -1;
+ return existingAttr->isWeak() ? CollisionResult::kTakeNew : CollisionResult::kKeepOriginal;
}
if (existingAttr->isWeak() && existingAttr->typeMask == android::ResTable_map::TYPE_ANY) {
// Any incoming attribute is better than this.
- return 1;
+ return CollisionResult::kTakeNew;
}
if (incomingAttr->isWeak() && incomingAttr->typeMask == android::ResTable_map::TYPE_ANY) {
// The incoming attribute may be a USE instead of a DECL.
// Keep the existing attribute.
- return -1;
+ return CollisionResult::kKeepOriginal;
}
- return 0;
+ return CollisionResult::kConflict;
}
-static constexpr const char16_t* kValidNameChars = u"._-";
-static constexpr const char16_t* kValidNameMangledChars = u"._-$";
+static constexpr const char* kValidNameChars = "._-";
+static constexpr const char* kValidNameMangledChars = "._-$";
bool ResourceTable::addResource(const ResourceNameRef& name,
const ConfigDescription& config,
@@ -286,7 +301,7 @@ bool ResourceTable::addResource(const ResourceNameRef& name,
bool ResourceTable::addFileReference(const ResourceNameRef& name,
const ConfigDescription& config,
const Source& source,
- const StringPiece16& path,
+ const StringPiece& path,
IDiagnostics* diag) {
return addFileReferenceImpl(name, config, source, path, nullptr, kValidNameChars, diag);
}
@@ -294,7 +309,7 @@ bool ResourceTable::addFileReference(const ResourceNameRef& name,
bool ResourceTable::addFileReferenceAllowMangled(const ResourceNameRef& name,
const ConfigDescription& config,
const Source& source,
- const StringPiece16& path,
+ const StringPiece& path,
io::IFile* file,
IDiagnostics* diag) {
return addFileReferenceImpl(name, config, source, path, file, kValidNameMangledChars, diag);
@@ -303,16 +318,16 @@ bool ResourceTable::addFileReferenceAllowMangled(const ResourceNameRef& name,
bool ResourceTable::addFileReferenceImpl(const ResourceNameRef& name,
const ConfigDescription& config,
const Source& source,
- const StringPiece16& path,
+ const StringPiece& path,
io::IFile* file,
- const char16_t* validChars,
+ const char* validChars,
IDiagnostics* diag) {
std::unique_ptr<FileReference> fileRef = util::make_unique<FileReference>(
stringPool.makeRef(path));
fileRef->setSource(source);
fileRef->file = file;
return addResourceImpl(name, ResourceId{}, config, StringPiece{}, std::move(fileRef),
- kValidNameChars, resolveValueCollision, diag);
+ validChars, resolveValueCollision, diag);
}
bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name,
@@ -339,8 +354,8 @@ bool ResourceTable::addResourceImpl(const ResourceNameRef& name,
const ConfigDescription& config,
const StringPiece& product,
std::unique_ptr<Value> value,
- const char16_t* validChars,
- std::function<int(Value*,Value*)> conflictResolver,
+ const char* validChars,
+ const CollisionResolverFunc& conflictResolver,
IDiagnostics* diag) {
assert(value && "value can't be nullptr");
assert(diag && "diagnostics can't be nullptr");
@@ -353,7 +368,7 @@ bool ResourceTable::addResourceImpl(const ResourceNameRef& name,
<< "' has invalid entry name '"
<< name.entry
<< "'. Invalid character '"
- << StringPiece16(badCharIter, 1)
+ << StringPiece(badCharIter, 1)
<< "'");
return false;
}
@@ -404,17 +419,22 @@ bool ResourceTable::addResourceImpl(const ResourceNameRef& name,
configValue->value = std::move(value);
} else {
- int collisionResult = conflictResolver(configValue->value.get(), value.get());
- if (collisionResult > 0) {
+ switch (conflictResolver(configValue->value.get(), value.get())) {
+ case CollisionResult::kTakeNew:
// Take the incoming value.
configValue->value = std::move(value);
- } else if (collisionResult == 0) {
+ break;
+
+ case CollisionResult::kConflict:
diag->error(DiagMessage(value->getSource())
- << "duplicate value for resource '" << name << "' "
- << "with config '" << config << "'");
+ << "duplicate value for resource '" << name << "' "
+ << "with config '" << config << "'");
diag->error(DiagMessage(configValue->value->getSource())
- << "resource previously defined here");
+ << "resource previously defined here");
return false;
+
+ case CollisionResult::kKeepOriginal:
+ break;
}
}
@@ -438,7 +458,7 @@ bool ResourceTable::setSymbolStateAllowMangled(const ResourceNameRef& name,
}
bool ResourceTable::setSymbolStateImpl(const ResourceNameRef& name, const ResourceId& resId,
- const Symbol& symbol, const char16_t* validChars,
+ const Symbol& symbol, const char* validChars,
IDiagnostics* diag) {
assert(diag && "diagnostics can't be nullptr");
@@ -450,7 +470,7 @@ bool ResourceTable::setSymbolStateImpl(const ResourceNameRef& name, const Resour
<< "' has invalid entry name '"
<< name.entry
<< "'. Invalid character '"
- << StringPiece16(badCharIter, 1)
+ << StringPiece(badCharIter, 1)
<< "'");
return false;
}