diff options
author | David Chaloupka <chaloupka@google.com> | 2018-01-18 13:44:36 +0000 |
---|---|---|
committer | David Chaloupka <chaloupka@google.com> | 2018-01-18 19:20:01 +0000 |
commit | e3c1a4a9d21e7698e9e5196086198569ac5cc6cd (patch) | |
tree | e26d206ea6ea40e0d670f6daf14fce0e894130e5 /tools/aapt2/ResourceTable.cpp | |
parent | 588a06f5a25adad63337ac481f9e1b55dcc169a1 (diff) |
Handle multiple packages of same name in 'aapt2 convert'
aapt2 currently looks-up packages only by package name and then verifies
whether the package ID has the expected value. For pre-L we need to be able
to handle resource tables having packages of same package name but
different IDs.
Note that this CL fixes only proto->binary conversion but many other aapt2
commands are still affected. This is because many transformations still
consider package name as sufficient identifier of a package.
Bug: 72143207
Test: Manual
Change-Id: Id8a920d6cd15bec747d3124270f5bcb7f48924cf
Diffstat (limited to 'tools/aapt2/ResourceTable.cpp')
-rw-r--r-- | tools/aapt2/ResourceTable.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp index 9905f827d663..95bf9210ba97 100644 --- a/tools/aapt2/ResourceTable.cpp +++ b/tools/aapt2/ResourceTable.cpp @@ -47,6 +47,13 @@ static bool less_than_struct_with_name(const std::unique_ptr<T>& lhs, const Stri return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0; } +template <typename T> +static bool less_than_struct_with_name_and_id(const std::unique_ptr<T>& lhs, + const std::pair<StringPiece, Maybe<uint8_t>>& rhs) { + int name_cmp = lhs->name.compare(0, lhs->name.size(), rhs.first.data(), rhs.first.size()); + return name_cmp < 0 || (name_cmp == 0 && lhs->id < rhs.second); +} + ResourceTablePackage* ResourceTable::FindPackage(const StringPiece& name) const { const auto last = packages.end(); auto iter = std::lower_bound(packages.begin(), last, name, @@ -79,6 +86,22 @@ ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name, Mayb return package; } +ResourceTablePackage* ResourceTable::CreatePackageAllowingDuplicateNames(const StringPiece& name, + const Maybe<uint8_t> id) { + const auto last = packages.end(); + auto iter = std::lower_bound(packages.begin(), last, std::make_pair(name, id), + less_than_struct_with_name_and_id<ResourceTablePackage>); + + if (iter != last && name == (*iter)->name && id == (*iter)->id) { + return iter->get(); + } + + std::unique_ptr<ResourceTablePackage> new_package = util::make_unique<ResourceTablePackage>(); + new_package->name = name.to_string(); + new_package->id = id; + return packages.emplace(iter, std::move(new_package))->get(); +} + ResourceTablePackage* ResourceTable::FindOrCreatePackage(const StringPiece& name) { const auto last = packages.end(); auto iter = std::lower_bound(packages.begin(), last, name, |