diff options
Diffstat (limited to 'cmds/idmap2/libidmap2/Idmap.cpp')
-rw-r--r-- | cmds/idmap2/libidmap2/Idmap.cpp | 91 |
1 files changed, 51 insertions, 40 deletions
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 5a47e301b66c..5822745a95c3 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -33,29 +33,38 @@ #include "idmap2/Idmap.h" #include "idmap2/ResourceUtils.h" +#include "idmap2/Result.h" #include "idmap2/ZipFile.h" namespace android { namespace idmap2 { +namespace { + #define EXTRACT_TYPE(resid) ((0x00ff0000 & (resid)) >> 16) #define EXTRACT_ENTRY(resid) (0x0000ffff & (resid)) -struct MatchingResources { +class MatchingResources { + public: void Add(ResourceId target_resid, ResourceId overlay_resid) { TypeId target_typeid = EXTRACT_TYPE(target_resid); - if (map.find(target_typeid) == map.end()) { - map.emplace(target_typeid, std::set<std::pair<ResourceId, ResourceId>>()); + if (map_.find(target_typeid) == map_.end()) { + map_.emplace(target_typeid, std::set<std::pair<ResourceId, ResourceId>>()); } - map[target_typeid].insert(std::make_pair(target_resid, overlay_resid)); + map_[target_typeid].insert(std::make_pair(target_resid, overlay_resid)); + } + + inline const std::map<TypeId, std::set<std::pair<ResourceId, ResourceId>>>& Map() const { + return map_; } + private: // target type id -> set { pair { overlay entry id, overlay entry id } } - std::map<TypeId, std::set<std::pair<ResourceId, ResourceId>>> map; + std::map<TypeId, std::set<std::pair<ResourceId, ResourceId>>> map_; }; -static bool WARN_UNUSED Read16(std::istream& stream, uint16_t* out) { +bool WARN_UNUSED Read16(std::istream& stream, uint16_t* out) { uint16_t value; if (stream.read(reinterpret_cast<char*>(&value), sizeof(uint16_t))) { *out = dtohl(value); @@ -64,7 +73,7 @@ static bool WARN_UNUSED Read16(std::istream& stream, uint16_t* out) { return false; } -static bool WARN_UNUSED Read32(std::istream& stream, uint32_t* out) { +bool WARN_UNUSED Read32(std::istream& stream, uint32_t* out) { uint32_t value; if (stream.read(reinterpret_cast<char*>(&value), sizeof(uint32_t))) { *out = dtohl(value); @@ -74,7 +83,7 @@ static bool WARN_UNUSED Read32(std::istream& stream, uint32_t* out) { } // a string is encoded as a kIdmapStringLength char array; the array is always null-terminated -static bool WARN_UNUSED ReadString(std::istream& stream, char out[kIdmapStringLength]) { +bool WARN_UNUSED ReadString(std::istream& stream, char out[kIdmapStringLength]) { char buf[kIdmapStringLength]; memset(buf, 0, sizeof(buf)); if (!stream.read(buf, sizeof(buf))) { @@ -87,7 +96,7 @@ static bool WARN_UNUSED ReadString(std::istream& stream, char out[kIdmapStringLe return true; } -static ResourceId NameToResid(const AssetManager2& am, const std::string& name) { +ResourceId NameToResid(const AssetManager2& am, const std::string& name) { return am.GetResourceId(name); } @@ -100,7 +109,7 @@ static ResourceId NameToResid(const AssetManager2& am, const std::string& name) // relying on a hard-coded index. This however requires storing the package name in the idmap // header, which in turn requires incrementing the idmap version. Because the initial version of // idmap2 is compatible with idmap, this will have to wait for now. -static const LoadedPackage* GetPackageAtIndex0(const LoadedArsc& loaded_arsc) { +const LoadedPackage* GetPackageAtIndex0(const LoadedArsc& loaded_arsc) { const std::vector<std::unique_ptr<const LoadedPackage>>& packages = loaded_arsc.GetPackages(); if (packages.empty()) { return nullptr; @@ -109,6 +118,8 @@ static const LoadedPackage* GetPackageAtIndex0(const LoadedArsc& loaded_arsc) { return loaded_arsc.GetPackageById(id); } +} // namespace + std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) { std::unique_ptr<IdmapHeader> idmap_header(new IdmapHeader()); @@ -143,18 +154,16 @@ bool IdmapHeader::IsUpToDate(std::ostream& out_error) const { return false; } - bool status; - uint32_t target_crc; - std::tie(status, target_crc) = target_zip->Crc("resources.arsc"); - if (!status) { + Result<uint32_t> target_crc = target_zip->Crc("resources.arsc"); + if (!target_crc) { out_error << "error: failed to get target crc" << std::endl; return false; } - if (target_crc_ != target_crc) { + if (target_crc_ != *target_crc) { out_error << base::StringPrintf( "error: bad target crc: idmap version 0x%08x, file system version 0x%08x", - target_crc_, target_crc) + target_crc_, *target_crc) << std::endl; return false; } @@ -165,17 +174,16 @@ bool IdmapHeader::IsUpToDate(std::ostream& out_error) const { return false; } - uint32_t overlay_crc; - std::tie(status, overlay_crc) = overlay_zip->Crc("resources.arsc"); - if (!status) { + Result<uint32_t> overlay_crc = overlay_zip->Crc("resources.arsc"); + if (!overlay_crc) { out_error << "error: failed to get overlay crc" << std::endl; return false; } - if (overlay_crc_ != overlay_crc) { + if (overlay_crc_ != *overlay_crc) { out_error << base::StringPrintf( "error: bad overlay crc: idmap version 0x%08x, file system version 0x%08x", - overlay_crc_, overlay_crc) + overlay_crc_, *overlay_crc) << std::endl; return false; } @@ -198,8 +206,9 @@ std::unique_ptr<const IdmapData::Header> IdmapData::Header::FromBinaryStream(std std::unique_ptr<const IdmapData::TypeEntry> IdmapData::TypeEntry::FromBinaryStream( std::istream& stream) { std::unique_ptr<IdmapData::TypeEntry> data(new IdmapData::TypeEntry()); - - uint16_t target_type16, overlay_type16, entry_count; + uint16_t target_type16; + uint16_t overlay_type16; + uint16_t entry_count; if (!Read16(stream, &target_type16) || !Read16(stream, &overlay_type16) || !Read16(stream, &entry_count) || !Read16(stream, &data->entry_offset_)) { return nullptr; @@ -284,25 +293,25 @@ std::unique_ptr<const Idmap> Idmap::FromApkAssets(const std::string& target_apk_ } const LoadedArsc* target_arsc = target_apk_assets.GetLoadedArsc(); - if (!target_arsc) { + if (target_arsc == nullptr) { out_error << "error: failed to load target resources.arsc" << std::endl; return nullptr; } const LoadedArsc* overlay_arsc = overlay_apk_assets.GetLoadedArsc(); - if (!overlay_arsc) { + if (overlay_arsc == nullptr) { out_error << "error: failed to load overlay resources.arsc" << std::endl; return nullptr; } const LoadedPackage* target_pkg = GetPackageAtIndex0(*target_arsc); - if (!target_pkg) { + if (target_pkg == nullptr) { out_error << "error: failed to load target package from resources.arsc" << std::endl; return nullptr; } const LoadedPackage* overlay_pkg = GetPackageAtIndex0(*overlay_arsc); - if (!overlay_pkg) { + if (overlay_pkg == nullptr) { out_error << "error: failed to load overlay package from resources.arsc" << std::endl; return nullptr; } @@ -322,17 +331,20 @@ std::unique_ptr<const Idmap> Idmap::FromApkAssets(const std::string& target_apk_ std::unique_ptr<IdmapHeader> header(new IdmapHeader()); header->magic_ = kIdmapMagic; header->version_ = kIdmapCurrentVersion; - bool crc_status; - std::tie(crc_status, header->target_crc_) = target_zip->Crc("resources.arsc"); - if (!crc_status) { + + Result<uint32_t> crc = target_zip->Crc("resources.arsc"); + if (!crc) { out_error << "error: failed to get zip crc for target" << std::endl; return nullptr; } - std::tie(crc_status, header->overlay_crc_) = overlay_zip->Crc("resources.arsc"); - if (!crc_status) { + header->target_crc_ = *crc; + + crc = overlay_zip->Crc("resources.arsc"); + if (!crc) { out_error << "error: failed to get zip crc for overlay" << std::endl; return nullptr; } + header->overlay_crc_ = *crc; if (target_apk_path.size() > sizeof(header->target_path_)) { out_error << "error: target apk path \"" << target_apk_path << "\" longer that maximum size " @@ -358,15 +370,14 @@ std::unique_ptr<const Idmap> Idmap::FromApkAssets(const std::string& target_apk_ const auto end = overlay_pkg->end(); for (auto iter = overlay_pkg->begin(); iter != end; ++iter) { const ResourceId overlay_resid = *iter; - bool lookup_ok; - std::string name; - std::tie(lookup_ok, name) = utils::ResToTypeEntryName(overlay_asset_manager, overlay_resid); - if (!lookup_ok) { + Result<std::string> name = utils::ResToTypeEntryName(overlay_asset_manager, overlay_resid); + if (!name) { continue; } // prepend "<package>:" to turn name into "<package>:<type>/<name>" - name = base::StringPrintf("%s:%s", target_pkg->GetPackageName().c_str(), name.c_str()); - const ResourceId target_resid = NameToResid(target_asset_manager, name); + const std::string full_name = + base::StringPrintf("%s:%s", target_pkg->GetPackageName().c_str(), name->c_str()); + const ResourceId target_resid = NameToResid(target_asset_manager, full_name); if (target_resid == 0) { continue; } @@ -375,8 +386,8 @@ std::unique_ptr<const Idmap> Idmap::FromApkAssets(const std::string& target_apk_ // encode idmap data std::unique_ptr<IdmapData> data(new IdmapData()); - const auto types_end = matching_resources.map.cend(); - for (auto ti = matching_resources.map.cbegin(); ti != types_end; ++ti) { + const auto types_end = matching_resources.Map().cend(); + for (auto ti = matching_resources.Map().cbegin(); ti != types_end; ++ti) { auto ei = ti->second.cbegin(); std::unique_ptr<IdmapData::TypeEntry> type(new IdmapData::TypeEntry()); type->target_type_id_ = EXTRACT_TYPE(ei->first); |