diff options
author | 2016-10-21 17:56:45 -0700 | |
---|---|---|
committer | 2016-10-26 19:30:23 -0700 | |
commit | ce5e56e243d262a9b65459c3bd0bb9eaadd40628 (patch) | |
tree | cf0ecea98883d090d8d2856fc6d32046c7e3d9e8 | |
parent | 0f7cc4dc2c49a30c072cbc7aa6c0c5d5c31496d4 (diff) |
AAPT2: Rename to match new style
Use Google3 naming style to match new
projects' and open source google projects' style.
Preferred to do this in a massive CL so as to avoid
style inconsistencies that plague legacy code bases.
This is a relatively NEW code base, may as well keep
it up to date.
Test: name/style refactor - existing tests pass
Change-Id: Ie80ecb78d46ec53efdfca2336bb57d96cbb7fb87
181 files changed, 13858 insertions, 13334 deletions
diff --git a/cmds/idmap/inspect.cpp b/cmds/idmap/inspect.cpp index f6afc8594309..154cb25a02a1 100644 --- a/cmds/idmap/inspect.cpp +++ b/cmds/idmap/inspect.cpp @@ -2,6 +2,7 @@ #include <androidfw/AssetManager.h> #include <androidfw/ResourceTypes.h> +#include <utils/ByteOrder.h> #include <utils/String8.h> #include <fcntl.h> diff --git a/include/androidfw/Asset.h b/include/androidfw/Asset.h index 52c863774efb..11709ce5f91b 100644 --- a/include/androidfw/Asset.h +++ b/include/androidfw/Asset.h @@ -26,11 +26,12 @@ #include <utils/Compat.h> #include <utils/Errors.h> -#include <utils/FileMap.h> #include <utils/String8.h> namespace android { +class FileMap; + /* * Instances of this class provide read-only operations on a byte stream. * diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h index 6349e86dae94..08d6591e6886 100644 --- a/include/androidfw/ResourceTypes.h +++ b/include/androidfw/ResourceTypes.h @@ -22,7 +22,6 @@ #include <androidfw/Asset.h> #include <androidfw/LocaleData.h> -#include <utils/ByteOrder.h> #include <utils/Errors.h> #include <utils/String16.h> #include <utils/Vector.h> diff --git a/include/androidfw/TypeWrappers.h b/include/androidfw/TypeWrappers.h index 7bdf8af0ad4c..4233b6bbee83 100644 --- a/include/androidfw/TypeWrappers.h +++ b/include/androidfw/TypeWrappers.h @@ -18,6 +18,7 @@ #define __TYPE_WRAPPERS_H #include <androidfw/ResourceTypes.h> +#include <utils/ByteOrder.h> namespace android { diff --git a/tools/aapt2/.clang-format b/tools/aapt2/.clang-format index 71c5ef2fcda0..545366a9b70b 100644 --- a/tools/aapt2/.clang-format +++ b/tools/aapt2/.clang-format @@ -1,3 +1,2 @@ BasedOnStyle: Google -ColumnLimit: 100 diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk index 284c7877d054..197884dcf85c 100644 --- a/tools/aapt2/Android.mk +++ b/tools/aapt2/Android.mk @@ -158,7 +158,7 @@ hostStaticLibs_windows := libz hostLdLibs_linux := -lz hostLdLibs_darwin := -lz -cFlags := -Wall -Werror -Wno-unused-parameter -UNDEBUG +cFlags := -Wall -Werror -Wno-unused-parameter cFlags_darwin := -D_DARWIN_UNLIMITED_STREAMS cFlags_windows := -Wno-maybe-uninitialized # Incorrectly marking use of Maybe.value() as error. cppFlags := -Wno-missing-field-initializers -fno-exceptions -fno-rtti diff --git a/tools/aapt2/AppInfo.h b/tools/aapt2/AppInfo.h index 2cbe11797440..1e488f70bd4d 100644 --- a/tools/aapt2/AppInfo.h +++ b/tools/aapt2/AppInfo.h @@ -17,10 +17,10 @@ #ifndef AAPT_APP_INFO_H #define AAPT_APP_INFO_H -#include "util/Maybe.h" - #include <string> +#include "util/Maybe.h" + namespace aapt { /** @@ -36,17 +36,17 @@ struct AppInfo { /** * The App's minimum SDK version. */ - Maybe<std::string> minSdkVersion; + Maybe<std::string> min_sdk_version; /** * The Version code of the app. */ - Maybe<uint32_t> versionCode; + Maybe<uint32_t> version_code; /** * The revision code of the app. */ - Maybe<uint32_t> revisionCode; + Maybe<uint32_t> revision_code; }; } // namespace aapt diff --git a/tools/aapt2/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp index 6598d6388200..289919a39373 100644 --- a/tools/aapt2/ConfigDescription.cpp +++ b/tools/aapt2/ConfigDescription.cpp @@ -15,22 +15,24 @@ */ #include "ConfigDescription.h" + +#include <string> +#include <vector> + +#include "androidfw/ResourceTypes.h" + #include "Locale.h" #include "SdkConstants.h" #include "util/StringPiece.h" #include "util/Util.h" -#include <androidfw/ResourceTypes.h> -#include <string> -#include <vector> - namespace aapt { using android::ResTable_config; static const char* kWildcardName = "any"; -const ConfigDescription& ConfigDescription::defaultConfig() { +const ConfigDescription& ConfigDescription::DefaultConfig() { static ConfigDescription config = {}; return config; } @@ -589,169 +591,169 @@ static bool parseVersion(const char* name, ResTable_config* out) { return true; } -bool ConfigDescription::parse(const StringPiece& str, ConfigDescription* out) { - std::vector<std::string> parts = util::splitAndLowercase(str, '-'); +bool ConfigDescription::Parse(const StringPiece& str, ConfigDescription* out) { + std::vector<std::string> parts = util::SplitAndLowercase(str, '-'); ConfigDescription config; - ssize_t partsConsumed = 0; + ssize_t parts_consumed = 0; LocaleValue locale; - const auto partsEnd = parts.end(); - auto partIter = parts.begin(); + const auto parts_end = parts.end(); + auto part_iter = parts.begin(); if (str.size() == 0) { goto success; } - if (parseMcc(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseMcc(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseMnc(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseMnc(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } // Locale spans a few '-' separators, so we let it // control the index. - partsConsumed = locale.initFromParts(partIter, partsEnd); - if (partsConsumed < 0) { + parts_consumed = locale.InitFromParts(part_iter, parts_end); + if (parts_consumed < 0) { return false; } else { - locale.writeTo(&config); - partIter += partsConsumed; - if (partIter == partsEnd) { + locale.WriteTo(&config); + part_iter += parts_consumed; + if (part_iter == parts_end) { goto success; } } - if (parseLayoutDirection(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseLayoutDirection(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseSmallestScreenWidthDp(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseSmallestScreenWidthDp(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseScreenWidthDp(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseScreenWidthDp(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseScreenHeightDp(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseScreenHeightDp(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseScreenLayoutSize(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseScreenLayoutSize(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseScreenLayoutLong(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseScreenLayoutLong(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseScreenRound(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseScreenRound(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseOrientation(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseOrientation(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseUiModeType(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseUiModeType(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseUiModeNight(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseUiModeNight(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseDensity(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseDensity(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseTouchscreen(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseTouchscreen(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseKeysHidden(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseKeysHidden(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseKeyboard(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseKeyboard(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseNavHidden(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseNavHidden(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseNavigation(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseNavigation(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseScreenSize(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseScreenSize(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } - if (parseVersion(partIter->c_str(), &config)) { - ++partIter; - if (partIter == partsEnd) { + if (parseVersion(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { goto success; } } @@ -761,57 +763,57 @@ bool ConfigDescription::parse(const StringPiece& str, ConfigDescription* out) { success: if (out != NULL) { - applyVersionForCompatibility(&config); + ApplyVersionForCompatibility(&config); *out = config; } return true; } -void ConfigDescription::applyVersionForCompatibility( +void ConfigDescription::ApplyVersionForCompatibility( ConfigDescription* config) { - uint16_t minSdk = 0; + uint16_t min_sdk = 0; if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) { - minSdk = SDK_MARSHMALLOW; + min_sdk = SDK_MARSHMALLOW; } else if (config->density == ResTable_config::DENSITY_ANY) { - minSdk = SDK_LOLLIPOP; + min_sdk = SDK_LOLLIPOP; } else if (config->smallestScreenWidthDp != ResTable_config::SCREENWIDTH_ANY || config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY || config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) { - minSdk = SDK_HONEYCOMB_MR2; + min_sdk = SDK_HONEYCOMB_MR2; } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) != ResTable_config::UI_MODE_TYPE_ANY || (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT) != ResTable_config::UI_MODE_NIGHT_ANY) { - minSdk = SDK_FROYO; + min_sdk = SDK_FROYO; } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE) != ResTable_config::SCREENSIZE_ANY || (config->screenLayout & ResTable_config::MASK_SCREENLONG) != ResTable_config::SCREENLONG_ANY || config->density != ResTable_config::DENSITY_DEFAULT) { - minSdk = SDK_DONUT; + min_sdk = SDK_DONUT; } - if (minSdk > config->sdkVersion) { - config->sdkVersion = minSdk; + if (min_sdk > config->sdkVersion) { + config->sdkVersion = min_sdk; } } -ConfigDescription ConfigDescription::copyWithoutSdkVersion() const { +ConfigDescription ConfigDescription::CopyWithoutSdkVersion() const { ConfigDescription copy = *this; copy.sdkVersion = 0; return copy; } -bool ConfigDescription::dominates(const ConfigDescription& o) const { - if (*this == defaultConfig() || *this == o) { +bool ConfigDescription::Dominates(const ConfigDescription& o) const { + if (*this == DefaultConfig() || *this == o) { return true; } - return matchWithDensity(o) && !o.matchWithDensity(*this) && - !isMoreSpecificThan(o) && !o.hasHigherPrecedenceThan(*this); + return MatchWithDensity(o) && !o.MatchWithDensity(*this) && + !isMoreSpecificThan(o) && !o.HasHigherPrecedenceThan(*this); } -bool ConfigDescription::hasHigherPrecedenceThan( +bool ConfigDescription::HasHigherPrecedenceThan( const ConfigDescription& o) const { // The order of the following tests defines the importance of one // configuration parameter over another. Those tests first are more @@ -866,7 +868,7 @@ bool ConfigDescription::hasHigherPrecedenceThan( return *this != o; } -bool ConfigDescription::conflictsWith(const ConfigDescription& o) const { +bool ConfigDescription::ConflictsWith(const ConfigDescription& o) const { // This method should be updated as new configuration parameters are // introduced (e.g. screenConfig2). auto pred = [](const uint32_t a, const uint32_t b) -> bool { @@ -892,8 +894,8 @@ bool ConfigDescription::conflictsWith(const ConfigDescription& o) const { !pred(keyboard, o.keyboard) || !pred(navigation, o.navigation); } -bool ConfigDescription::isCompatibleWith(const ConfigDescription& o) const { - return !conflictsWith(o) && !dominates(o) && !o.dominates(*this); +bool ConfigDescription::IsCompatibleWith(const ConfigDescription& o) const { + return !ConflictsWith(o) && !Dominates(o) && !o.Dominates(*this); } } // namespace aapt diff --git a/tools/aapt2/ConfigDescription.h b/tools/aapt2/ConfigDescription.h index bb5488673975..97d0f38a5af1 100644 --- a/tools/aapt2/ConfigDescription.h +++ b/tools/aapt2/ConfigDescription.h @@ -17,11 +17,12 @@ #ifndef AAPT_CONFIG_DESCRIPTION_H #define AAPT_CONFIG_DESCRIPTION_H -#include "util/StringPiece.h" - -#include <androidfw/ResourceTypes.h> #include <ostream> +#include "androidfw/ResourceTypes.h" + +#include "util/StringPiece.h" + namespace aapt { /* @@ -32,7 +33,7 @@ struct ConfigDescription : public android::ResTable_config { /** * Returns an immutable default config. */ - static const ConfigDescription& defaultConfig(); + static const ConfigDescription& DefaultConfig(); /* * Parse a string of the form 'fr-sw600dp-land' and fill in the @@ -41,14 +42,14 @@ struct ConfigDescription : public android::ResTable_config { * The resulting configuration has the appropriate sdkVersion defined * for backwards compatibility. */ - static bool parse(const StringPiece& str, ConfigDescription* out = nullptr); + static bool Parse(const StringPiece& str, ConfigDescription* out = nullptr); /** * If the configuration uses an axis that was added after * the original Android release, make sure the SDK version * is set accordingly. */ - static void applyVersionForCompatibility(ConfigDescription* config); + static void ApplyVersionForCompatibility(ConfigDescription* config); ConfigDescription(); ConfigDescription(const android::ResTable_config& o); // NOLINT(implicit) @@ -59,7 +60,7 @@ struct ConfigDescription : public android::ResTable_config { ConfigDescription& operator=(const ConfigDescription& o); ConfigDescription& operator=(ConfigDescription&& o); - ConfigDescription copyWithoutSdkVersion() const; + ConfigDescription CopyWithoutSdkVersion() const; /** * A configuration X dominates another configuration Y, if X has at least the @@ -70,14 +71,14 @@ struct ConfigDescription : public android::ResTable_config { * For example, the configuration 'en-w800dp' dominates 'en-rGB-w1024dp'. It * does not dominate 'fr', 'en-w720dp', or 'mcc001-en-w800dp'. */ - bool dominates(const ConfigDescription& o) const; + bool Dominates(const ConfigDescription& o) const; /** * Returns true if this configuration defines a more important configuration * parameter than o. For example, "en" has higher precedence than "v23", * whereas "en" has the same precedence as "en-v23". */ - bool hasHigherPrecedenceThan(const ConfigDescription& o) const; + bool HasHigherPrecedenceThan(const ConfigDescription& o) const; /** * A configuration conflicts with another configuration if both @@ -85,7 +86,7 @@ struct ConfigDescription : public android::ResTable_config { * incompatible configuration parameter is a non-range, non-density parameter * that is defined in both configurations as a different, non-default value. */ - bool conflictsWith(const ConfigDescription& o) const; + bool ConflictsWith(const ConfigDescription& o) const; /** * A configuration is compatible with another configuration if both @@ -93,9 +94,9 @@ struct ConfigDescription : public android::ResTable_config { * unrelated by domination. For example, land-v11 conflicts with port-v21 * but is compatible with v21 (both land-v11 and v21 would match en-land-v23). */ - bool isCompatibleWith(const ConfigDescription& o) const; + bool IsCompatibleWith(const ConfigDescription& o) const; - bool matchWithDensity(const ConfigDescription& o) const; + bool MatchWithDensity(const ConfigDescription& o) const; bool operator<(const ConfigDescription& o) const; bool operator<=(const ConfigDescription& o) const; @@ -141,7 +142,7 @@ inline ConfigDescription& ConfigDescription::operator=(ConfigDescription&& o) { return *this; } -inline bool ConfigDescription::matchWithDensity( +inline bool ConfigDescription::MatchWithDensity( const ConfigDescription& o) const { return match(o) && (density == 0 || density == o.density); } diff --git a/tools/aapt2/ConfigDescription_test.cpp b/tools/aapt2/ConfigDescription_test.cpp index 66b7d4776118..c331dc0f6909 100644 --- a/tools/aapt2/ConfigDescription_test.cpp +++ b/tools/aapt2/ConfigDescription_test.cpp @@ -15,17 +15,18 @@ */ #include "ConfigDescription.h" + +#include <string> + #include "SdkConstants.h" #include "test/Test.h" #include "util/StringPiece.h" -#include <string> - namespace aapt { static ::testing::AssertionResult TestParse( const StringPiece& input, ConfigDescription* config = nullptr) { - if (ConfigDescription::parse(input, config)) { + if (ConfigDescription::Parse(input, config)) { return ::testing::AssertionSuccess() << input << " was successfully parsed"; } return ::testing::AssertionFailure() << input << " could not be parsed"; diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp index 965db9ebc9c8..60b01e372d7b 100644 --- a/tools/aapt2/Debug.cpp +++ b/tools/aapt2/Debug.cpp @@ -15,10 +15,6 @@ */ #include "Debug.h" -#include "ResourceTable.h" -#include "ResourceValues.h" -#include "ValueVisitor.h" -#include "util/Util.h" #include <algorithm> #include <iostream> @@ -28,18 +24,25 @@ #include <set> #include <vector> +#include "android-base/logging.h" + +#include "ResourceTable.h" +#include "ResourceValues.h" +#include "ValueVisitor.h" +#include "util/Util.h" + namespace aapt { class PrintVisitor : public ValueVisitor { public: - using ValueVisitor::visit; + using ValueVisitor::Visit; - void visit(Attribute* attr) override { + void Visit(Attribute* attr) override { std::cout << "(attr) type="; - attr->printMask(&std::cout); + attr->PrintMask(&std::cout); static constexpr uint32_t kMask = android::ResTable_map::TYPE_ENUM | android::ResTable_map::TYPE_FLAGS; - if (attr->typeMask & kMask) { + if (attr->type_mask & kMask) { for (const auto& symbol : attr->symbols) { std::cout << "\n " << symbol.symbol.name.value().entry; if (symbol.symbol.id) { @@ -50,20 +53,20 @@ class PrintVisitor : public ValueVisitor { } } - void visit(Style* style) override { + void Visit(Style* style) override { std::cout << "(style)"; if (style->parent) { - const Reference& parentRef = style->parent.value(); + const Reference& parent_ref = style->parent.value(); std::cout << " parent="; - if (parentRef.name) { - if (parentRef.privateReference) { + if (parent_ref.name) { + if (parent_ref.private_reference) { std::cout << "*"; } - std::cout << parentRef.name.value() << " "; + std::cout << parent_ref.name.value() << " "; } - if (parentRef.id) { - std::cout << parentRef.id.value(); + if (parent_ref.id) { + std::cout << parent_ref.id.value(); } } @@ -85,11 +88,11 @@ class PrintVisitor : public ValueVisitor { } } - void visit(Array* array) override { array->print(&std::cout); } + void Visit(Array* array) override { array->Print(&std::cout); } - void visit(Plural* plural) override { plural->print(&std::cout); } + void Visit(Plural* plural) override { plural->Print(&std::cout); } - void visit(Styleable* styleable) override { + void Visit(Styleable* styleable) override { std::cout << "(styleable)"; for (const auto& attr : styleable->entries) { std::cout << "\n "; @@ -107,10 +110,10 @@ class PrintVisitor : public ValueVisitor { } } - void visitItem(Item* item) override { item->print(&std::cout); } + void VisitItem(Item* item) override { item->Print(&std::cout); } }; -void Debug::printTable(ResourceTable* table, +void Debug::PrintTable(ResourceTable* table, const DebugPrintTableOptions& options) { PrintVisitor visitor; @@ -128,10 +131,10 @@ void Debug::printTable(ResourceTable* table, } std::cout << " entryCount=" << type->entries.size() << std::endl; - std::vector<const ResourceEntry*> sortedEntries; + std::vector<const ResourceEntry*> sorted_entries; for (const auto& entry : type->entries) { auto iter = std::lower_bound( - sortedEntries.begin(), sortedEntries.end(), entry.get(), + sorted_entries.begin(), sorted_entries.end(), entry.get(), [](const ResourceEntry* a, const ResourceEntry* b) -> bool { if (a->id && b->id) { return a->id.value() < b->id.value(); @@ -141,17 +144,17 @@ void Debug::printTable(ResourceTable* table, return false; } }); - sortedEntries.insert(iter, entry.get()); + sorted_entries.insert(iter, entry.get()); } - for (const ResourceEntry* entry : sortedEntries) { + for (const ResourceEntry* entry : sorted_entries) { ResourceId id(package->id ? package->id.value() : uint8_t(0), type->id ? type->id.value() : uint8_t(0), entry->id ? entry->id.value() : uint16_t(0)); ResourceName name(package->name, type->type, entry->name); std::cout << " spec resource " << id << " " << name; - switch (entry->symbolStatus.state) { + switch (entry->symbol_status.state) { case SymbolState::kPublic: std::cout << " PUBLIC"; break; @@ -166,9 +169,9 @@ void Debug::printTable(ResourceTable* table, for (const auto& value : entry->values) { std::cout << " (" << value->config << ") "; - value->value->accept(&visitor); - if (options.showSources && !value->value->getSource().path.empty()) { - std::cout << " src=" << value->value->getSource(); + value->value->Accept(&visitor); + if (options.show_sources && !value->value->GetSource().path.empty()) { + std::cout << " src=" << value->value->GetSource(); } std::cout << std::endl; } @@ -177,35 +180,36 @@ void Debug::printTable(ResourceTable* table, } } -static size_t getNodeIndex(const std::vector<ResourceName>& names, +static size_t GetNodeIndex(const std::vector<ResourceName>& names, const ResourceName& name) { auto iter = std::lower_bound(names.begin(), names.end(), name); - assert(iter != names.end() && *iter == name); + CHECK(iter != names.end()); + CHECK(*iter == name); return std::distance(names.begin(), iter); } -void Debug::printStyleGraph(ResourceTable* table, - const ResourceName& targetStyle) { +void Debug::PrintStyleGraph(ResourceTable* table, + const ResourceName& target_style) { std::map<ResourceName, std::set<ResourceName>> graph; - std::queue<ResourceName> stylesToVisit; - stylesToVisit.push(targetStyle); - for (; !stylesToVisit.empty(); stylesToVisit.pop()) { - const ResourceName& styleName = stylesToVisit.front(); - std::set<ResourceName>& parents = graph[styleName]; + std::queue<ResourceName> styles_to_visit; + styles_to_visit.push(target_style); + for (; !styles_to_visit.empty(); styles_to_visit.pop()) { + const ResourceName& style_name = styles_to_visit.front(); + std::set<ResourceName>& parents = graph[style_name]; if (!parents.empty()) { // We've already visited this style. continue; } - Maybe<ResourceTable::SearchResult> result = table->findResource(styleName); + Maybe<ResourceTable::SearchResult> result = table->FindResource(style_name); if (result) { ResourceEntry* entry = result.value().entry; for (const auto& value : entry->values) { - if (Style* style = valueCast<Style>(value->value.get())) { + if (Style* style = ValueCast<Style>(value->value.get())) { if (style->parent && style->parent.value().name) { parents.insert(style->parent.value().name.value()); - stylesToVisit.push(style->parent.value().name.value()); + styles_to_visit.push(style->parent.value().name.value()); } } } @@ -219,24 +223,24 @@ void Debug::printStyleGraph(ResourceTable* table, std::cout << "digraph styles {\n"; for (const auto& name : names) { - std::cout << " node_" << getNodeIndex(names, name) << " [label=\"" << name + std::cout << " node_" << GetNodeIndex(names, name) << " [label=\"" << name << "\"];\n"; } for (const auto& entry : graph) { - const ResourceName& styleName = entry.first; - size_t styleNodeIndex = getNodeIndex(names, styleName); + const ResourceName& style_name = entry.first; + size_t style_node_index = GetNodeIndex(names, style_name); - for (const auto& parentName : entry.second) { - std::cout << " node_" << styleNodeIndex << " -> " - << "node_" << getNodeIndex(names, parentName) << ";\n"; + for (const auto& parent_name : entry.second) { + std::cout << " node_" << style_node_index << " -> " + << "node_" << GetNodeIndex(names, parent_name) << ";\n"; } } std::cout << "}" << std::endl; } -void Debug::dumpHex(const void* data, size_t len) { +void Debug::DumpHex(const void* data, size_t len) { const uint8_t* d = (const uint8_t*)data; for (size_t i = 0; i < len; i++) { std::cerr << std::hex << std::setfill('0') << std::setw(2) << (uint32_t)d[i] @@ -255,55 +259,55 @@ namespace { class XmlPrinter : public xml::Visitor { public: - using xml::Visitor::visit; + using xml::Visitor::Visit; - void visit(xml::Element* el) override { - std::cerr << mPrefix; + void Visit(xml::Element* el) override { + std::cerr << prefix_; std::cerr << "E: "; - if (!el->namespaceUri.empty()) { - std::cerr << el->namespaceUri << ":"; + if (!el->namespace_uri.empty()) { + std::cerr << el->namespace_uri << ":"; } - std::cerr << el->name << " (line=" << el->lineNumber << ")\n"; + std::cerr << el->name << " (line=" << el->line_number << ")\n"; for (const xml::Attribute& attr : el->attributes) { - std::cerr << mPrefix << " A: "; - if (!attr.namespaceUri.empty()) { - std::cerr << attr.namespaceUri << ":"; + std::cerr << prefix_ << " A: "; + if (!attr.namespace_uri.empty()) { + std::cerr << attr.namespace_uri << ":"; } std::cerr << attr.name << "=" << attr.value << "\n"; } - const size_t previousSize = mPrefix.size(); - mPrefix += " "; - xml::Visitor::visit(el); - mPrefix.resize(previousSize); + const size_t previous_size = prefix_.size(); + prefix_ += " "; + xml::Visitor::Visit(el); + prefix_.resize(previous_size); } - void visit(xml::Namespace* ns) override { - std::cerr << mPrefix; - std::cerr << "N: " << ns->namespacePrefix << "=" << ns->namespaceUri - << " (line=" << ns->lineNumber << ")\n"; + void Visit(xml::Namespace* ns) override { + std::cerr << prefix_; + std::cerr << "N: " << ns->namespace_prefix << "=" << ns->namespace_uri + << " (line=" << ns->line_number << ")\n"; - const size_t previousSize = mPrefix.size(); - mPrefix += " "; - xml::Visitor::visit(ns); - mPrefix.resize(previousSize); + const size_t previous_size = prefix_.size(); + prefix_ += " "; + xml::Visitor::Visit(ns); + prefix_.resize(previous_size); } - void visit(xml::Text* text) override { - std::cerr << mPrefix; + void Visit(xml::Text* text) override { + std::cerr << prefix_; std::cerr << "T: '" << text->text << "'\n"; } private: - std::string mPrefix; + std::string prefix_; }; } // namespace -void Debug::dumpXml(xml::XmlResource* doc) { +void Debug::DumpXml(xml::XmlResource* doc) { XmlPrinter printer; - doc->root->accept(&printer); + doc->root->Accept(&printer); } } // namespace aapt diff --git a/tools/aapt2/Debug.h b/tools/aapt2/Debug.h index bd92ec17d71a..56e2e95df6cb 100644 --- a/tools/aapt2/Debug.h +++ b/tools/aapt2/Debug.h @@ -17,26 +17,26 @@ #ifndef AAPT_DEBUG_H #define AAPT_DEBUG_H +// Include for printf-like debugging. +#include <iostream> + #include "Resource.h" #include "ResourceTable.h" #include "xml/XmlDom.h" -// Include for printf-like debugging. -#include <iostream> - namespace aapt { struct DebugPrintTableOptions { - bool showSources = false; + bool show_sources = false; }; struct Debug { - static void printTable(ResourceTable* table, + static void PrintTable(ResourceTable* table, const DebugPrintTableOptions& options = {}); - static void printStyleGraph(ResourceTable* table, - const ResourceName& targetStyle); - static void dumpHex(const void* data, size_t len); - static void dumpXml(xml::XmlResource* doc); + static void PrintStyleGraph(ResourceTable* table, + const ResourceName& target_style); + static void DumpHex(const void* data, size_t len); + static void DumpXml(xml::XmlResource* doc); }; } // namespace aapt diff --git a/tools/aapt2/Diagnostics.h b/tools/aapt2/Diagnostics.h index d39cf4c35976..5bc86a9fdbaf 100644 --- a/tools/aapt2/Diagnostics.h +++ b/tools/aapt2/Diagnostics.h @@ -17,15 +17,16 @@ #ifndef AAPT_DIAGNOSTICS_H #define AAPT_DIAGNOSTICS_H -#include "Source.h" -#include "util/StringPiece.h" -#include "util/Util.h" - -#include <android-base/macros.h> #include <iostream> #include <sstream> #include <string> +#include "android-base/macros.h" + +#include "Source.h" +#include "util/StringPiece.h" +#include "util/Util.h" + namespace aapt { struct DiagMessageActual { @@ -34,28 +35,28 @@ struct DiagMessageActual { }; struct DiagMessage { - private: - Source mSource; - std::stringstream mMessage; - public: DiagMessage() = default; - explicit DiagMessage(const StringPiece& src) : mSource(src) {} + explicit DiagMessage(const StringPiece& src) : source_(src) {} - explicit DiagMessage(const Source& src) : mSource(src) {} + explicit DiagMessage(const Source& src) : source_(src) {} - explicit DiagMessage(size_t line) : mSource(Source().withLine(line)) {} + explicit DiagMessage(size_t line) : source_(Source().WithLine(line)) {} template <typename T> DiagMessage& operator<<(const T& value) { - mMessage << value; + message_ << value; return *this; } - DiagMessageActual build() const { - return DiagMessageActual{mSource, mMessage.str()}; + DiagMessageActual Build() const { + return DiagMessageActual{source_, message_.str()}; } + + private: + Source source_; + std::stringstream message_; }; struct IDiagnostics { @@ -63,21 +64,21 @@ struct IDiagnostics { enum class Level { Note, Warn, Error }; - virtual void log(Level level, DiagMessageActual& actualMsg) = 0; + virtual void Log(Level level, DiagMessageActual& actualMsg) = 0; - virtual void error(const DiagMessage& message) { - DiagMessageActual actual = message.build(); - log(Level::Error, actual); + virtual void Error(const DiagMessage& message) { + DiagMessageActual actual = message.Build(); + Log(Level::Error, actual); } - virtual void warn(const DiagMessage& message) { - DiagMessageActual actual = message.build(); - log(Level::Warn, actual); + virtual void Warn(const DiagMessage& message) { + DiagMessageActual actual = message.Build(); + Log(Level::Warn, actual); } - virtual void note(const DiagMessage& message) { - DiagMessageActual actual = message.build(); - log(Level::Note, actual); + virtual void Note(const DiagMessage& message) { + DiagMessageActual actual = message.Build(); + Log(Level::Note, actual); } }; @@ -85,13 +86,13 @@ class StdErrDiagnostics : public IDiagnostics { public: StdErrDiagnostics() = default; - void log(Level level, DiagMessageActual& actualMsg) override { + void Log(Level level, DiagMessageActual& actual_msg) override { const char* tag; switch (level) { case Level::Error: - mNumErrors++; - if (mNumErrors > 20) { + num_errors_++; + if (num_errors_ > 20) { return; } tag = "error"; @@ -106,14 +107,14 @@ class StdErrDiagnostics : public IDiagnostics { break; } - if (!actualMsg.source.path.empty()) { - std::cerr << actualMsg.source << ": "; + if (!actual_msg.source.path.empty()) { + std::cerr << actual_msg.source << ": "; } - std::cerr << tag << ": " << actualMsg.message << "." << std::endl; + std::cerr << tag << ": " << actual_msg.message << "." << std::endl; } private: - size_t mNumErrors = 0; + size_t num_errors_ = 0; DISALLOW_COPY_AND_ASSIGN(StdErrDiagnostics); }; @@ -121,16 +122,16 @@ class StdErrDiagnostics : public IDiagnostics { class SourcePathDiagnostics : public IDiagnostics { public: SourcePathDiagnostics(const Source& src, IDiagnostics* diag) - : mSource(src), mDiag(diag) {} + : source_(src), diag_(diag) {} - void log(Level level, DiagMessageActual& actualMsg) override { - actualMsg.source.path = mSource.path; - mDiag->log(level, actualMsg); + void Log(Level level, DiagMessageActual& actual_msg) override { + actual_msg.source.path = source_.path; + diag_->Log(level, actual_msg); } private: - Source mSource; - IDiagnostics* mDiag; + Source source_; + IDiagnostics* diag_; DISALLOW_COPY_AND_ASSIGN(SourcePathDiagnostics); }; diff --git a/tools/aapt2/DominatorTree.cpp b/tools/aapt2/DominatorTree.cpp index 8f6f78327559..118a385e2253 100644 --- a/tools/aapt2/DominatorTree.cpp +++ b/tools/aapt2/DominatorTree.cpp @@ -15,77 +15,80 @@ */ #include "DominatorTree.h" -#include "ConfigDescription.h" #include <algorithm> +#include "android-base/logging.h" + +#include "ConfigDescription.h" + namespace aapt { DominatorTree::DominatorTree( const std::vector<std::unique_ptr<ResourceConfigValue>>& configs) { for (const auto& config : configs) { - mProductRoots[config->product].tryAddChild( + product_roots_[config->product].TryAddChild( util::make_unique<Node>(config.get(), nullptr)); } } -void DominatorTree::accept(Visitor* visitor) { - for (auto& entry : mProductRoots) { - visitor->visitTree(entry.first, &entry.second); +void DominatorTree::Accept(Visitor* visitor) { + for (auto& entry : product_roots_) { + visitor->VisitTree(entry.first, &entry.second); } } -bool DominatorTree::Node::tryAddChild(std::unique_ptr<Node> newChild) { - assert(newChild->mValue && "cannot add a root or empty node as a child"); - if (mValue && !dominates(newChild.get())) { +bool DominatorTree::Node::TryAddChild(std::unique_ptr<Node> new_child) { + CHECK(new_child->value_) << "cannot add a root or empty node as a child"; + if (value_ && !Dominates(new_child.get())) { // This is not the root and the child dominates us. return false; } - return addChild(std::move(newChild)); + return AddChild(std::move(new_child)); } -bool DominatorTree::Node::addChild(std::unique_ptr<Node> newChild) { - bool hasDominatedChildren = false; +bool DominatorTree::Node::AddChild(std::unique_ptr<Node> new_child) { + bool has_dominated_children = false; // Demote children dominated by the new config. - for (auto& child : mChildren) { - if (newChild->dominates(child.get())) { - child->mParent = newChild.get(); - newChild->mChildren.push_back(std::move(child)); + for (auto& child : children_) { + if (new_child->Dominates(child.get())) { + child->parent_ = new_child.get(); + new_child->children_.push_back(std::move(child)); child = {}; - hasDominatedChildren = true; + has_dominated_children = true; } } // Remove dominated children. - if (hasDominatedChildren) { - mChildren.erase( - std::remove_if(mChildren.begin(), mChildren.end(), + if (has_dominated_children) { + children_.erase( + std::remove_if(children_.begin(), children_.end(), [](const std::unique_ptr<Node>& child) -> bool { return child == nullptr; }), - mChildren.end()); + children_.end()); } // Add the new config to a child if a child dominates the new config. - for (auto& child : mChildren) { - if (child->dominates(newChild.get())) { - child->addChild(std::move(newChild)); + for (auto& child : children_) { + if (child->Dominates(new_child.get())) { + child->AddChild(std::move(new_child)); return true; } } // The new config is not dominated by a child, so add it here. - newChild->mParent = this; - mChildren.push_back(std::move(newChild)); + new_child->parent_ = this; + children_.push_back(std::move(new_child)); return true; } -bool DominatorTree::Node::dominates(const Node* other) const { +bool DominatorTree::Node::Dominates(const Node* other) const { // Check root node dominations. - if (other->isRootNode()) { - return isRootNode(); - } else if (isRootNode()) { + if (other->is_root_node()) { + return is_root_node(); + } else if (is_root_node()) { return true; } // Neither node is a root node; compare the configurations. - return mValue->config.dominates(other->mValue->config); + return value_->config.Dominates(other->value_->config); } } // namespace aapt diff --git a/tools/aapt2/DominatorTree.h b/tools/aapt2/DominatorTree.h index 6d45b5d59ded..7d50935eabfd 100644 --- a/tools/aapt2/DominatorTree.h +++ b/tools/aapt2/DominatorTree.h @@ -17,13 +17,13 @@ #ifndef AAPT_DOMINATOR_TREE_H #define AAPT_DOMINATOR_TREE_H -#include "ResourceTable.h" - #include <map> #include <memory> #include <string> #include <vector> +#include "ResourceTable.h" + namespace aapt { /** @@ -53,67 +53,67 @@ class DominatorTree { class Node { public: explicit Node(ResourceConfigValue* value = nullptr, Node* parent = nullptr) - : mValue(value), mParent(parent) {} + : value_(value), parent_(parent) {} - inline ResourceConfigValue* value() const { return mValue; } + inline ResourceConfigValue* value() const { return value_; } - inline Node* parent() const { return mParent; } + inline Node* parent() const { return parent_; } - inline bool isRootNode() const { return !mValue; } + inline bool is_root_node() const { return !value_; } inline const std::vector<std::unique_ptr<Node>>& children() const { - return mChildren; + return children_; } - bool tryAddChild(std::unique_ptr<Node> newChild); + bool TryAddChild(std::unique_ptr<Node> new_child); private: - bool addChild(std::unique_ptr<Node> newChild); - bool dominates(const Node* other) const; + bool AddChild(std::unique_ptr<Node> new_child); + bool Dominates(const Node* other) const; - ResourceConfigValue* mValue; - Node* mParent; - std::vector<std::unique_ptr<Node>> mChildren; + ResourceConfigValue* value_; + Node* parent_; + std::vector<std::unique_ptr<Node>> children_; DISALLOW_COPY_AND_ASSIGN(Node); }; struct Visitor { virtual ~Visitor() = default; - virtual void visitTree(const std::string& product, Node* root) = 0; + virtual void VisitTree(const std::string& product, Node* root) = 0; }; class BottomUpVisitor : public Visitor { public: virtual ~BottomUpVisitor() = default; - void visitTree(const std::string& product, Node* root) override { + void VisitTree(const std::string& product, Node* root) override { for (auto& child : root->children()) { - visitNode(child.get()); + VisitNode(child.get()); } } - virtual void visitConfig(Node* node) = 0; + virtual void VisitConfig(Node* node) = 0; private: - void visitNode(Node* node) { + void VisitNode(Node* node) { for (auto& child : node->children()) { - visitNode(child.get()); + VisitNode(child.get()); } - visitConfig(node); + VisitConfig(node); } }; - void accept(Visitor* visitor); + void Accept(Visitor* visitor); - inline const std::map<std::string, Node>& getProductRoots() const { - return mProductRoots; + inline const std::map<std::string, Node>& product_roots() const { + return product_roots_; } private: DISALLOW_COPY_AND_ASSIGN(DominatorTree); - std::map<std::string, Node> mProductRoots; + std::map<std::string, Node> product_roots_; }; } // namespace aapt diff --git a/tools/aapt2/DominatorTree_test.cpp b/tools/aapt2/DominatorTree_test.cpp index a42d2f744ef3..e89c6beb0c57 100644 --- a/tools/aapt2/DominatorTree_test.cpp +++ b/tools/aapt2/DominatorTree_test.cpp @@ -15,67 +15,68 @@ */ #include "DominatorTree.h" -#include "test/Test.h" -#include "util/Util.h" #include <sstream> #include <string> #include <vector> +#include "test/Test.h" +#include "util/Util.h" + namespace aapt { namespace { class PrettyPrinter : public DominatorTree::Visitor { public: - explicit PrettyPrinter(const int indent = 2) : mIndent(indent) {} + explicit PrettyPrinter(const int indent = 2) : indent_(indent) {} - void visitTree(const std::string& product, + void VisitTree(const std::string& product, DominatorTree::Node* root) override { for (auto& child : root->children()) { - visitNode(child.get(), 0); + VisitNode(child.get(), 0); } } - std::string toString(DominatorTree* tree) { - mBuffer.str(""); - mBuffer.clear(); - tree->accept(this); - return mBuffer.str(); + std::string ToString(DominatorTree* tree) { + buffer_.str(""); + buffer_.clear(); + tree->Accept(this); + return buffer_.str(); } private: - void visitConfig(const DominatorTree::Node* node, const int indent) { - auto configString = node->value()->config.toString(); - mBuffer << std::string(indent, ' ') - << (configString.isEmpty() ? "<default>" : configString) + void VisitConfig(const DominatorTree::Node* node, const int indent) { + auto config_string = node->value()->config.toString(); + buffer_ << std::string(indent, ' ') + << (config_string.isEmpty() ? "<default>" : config_string) << std::endl; } - void visitNode(const DominatorTree::Node* node, const int indent) { - visitConfig(node, indent); + void VisitNode(const DominatorTree::Node* node, const int indent) { + VisitConfig(node, indent); for (const auto& child : node->children()) { - visitNode(child.get(), indent + mIndent); + VisitNode(child.get(), indent + indent_); } } - std::stringstream mBuffer; - const int mIndent = 2; + std::stringstream buffer_; + const int indent_ = 2; }; } // namespace TEST(DominatorTreeTest, DefaultDominatesEverything) { - const ConfigDescription defaultConfig = {}; - const ConfigDescription landConfig = test::parseConfigOrDie("land"); - const ConfigDescription sw600dpLandConfig = - test::parseConfigOrDie("sw600dp-land-v13"); + const ConfigDescription default_config = {}; + const ConfigDescription land_config = test::ParseConfigOrDie("land"); + const ConfigDescription sw600dp_land_config = + test::ParseConfigOrDie("sw600dp-land-v13"); std::vector<std::unique_ptr<ResourceConfigValue>> configs; - configs.push_back(util::make_unique<ResourceConfigValue>(defaultConfig, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(landConfig, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(default_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(land_config, "")); configs.push_back( - util::make_unique<ResourceConfigValue>(sw600dpLandConfig, "")); + util::make_unique<ResourceConfigValue>(sw600dp_land_config, "")); DominatorTree tree(configs); PrettyPrinter printer; @@ -84,22 +85,22 @@ TEST(DominatorTreeTest, DefaultDominatesEverything) { "<default>\n" " land\n" " sw600dp-land-v13\n"; - EXPECT_EQ(expected, printer.toString(&tree)); + EXPECT_EQ(expected, printer.ToString(&tree)); } TEST(DominatorTreeTest, ProductsAreDominatedSeparately) { - const ConfigDescription defaultConfig = {}; - const ConfigDescription landConfig = test::parseConfigOrDie("land"); - const ConfigDescription sw600dpLandConfig = - test::parseConfigOrDie("sw600dp-land-v13"); + const ConfigDescription default_config = {}; + const ConfigDescription land_config = test::ParseConfigOrDie("land"); + const ConfigDescription sw600dp_land_config = + test::ParseConfigOrDie("sw600dp-land-v13"); std::vector<std::unique_ptr<ResourceConfigValue>> configs; - configs.push_back(util::make_unique<ResourceConfigValue>(defaultConfig, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(landConfig, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(default_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(land_config, "")); configs.push_back( - util::make_unique<ResourceConfigValue>(defaultConfig, "phablet")); + util::make_unique<ResourceConfigValue>(default_config, "phablet")); configs.push_back( - util::make_unique<ResourceConfigValue>(sw600dpLandConfig, "phablet")); + util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet")); DominatorTree tree(configs); PrettyPrinter printer; @@ -109,34 +110,38 @@ TEST(DominatorTreeTest, ProductsAreDominatedSeparately) { " land\n" "<default>\n" " sw600dp-land-v13\n"; - EXPECT_EQ(expected, printer.toString(&tree)); + EXPECT_EQ(expected, printer.ToString(&tree)); } TEST(DominatorTreeTest, MoreSpecificConfigurationsAreDominated) { - const ConfigDescription defaultConfig = {}; - const ConfigDescription enConfig = test::parseConfigOrDie("en"); - const ConfigDescription enV21Config = test::parseConfigOrDie("en-v21"); - const ConfigDescription ldrtlConfig = test::parseConfigOrDie("ldrtl-v4"); - const ConfigDescription ldrtlXhdpiConfig = - test::parseConfigOrDie("ldrtl-xhdpi-v4"); - const ConfigDescription sw300dpConfig = test::parseConfigOrDie("sw300dp-v13"); - const ConfigDescription sw540dpConfig = test::parseConfigOrDie("sw540dp-v14"); - const ConfigDescription sw600dpConfig = test::parseConfigOrDie("sw600dp-v14"); - const ConfigDescription sw720dpConfig = test::parseConfigOrDie("sw720dp-v13"); - const ConfigDescription v20Config = test::parseConfigOrDie("v20"); + const ConfigDescription default_config = {}; + const ConfigDescription en_config = test::ParseConfigOrDie("en"); + const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21"); + const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl-v4"); + const ConfigDescription ldrtl_xhdpi_config = + test::ParseConfigOrDie("ldrtl-xhdpi-v4"); + const ConfigDescription sw300dp_config = + test::ParseConfigOrDie("sw300dp-v13"); + const ConfigDescription sw540dp_config = + test::ParseConfigOrDie("sw540dp-v14"); + const ConfigDescription sw600dp_config = + test::ParseConfigOrDie("sw600dp-v14"); + const ConfigDescription sw720dp_config = + test::ParseConfigOrDie("sw720dp-v13"); + const ConfigDescription v20_config = test::ParseConfigOrDie("v20"); std::vector<std::unique_ptr<ResourceConfigValue>> configs; - configs.push_back(util::make_unique<ResourceConfigValue>(defaultConfig, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(enConfig, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(enV21Config, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(ldrtlConfig, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(default_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(en_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(en_v21_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_config, "")); configs.push_back( - util::make_unique<ResourceConfigValue>(ldrtlXhdpiConfig, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(sw300dpConfig, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(sw540dpConfig, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(sw600dpConfig, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(sw720dpConfig, "")); - configs.push_back(util::make_unique<ResourceConfigValue>(v20Config, "")); + util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(sw300dp_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(sw540dp_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(sw720dp_config, "")); + configs.push_back(util::make_unique<ResourceConfigValue>(v20_config, "")); DominatorTree tree(configs); PrettyPrinter printer; @@ -152,7 +157,7 @@ TEST(DominatorTreeTest, MoreSpecificConfigurationsAreDominated) { " sw600dp-v14\n" " sw720dp-v13\n" " v20\n"; - EXPECT_EQ(expected, printer.toString(&tree)); + EXPECT_EQ(expected, printer.ToString(&tree)); } } // namespace aapt diff --git a/tools/aapt2/Flags.cpp b/tools/aapt2/Flags.cpp index cb1619657b4f..c98cd374602f 100644 --- a/tools/aapt2/Flags.cpp +++ b/tools/aapt2/Flags.cpp @@ -15,97 +15,98 @@ */ #include "Flags.h" -#include "util/StringPiece.h" -#include "util/Util.h" #include <iomanip> #include <iostream> #include <string> #include <vector> +#include "util/StringPiece.h" +#include "util/Util.h" + namespace aapt { -Flags& Flags::requiredFlag(const StringPiece& name, +Flags& Flags::RequiredFlag(const StringPiece& name, const StringPiece& description, std::string* value) { auto func = [value](const StringPiece& arg) -> bool { - *value = arg.toString(); + *value = arg.ToString(); return true; }; - mFlags.push_back( - Flag{name.toString(), description.toString(), func, true, 1, false}); + flags_.push_back( + Flag{name.ToString(), description.ToString(), func, true, 1, false}); return *this; } -Flags& Flags::requiredFlagList(const StringPiece& name, +Flags& Flags::RequiredFlagList(const StringPiece& name, const StringPiece& description, std::vector<std::string>* value) { auto func = [value](const StringPiece& arg) -> bool { - value->push_back(arg.toString()); + value->push_back(arg.ToString()); return true; }; - mFlags.push_back( - Flag{name.toString(), description.toString(), func, true, 1, false}); + flags_.push_back( + Flag{name.ToString(), description.ToString(), func, true, 1, false}); return *this; } -Flags& Flags::optionalFlag(const StringPiece& name, +Flags& Flags::OptionalFlag(const StringPiece& name, const StringPiece& description, Maybe<std::string>* value) { auto func = [value](const StringPiece& arg) -> bool { - *value = arg.toString(); + *value = arg.ToString(); return true; }; - mFlags.push_back( - Flag{name.toString(), description.toString(), func, false, 1, false}); + flags_.push_back( + Flag{name.ToString(), description.ToString(), func, false, 1, false}); return *this; } -Flags& Flags::optionalFlagList(const StringPiece& name, +Flags& Flags::OptionalFlagList(const StringPiece& name, const StringPiece& description, std::vector<std::string>* value) { auto func = [value](const StringPiece& arg) -> bool { - value->push_back(arg.toString()); + value->push_back(arg.ToString()); return true; }; - mFlags.push_back( - Flag{name.toString(), description.toString(), func, false, 1, false}); + flags_.push_back( + Flag{name.ToString(), description.ToString(), func, false, 1, false}); return *this; } -Flags& Flags::optionalFlagList(const StringPiece& name, +Flags& Flags::OptionalFlagList(const StringPiece& name, const StringPiece& description, std::unordered_set<std::string>* value) { auto func = [value](const StringPiece& arg) -> bool { - value->insert(arg.toString()); + value->insert(arg.ToString()); return true; }; - mFlags.push_back( - Flag{name.toString(), description.toString(), func, false, 1, false}); + flags_.push_back( + Flag{name.ToString(), description.ToString(), func, false, 1, false}); return *this; } -Flags& Flags::optionalSwitch(const StringPiece& name, +Flags& Flags::OptionalSwitch(const StringPiece& name, const StringPiece& description, bool* value) { auto func = [value](const StringPiece& arg) -> bool { *value = true; return true; }; - mFlags.push_back( - Flag{name.toString(), description.toString(), func, false, 0, false}); + flags_.push_back( + Flag{name.ToString(), description.ToString(), func, false, 0, false}); return *this; } -void Flags::usage(const StringPiece& command, std::ostream* out) { +void Flags::Usage(const StringPiece& command, std::ostream* out) { constexpr size_t kWidth = 50; *out << command << " [options]"; - for (const Flag& flag : mFlags) { + for (const Flag& flag : flags_) { if (flag.required) { *out << " " << flag.name << " arg"; } @@ -113,10 +114,10 @@ void Flags::usage(const StringPiece& command, std::ostream* out) { *out << " files...\n\nOptions:\n"; - for (const Flag& flag : mFlags) { - std::string argLine = flag.name; - if (flag.numArgs > 0) { - argLine += " arg"; + for (const Flag& flag : flags_) { + std::string argline = flag.name; + if (flag.num_args > 0) { + argline += " arg"; } // Split the description by newlines and write out the argument (which is @@ -124,9 +125,9 @@ void Flags::usage(const StringPiece& command, std::ostream* out) { // the first line) followed by the description line. This will make sure // that multiline // descriptions are still right justified and aligned. - for (StringPiece line : util::tokenize(flag.description, '\n')) { - *out << " " << std::setw(kWidth) << std::left << argLine << line << "\n"; - argLine = " "; + for (StringPiece line : util::Tokenize(flag.description, '\n')) { + *out << " " << std::setw(kWidth) << std::left << argline << line << "\n"; + argline = " "; } } *out << " " << std::setw(kWidth) << std::left << "-h" @@ -134,29 +135,29 @@ void Flags::usage(const StringPiece& command, std::ostream* out) { out->flush(); } -bool Flags::parse(const StringPiece& command, +bool Flags::Parse(const StringPiece& command, const std::vector<StringPiece>& args, - std::ostream* outError) { + std::ostream* out_error) { for (size_t i = 0; i < args.size(); i++) { StringPiece arg = args[i]; if (*(arg.data()) != '-') { - mArgs.push_back(arg.toString()); + args_.push_back(arg.ToString()); continue; } if (arg == "-h" || arg == "--help") { - usage(command, outError); + Usage(command, out_error); return false; } bool match = false; - for (Flag& flag : mFlags) { + for (Flag& flag : flags_) { if (arg == flag.name) { - if (flag.numArgs > 0) { + if (flag.num_args > 0) { i++; if (i >= args.size()) { - *outError << flag.name << " missing argument.\n\n"; - usage(command, outError); + *out_error << flag.name << " missing argument.\n\n"; + Usage(command, out_error); return false; } flag.action(args[i]); @@ -170,22 +171,22 @@ bool Flags::parse(const StringPiece& command, } if (!match) { - *outError << "unknown option '" << arg << "'.\n\n"; - usage(command, outError); + *out_error << "unknown option '" << arg << "'.\n\n"; + Usage(command, out_error); return false; } } - for (const Flag& flag : mFlags) { + for (const Flag& flag : flags_) { if (flag.required && !flag.parsed) { - *outError << "missing required flag " << flag.name << "\n\n"; - usage(command, outError); + *out_error << "missing required flag " << flag.name << "\n\n"; + Usage(command, out_error); return false; } } return true; } -const std::vector<std::string>& Flags::getArgs() { return mArgs; } +const std::vector<std::string>& Flags::GetArgs() { return args_; } } // namespace aapt diff --git a/tools/aapt2/Flags.h b/tools/aapt2/Flags.h index 4a0efdb5b378..9feff6b4faca 100644 --- a/tools/aapt2/Flags.h +++ b/tools/aapt2/Flags.h @@ -17,41 +17,41 @@ #ifndef AAPT_FLAGS_H #define AAPT_FLAGS_H -#include "util/Maybe.h" -#include "util/StringPiece.h" - #include <functional> #include <ostream> #include <string> #include <unordered_set> #include <vector> +#include "util/Maybe.h" +#include "util/StringPiece.h" + namespace aapt { class Flags { public: - Flags& requiredFlag(const StringPiece& name, const StringPiece& description, + Flags& RequiredFlag(const StringPiece& name, const StringPiece& description, std::string* value); - Flags& requiredFlagList(const StringPiece& name, + Flags& RequiredFlagList(const StringPiece& name, const StringPiece& description, std::vector<std::string>* value); - Flags& optionalFlag(const StringPiece& name, const StringPiece& description, + Flags& OptionalFlag(const StringPiece& name, const StringPiece& description, Maybe<std::string>* value); - Flags& optionalFlagList(const StringPiece& name, + Flags& OptionalFlagList(const StringPiece& name, const StringPiece& description, std::vector<std::string>* value); - Flags& optionalFlagList(const StringPiece& name, + Flags& OptionalFlagList(const StringPiece& name, const StringPiece& description, std::unordered_set<std::string>* value); - Flags& optionalSwitch(const StringPiece& name, const StringPiece& description, + Flags& OptionalSwitch(const StringPiece& name, const StringPiece& description, bool* value); - void usage(const StringPiece& command, std::ostream* out); + void Usage(const StringPiece& command, std::ostream* out); - bool parse(const StringPiece& command, const std::vector<StringPiece>& args, + bool Parse(const StringPiece& command, const std::vector<StringPiece>& args, std::ostream* outError); - const std::vector<std::string>& getArgs(); + const std::vector<std::string>& GetArgs(); private: struct Flag { @@ -59,13 +59,13 @@ class Flags { std::string description; std::function<bool(const StringPiece& value)> action; bool required; - size_t numArgs; + size_t num_args; bool parsed; }; - std::vector<Flag> mFlags; - std::vector<std::string> mArgs; + std::vector<Flag> flags_; + std::vector<std::string> args_; }; } // namespace aapt diff --git a/tools/aapt2/Locale.cpp b/tools/aapt2/Locale.cpp index a0f764175e24..78f56c7a5b93 100644 --- a/tools/aapt2/Locale.cpp +++ b/tools/aapt2/Locale.cpp @@ -15,174 +15,176 @@ */ #include "Locale.h" -#include "util/Util.h" #include <ctype.h> + #include <algorithm> #include <string> #include <vector> +#include "util/Util.h" + namespace aapt { using android::ResTable_config; -void LocaleValue::setLanguage(const char* languageChars) { +void LocaleValue::set_language(const char* language_chars) { size_t i = 0; - while ((*languageChars) != '\0') { - language[i++] = ::tolower(*languageChars); - languageChars++; + while ((*language_chars) != '\0') { + language[i++] = ::tolower(*language_chars); + language_chars++; } } -void LocaleValue::setRegion(const char* regionChars) { +void LocaleValue::set_region(const char* region_chars) { size_t i = 0; - while ((*regionChars) != '\0') { - region[i++] = ::toupper(*regionChars); - regionChars++; + while ((*region_chars) != '\0') { + region[i++] = ::toupper(*region_chars); + region_chars++; } } -void LocaleValue::setScript(const char* scriptChars) { +void LocaleValue::set_script(const char* script_chars) { size_t i = 0; - while ((*scriptChars) != '\0') { + while ((*script_chars) != '\0') { if (i == 0) { - script[i++] = ::toupper(*scriptChars); + script[i++] = ::toupper(*script_chars); } else { - script[i++] = ::tolower(*scriptChars); + script[i++] = ::tolower(*script_chars); } - scriptChars++; + script_chars++; } } -void LocaleValue::setVariant(const char* variantChars) { +void LocaleValue::set_variant(const char* variant_chars) { size_t i = 0; - while ((*variantChars) != '\0') { - variant[i++] = *variantChars; - variantChars++; + while ((*variant_chars) != '\0') { + variant[i++] = *variant_chars; + variant_chars++; } } -static inline bool isAlpha(const std::string& str) { +static inline bool is_alpha(const std::string& str) { return std::all_of(std::begin(str), std::end(str), ::isalpha); } -static inline bool isNumber(const std::string& str) { +static inline bool is_number(const std::string& str) { return std::all_of(std::begin(str), std::end(str), ::isdigit); } -bool LocaleValue::initFromFilterString(const StringPiece& str) { +bool LocaleValue::InitFromFilterString(const StringPiece& str) { // A locale (as specified in the filter) is an underscore separated name such // as "en_US", "en_Latn_US", or "en_US_POSIX". - std::vector<std::string> parts = util::splitAndLowercase(str, '_'); + std::vector<std::string> parts = util::SplitAndLowercase(str, '_'); - const int numTags = parts.size(); + const int num_tags = parts.size(); bool valid = false; - if (numTags >= 1) { + if (num_tags >= 1) { const std::string& lang = parts[0]; - if (isAlpha(lang) && (lang.length() == 2 || lang.length() == 3)) { - setLanguage(lang.c_str()); + if (is_alpha(lang) && (lang.length() == 2 || lang.length() == 3)) { + set_language(lang.c_str()); valid = true; } } - if (!valid || numTags == 1) { + if (!valid || num_tags == 1) { return valid; } // At this point, valid == true && numTags > 1. const std::string& part2 = parts[1]; - if ((part2.length() == 2 && isAlpha(part2)) || - (part2.length() == 3 && isNumber(part2))) { - setRegion(part2.c_str()); - } else if (part2.length() == 4 && isAlpha(part2)) { - setScript(part2.c_str()); + if ((part2.length() == 2 && is_alpha(part2)) || + (part2.length() == 3 && is_number(part2))) { + set_region(part2.c_str()); + } else if (part2.length() == 4 && is_alpha(part2)) { + set_script(part2.c_str()); } else if (part2.length() >= 4 && part2.length() <= 8) { - setVariant(part2.c_str()); + set_variant(part2.c_str()); } else { valid = false; } - if (!valid || numTags == 2) { + if (!valid || num_tags == 2) { return valid; } // At this point, valid == true && numTags > 1. const std::string& part3 = parts[2]; - if (((part3.length() == 2 && isAlpha(part3)) || - (part3.length() == 3 && isNumber(part3))) && + if (((part3.length() == 2 && is_alpha(part3)) || + (part3.length() == 3 && is_number(part3))) && script[0]) { - setRegion(part3.c_str()); + set_region(part3.c_str()); } else if (part3.length() >= 4 && part3.length() <= 8) { - setVariant(part3.c_str()); + set_variant(part3.c_str()); } else { valid = false; } - if (!valid || numTags == 3) { + if (!valid || num_tags == 3) { return valid; } const std::string& part4 = parts[3]; if (part4.length() >= 4 && part4.length() <= 8) { - setVariant(part4.c_str()); + set_variant(part4.c_str()); } else { valid = false; } - if (!valid || numTags > 4) { + if (!valid || num_tags > 4) { return false; } return true; } -ssize_t LocaleValue::initFromParts(std::vector<std::string>::iterator iter, +ssize_t LocaleValue::InitFromParts(std::vector<std::string>::iterator iter, std::vector<std::string>::iterator end) { - const std::vector<std::string>::iterator startIter = iter; + const std::vector<std::string>::iterator start_iter = iter; std::string& part = *iter; if (part[0] == 'b' && part[1] == '+') { // This is a "modified" BCP 47 language tag. Same semantics as BCP 47 tags, // except that the separator is "+" and not "-". - std::vector<std::string> subtags = util::splitAndLowercase(part, '+'); + std::vector<std::string> subtags = util::SplitAndLowercase(part, '+'); subtags.erase(subtags.begin()); if (subtags.size() == 1) { - setLanguage(subtags[0].c_str()); + set_language(subtags[0].c_str()); } else if (subtags.size() == 2) { - setLanguage(subtags[0].c_str()); + set_language(subtags[0].c_str()); // The second tag can either be a region, a variant or a script. switch (subtags[1].size()) { case 2: case 3: - setRegion(subtags[1].c_str()); + set_region(subtags[1].c_str()); break; case 4: if ('0' <= subtags[1][0] && subtags[1][0] <= '9') { // This is a variant: fall through } else { - setScript(subtags[1].c_str()); + set_script(subtags[1].c_str()); break; } case 5: case 6: case 7: case 8: - setVariant(subtags[1].c_str()); + set_variant(subtags[1].c_str()); break; default: return -1; } } else if (subtags.size() == 3) { // The language is always the first subtag. - setLanguage(subtags[0].c_str()); + set_language(subtags[0].c_str()); // The second subtag can either be a script or a region code. // If its size is 4, it's a script code, else it's a region code. if (subtags[1].size() == 4) { - setScript(subtags[1].c_str()); + set_script(subtags[1].c_str()); } else if (subtags[1].size() == 2 || subtags[1].size() == 3) { - setRegion(subtags[1].c_str()); + set_region(subtags[1].c_str()); } else { return -1; } @@ -190,15 +192,15 @@ ssize_t LocaleValue::initFromParts(std::vector<std::string>::iterator iter, // The third tag can either be a region code (if the second tag was // a script), else a variant code. if (subtags[2].size() >= 4) { - setVariant(subtags[2].c_str()); + set_variant(subtags[2].c_str()); } else { - setRegion(subtags[2].c_str()); + set_region(subtags[2].c_str()); } } else if (subtags.size() == 4) { - setLanguage(subtags[0].c_str()); - setScript(subtags[1].c_str()); - setRegion(subtags[2].c_str()); - setVariant(subtags[3].c_str()); + set_language(subtags[0].c_str()); + set_script(subtags[1].c_str()); + set_region(subtags[2].c_str()); + set_variant(subtags[3].c_str()); } else { return -1; } @@ -206,25 +208,25 @@ ssize_t LocaleValue::initFromParts(std::vector<std::string>::iterator iter, ++iter; } else { - if ((part.length() == 2 || part.length() == 3) && isAlpha(part) && + if ((part.length() == 2 || part.length() == 3) && is_alpha(part) && part != "car") { - setLanguage(part.c_str()); + set_language(part.c_str()); ++iter; if (iter != end) { - const std::string& regionPart = *iter; - if (regionPart.c_str()[0] == 'r' && regionPart.length() == 3) { - setRegion(regionPart.c_str() + 1); + const std::string& region_part = *iter; + if (region_part.c_str()[0] == 'r' && region_part.length() == 3) { + set_region(region_part.c_str() + 1); ++iter; } } } } - return static_cast<ssize_t>(iter - startIter); + return static_cast<ssize_t>(iter - start_iter); } -void LocaleValue::initFromResTable(const ResTable_config& config) { +void LocaleValue::InitFromResTable(const ResTable_config& config) { config.unpackLanguage(language); config.unpackRegion(region); if (config.localeScript[0] && !config.localeScriptWasComputed) { @@ -236,7 +238,7 @@ void LocaleValue::initFromResTable(const ResTable_config& config) { } } -void LocaleValue::writeTo(ResTable_config* out) const { +void LocaleValue::WriteTo(ResTable_config* out) const { out->packLanguage(language); out->packRegion(region); diff --git a/tools/aapt2/Locale.h b/tools/aapt2/Locale.h index 0f7585033af7..fc6c448ac1dc 100644 --- a/tools/aapt2/Locale.h +++ b/tools/aapt2/Locale.h @@ -17,12 +17,13 @@ #ifndef AAPT_LOCALE_VALUE_H #define AAPT_LOCALE_VALUE_H -#include "util/StringPiece.h" - -#include <androidfw/ResourceTypes.h> #include <string> #include <vector> +#include "androidfw/ResourceTypes.h" + +#include "util/StringPiece.h" + namespace aapt { /** @@ -39,23 +40,23 @@ struct LocaleValue { /** * Initialize this LocaleValue from a config string. */ - bool initFromFilterString(const StringPiece& config); + bool InitFromFilterString(const StringPiece& config); /** * Initialize this LocaleValue from parts of a vector. */ - ssize_t initFromParts(std::vector<std::string>::iterator iter, + ssize_t InitFromParts(std::vector<std::string>::iterator iter, std::vector<std::string>::iterator end); /** * Initialize this LocaleValue from a ResTable_config. */ - void initFromResTable(const android::ResTable_config& config); + void InitFromResTable(const android::ResTable_config& config); /** * Set the locale in a ResTable_config from this LocaleValue. */ - void writeTo(android::ResTable_config* out) const; + void WriteTo(android::ResTable_config* out) const; inline int compare(const LocaleValue& other) const; @@ -67,10 +68,10 @@ struct LocaleValue { inline bool operator>(const LocaleValue& o) const; private: - void setLanguage(const char* language); - void setRegion(const char* language); - void setScript(const char* script); - void setVariant(const char* variant); + void set_language(const char* language); + void set_region(const char* language); + void set_script(const char* script); + void set_variant(const char* variant); }; // diff --git a/tools/aapt2/Locale_test.cpp b/tools/aapt2/Locale_test.cpp index b82d2b9cbc0d..68b4cae44e15 100644 --- a/tools/aapt2/Locale_test.cpp +++ b/tools/aapt2/Locale_test.cpp @@ -15,18 +15,20 @@ */ #include "Locale.h" -#include "util/Util.h" -#include <gtest/gtest.h> #include <string> +#include "gtest/gtest.h" + +#include "util/Util.h" + namespace aapt { static ::testing::AssertionResult TestLanguage(const char* input, const char* lang) { - std::vector<std::string> parts = util::splitAndLowercase(input, '-'); + std::vector<std::string> parts = util::SplitAndLowercase(input, '-'); LocaleValue lv; - ssize_t count = lv.initFromParts(std::begin(parts), std::end(parts)); + ssize_t count = lv.InitFromParts(std::begin(parts), std::end(parts)); if (count < 0) { return ::testing::AssertionFailure() << " failed to parse '" << input << "'."; @@ -51,9 +53,9 @@ static ::testing::AssertionResult TestLanguage(const char* input, static ::testing::AssertionResult TestLanguageRegion(const char* input, const char* lang, const char* region) { - std::vector<std::string> parts = util::splitAndLowercase(input, '-'); + std::vector<std::string> parts = util::SplitAndLowercase(input, '-'); LocaleValue lv; - ssize_t count = lv.initFromParts(std::begin(parts), std::end(parts)); + ssize_t count = lv.InitFromParts(std::begin(parts), std::end(parts)); if (count < 0) { return ::testing::AssertionFailure() << " failed to parse '" << input << "'."; diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 8aedd44656be..8dd176d27345 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -14,11 +14,11 @@ * limitations under the License. */ -#include "util/StringPiece.h" - #include <iostream> #include <vector> +#include "util/StringPiece.h" + namespace aapt { // DO NOT UPDATE, this is more of a marketing version. @@ -27,16 +27,16 @@ static const char* sMajorVersion = "2"; // Update minor version whenever a feature or flag is added. static const char* sMinorVersion = "2"; -int printVersion() { +int PrintVersion() { std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "." << sMinorVersion << std::endl; return 0; } -extern int compile(const std::vector<StringPiece>& args); -extern int link(const std::vector<StringPiece>& args); -extern int dump(const std::vector<StringPiece>& args); -extern int diff(const std::vector<StringPiece>& args); +extern int Compile(const std::vector<StringPiece>& args); +extern int Link(const std::vector<StringPiece>& args); +extern int Dump(const std::vector<StringPiece>& args); +extern int Diff(const std::vector<StringPiece>& args); } // namespace aapt @@ -52,15 +52,15 @@ int main(int argc, char** argv) { aapt::StringPiece command(argv[0]); if (command == "compile" || command == "c") { - return aapt::compile(args); + return aapt::Compile(args); } else if (command == "link" || command == "l") { - return aapt::link(args); + return aapt::Link(args); } else if (command == "dump" || command == "d") { - return aapt::dump(args); + return aapt::Dump(args); } else if (command == "diff") { - return aapt::diff(args); + return aapt::Diff(args); } else if (command == "version") { - return aapt::printVersion(); + return aapt::PrintVersion(); } std::cerr << "unknown command '" << command << "'\n"; } else { diff --git a/tools/aapt2/NameMangler.h b/tools/aapt2/NameMangler.h index 6d244aac9716..dba2d096dd9d 100644 --- a/tools/aapt2/NameMangler.h +++ b/tools/aapt2/NameMangler.h @@ -17,12 +17,12 @@ #ifndef AAPT_NAME_MANGLER_H #define AAPT_NAME_MANGLER_H -#include "Resource.h" -#include "util/Maybe.h" - #include <set> #include <string> +#include "Resource.h" +#include "util/Maybe.h" + namespace aapt { struct NameManglerPolicy { @@ -31,37 +31,35 @@ struct NameManglerPolicy { * to this package are not mangled, and mangled references inherit this * package name. */ - std::string targetPackageName; + std::string target_package_name; /** * We must know which references to mangle, and which to keep (android vs. * com.android.support). */ - std::set<std::string> packagesToMangle; + std::set<std::string> packages_to_mangle; }; class NameMangler { - private: - NameManglerPolicy mPolicy; - public: - explicit NameMangler(NameManglerPolicy policy) : mPolicy(policy) {} + explicit NameMangler(NameManglerPolicy policy) : policy_(policy) {} - Maybe<ResourceName> mangleName(const ResourceName& name) { - if (mPolicy.targetPackageName == name.package || - mPolicy.packagesToMangle.count(name.package) == 0) { + Maybe<ResourceName> MangleName(const ResourceName& name) { + if (policy_.target_package_name == name.package || + policy_.packages_to_mangle.count(name.package) == 0) { return {}; } - std::string mangledEntryName = mangleEntry(name.package, name.entry); - return ResourceName(mPolicy.targetPackageName, name.type, mangledEntryName); + std::string mangled_entry_name = MangleEntry(name.package, name.entry); + return ResourceName(policy_.target_package_name, name.type, + mangled_entry_name); } - bool shouldMangle(const std::string& package) const { - if (package.empty() || mPolicy.targetPackageName == package) { + bool ShouldMangle(const std::string& package) const { + if (package.empty() || policy_.target_package_name == package) { return false; } - return mPolicy.packagesToMangle.count(package) != 0; + return policy_.packages_to_mangle.count(package) != 0; } /** @@ -69,7 +67,7 @@ class NameMangler { * The mangled name should contain symbols that are illegal to define in XML, * so that there will never be name mangling collisions. */ - static std::string mangleEntry(const std::string& package, + static std::string MangleEntry(const std::string& package, const std::string& name) { return package + "$" + name; } @@ -79,16 +77,20 @@ class NameMangler { * and the package in `outPackage`. Returns true if the name was unmangled or * false if the name was never mangled to begin with. */ - static bool unmangle(std::string* outName, std::string* outPackage) { - size_t pivot = outName->find('$'); + static bool Unmangle(std::string* out_name, std::string* out_package) { + size_t pivot = out_name->find('$'); if (pivot == std::string::npos) { return false; } - outPackage->assign(outName->data(), pivot); - outName->assign(outName->data() + pivot + 1, outName->size() - (pivot + 1)); + out_package->assign(out_name->data(), pivot); + out_name->assign(out_name->data() + pivot + 1, + out_name->size() - (pivot + 1)); return true; } + + private: + NameManglerPolicy policy_; }; } // namespace aapt diff --git a/tools/aapt2/NameMangler_test.cpp b/tools/aapt2/NameMangler_test.cpp index b02986d8e611..bc89b5c3fb43 100644 --- a/tools/aapt2/NameMangler_test.cpp +++ b/tools/aapt2/NameMangler_test.cpp @@ -15,31 +15,32 @@ */ #include "NameMangler.h" -#include "test/Test.h" #include <string> +#include "test/Test.h" + namespace aapt { TEST(NameManglerTest, MangleName) { std::string package = "android.appcompat"; std::string name = "Platform.AppCompat"; - std::string mangledName = NameMangler::mangleEntry(package, name); - EXPECT_EQ(mangledName, "android.appcompat$Platform.AppCompat"); + std::string mangled_name = NameMangler::MangleEntry(package, name); + EXPECT_EQ(mangled_name, "android.appcompat$Platform.AppCompat"); - std::string unmangledPackage; - std::string unmangledName = mangledName; - ASSERT_TRUE(NameMangler::unmangle(&unmangledName, &unmangledPackage)); - EXPECT_EQ(unmangledName, "Platform.AppCompat"); - EXPECT_EQ(unmangledPackage, "android.appcompat"); + std::string unmangled_package; + std::string unmangled_name = mangled_name; + ASSERT_TRUE(NameMangler::Unmangle(&unmangled_name, &unmangled_package)); + EXPECT_EQ(unmangled_name, "Platform.AppCompat"); + EXPECT_EQ(unmangled_package, "android.appcompat"); } TEST(NameManglerTest, IgnoreUnmangledName) { std::string package; std::string name = "foo_bar"; - EXPECT_FALSE(NameMangler::unmangle(&name, &package)); + EXPECT_FALSE(NameMangler::Unmangle(&name, &package)); EXPECT_EQ(name, "foo_bar"); } diff --git a/tools/aapt2/Resource.cpp b/tools/aapt2/Resource.cpp index 6805631bd260..1d414743de71 100644 --- a/tools/aapt2/Resource.cpp +++ b/tools/aapt2/Resource.cpp @@ -15,14 +15,13 @@ */ #include "Resource.h" -#include "util/StringPiece.h" #include <map> #include <string> namespace aapt { -StringPiece toString(ResourceType type) { +StringPiece ToString(ResourceType type) { switch (type) { case ResourceType::kAnim: return "anim"; @@ -100,7 +99,7 @@ static const std::map<StringPiece, ResourceType> sResourceTypeMap{ {"xml", ResourceType::kXml}, }; -const ResourceType* parseResourceType(const StringPiece& str) { +const ResourceType* ParseResourceType(const StringPiece& str) { auto iter = sResourceTypeMap.find(str); if (iter == std::end(sResourceTypeMap)) { return nullptr; diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h index 30739db543d3..78acb700c7c0 100644 --- a/tools/aapt2/Resource.h +++ b/tools/aapt2/Resource.h @@ -17,12 +17,6 @@ #ifndef AAPT_RESOURCE_H #define AAPT_RESOURCE_H -#include "ConfigDescription.h" -#include "Source.h" -#include "util/StringPiece.h" - -#include <utils/JenkinsHash.h> - #include <iomanip> #include <limits> #include <sstream> @@ -30,6 +24,12 @@ #include <tuple> #include <vector> +#include "utils/JenkinsHash.h" + +#include "ConfigDescription.h" +#include "Source.h" +#include "util/StringPiece.h" + namespace aapt { /** @@ -62,13 +62,13 @@ enum class ResourceType { kXml, }; -StringPiece toString(ResourceType type); +StringPiece ToString(ResourceType type); /** * Returns a pointer to a valid ResourceType, or nullptr if * the string was invalid. */ -const ResourceType* parseResourceType(const StringPiece& str); +const ResourceType* ParseResourceType(const StringPiece& str); /** * A resource's name. This can uniquely identify @@ -76,16 +76,16 @@ const ResourceType* parseResourceType(const StringPiece& str); */ struct ResourceName { std::string package; - ResourceType type; + ResourceType type = ResourceType::kRaw; std::string entry; - ResourceName() : type(ResourceType::kRaw) {} + ResourceName() = default; ResourceName(const StringPiece& p, ResourceType t, const StringPiece& e); int compare(const ResourceName& other) const; - bool isValid() const; - std::string toString() const; + bool is_valid() const; + std::string ToString() const; }; /** @@ -96,7 +96,7 @@ struct ResourceName { */ struct ResourceNameRef { StringPiece package; - ResourceType type; + ResourceType type = ResourceType::kRaw; StringPiece entry; ResourceNameRef() = default; @@ -108,8 +108,8 @@ struct ResourceNameRef { ResourceNameRef& operator=(ResourceNameRef&& rhs) = default; ResourceNameRef& operator=(const ResourceName& rhs); - ResourceName toResourceName() const; - bool isValid() const; + ResourceName ToResourceName() const; + bool is_valid() const; }; /** @@ -128,13 +128,13 @@ struct ResourceId { ResourceId(); ResourceId(const ResourceId& rhs); - ResourceId(uint32_t resId); // NOLINT(implicit) + ResourceId(uint32_t res_id); // NOLINT(implicit) ResourceId(uint8_t p, uint8_t t, uint16_t e); - bool isValid() const; - uint8_t packageId() const; - uint8_t typeId() const; - uint16_t entryId() const; + bool is_valid() const; + uint8_t package_id() const; + uint8_t type_id() const; + uint16_t entry_id() const; }; struct SourcedResourceName { @@ -153,7 +153,7 @@ struct ResourceFile { Source source; // Exported symbols - std::vector<SourcedResourceName> exportedSymbols; + std::vector<SourcedResourceName> exported_symbols; }; /** @@ -196,24 +196,24 @@ inline ResourceId::ResourceId() : id(0) {} inline ResourceId::ResourceId(const ResourceId& rhs) : id(rhs.id) {} -inline ResourceId::ResourceId(uint32_t resId) : id(resId) {} +inline ResourceId::ResourceId(uint32_t res_id) : id(res_id) {} inline ResourceId::ResourceId(uint8_t p, uint8_t t, uint16_t e) : id((p << 24) | (t << 16) | e) {} -inline bool ResourceId::isValid() const { +inline bool ResourceId::is_valid() const { return (id & 0xff000000u) != 0 && (id & 0x00ff0000u) != 0; } -inline uint8_t ResourceId::packageId() const { +inline uint8_t ResourceId::package_id() const { return static_cast<uint8_t>(id >> 24); } -inline uint8_t ResourceId::typeId() const { +inline uint8_t ResourceId::type_id() const { return static_cast<uint8_t>(id >> 16); } -inline uint16_t ResourceId::entryId() const { +inline uint16_t ResourceId::entry_id() const { return static_cast<uint16_t>(id); } @@ -234,13 +234,13 @@ inline bool operator!=(const ResourceId& lhs, const ResourceId& rhs) { } inline ::std::ostream& operator<<(::std::ostream& out, - const ResourceId& resId) { - std::ios_base::fmtflags oldFlags = out.flags(); - char oldFill = out.fill(); + const ResourceId& res_id) { + std::ios_base::fmtflags old_flags = out.flags(); + char old_fill = out.fill(); out << "0x" << std::internal << std::setfill('0') << std::setw(8) << std::hex - << resId.id; - out.flags(oldFlags); - out.fill(oldFill); + << res_id.id; + out.flags(old_flags); + out.fill(old_fill); return out; } @@ -250,7 +250,7 @@ inline ::std::ostream& operator<<(::std::ostream& out, inline ::std::ostream& operator<<(::std::ostream& out, const ResourceType& val) { - return out << toString(val); + return out << ToString(val); } // @@ -259,7 +259,7 @@ inline ::std::ostream& operator<<(::std::ostream& out, inline ResourceName::ResourceName(const StringPiece& p, ResourceType t, const StringPiece& e) - : package(p.toString()), type(t), entry(e.toString()) {} + : package(p.ToString()), type(t), entry(e.ToString()) {} inline int ResourceName::compare(const ResourceName& other) const { int cmp = package.compare(other.package); @@ -270,7 +270,7 @@ inline int ResourceName::compare(const ResourceName& other) const { return cmp; } -inline bool ResourceName::isValid() const { +inline bool ResourceName::is_valid() const { return !package.empty() && !entry.empty(); } @@ -297,7 +297,7 @@ inline ::std::ostream& operator<<(::std::ostream& out, return out << name.type << "/" << name.entry; } -inline std::string ResourceName::toString() const { +inline std::string ResourceName::ToString() const { std::stringstream stream; stream << *this; return stream.str(); @@ -321,11 +321,11 @@ inline ResourceNameRef& ResourceNameRef::operator=(const ResourceName& rhs) { return *this; } -inline ResourceName ResourceNameRef::toResourceName() const { +inline ResourceName ResourceNameRef::ToResourceName() const { return ResourceName(package, type, entry); } -inline bool ResourceNameRef::isValid() const { +inline bool ResourceNameRef::is_valid() const { return !package.empty() && !entry.empty(); } diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 7d50e1d38816..b16def4025ff 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -15,6 +15,12 @@ */ #include "ResourceParser.h" + +#include <functional> +#include <sstream> + +#include "android-base/logging.h" + #include "ResourceTable.h" #include "ResourceUtils.h" #include "ResourceValues.h" @@ -23,9 +29,6 @@ #include "util/Util.h" #include "xml/XmlPullParser.h" -#include <functional> -#include <sstream> - namespace aapt { constexpr const char* sXliffNamespaceUri = @@ -35,12 +38,12 @@ constexpr const char* sXliffNamespaceUri = * Returns true if the element is <skip> or <eat-comment> and can be safely * ignored. */ -static bool shouldIgnoreElement(const StringPiece& ns, +static bool ShouldIgnoreElement(const StringPiece& ns, const StringPiece& name) { return ns.empty() && (name == "skip" || name == "eat-comment"); } -static uint32_t parseFormatType(const StringPiece& piece) { +static uint32_t ParseFormatType(const StringPiece& piece) { if (piece == "reference") return android::ResTable_map::TYPE_REFERENCE; else if (piece == "string") @@ -64,11 +67,11 @@ static uint32_t parseFormatType(const StringPiece& piece) { return 0; } -static uint32_t parseFormatAttribute(const StringPiece& str) { +static uint32_t ParseFormatAttribute(const StringPiece& str) { uint32_t mask = 0; - for (StringPiece part : util::tokenize(str, '|')) { - StringPiece trimmedPart = util::trimWhitespace(part); - uint32_t type = parseFormatType(trimmedPart); + for (StringPiece part : util::Tokenize(str, '|')) { + StringPiece trimmed_part = util::TrimWhitespace(part); + uint32_t type = ParseFormatType(trimmed_part); if (type == 0) { return 0; } @@ -86,45 +89,45 @@ struct ParsedResource { std::string product; Source source; ResourceId id; - Maybe<SymbolState> symbolState; + Maybe<SymbolState> symbol_state; std::string comment; std::unique_ptr<Value> value; - std::list<ParsedResource> childResources; + std::list<ParsedResource> child_resources; }; // Recursively adds resources to the ResourceTable. -static bool addResourcesToTable(ResourceTable* table, IDiagnostics* diag, +static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag, ParsedResource* res) { - StringPiece trimmedComment = util::trimWhitespace(res->comment); - if (trimmedComment.size() != res->comment.size()) { + StringPiece trimmed_comment = util::TrimWhitespace(res->comment); + if (trimmed_comment.size() != res->comment.size()) { // Only if there was a change do we re-assign. - res->comment = trimmedComment.toString(); + res->comment = trimmed_comment.ToString(); } - if (res->symbolState) { + if (res->symbol_state) { Symbol symbol; - symbol.state = res->symbolState.value(); + symbol.state = res->symbol_state.value(); symbol.source = res->source; symbol.comment = res->comment; - if (!table->setSymbolState(res->name, res->id, symbol, diag)) { + if (!table->SetSymbolState(res->name, res->id, symbol, diag)) { return false; } } if (res->value) { // Attach the comment, source and config to the value. - res->value->setComment(std::move(res->comment)); - res->value->setSource(std::move(res->source)); + res->value->SetComment(std::move(res->comment)); + res->value->SetSource(std::move(res->source)); - if (!table->addResource(res->name, res->id, res->config, res->product, + if (!table->AddResource(res->name, res->id, res->config, res->product, std::move(res->value), diag)) { return false; } } bool error = false; - for (ParsedResource& child : res->childResources) { - error |= !addResourcesToTable(table, diag, &child); + for (ParsedResource& child : res->child_resources) { + error |= !AddResourcesToTable(table, diag, &child); } return !error; } @@ -136,29 +139,29 @@ ResourceParser::ResourceParser(IDiagnostics* diag, ResourceTable* table, const Source& source, const ConfigDescription& config, const ResourceParserOptions& options) - : mDiag(diag), - mTable(table), - mSource(source), - mConfig(config), - mOptions(options) {} + : diag_(diag), + table_(table), + source_(source), + config_(config), + options_(options) {} /** * Build a string from XML that converts nested elements into Span objects. */ -bool ResourceParser::flattenXmlSubtree(xml::XmlPullParser* parser, - std::string* outRawString, - StyleString* outStyleString) { - std::vector<Span> spanStack; +bool ResourceParser::FlattenXmlSubtree(xml::XmlPullParser* parser, + std::string* out_raw_string, + StyleString* out_style_string) { + std::vector<Span> span_stack; bool error = false; - outRawString->clear(); - outStyleString->spans.clear(); + out_raw_string->clear(); + out_style_string->spans.clear(); util::StringBuilder builder; size_t depth = 1; - while (xml::XmlPullParser::isGoodEvent(parser->next())) { - const xml::XmlPullParser::Event event = parser->getEvent(); + while (xml::XmlPullParser::IsGoodEvent(parser->Next())) { + const xml::XmlPullParser::Event event = parser->event(); if (event == xml::XmlPullParser::Event::kEndElement) { - if (!parser->getElementNamespace().empty()) { + if (!parser->element_namespace().empty()) { // We already warned and skipped the start element, so just skip here // too continue; @@ -169,150 +172,151 @@ bool ResourceParser::flattenXmlSubtree(xml::XmlPullParser* parser, break; } - spanStack.back().lastChar = builder.utf16Len() - 1; - outStyleString->spans.push_back(spanStack.back()); - spanStack.pop_back(); + span_stack.back().last_char = builder.Utf16Len() - 1; + out_style_string->spans.push_back(span_stack.back()); + span_stack.pop_back(); } else if (event == xml::XmlPullParser::Event::kText) { - outRawString->append(parser->getText()); - builder.append(parser->getText()); + out_raw_string->append(parser->text()); + builder.Append(parser->text()); } else if (event == xml::XmlPullParser::Event::kStartElement) { - if (!parser->getElementNamespace().empty()) { - if (parser->getElementNamespace() != sXliffNamespaceUri) { + if (!parser->element_namespace().empty()) { + if (parser->element_namespace() != sXliffNamespaceUri) { // Only warn if this isn't an xliff namespace. - mDiag->warn(DiagMessage(mSource.withLine(parser->getLineNumber())) - << "skipping element '" << parser->getElementName() + diag_->Warn(DiagMessage(source_.WithLine(parser->line_number())) + << "skipping element '" << parser->element_name() << "' with unknown namespace '" - << parser->getElementNamespace() << "'"); + << parser->element_namespace() << "'"); } continue; } depth++; // Build a span object out of the nested element. - std::string spanName = parser->getElementName(); - const auto endAttrIter = parser->endAttributes(); - for (auto attrIter = parser->beginAttributes(); attrIter != endAttrIter; - ++attrIter) { - spanName += ";"; - spanName += attrIter->name; - spanName += "="; - spanName += attrIter->value; + std::string span_name = parser->element_name(); + const auto end_attr_iter = parser->end_attributes(); + for (auto attr_iter = parser->begin_attributes(); + attr_iter != end_attr_iter; ++attr_iter) { + span_name += ";"; + span_name += attr_iter->name; + span_name += "="; + span_name += attr_iter->value; } - if (builder.utf16Len() > std::numeric_limits<uint32_t>::max()) { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) - << "style string '" << builder.str() << "' is too long"); + if (builder.Utf16Len() > std::numeric_limits<uint32_t>::max()) { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) + << "style string '" << builder.ToString() + << "' is too long"); error = true; } else { - spanStack.push_back( - Span{spanName, static_cast<uint32_t>(builder.utf16Len())}); + span_stack.push_back( + Span{span_name, static_cast<uint32_t>(builder.Utf16Len())}); } } else if (event == xml::XmlPullParser::Event::kComment) { // Skip } else { - assert(false); + LOG(FATAL) << "unhandled XML event"; } } - assert(spanStack.empty() && "spans haven't been fully processed"); + CHECK(span_stack.empty()) << "spans haven't been fully processed"; - outStyleString->str = builder.str(); + out_style_string->str = builder.ToString(); return !error; } -bool ResourceParser::parse(xml::XmlPullParser* parser) { +bool ResourceParser::Parse(xml::XmlPullParser* parser) { bool error = false; - const size_t depth = parser->getDepth(); - while (xml::XmlPullParser::nextChildNode(parser, depth)) { - if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) { + const size_t depth = parser->depth(); + while (xml::XmlPullParser::NextChildNode(parser, depth)) { + if (parser->event() != xml::XmlPullParser::Event::kStartElement) { // Skip comments and text. continue; } - if (!parser->getElementNamespace().empty() || - parser->getElementName() != "resources") { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) + if (!parser->element_namespace().empty() || + parser->element_name() != "resources") { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) << "root element must be <resources>"); return false; } - error |= !parseResources(parser); + error |= !ParseResources(parser); break; }; - if (parser->getEvent() == xml::XmlPullParser::Event::kBadDocument) { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) - << "xml parser error: " << parser->getLastError()); + if (parser->event() == xml::XmlPullParser::Event::kBadDocument) { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) + << "xml parser error: " << parser->error()); return false; } return !error; } -bool ResourceParser::parseResources(xml::XmlPullParser* parser) { - std::set<ResourceName> strippedResources; +bool ResourceParser::ParseResources(xml::XmlPullParser* parser) { + std::set<ResourceName> stripped_resources; bool error = false; std::string comment; - const size_t depth = parser->getDepth(); - while (xml::XmlPullParser::nextChildNode(parser, depth)) { - const xml::XmlPullParser::Event event = parser->getEvent(); + const size_t depth = parser->depth(); + while (xml::XmlPullParser::NextChildNode(parser, depth)) { + const xml::XmlPullParser::Event event = parser->event(); if (event == xml::XmlPullParser::Event::kComment) { - comment = parser->getComment(); + comment = parser->comment(); continue; } if (event == xml::XmlPullParser::Event::kText) { - if (!util::trimWhitespace(parser->getText()).empty()) { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) + if (!util::TrimWhitespace(parser->text()).empty()) { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) << "plain text not allowed here"); error = true; } continue; } - assert(event == xml::XmlPullParser::Event::kStartElement); + CHECK(event == xml::XmlPullParser::Event::kStartElement); - if (!parser->getElementNamespace().empty()) { + if (!parser->element_namespace().empty()) { // Skip unknown namespace. continue; } - std::string elementName = parser->getElementName(); - if (elementName == "skip" || elementName == "eat-comment") { + std::string element_name = parser->element_name(); + if (element_name == "skip" || element_name == "eat-comment") { comment = ""; continue; } - ParsedResource parsedResource; - parsedResource.config = mConfig; - parsedResource.source = mSource.withLine(parser->getLineNumber()); - parsedResource.comment = std::move(comment); + ParsedResource parsed_resource; + parsed_resource.config = config_; + parsed_resource.source = source_.WithLine(parser->line_number()); + parsed_resource.comment = std::move(comment); // Extract the product name if it exists. - if (Maybe<StringPiece> maybeProduct = - xml::findNonEmptyAttribute(parser, "product")) { - parsedResource.product = maybeProduct.value().toString(); + if (Maybe<StringPiece> maybe_product = + xml::FindNonEmptyAttribute(parser, "product")) { + parsed_resource.product = maybe_product.value().ToString(); } // Parse the resource regardless of product. - if (!parseResource(parser, &parsedResource)) { + if (!ParseResource(parser, &parsed_resource)) { error = true; continue; } - if (!addResourcesToTable(mTable, mDiag, &parsedResource)) { + if (!AddResourcesToTable(table_, diag_, &parsed_resource)) { error = true; } } // Check that we included at least one variant of each stripped resource. - for (const ResourceName& strippedResource : strippedResources) { - if (!mTable->findResource(strippedResource)) { + for (const ResourceName& stripped_resource : stripped_resources) { + if (!table_->FindResource(stripped_resource)) { // Failed to find the resource. - mDiag->error(DiagMessage(mSource) - << "resource '" << strippedResource + diag_->Error(DiagMessage(source_) + << "resource '" << stripped_resource << "' " "was filtered out but no product variant remains"); error = true; @@ -322,8 +326,8 @@ bool ResourceParser::parseResources(xml::XmlPullParser* parser) { return !error; } -bool ResourceParser::parseResource(xml::XmlPullParser* parser, - ParsedResource* outResource) { +bool ResourceParser::ParseResource(xml::XmlPullParser* parser, + ParsedResource* out_resource) { struct ItemTypeFormat { ResourceType type; uint32_t format; @@ -333,7 +337,7 @@ bool ResourceParser::parseResource(xml::XmlPullParser* parser, ParsedResource*)>; static const auto elToItemMap = - ImmutableMap<std::string, ItemTypeFormat>::createPreSorted({ + ImmutableMap<std::string, ItemTypeFormat>::CreatePreSorted({ {"bool", {ResourceType::kBool, android::ResTable_map::TYPE_BOOLEAN}}, {"color", {ResourceType::kColor, android::ResTable_map::TYPE_COLOR}}, {"dimen", @@ -354,48 +358,49 @@ bool ResourceParser::parseResource(xml::XmlPullParser* parser, }); static const auto elToBagMap = - ImmutableMap<std::string, BagParseFunc>::createPreSorted({ - {"add-resource", std::mem_fn(&ResourceParser::parseAddResource)}, - {"array", std::mem_fn(&ResourceParser::parseArray)}, - {"attr", std::mem_fn(&ResourceParser::parseAttr)}, + ImmutableMap<std::string, BagParseFunc>::CreatePreSorted({ + {"add-resource", std::mem_fn(&ResourceParser::ParseAddResource)}, + {"array", std::mem_fn(&ResourceParser::ParseArray)}, + {"attr", std::mem_fn(&ResourceParser::ParseAttr)}, {"declare-styleable", - std::mem_fn(&ResourceParser::parseDeclareStyleable)}, - {"integer-array", std::mem_fn(&ResourceParser::parseIntegerArray)}, - {"java-symbol", std::mem_fn(&ResourceParser::parseSymbol)}, - {"plurals", std::mem_fn(&ResourceParser::parsePlural)}, - {"public", std::mem_fn(&ResourceParser::parsePublic)}, - {"public-group", std::mem_fn(&ResourceParser::parsePublicGroup)}, - {"string-array", std::mem_fn(&ResourceParser::parseStringArray)}, - {"style", std::mem_fn(&ResourceParser::parseStyle)}, - {"symbol", std::mem_fn(&ResourceParser::parseSymbol)}, + std::mem_fn(&ResourceParser::ParseDeclareStyleable)}, + {"integer-array", std::mem_fn(&ResourceParser::ParseIntegerArray)}, + {"java-symbol", std::mem_fn(&ResourceParser::ParseSymbol)}, + {"plurals", std::mem_fn(&ResourceParser::ParsePlural)}, + {"public", std::mem_fn(&ResourceParser::ParsePublic)}, + {"public-group", std::mem_fn(&ResourceParser::ParsePublicGroup)}, + {"string-array", std::mem_fn(&ResourceParser::ParseStringArray)}, + {"style", std::mem_fn(&ResourceParser::ParseStyle)}, + {"symbol", std::mem_fn(&ResourceParser::ParseSymbol)}, }); - std::string resourceType = parser->getElementName(); + std::string resource_type = parser->element_name(); // The value format accepted for this resource. - uint32_t resourceFormat = 0u; + uint32_t resource_format = 0u; - if (resourceType == "item") { + if (resource_type == "item") { // Items have their type encoded in the type attribute. - if (Maybe<StringPiece> maybeType = - xml::findNonEmptyAttribute(parser, "type")) { - resourceType = maybeType.value().toString(); + if (Maybe<StringPiece> maybe_type = + xml::FindNonEmptyAttribute(parser, "type")) { + resource_type = maybe_type.value().ToString(); } else { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) << "<item> must have a 'type' attribute"); return false; } - if (Maybe<StringPiece> maybeFormat = - xml::findNonEmptyAttribute(parser, "format")) { + if (Maybe<StringPiece> maybe_format = + xml::FindNonEmptyAttribute(parser, "format")) { // An explicit format for this resource was specified. The resource will // retain // its type in its name, but the accepted value for this type is // overridden. - resourceFormat = parseFormatType(maybeFormat.value()); - if (!resourceFormat) { - mDiag->error(DiagMessage(outResource->source) - << "'" << maybeFormat.value() << "' is an invalid format"); + resource_format = ParseFormatType(maybe_format.value()); + if (!resource_format) { + diag_->Error(DiagMessage(out_resource->source) + << "'" << maybe_format.value() + << "' is an invalid format"); return false; } } @@ -403,65 +408,65 @@ bool ResourceParser::parseResource(xml::XmlPullParser* parser, // Get the name of the resource. This will be checked later, because not all // XML elements require a name. - Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name"); + Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name"); - if (resourceType == "id") { - if (!maybeName) { - mDiag->error(DiagMessage(outResource->source) - << "<" << parser->getElementName() + if (resource_type == "id") { + if (!maybe_name) { + diag_->Error(DiagMessage(out_resource->source) + << "<" << parser->element_name() << "> missing 'name' attribute"); return false; } - outResource->name.type = ResourceType::kId; - outResource->name.entry = maybeName.value().toString(); - outResource->value = util::make_unique<Id>(); + out_resource->name.type = ResourceType::kId; + out_resource->name.entry = maybe_name.value().ToString(); + out_resource->value = util::make_unique<Id>(); return true; } - const auto itemIter = elToItemMap.find(resourceType); - if (itemIter != elToItemMap.end()) { + const auto item_iter = elToItemMap.find(resource_type); + if (item_iter != elToItemMap.end()) { // This is an item, record its type and format and start parsing. - if (!maybeName) { - mDiag->error(DiagMessage(outResource->source) - << "<" << parser->getElementName() + if (!maybe_name) { + diag_->Error(DiagMessage(out_resource->source) + << "<" << parser->element_name() << "> missing 'name' attribute"); return false; } - outResource->name.type = itemIter->second.type; - outResource->name.entry = maybeName.value().toString(); + out_resource->name.type = item_iter->second.type; + out_resource->name.entry = maybe_name.value().ToString(); // Only use the implicit format for this type if it wasn't overridden. - if (!resourceFormat) { - resourceFormat = itemIter->second.format; + if (!resource_format) { + resource_format = item_iter->second.format; } - if (!parseItem(parser, outResource, resourceFormat)) { + if (!ParseItem(parser, out_resource, resource_format)) { return false; } return true; } // This might be a bag or something. - const auto bagIter = elToBagMap.find(resourceType); - if (bagIter != elToBagMap.end()) { + const auto bag_iter = elToBagMap.find(resource_type); + if (bag_iter != elToBagMap.end()) { // Ensure we have a name (unless this is a <public-group>). - if (resourceType != "public-group") { - if (!maybeName) { - mDiag->error(DiagMessage(outResource->source) - << "<" << parser->getElementName() + if (resource_type != "public-group") { + if (!maybe_name) { + diag_->Error(DiagMessage(out_resource->source) + << "<" << parser->element_name() << "> missing 'name' attribute"); return false; } - outResource->name.entry = maybeName.value().toString(); + out_resource->name.entry = maybe_name.value().ToString(); } // Call the associated parse method. The type will be filled in by the // parse func. - if (!bagIter->second(this, parser, outResource)) { + if (!bag_iter->second(this, parser, out_resource)) { return false; } return true; @@ -469,44 +474,44 @@ bool ResourceParser::parseResource(xml::XmlPullParser* parser, // Try parsing the elementName (or type) as a resource. These shall only be // resources like 'layout' or 'xml' and they can only be references. - const ResourceType* parsedType = parseResourceType(resourceType); - if (parsedType) { - if (!maybeName) { - mDiag->error(DiagMessage(outResource->source) - << "<" << parser->getElementName() + const ResourceType* parsed_type = ParseResourceType(resource_type); + if (parsed_type) { + if (!maybe_name) { + diag_->Error(DiagMessage(out_resource->source) + << "<" << parser->element_name() << "> missing 'name' attribute"); return false; } - outResource->name.type = *parsedType; - outResource->name.entry = maybeName.value().toString(); - outResource->value = - parseXml(parser, android::ResTable_map::TYPE_REFERENCE, kNoRawString); - if (!outResource->value) { - mDiag->error(DiagMessage(outResource->source) - << "invalid value for type '" << *parsedType + out_resource->name.type = *parsed_type; + out_resource->name.entry = maybe_name.value().ToString(); + out_resource->value = + ParseXml(parser, android::ResTable_map::TYPE_REFERENCE, kNoRawString); + if (!out_resource->value) { + diag_->Error(DiagMessage(out_resource->source) + << "invalid value for type '" << *parsed_type << "'. Expected a reference"); return false; } return true; } - mDiag->warn(DiagMessage(outResource->source) - << "unknown resource type '" << parser->getElementName() << "'"); + diag_->Warn(DiagMessage(out_resource->source) + << "unknown resource type '" << parser->element_name() << "'"); return false; } -bool ResourceParser::parseItem(xml::XmlPullParser* parser, - ParsedResource* outResource, +bool ResourceParser::ParseItem(xml::XmlPullParser* parser, + ParsedResource* out_resource, const uint32_t format) { if (format == android::ResTable_map::TYPE_STRING) { - return parseString(parser, outResource); + return ParseString(parser, out_resource); } - outResource->value = parseXml(parser, format, kNoRawString); - if (!outResource->value) { - mDiag->error(DiagMessage(outResource->source) << "invalid " - << outResource->name.type); + out_resource->value = ParseXml(parser, format, kNoRawString); + if (!out_resource->value) { + diag_->Error(DiagMessage(out_resource->source) << "invalid " + << out_resource->name.type); return false; } return true; @@ -519,362 +524,364 @@ bool ResourceParser::parseItem(xml::XmlPullParser* parser, * an Item. If allowRawValue is false, nullptr is returned in this * case. */ -std::unique_ptr<Item> ResourceParser::parseXml(xml::XmlPullParser* parser, - const uint32_t typeMask, - const bool allowRawValue) { - const size_t beginXmlLine = parser->getLineNumber(); - - std::string rawValue; - StyleString styleString; - if (!flattenXmlSubtree(parser, &rawValue, &styleString)) { +std::unique_ptr<Item> ResourceParser::ParseXml(xml::XmlPullParser* parser, + const uint32_t type_mask, + const bool allow_raw_value) { + const size_t begin_xml_line = parser->line_number(); + + std::string raw_value; + StyleString style_string; + if (!FlattenXmlSubtree(parser, &raw_value, &style_string)) { return {}; } - if (!styleString.spans.empty()) { + if (!style_string.spans.empty()) { // This can only be a StyledString. - return util::make_unique<StyledString>(mTable->stringPool.makeRef( - styleString, - StringPool::Context(StringPool::Context::kStylePriority, mConfig))); + return util::make_unique<StyledString>(table_->string_pool.MakeRef( + style_string, + StringPool::Context(StringPool::Context::kStylePriority, config_))); } - auto onCreateReference = [&](const ResourceName& name) { + auto on_create_reference = [&](const ResourceName& name) { // name.package can be empty here, as it will assume the package name of the // table. std::unique_ptr<Id> id = util::make_unique<Id>(); - id->setSource(mSource.withLine(beginXmlLine)); - mTable->addResource(name, {}, {}, std::move(id), mDiag); + id->SetSource(source_.WithLine(begin_xml_line)); + table_->AddResource(name, {}, {}, std::move(id), diag_); }; // Process the raw value. - std::unique_ptr<Item> processedItem = ResourceUtils::tryParseItemForAttribute( - rawValue, typeMask, onCreateReference); - if (processedItem) { + std::unique_ptr<Item> processed_item = + ResourceUtils::TryParseItemForAttribute(raw_value, type_mask, + on_create_reference); + if (processed_item) { // Fix up the reference. - if (Reference* ref = valueCast<Reference>(processedItem.get())) { - transformReferenceFromNamespace(parser, "", ref); + if (Reference* ref = ValueCast<Reference>(processed_item.get())) { + TransformReferenceFromNamespace(parser, "", ref); } - return processedItem; + return processed_item; } // Try making a regular string. - if (typeMask & android::ResTable_map::TYPE_STRING) { + if (type_mask & android::ResTable_map::TYPE_STRING) { // Use the trimmed, escaped string. - return util::make_unique<String>(mTable->stringPool.makeRef( - styleString.str, StringPool::Context(mConfig))); + return util::make_unique<String>(table_->string_pool.MakeRef( + style_string.str, StringPool::Context(config_))); } - if (allowRawValue) { + if (allow_raw_value) { // We can't parse this so return a RawString if we are allowed. return util::make_unique<RawString>( - mTable->stringPool.makeRef(rawValue, StringPool::Context(mConfig))); + table_->string_pool.MakeRef(raw_value, StringPool::Context(config_))); } return {}; } -bool ResourceParser::parseString(xml::XmlPullParser* parser, - ParsedResource* outResource) { +bool ResourceParser::ParseString(xml::XmlPullParser* parser, + ParsedResource* out_resource) { bool formatted = true; - if (Maybe<StringPiece> formattedAttr = - xml::findAttribute(parser, "formatted")) { - Maybe<bool> maybeFormatted = - ResourceUtils::parseBool(formattedAttr.value()); - if (!maybeFormatted) { - mDiag->error(DiagMessage(outResource->source) + if (Maybe<StringPiece> formatted_attr = + xml::FindAttribute(parser, "formatted")) { + Maybe<bool> maybe_formatted = + ResourceUtils::ParseBool(formatted_attr.value()); + if (!maybe_formatted) { + diag_->Error(DiagMessage(out_resource->source) << "invalid value for 'formatted'. Must be a boolean"); return false; } - formatted = maybeFormatted.value(); + formatted = maybe_formatted.value(); } - bool translateable = mOptions.translatable; - if (Maybe<StringPiece> translateableAttr = - xml::findAttribute(parser, "translatable")) { - Maybe<bool> maybeTranslateable = - ResourceUtils::parseBool(translateableAttr.value()); - if (!maybeTranslateable) { - mDiag->error(DiagMessage(outResource->source) + bool translateable = options_.translatable; + if (Maybe<StringPiece> translateable_attr = + xml::FindAttribute(parser, "translatable")) { + Maybe<bool> maybe_translateable = + ResourceUtils::ParseBool(translateable_attr.value()); + if (!maybe_translateable) { + diag_->Error(DiagMessage(out_resource->source) << "invalid value for 'translatable'. Must be a boolean"); return false; } - translateable = maybeTranslateable.value(); + translateable = maybe_translateable.value(); } - outResource->value = - parseXml(parser, android::ResTable_map::TYPE_STRING, kNoRawString); - if (!outResource->value) { - mDiag->error(DiagMessage(outResource->source) << "not a valid string"); + out_resource->value = + ParseXml(parser, android::ResTable_map::TYPE_STRING, kNoRawString); + if (!out_resource->value) { + diag_->Error(DiagMessage(out_resource->source) << "not a valid string"); return false; } - if (String* stringValue = valueCast<String>(outResource->value.get())) { - stringValue->setTranslateable(translateable); + if (String* string_value = ValueCast<String>(out_resource->value.get())) { + string_value->SetTranslateable(translateable); if (formatted && translateable) { - if (!util::verifyJavaStringFormat(*stringValue->value)) { - DiagMessage msg(outResource->source); + if (!util::VerifyJavaStringFormat(*string_value->value)) { + DiagMessage msg(out_resource->source); msg << "multiple substitutions specified in non-positional format; " "did you mean to add the formatted=\"false\" attribute?"; - if (mOptions.errorOnPositionalArguments) { - mDiag->error(msg); + if (options_.error_on_positional_arguments) { + diag_->Error(msg); return false; } - mDiag->warn(msg); + diag_->Warn(msg); } } - } else if (StyledString* stringValue = - valueCast<StyledString>(outResource->value.get())) { - stringValue->setTranslateable(translateable); + } else if (StyledString* string_value = + ValueCast<StyledString>(out_resource->value.get())) { + string_value->SetTranslateable(translateable); } return true; } -bool ResourceParser::parsePublic(xml::XmlPullParser* parser, - ParsedResource* outResource) { - Maybe<StringPiece> maybeType = xml::findNonEmptyAttribute(parser, "type"); - if (!maybeType) { - mDiag->error(DiagMessage(outResource->source) +bool ResourceParser::ParsePublic(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type"); + if (!maybe_type) { + diag_->Error(DiagMessage(out_resource->source) << "<public> must have a 'type' attribute"); return false; } - const ResourceType* parsedType = parseResourceType(maybeType.value()); - if (!parsedType) { - mDiag->error(DiagMessage(outResource->source) << "invalid resource type '" - << maybeType.value() - << "' in <public>"); + const ResourceType* parsed_type = ParseResourceType(maybe_type.value()); + if (!parsed_type) { + diag_->Error(DiagMessage(out_resource->source) << "invalid resource type '" + << maybe_type.value() + << "' in <public>"); return false; } - outResource->name.type = *parsedType; + out_resource->name.type = *parsed_type; - if (Maybe<StringPiece> maybeIdStr = - xml::findNonEmptyAttribute(parser, "id")) { - Maybe<ResourceId> maybeId = - ResourceUtils::parseResourceId(maybeIdStr.value()); - if (!maybeId) { - mDiag->error(DiagMessage(outResource->source) << "invalid resource ID '" - << maybeId.value() - << "' in <public>"); + if (Maybe<StringPiece> maybe_id_str = + xml::FindNonEmptyAttribute(parser, "id")) { + Maybe<ResourceId> maybe_id = + ResourceUtils::ParseResourceId(maybe_id_str.value()); + if (!maybe_id) { + diag_->Error(DiagMessage(out_resource->source) << "invalid resource ID '" + << maybe_id.value() + << "' in <public>"); return false; } - outResource->id = maybeId.value(); + out_resource->id = maybe_id.value(); } - if (*parsedType == ResourceType::kId) { + if (*parsed_type == ResourceType::kId) { // An ID marked as public is also the definition of an ID. - outResource->value = util::make_unique<Id>(); + out_resource->value = util::make_unique<Id>(); } - outResource->symbolState = SymbolState::kPublic; + out_resource->symbol_state = SymbolState::kPublic; return true; } -bool ResourceParser::parsePublicGroup(xml::XmlPullParser* parser, - ParsedResource* outResource) { - Maybe<StringPiece> maybeType = xml::findNonEmptyAttribute(parser, "type"); - if (!maybeType) { - mDiag->error(DiagMessage(outResource->source) +bool ResourceParser::ParsePublicGroup(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type"); + if (!maybe_type) { + diag_->Error(DiagMessage(out_resource->source) << "<public-group> must have a 'type' attribute"); return false; } - const ResourceType* parsedType = parseResourceType(maybeType.value()); - if (!parsedType) { - mDiag->error(DiagMessage(outResource->source) << "invalid resource type '" - << maybeType.value() - << "' in <public-group>"); + const ResourceType* parsed_type = ParseResourceType(maybe_type.value()); + if (!parsed_type) { + diag_->Error(DiagMessage(out_resource->source) << "invalid resource type '" + << maybe_type.value() + << "' in <public-group>"); return false; } - Maybe<StringPiece> maybeIdStr = - xml::findNonEmptyAttribute(parser, "first-id"); - if (!maybeIdStr) { - mDiag->error(DiagMessage(outResource->source) + Maybe<StringPiece> maybe_id_str = + xml::FindNonEmptyAttribute(parser, "first-id"); + if (!maybe_id_str) { + diag_->Error(DiagMessage(out_resource->source) << "<public-group> must have a 'first-id' attribute"); return false; } - Maybe<ResourceId> maybeId = - ResourceUtils::parseResourceId(maybeIdStr.value()); - if (!maybeId) { - mDiag->error(DiagMessage(outResource->source) << "invalid resource ID '" - << maybeIdStr.value() - << "' in <public-group>"); + Maybe<ResourceId> maybe_id = + ResourceUtils::ParseResourceId(maybe_id_str.value()); + if (!maybe_id) { + diag_->Error(DiagMessage(out_resource->source) << "invalid resource ID '" + << maybe_id_str.value() + << "' in <public-group>"); return false; } - ResourceId nextId = maybeId.value(); + ResourceId next_id = maybe_id.value(); std::string comment; bool error = false; - const size_t depth = parser->getDepth(); - while (xml::XmlPullParser::nextChildNode(parser, depth)) { - if (parser->getEvent() == xml::XmlPullParser::Event::kComment) { - comment = util::trimWhitespace(parser->getComment()).toString(); + const size_t depth = parser->depth(); + while (xml::XmlPullParser::NextChildNode(parser, depth)) { + if (parser->event() == xml::XmlPullParser::Event::kComment) { + comment = util::TrimWhitespace(parser->comment()).ToString(); continue; - } else if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) { + } else if (parser->event() != xml::XmlPullParser::Event::kStartElement) { // Skip text. continue; } - const Source itemSource = mSource.withLine(parser->getLineNumber()); - const std::string& elementNamespace = parser->getElementNamespace(); - const std::string& elementName = parser->getElementName(); - if (elementNamespace.empty() && elementName == "public") { - Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name"); - if (!maybeName) { - mDiag->error(DiagMessage(itemSource) + const Source item_source = source_.WithLine(parser->line_number()); + const std::string& element_namespace = parser->element_namespace(); + const std::string& element_name = parser->element_name(); + if (element_namespace.empty() && element_name == "public") { + Maybe<StringPiece> maybe_name = + xml::FindNonEmptyAttribute(parser, "name"); + if (!maybe_name) { + diag_->Error(DiagMessage(item_source) << "<public> must have a 'name' attribute"); error = true; continue; } - if (xml::findNonEmptyAttribute(parser, "id")) { - mDiag->error(DiagMessage(itemSource) + if (xml::FindNonEmptyAttribute(parser, "id")) { + diag_->Error(DiagMessage(item_source) << "'id' is ignored within <public-group>"); error = true; continue; } - if (xml::findNonEmptyAttribute(parser, "type")) { - mDiag->error(DiagMessage(itemSource) + if (xml::FindNonEmptyAttribute(parser, "type")) { + diag_->Error(DiagMessage(item_source) << "'type' is ignored within <public-group>"); error = true; continue; } - ParsedResource childResource; - childResource.name.type = *parsedType; - childResource.name.entry = maybeName.value().toString(); - childResource.id = nextId; - childResource.comment = std::move(comment); - childResource.source = itemSource; - childResource.symbolState = SymbolState::kPublic; - outResource->childResources.push_back(std::move(childResource)); + ParsedResource child_resource; + child_resource.name.type = *parsed_type; + child_resource.name.entry = maybe_name.value().ToString(); + child_resource.id = next_id; + child_resource.comment = std::move(comment); + child_resource.source = item_source; + child_resource.symbol_state = SymbolState::kPublic; + out_resource->child_resources.push_back(std::move(child_resource)); - nextId.id += 1; + next_id.id += 1; - } else if (!shouldIgnoreElement(elementNamespace, elementName)) { - mDiag->error(DiagMessage(itemSource) << ":" << elementName << ">"); + } else if (!ShouldIgnoreElement(element_namespace, element_name)) { + diag_->Error(DiagMessage(item_source) << ":" << element_name << ">"); error = true; } } return !error; } -bool ResourceParser::parseSymbolImpl(xml::XmlPullParser* parser, - ParsedResource* outResource) { - Maybe<StringPiece> maybeType = xml::findNonEmptyAttribute(parser, "type"); - if (!maybeType) { - mDiag->error(DiagMessage(outResource->source) - << "<" << parser->getElementName() +bool ResourceParser::ParseSymbolImpl(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type"); + if (!maybe_type) { + diag_->Error(DiagMessage(out_resource->source) + << "<" << parser->element_name() << "> must have a 'type' attribute"); return false; } - const ResourceType* parsedType = parseResourceType(maybeType.value()); - if (!parsedType) { - mDiag->error(DiagMessage(outResource->source) - << "invalid resource type '" << maybeType.value() << "' in <" - << parser->getElementName() << ">"); + const ResourceType* parsed_type = ParseResourceType(maybe_type.value()); + if (!parsed_type) { + diag_->Error(DiagMessage(out_resource->source) + << "invalid resource type '" << maybe_type.value() << "' in <" + << parser->element_name() << ">"); return false; } - outResource->name.type = *parsedType; + out_resource->name.type = *parsed_type; return true; } -bool ResourceParser::parseSymbol(xml::XmlPullParser* parser, - ParsedResource* outResource) { - if (parseSymbolImpl(parser, outResource)) { - outResource->symbolState = SymbolState::kPrivate; +bool ResourceParser::ParseSymbol(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + if (ParseSymbolImpl(parser, out_resource)) { + out_resource->symbol_state = SymbolState::kPrivate; return true; } return false; } -bool ResourceParser::parseAddResource(xml::XmlPullParser* parser, - ParsedResource* outResource) { - if (parseSymbolImpl(parser, outResource)) { - outResource->symbolState = SymbolState::kUndefined; +bool ResourceParser::ParseAddResource(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + if (ParseSymbolImpl(parser, out_resource)) { + out_resource->symbol_state = SymbolState::kUndefined; return true; } return false; } -bool ResourceParser::parseAttr(xml::XmlPullParser* parser, - ParsedResource* outResource) { - return parseAttrImpl(parser, outResource, false); +bool ResourceParser::ParseAttr(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + return ParseAttrImpl(parser, out_resource, false); } -bool ResourceParser::parseAttrImpl(xml::XmlPullParser* parser, - ParsedResource* outResource, bool weak) { - outResource->name.type = ResourceType::kAttr; +bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser, + ParsedResource* out_resource, bool weak) { + out_resource->name.type = ResourceType::kAttr; // Attributes only end up in default configuration. - if (outResource->config != ConfigDescription::defaultConfig()) { - mDiag->warn(DiagMessage(outResource->source) - << "ignoring configuration '" << outResource->config - << "' for attribute " << outResource->name); - outResource->config = ConfigDescription::defaultConfig(); + if (out_resource->config != ConfigDescription::DefaultConfig()) { + diag_->Warn(DiagMessage(out_resource->source) + << "ignoring configuration '" << out_resource->config + << "' for attribute " << out_resource->name); + out_resource->config = ConfigDescription::DefaultConfig(); } - uint32_t typeMask = 0; + uint32_t type_mask = 0; - Maybe<StringPiece> maybeFormat = xml::findAttribute(parser, "format"); - if (maybeFormat) { - typeMask = parseFormatAttribute(maybeFormat.value()); - if (typeMask == 0) { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) - << "invalid attribute format '" << maybeFormat.value() + Maybe<StringPiece> maybe_format = xml::FindAttribute(parser, "format"); + if (maybe_format) { + type_mask = ParseFormatAttribute(maybe_format.value()); + if (type_mask == 0) { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) + << "invalid attribute format '" << maybe_format.value() << "'"); return false; } } - Maybe<int32_t> maybeMin, maybeMax; + Maybe<int32_t> maybe_min, maybe_max; - if (Maybe<StringPiece> maybeMinStr = xml::findAttribute(parser, "min")) { - StringPiece minStr = util::trimWhitespace(maybeMinStr.value()); - if (!minStr.empty()) { - std::u16string minStr16 = util::utf8ToUtf16(minStr); + if (Maybe<StringPiece> maybe_min_str = xml::FindAttribute(parser, "min")) { + StringPiece min_str = util::TrimWhitespace(maybe_min_str.value()); + if (!min_str.empty()) { + std::u16string min_str16 = util::Utf8ToUtf16(min_str); android::Res_value value; - if (android::ResTable::stringToInt(minStr16.data(), minStr16.size(), + if (android::ResTable::stringToInt(min_str16.data(), min_str16.size(), &value)) { - maybeMin = static_cast<int32_t>(value.data); + maybe_min = static_cast<int32_t>(value.data); } } - if (!maybeMin) { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) - << "invalid 'min' value '" << minStr << "'"); + if (!maybe_min) { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) + << "invalid 'min' value '" << min_str << "'"); return false; } } - if (Maybe<StringPiece> maybeMaxStr = xml::findAttribute(parser, "max")) { - StringPiece maxStr = util::trimWhitespace(maybeMaxStr.value()); - if (!maxStr.empty()) { - std::u16string maxStr16 = util::utf8ToUtf16(maxStr); + if (Maybe<StringPiece> maybe_max_str = xml::FindAttribute(parser, "max")) { + StringPiece max_str = util::TrimWhitespace(maybe_max_str.value()); + if (!max_str.empty()) { + std::u16string max_str16 = util::Utf8ToUtf16(max_str); android::Res_value value; - if (android::ResTable::stringToInt(maxStr16.data(), maxStr16.size(), + if (android::ResTable::stringToInt(max_str16.data(), max_str16.size(), &value)) { - maybeMax = static_cast<int32_t>(value.data); + maybe_max = static_cast<int32_t>(value.data); } } - if (!maybeMax) { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) - << "invalid 'max' value '" << maxStr << "'"); + if (!maybe_max) { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) + << "invalid 'max' value '" << max_str << "'"); return false; } } - if ((maybeMin || maybeMax) && - (typeMask & android::ResTable_map::TYPE_INTEGER) == 0) { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) + if ((maybe_min || maybe_max) && + (type_mask & android::ResTable_map::TYPE_INTEGER) == 0) { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) << "'min' and 'max' can only be used when format='integer'"); return false; } @@ -889,68 +896,68 @@ bool ResourceParser::parseAttrImpl(xml::XmlPullParser* parser, std::string comment; bool error = false; - const size_t depth = parser->getDepth(); - while (xml::XmlPullParser::nextChildNode(parser, depth)) { - if (parser->getEvent() == xml::XmlPullParser::Event::kComment) { - comment = util::trimWhitespace(parser->getComment()).toString(); + const size_t depth = parser->depth(); + while (xml::XmlPullParser::NextChildNode(parser, depth)) { + if (parser->event() == xml::XmlPullParser::Event::kComment) { + comment = util::TrimWhitespace(parser->comment()).ToString(); continue; - } else if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) { + } else if (parser->event() != xml::XmlPullParser::Event::kStartElement) { // Skip text. continue; } - const Source itemSource = mSource.withLine(parser->getLineNumber()); - const std::string& elementNamespace = parser->getElementNamespace(); - const std::string& elementName = parser->getElementName(); - if (elementNamespace.empty() && - (elementName == "flag" || elementName == "enum")) { - if (elementName == "enum") { - if (typeMask & android::ResTable_map::TYPE_FLAGS) { - mDiag->error(DiagMessage(itemSource) + const Source item_source = source_.WithLine(parser->line_number()); + const std::string& element_namespace = parser->element_namespace(); + const std::string& element_name = parser->element_name(); + if (element_namespace.empty() && + (element_name == "flag" || element_name == "enum")) { + if (element_name == "enum") { + if (type_mask & android::ResTable_map::TYPE_FLAGS) { + diag_->Error(DiagMessage(item_source) << "can not define an <enum>; already defined a <flag>"); error = true; continue; } - typeMask |= android::ResTable_map::TYPE_ENUM; + type_mask |= android::ResTable_map::TYPE_ENUM; - } else if (elementName == "flag") { - if (typeMask & android::ResTable_map::TYPE_ENUM) { - mDiag->error(DiagMessage(itemSource) + } else if (element_name == "flag") { + if (type_mask & android::ResTable_map::TYPE_ENUM) { + diag_->Error(DiagMessage(item_source) << "can not define a <flag>; already defined an <enum>"); error = true; continue; } - typeMask |= android::ResTable_map::TYPE_FLAGS; + type_mask |= android::ResTable_map::TYPE_FLAGS; } if (Maybe<Attribute::Symbol> s = - parseEnumOrFlagItem(parser, elementName)) { + ParseEnumOrFlagItem(parser, element_name)) { Attribute::Symbol& symbol = s.value(); - ParsedResource childResource; - childResource.name = symbol.symbol.name.value(); - childResource.source = itemSource; - childResource.value = util::make_unique<Id>(); - outResource->childResources.push_back(std::move(childResource)); - - symbol.symbol.setComment(std::move(comment)); - symbol.symbol.setSource(itemSource); - - auto insertResult = items.insert(std::move(symbol)); - if (!insertResult.second) { - const Attribute::Symbol& existingSymbol = *insertResult.first; - mDiag->error(DiagMessage(itemSource) + ParsedResource child_resource; + child_resource.name = symbol.symbol.name.value(); + child_resource.source = item_source; + child_resource.value = util::make_unique<Id>(); + out_resource->child_resources.push_back(std::move(child_resource)); + + symbol.symbol.SetComment(std::move(comment)); + symbol.symbol.SetSource(item_source); + + auto insert_result = items.insert(std::move(symbol)); + if (!insert_result.second) { + const Attribute::Symbol& existing_symbol = *insert_result.first; + diag_->Error(DiagMessage(item_source) << "duplicate symbol '" - << existingSymbol.symbol.name.value().entry << "'"); + << existing_symbol.symbol.name.value().entry << "'"); - mDiag->note(DiagMessage(existingSymbol.symbol.getSource()) + diag_->Note(DiagMessage(existing_symbol.symbol.GetSource()) << "first defined here"); error = true; } } else { error = true; } - } else if (!shouldIgnoreElement(elementNamespace, elementName)) { - mDiag->error(DiagMessage(itemSource) << ":" << elementName << ">"); + } else if (!ShouldIgnoreElement(element_namespace, element_name)) { + diag_->Error(DiagMessage(item_source) << ":" << element_name << ">"); error = true; } @@ -963,134 +970,134 @@ bool ResourceParser::parseAttrImpl(xml::XmlPullParser* parser, std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(weak); attr->symbols = std::vector<Attribute::Symbol>(items.begin(), items.end()); - attr->typeMask = - typeMask ? typeMask : uint32_t(android::ResTable_map::TYPE_ANY); - if (maybeMin) { - attr->minInt = maybeMin.value(); + attr->type_mask = + type_mask ? type_mask : uint32_t(android::ResTable_map::TYPE_ANY); + if (maybe_min) { + attr->min_int = maybe_min.value(); } - if (maybeMax) { - attr->maxInt = maybeMax.value(); + if (maybe_max) { + attr->max_int = maybe_max.value(); } - outResource->value = std::move(attr); + out_resource->value = std::move(attr); return true; } -Maybe<Attribute::Symbol> ResourceParser::parseEnumOrFlagItem( +Maybe<Attribute::Symbol> ResourceParser::ParseEnumOrFlagItem( xml::XmlPullParser* parser, const StringPiece& tag) { - const Source source = mSource.withLine(parser->getLineNumber()); + const Source source = source_.WithLine(parser->line_number()); - Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name"); - if (!maybeName) { - mDiag->error(DiagMessage(source) << "no attribute 'name' found for tag <" + Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name"); + if (!maybe_name) { + diag_->Error(DiagMessage(source) << "no attribute 'name' found for tag <" << tag << ">"); return {}; } - Maybe<StringPiece> maybeValue = xml::findNonEmptyAttribute(parser, "value"); - if (!maybeValue) { - mDiag->error(DiagMessage(source) << "no attribute 'value' found for tag <" + Maybe<StringPiece> maybe_value = xml::FindNonEmptyAttribute(parser, "value"); + if (!maybe_value) { + diag_->Error(DiagMessage(source) << "no attribute 'value' found for tag <" << tag << ">"); return {}; } - std::u16string value16 = util::utf8ToUtf16(maybeValue.value()); + std::u16string value16 = util::Utf8ToUtf16(maybe_value.value()); android::Res_value val; if (!android::ResTable::stringToInt(value16.data(), value16.size(), &val)) { - mDiag->error(DiagMessage(source) << "invalid value '" << maybeValue.value() + diag_->Error(DiagMessage(source) << "invalid value '" << maybe_value.value() << "' for <" << tag << ">; must be an integer"); return {}; } return Attribute::Symbol{ - Reference(ResourceNameRef({}, ResourceType::kId, maybeName.value())), + Reference(ResourceNameRef({}, ResourceType::kId, maybe_name.value())), val.data}; } -bool ResourceParser::parseStyleItem(xml::XmlPullParser* parser, Style* style) { - const Source source = mSource.withLine(parser->getLineNumber()); +bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) { + const Source source = source_.WithLine(parser->line_number()); - Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name"); - if (!maybeName) { - mDiag->error(DiagMessage(source) << "<item> must have a 'name' attribute"); + Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name"); + if (!maybe_name) { + diag_->Error(DiagMessage(source) << "<item> must have a 'name' attribute"); return false; } - Maybe<Reference> maybeKey = - ResourceUtils::parseXmlAttributeName(maybeName.value()); - if (!maybeKey) { - mDiag->error(DiagMessage(source) << "invalid attribute name '" - << maybeName.value() << "'"); + Maybe<Reference> maybe_key = + ResourceUtils::ParseXmlAttributeName(maybe_name.value()); + if (!maybe_key) { + diag_->Error(DiagMessage(source) << "invalid attribute name '" + << maybe_name.value() << "'"); return false; } - transformReferenceFromNamespace(parser, "", &maybeKey.value()); - maybeKey.value().setSource(source); + TransformReferenceFromNamespace(parser, "", &maybe_key.value()); + maybe_key.value().SetSource(source); - std::unique_ptr<Item> value = parseXml(parser, 0, kAllowRawString); + std::unique_ptr<Item> value = ParseXml(parser, 0, kAllowRawString); if (!value) { - mDiag->error(DiagMessage(source) << "could not parse style item"); + diag_->Error(DiagMessage(source) << "could not parse style item"); return false; } style->entries.push_back( - Style::Entry{std::move(maybeKey.value()), std::move(value)}); + Style::Entry{std::move(maybe_key.value()), std::move(value)}); return true; } -bool ResourceParser::parseStyle(xml::XmlPullParser* parser, - ParsedResource* outResource) { - outResource->name.type = ResourceType::kStyle; +bool ResourceParser::ParseStyle(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + out_resource->name.type = ResourceType::kStyle; std::unique_ptr<Style> style = util::make_unique<Style>(); - Maybe<StringPiece> maybeParent = xml::findAttribute(parser, "parent"); - if (maybeParent) { + Maybe<StringPiece> maybe_parent = xml::FindAttribute(parser, "parent"); + if (maybe_parent) { // If the parent is empty, we don't have a parent, but we also don't infer // either. - if (!maybeParent.value().empty()) { - std::string errStr; - style->parent = ResourceUtils::parseStyleParentReference( - maybeParent.value(), &errStr); + if (!maybe_parent.value().empty()) { + std::string err_str; + style->parent = ResourceUtils::ParseStyleParentReference( + maybe_parent.value(), &err_str); if (!style->parent) { - mDiag->error(DiagMessage(outResource->source) << errStr); + diag_->Error(DiagMessage(out_resource->source) << err_str); return false; } // Transform the namespace prefix to the actual package name, and mark the // reference as // private if appropriate. - transformReferenceFromNamespace(parser, "", &style->parent.value()); + TransformReferenceFromNamespace(parser, "", &style->parent.value()); } } else { // No parent was specified, so try inferring it from the style name. - std::string styleName = outResource->name.entry; - size_t pos = styleName.find_last_of(u'.'); + std::string style_name = out_resource->name.entry; + size_t pos = style_name.find_last_of(u'.'); if (pos != std::string::npos) { - style->parentInferred = true; + style->parent_inferred = true; style->parent = Reference( - ResourceName({}, ResourceType::kStyle, styleName.substr(0, pos))); + ResourceName({}, ResourceType::kStyle, style_name.substr(0, pos))); } } bool error = false; - const size_t depth = parser->getDepth(); - while (xml::XmlPullParser::nextChildNode(parser, depth)) { - if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) { + const size_t depth = parser->depth(); + while (xml::XmlPullParser::NextChildNode(parser, depth)) { + if (parser->event() != xml::XmlPullParser::Event::kStartElement) { // Skip text and comments. continue; } - const std::string& elementNamespace = parser->getElementNamespace(); - const std::string& elementName = parser->getElementName(); - if (elementNamespace == "" && elementName == "item") { - error |= !parseStyleItem(parser, style.get()); + const std::string& element_namespace = parser->element_namespace(); + const std::string& element_name = parser->element_name(); + if (element_namespace == "" && element_name == "item") { + error |= !ParseStyleItem(parser, style.get()); - } else if (!shouldIgnoreElement(elementNamespace, elementName)) { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) - << ":" << elementName << ">"); + } else if (!ShouldIgnoreElement(element_namespace, element_name)) { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) + << ":" << element_name << ">"); error = true; } } @@ -1099,73 +1106,73 @@ bool ResourceParser::parseStyle(xml::XmlPullParser* parser, return false; } - outResource->value = std::move(style); + out_resource->value = std::move(style); return true; } -bool ResourceParser::parseArray(xml::XmlPullParser* parser, - ParsedResource* outResource) { - return parseArrayImpl(parser, outResource, android::ResTable_map::TYPE_ANY); +bool ResourceParser::ParseArray(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + return ParseArrayImpl(parser, out_resource, android::ResTable_map::TYPE_ANY); } -bool ResourceParser::parseIntegerArray(xml::XmlPullParser* parser, - ParsedResource* outResource) { - return parseArrayImpl(parser, outResource, +bool ResourceParser::ParseIntegerArray(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + return ParseArrayImpl(parser, out_resource, android::ResTable_map::TYPE_INTEGER); } -bool ResourceParser::parseStringArray(xml::XmlPullParser* parser, - ParsedResource* outResource) { - return parseArrayImpl(parser, outResource, +bool ResourceParser::ParseStringArray(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + return ParseArrayImpl(parser, out_resource, android::ResTable_map::TYPE_STRING); } -bool ResourceParser::parseArrayImpl(xml::XmlPullParser* parser, - ParsedResource* outResource, +bool ResourceParser::ParseArrayImpl(xml::XmlPullParser* parser, + ParsedResource* out_resource, const uint32_t typeMask) { - outResource->name.type = ResourceType::kArray; + out_resource->name.type = ResourceType::kArray; std::unique_ptr<Array> array = util::make_unique<Array>(); - bool translateable = mOptions.translatable; - if (Maybe<StringPiece> translateableAttr = - xml::findAttribute(parser, "translatable")) { - Maybe<bool> maybeTranslateable = - ResourceUtils::parseBool(translateableAttr.value()); - if (!maybeTranslateable) { - mDiag->error(DiagMessage(outResource->source) + bool translateable = options_.translatable; + if (Maybe<StringPiece> translateable_attr = + xml::FindAttribute(parser, "translatable")) { + Maybe<bool> maybe_translateable = + ResourceUtils::ParseBool(translateable_attr.value()); + if (!maybe_translateable) { + diag_->Error(DiagMessage(out_resource->source) << "invalid value for 'translatable'. Must be a boolean"); return false; } - translateable = maybeTranslateable.value(); + translateable = maybe_translateable.value(); } - array->setTranslateable(translateable); + array->SetTranslateable(translateable); bool error = false; - const size_t depth = parser->getDepth(); - while (xml::XmlPullParser::nextChildNode(parser, depth)) { - if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) { + const size_t depth = parser->depth(); + while (xml::XmlPullParser::NextChildNode(parser, depth)) { + if (parser->event() != xml::XmlPullParser::Event::kStartElement) { // Skip text and comments. continue; } - const Source itemSource = mSource.withLine(parser->getLineNumber()); - const std::string& elementNamespace = parser->getElementNamespace(); - const std::string& elementName = parser->getElementName(); - if (elementNamespace.empty() && elementName == "item") { - std::unique_ptr<Item> item = parseXml(parser, typeMask, kNoRawString); + const Source item_source = source_.WithLine(parser->line_number()); + const std::string& element_namespace = parser->element_namespace(); + const std::string& element_name = parser->element_name(); + if (element_namespace.empty() && element_name == "item") { + std::unique_ptr<Item> item = ParseXml(parser, typeMask, kNoRawString); if (!item) { - mDiag->error(DiagMessage(itemSource) << "could not parse array item"); + diag_->Error(DiagMessage(item_source) << "could not parse array item"); error = true; continue; } - item->setSource(itemSource); + item->SetSource(item_source); array->items.emplace_back(std::move(item)); - } else if (!shouldIgnoreElement(elementNamespace, elementName)) { - mDiag->error(DiagMessage(mSource.withLine(parser->getLineNumber())) - << "unknown tag <" << elementNamespace << ":" << elementName - << ">"); + } else if (!ShouldIgnoreElement(element_namespace, element_name)) { + diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) + << "unknown tag <" << element_namespace << ":" + << element_name << ">"); error = true; } } @@ -1174,77 +1181,78 @@ bool ResourceParser::parseArrayImpl(xml::XmlPullParser* parser, return false; } - outResource->value = std::move(array); + out_resource->value = std::move(array); return true; } -bool ResourceParser::parsePlural(xml::XmlPullParser* parser, - ParsedResource* outResource) { - outResource->name.type = ResourceType::kPlurals; +bool ResourceParser::ParsePlural(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + out_resource->name.type = ResourceType::kPlurals; std::unique_ptr<Plural> plural = util::make_unique<Plural>(); bool error = false; - const size_t depth = parser->getDepth(); - while (xml::XmlPullParser::nextChildNode(parser, depth)) { - if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) { + const size_t depth = parser->depth(); + while (xml::XmlPullParser::NextChildNode(parser, depth)) { + if (parser->event() != xml::XmlPullParser::Event::kStartElement) { // Skip text and comments. continue; } - const Source itemSource = mSource.withLine(parser->getLineNumber()); - const std::string& elementNamespace = parser->getElementNamespace(); - const std::string& elementName = parser->getElementName(); - if (elementNamespace.empty() && elementName == "item") { - Maybe<StringPiece> maybeQuantity = - xml::findNonEmptyAttribute(parser, "quantity"); - if (!maybeQuantity) { - mDiag->error(DiagMessage(itemSource) + const Source item_source = source_.WithLine(parser->line_number()); + const std::string& element_namespace = parser->element_namespace(); + const std::string& element_name = parser->element_name(); + if (element_namespace.empty() && element_name == "item") { + Maybe<StringPiece> maybe_quantity = + xml::FindNonEmptyAttribute(parser, "quantity"); + if (!maybe_quantity) { + diag_->Error(DiagMessage(item_source) << "<item> in <plurals> requires attribute " << "'quantity'"); error = true; continue; } - StringPiece trimmedQuantity = util::trimWhitespace(maybeQuantity.value()); + StringPiece trimmed_quantity = + util::TrimWhitespace(maybe_quantity.value()); size_t index = 0; - if (trimmedQuantity == "zero") { + if (trimmed_quantity == "zero") { index = Plural::Zero; - } else if (trimmedQuantity == "one") { + } else if (trimmed_quantity == "one") { index = Plural::One; - } else if (trimmedQuantity == "two") { + } else if (trimmed_quantity == "two") { index = Plural::Two; - } else if (trimmedQuantity == "few") { + } else if (trimmed_quantity == "few") { index = Plural::Few; - } else if (trimmedQuantity == "many") { + } else if (trimmed_quantity == "many") { index = Plural::Many; - } else if (trimmedQuantity == "other") { + } else if (trimmed_quantity == "other") { index = Plural::Other; } else { - mDiag->error(DiagMessage(itemSource) + diag_->Error(DiagMessage(item_source) << "<item> in <plural> has invalid value '" - << trimmedQuantity << "' for attribute 'quantity'"); + << trimmed_quantity << "' for attribute 'quantity'"); error = true; continue; } if (plural->values[index]) { - mDiag->error(DiagMessage(itemSource) << "duplicate quantity '" - << trimmedQuantity << "'"); + diag_->Error(DiagMessage(item_source) << "duplicate quantity '" + << trimmed_quantity << "'"); error = true; continue; } - if (!(plural->values[index] = parseXml( + if (!(plural->values[index] = ParseXml( parser, android::ResTable_map::TYPE_STRING, kNoRawString))) { error = true; } - plural->values[index]->setSource(itemSource); + plural->values[index]->SetSource(item_source); - } else if (!shouldIgnoreElement(elementNamespace, elementName)) { - mDiag->error(DiagMessage(itemSource) - << "unknown tag <" << elementNamespace << ":" << elementName - << ">"); + } else if (!ShouldIgnoreElement(element_namespace, element_name)) { + diag_->Error(DiagMessage(item_source) << "unknown tag <" + << element_namespace << ":" + << element_name << ">"); error = true; } } @@ -1253,47 +1261,48 @@ bool ResourceParser::parsePlural(xml::XmlPullParser* parser, return false; } - outResource->value = std::move(plural); + out_resource->value = std::move(plural); return true; } -bool ResourceParser::parseDeclareStyleable(xml::XmlPullParser* parser, - ParsedResource* outResource) { - outResource->name.type = ResourceType::kStyleable; +bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser, + ParsedResource* out_resource) { + out_resource->name.type = ResourceType::kStyleable; // Declare-styleable is kPrivate by default, because it technically only // exists in R.java. - outResource->symbolState = SymbolState::kPublic; + out_resource->symbol_state = SymbolState::kPublic; // Declare-styleable only ends up in default config; - if (outResource->config != ConfigDescription::defaultConfig()) { - mDiag->warn(DiagMessage(outResource->source) - << "ignoring configuration '" << outResource->config - << "' for styleable " << outResource->name.entry); - outResource->config = ConfigDescription::defaultConfig(); + if (out_resource->config != ConfigDescription::DefaultConfig()) { + diag_->Warn(DiagMessage(out_resource->source) + << "ignoring configuration '" << out_resource->config + << "' for styleable " << out_resource->name.entry); + out_resource->config = ConfigDescription::DefaultConfig(); } std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>(); std::string comment; bool error = false; - const size_t depth = parser->getDepth(); - while (xml::XmlPullParser::nextChildNode(parser, depth)) { - if (parser->getEvent() == xml::XmlPullParser::Event::kComment) { - comment = util::trimWhitespace(parser->getComment()).toString(); + const size_t depth = parser->depth(); + while (xml::XmlPullParser::NextChildNode(parser, depth)) { + if (parser->event() == xml::XmlPullParser::Event::kComment) { + comment = util::TrimWhitespace(parser->comment()).ToString(); continue; - } else if (parser->getEvent() != xml::XmlPullParser::Event::kStartElement) { + } else if (parser->event() != xml::XmlPullParser::Event::kStartElement) { // Ignore text. continue; } - const Source itemSource = mSource.withLine(parser->getLineNumber()); - const std::string& elementNamespace = parser->getElementNamespace(); - const std::string& elementName = parser->getElementName(); - if (elementNamespace.empty() && elementName == "attr") { - Maybe<StringPiece> maybeName = xml::findNonEmptyAttribute(parser, "name"); - if (!maybeName) { - mDiag->error(DiagMessage(itemSource) + const Source item_source = source_.WithLine(parser->line_number()); + const std::string& element_namespace = parser->element_namespace(); + const std::string& element_name = parser->element_name(); + if (element_namespace.empty() && element_name == "attr") { + Maybe<StringPiece> maybe_name = + xml::FindNonEmptyAttribute(parser, "name"); + if (!maybe_name) { + diag_->Error(DiagMessage(item_source) << "<attr> tag must have a 'name' attribute"); error = true; continue; @@ -1302,40 +1311,40 @@ bool ResourceParser::parseDeclareStyleable(xml::XmlPullParser* parser, // If this is a declaration, the package name may be in the name. Separate // these out. // Eg. <attr name="android:text" /> - Maybe<Reference> maybeRef = - ResourceUtils::parseXmlAttributeName(maybeName.value()); - if (!maybeRef) { - mDiag->error(DiagMessage(itemSource) << "<attr> tag has invalid name '" - << maybeName.value() << "'"); + Maybe<Reference> maybe_ref = + ResourceUtils::ParseXmlAttributeName(maybe_name.value()); + if (!maybe_ref) { + diag_->Error(DiagMessage(item_source) << "<attr> tag has invalid name '" + << maybe_name.value() << "'"); error = true; continue; } - Reference& childRef = maybeRef.value(); - xml::transformReferenceFromNamespace(parser, "", &childRef); + Reference& child_ref = maybe_ref.value(); + xml::TransformReferenceFromNamespace(parser, "", &child_ref); // Create the ParsedResource that will add the attribute to the table. - ParsedResource childResource; - childResource.name = childRef.name.value(); - childResource.source = itemSource; - childResource.comment = std::move(comment); + ParsedResource child_resource; + child_resource.name = child_ref.name.value(); + child_resource.source = item_source; + child_resource.comment = std::move(comment); - if (!parseAttrImpl(parser, &childResource, true)) { + if (!ParseAttrImpl(parser, &child_resource, true)) { error = true; continue; } // Create the reference to this attribute. - childRef.setComment(childResource.comment); - childRef.setSource(itemSource); - styleable->entries.push_back(std::move(childRef)); + child_ref.SetComment(child_resource.comment); + child_ref.SetSource(item_source); + styleable->entries.push_back(std::move(child_ref)); - outResource->childResources.push_back(std::move(childResource)); + out_resource->child_resources.push_back(std::move(child_resource)); - } else if (!shouldIgnoreElement(elementNamespace, elementName)) { - mDiag->error(DiagMessage(itemSource) - << "unknown tag <" << elementNamespace << ":" << elementName - << ">"); + } else if (!ShouldIgnoreElement(element_namespace, element_name)) { + diag_->Error(DiagMessage(item_source) << "unknown tag <" + << element_namespace << ":" + << element_name << ">"); error = true; } @@ -1346,7 +1355,7 @@ bool ResourceParser::parseDeclareStyleable(xml::XmlPullParser* parser, return false; } - outResource->value = std::move(styleable); + out_resource->value = std::move(styleable); return true; } diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h index 644ed4923c3a..11b1e5b787ca 100644 --- a/tools/aapt2/ResourceParser.h +++ b/tools/aapt2/ResourceParser.h @@ -17,6 +17,10 @@ #ifndef AAPT_RESOURCE_PARSER_H #define AAPT_RESOURCE_PARSER_H +#include <memory> + +#include "android-base/macros.h" + #include "ConfigDescription.h" #include "Diagnostics.h" #include "ResourceTable.h" @@ -26,8 +30,6 @@ #include "util/StringPiece.h" #include "xml/XmlPullParser.h" -#include <memory> - namespace aapt { struct ParsedResource; @@ -42,7 +44,7 @@ struct ResourceParserOptions { * Whether positional arguments in formatted strings are treated as errors or * warnings. */ - bool errorOnPositionalArguments = true; + bool error_on_positional_arguments = true; }; /* @@ -53,70 +55,71 @@ class ResourceParser { ResourceParser(IDiagnostics* diag, ResourceTable* table, const Source& source, const ConfigDescription& config, const ResourceParserOptions& options = {}); - - ResourceParser(const ResourceParser&) = delete; // No copy. - - bool parse(xml::XmlPullParser* parser); + bool Parse(xml::XmlPullParser* parser); private: + DISALLOW_COPY_AND_ASSIGN(ResourceParser); + /* * Parses the XML subtree as a StyleString (flattened XML representation for * strings - * with formatting). If successful, `outStyleString` - * contains the escaped and whitespace trimmed text, while `outRawString` + * with formatting). If successful, `out_style_string` + * contains the escaped and whitespace trimmed text, while `out_raw_string` * contains the unescaped text. Returns true on success. */ - bool flattenXmlSubtree(xml::XmlPullParser* parser, std::string* outRawString, - StyleString* outStyleString); + bool FlattenXmlSubtree(xml::XmlPullParser* parser, + std::string* out_raw_string, + StyleString* out_style_string); /* * Parses the XML subtree and returns an Item. - * The type of Item that can be parsed is denoted by the `typeMask`. - * If `allowRawValue` is true and the subtree can not be parsed as a regular + * The type of Item that can be parsed is denoted by the `type_mask`. + * If `allow_raw_value` is true and the subtree can not be parsed as a regular * Item, then a * RawString is returned. Otherwise this returns false; */ - std::unique_ptr<Item> parseXml(xml::XmlPullParser* parser, - const uint32_t typeMask, - const bool allowRawValue); + std::unique_ptr<Item> ParseXml(xml::XmlPullParser* parser, + const uint32_t type_mask, + const bool allow_raw_value); - bool parseResources(xml::XmlPullParser* parser); - bool parseResource(xml::XmlPullParser* parser, ParsedResource* outResource); + bool ParseResources(xml::XmlPullParser* parser); + bool ParseResource(xml::XmlPullParser* parser, ParsedResource* out_resource); - bool parseItem(xml::XmlPullParser* parser, ParsedResource* outResource, + bool ParseItem(xml::XmlPullParser* parser, ParsedResource* out_resource, uint32_t format); - bool parseString(xml::XmlPullParser* parser, ParsedResource* outResource); - - bool parsePublic(xml::XmlPullParser* parser, ParsedResource* outResource); - bool parsePublicGroup(xml::XmlPullParser* parser, - ParsedResource* outResource); - bool parseSymbolImpl(xml::XmlPullParser* parser, ParsedResource* outResource); - bool parseSymbol(xml::XmlPullParser* parser, ParsedResource* outResource); - bool parseAddResource(xml::XmlPullParser* parser, - ParsedResource* outResource); - bool parseAttr(xml::XmlPullParser* parser, ParsedResource* outResource); - bool parseAttrImpl(xml::XmlPullParser* parser, ParsedResource* outResource, + bool ParseString(xml::XmlPullParser* parser, ParsedResource* out_resource); + + bool ParsePublic(xml::XmlPullParser* parser, ParsedResource* out_resource); + bool ParsePublicGroup(xml::XmlPullParser* parser, + ParsedResource* out_resource); + bool ParseSymbolImpl(xml::XmlPullParser* parser, + ParsedResource* out_resource); + bool ParseSymbol(xml::XmlPullParser* parser, ParsedResource* out_resource); + bool ParseAddResource(xml::XmlPullParser* parser, + ParsedResource* out_resource); + bool ParseAttr(xml::XmlPullParser* parser, ParsedResource* out_resource); + bool ParseAttrImpl(xml::XmlPullParser* parser, ParsedResource* out_resource, bool weak); - Maybe<Attribute::Symbol> parseEnumOrFlagItem(xml::XmlPullParser* parser, + Maybe<Attribute::Symbol> ParseEnumOrFlagItem(xml::XmlPullParser* parser, const StringPiece& tag); - bool parseStyle(xml::XmlPullParser* parser, ParsedResource* outResource); - bool parseStyleItem(xml::XmlPullParser* parser, Style* style); - bool parseDeclareStyleable(xml::XmlPullParser* parser, - ParsedResource* outResource); - bool parseArray(xml::XmlPullParser* parser, ParsedResource* outResource); - bool parseIntegerArray(xml::XmlPullParser* parser, - ParsedResource* outResource); - bool parseStringArray(xml::XmlPullParser* parser, - ParsedResource* outResource); - bool parseArrayImpl(xml::XmlPullParser* parser, ParsedResource* outResource, + bool ParseStyle(xml::XmlPullParser* parser, ParsedResource* out_resource); + bool ParseStyleItem(xml::XmlPullParser* parser, Style* style); + bool ParseDeclareStyleable(xml::XmlPullParser* parser, + ParsedResource* out_resource); + bool ParseArray(xml::XmlPullParser* parser, ParsedResource* out_resource); + bool ParseIntegerArray(xml::XmlPullParser* parser, + ParsedResource* out_resource); + bool ParseStringArray(xml::XmlPullParser* parser, + ParsedResource* out_resource); + bool ParseArrayImpl(xml::XmlPullParser* parser, ParsedResource* out_resource, uint32_t typeMask); - bool parsePlural(xml::XmlPullParser* parser, ParsedResource* outResource); + bool ParsePlural(xml::XmlPullParser* parser, ParsedResource* out_resource); - IDiagnostics* mDiag; - ResourceTable* mTable; - Source mSource; - ConfigDescription mConfig; - ResourceParserOptions mOptions; + IDiagnostics* diag_; + ResourceTable* table_; + Source source_; + ConfigDescription config_; + ResourceParserOptions options_; }; } // namespace aapt diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp index b6d57c0f7b9b..2463911445e7 100644 --- a/tools/aapt2/ResourceParser_test.cpp +++ b/tools/aapt2/ResourceParser_test.cpp @@ -15,79 +15,82 @@ */ #include "ResourceParser.h" + +#include <sstream> +#include <string> + #include "ResourceTable.h" #include "ResourceUtils.h" #include "ResourceValues.h" #include "test/Test.h" #include "xml/XmlPullParser.h" -#include <sstream> -#include <string> - namespace aapt { constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; TEST(ResourceParserSingleTest, FailToParseWithNoRootResourcesElement) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); std::stringstream input(kXmlPreamble); input << "<attr name=\"foo\"/>" << std::endl; ResourceTable table; - ResourceParser parser(context->getDiagnostics(), &table, Source{"test"}, {}); - xml::XmlPullParser xmlParser(input); - ASSERT_FALSE(parser.parse(&xmlParser)); + ResourceParser parser(context->GetDiagnostics(), &table, Source{"test"}, {}); + xml::XmlPullParser xml_parser(input); + ASSERT_FALSE(parser.Parse(&xml_parser)); } -struct ResourceParserTest : public ::testing::Test { - ResourceTable mTable; - std::unique_ptr<IAaptContext> mContext; +class ResourceParserTest : public ::testing::Test { + public: + void SetUp() override { context_ = test::ContextBuilder().Build(); } - void SetUp() override { mContext = test::ContextBuilder().build(); } - - ::testing::AssertionResult testParse(const StringPiece& str) { - return testParse(str, ConfigDescription{}); + ::testing::AssertionResult TestParse(const StringPiece& str) { + return TestParse(str, ConfigDescription{}); } - ::testing::AssertionResult testParse(const StringPiece& str, + ::testing::AssertionResult TestParse(const StringPiece& str, const ConfigDescription& config) { std::stringstream input(kXmlPreamble); input << "<resources>\n" << str << "\n</resources>" << std::endl; ResourceParserOptions parserOptions; - ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{"test"}, + ResourceParser parser(context_->GetDiagnostics(), &table_, Source{"test"}, config, parserOptions); xml::XmlPullParser xmlParser(input); - if (parser.parse(&xmlParser)) { + if (parser.Parse(&xmlParser)) { return ::testing::AssertionSuccess(); } return ::testing::AssertionFailure(); } + + protected: + ResourceTable table_; + std::unique_ptr<IAaptContext> context_; }; TEST_F(ResourceParserTest, ParseQuotedString) { std::string input = "<string name=\"foo\"> \" hey there \" </string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - String* str = test::getValue<String>(&mTable, "string/foo"); + String* str = test::GetValue<String>(&table_, "string/foo"); ASSERT_NE(nullptr, str); EXPECT_EQ(std::string(" hey there "), *str->value); } TEST_F(ResourceParserTest, ParseEscapedString) { std::string input = "<string name=\"foo\">\\?123</string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - String* str = test::getValue<String>(&mTable, "string/foo"); + String* str = test::GetValue<String>(&table_, "string/foo"); ASSERT_NE(nullptr, str); EXPECT_EQ(std::string("?123"), *str->value); } TEST_F(ResourceParserTest, ParseFormattedString) { std::string input = "<string name=\"foo\">%d %s</string>"; - ASSERT_FALSE(testParse(input)); + ASSERT_FALSE(TestParse(input)); input = "<string name=\"foo\">%1$d %2$s</string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); } TEST_F(ResourceParserTest, ParseStyledString) { @@ -96,32 +99,32 @@ TEST_F(ResourceParserTest, ParseStyledString) { // use UTF-16 length and not UTF-18 length. std::string input = "<string name=\"foo\">This is my aunt\u2019s <b>string</b></string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - StyledString* str = test::getValue<StyledString>(&mTable, "string/foo"); + StyledString* str = test::GetValue<StyledString>(&table_, "string/foo"); ASSERT_NE(nullptr, str); - const std::string expectedStr = "This is my aunt\u2019s string"; - EXPECT_EQ(expectedStr, *str->value->str); + const std::string expected_str = "This is my aunt\u2019s string"; + EXPECT_EQ(expected_str, *str->value->str); EXPECT_EQ(1u, str->value->spans.size()); EXPECT_EQ(std::string("b"), *str->value->spans[0].name); - EXPECT_EQ(17u, str->value->spans[0].firstChar); - EXPECT_EQ(23u, str->value->spans[0].lastChar); + EXPECT_EQ(17u, str->value->spans[0].first_char); + EXPECT_EQ(23u, str->value->spans[0].last_char); } TEST_F(ResourceParserTest, ParseStringWithWhitespace) { std::string input = "<string name=\"foo\"> This is what I think </string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - String* str = test::getValue<String>(&mTable, "string/foo"); + String* str = test::GetValue<String>(&table_, "string/foo"); ASSERT_NE(nullptr, str); EXPECT_EQ(std::string("This is what I think"), *str->value); input = "<string name=\"foo2\">\" This is what I think \"</string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - str = test::getValue<String>(&mTable, "string/foo2"); + str = test::GetValue<String>(&table_, "string/foo2"); ASSERT_NE(nullptr, str); EXPECT_EQ(std::string(" This is what I think "), *str->value); } @@ -131,16 +134,16 @@ TEST_F(ResourceParserTest, IgnoreXliffTags) { "<string name=\"foo\" \n" " xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n" " There are <xliff:g id=\"count\">%1$d</xliff:g> apples</string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - String* str = test::getValue<String>(&mTable, "string/foo"); + String* str = test::GetValue<String>(&table_, "string/foo"); ASSERT_NE(nullptr, str); EXPECT_EQ(StringPiece("There are %1$d apples"), StringPiece(*str->value)); } TEST_F(ResourceParserTest, ParseNull) { std::string input = "<integer name=\"foo\">@null</integer>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); // The Android runtime treats a value of android::Res_value::TYPE_NULL as // a non-existing value, and this causes problems in styles when trying to @@ -149,7 +152,7 @@ TEST_F(ResourceParserTest, ParseNull) { // android::Res_value::TYPE_REFERENCE // with a data value of 0. BinaryPrimitive* integer = - test::getValue<BinaryPrimitive>(&mTable, "integer/foo"); + test::GetValue<BinaryPrimitive>(&table_, "integer/foo"); ASSERT_NE(nullptr, integer); EXPECT_EQ(uint16_t(android::Res_value::TYPE_REFERENCE), integer->value.dataType); @@ -158,10 +161,10 @@ TEST_F(ResourceParserTest, ParseNull) { TEST_F(ResourceParserTest, ParseEmpty) { std::string input = "<integer name=\"foo\">@empty</integer>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); BinaryPrimitive* integer = - test::getValue<BinaryPrimitive>(&mTable, "integer/foo"); + test::GetValue<BinaryPrimitive>(&table_, "integer/foo"); ASSERT_NE(nullptr, integer); EXPECT_EQ(uint16_t(android::Res_value::TYPE_NULL), integer->value.dataType); EXPECT_EQ(uint32_t(android::Res_value::DATA_NULL_EMPTY), integer->value.data); @@ -171,15 +174,15 @@ TEST_F(ResourceParserTest, ParseAttr) { std::string input = "<attr name=\"foo\" format=\"string\"/>\n" "<attr name=\"bar\"/>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo"); + Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo"); ASSERT_NE(nullptr, attr); - EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask); + EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->type_mask); - attr = test::getValue<Attribute>(&mTable, "attr/bar"); + attr = test::GetValue<Attribute>(&table_, "attr/bar"); ASSERT_NE(nullptr, attr); - EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_ANY), attr->typeMask); + EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_ANY), attr->type_mask); } // Old AAPT allowed attributes to be defined under different configurations, but @@ -188,42 +191,42 @@ TEST_F(ResourceParserTest, ParseAttr) { // behavior. TEST_F(ResourceParserTest, ParseAttrAndDeclareStyleableUnderConfigButRecordAsNoConfig) { - const ConfigDescription watchConfig = test::parseConfigOrDie("watch"); + const ConfigDescription watch_config = test::ParseConfigOrDie("watch"); std::string input = R"EOF( <attr name="foo" /> <declare-styleable name="bar"> <attr name="baz" /> </declare-styleable>)EOF"; - ASSERT_TRUE(testParse(input, watchConfig)); + ASSERT_TRUE(TestParse(input, watch_config)); - EXPECT_EQ(nullptr, test::getValueForConfig<Attribute>(&mTable, "attr/foo", - watchConfig)); - EXPECT_EQ(nullptr, test::getValueForConfig<Attribute>(&mTable, "attr/baz", - watchConfig)); - EXPECT_EQ(nullptr, test::getValueForConfig<Styleable>( - &mTable, "styleable/bar", watchConfig)); + EXPECT_EQ(nullptr, test::GetValueForConfig<Attribute>(&table_, "attr/foo", + watch_config)); + EXPECT_EQ(nullptr, test::GetValueForConfig<Attribute>(&table_, "attr/baz", + watch_config)); + EXPECT_EQ(nullptr, test::GetValueForConfig<Styleable>( + &table_, "styleable/bar", watch_config)); - EXPECT_NE(nullptr, test::getValue<Attribute>(&mTable, "attr/foo")); - EXPECT_NE(nullptr, test::getValue<Attribute>(&mTable, "attr/baz")); - EXPECT_NE(nullptr, test::getValue<Styleable>(&mTable, "styleable/bar")); + EXPECT_NE(nullptr, test::GetValue<Attribute>(&table_, "attr/foo")); + EXPECT_NE(nullptr, test::GetValue<Attribute>(&table_, "attr/baz")); + EXPECT_NE(nullptr, test::GetValue<Styleable>(&table_, "styleable/bar")); } TEST_F(ResourceParserTest, ParseAttrWithMinMax) { std::string input = "<attr name=\"foo\" min=\"10\" max=\"23\" format=\"integer\"/>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo"); + Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo"); ASSERT_NE(nullptr, attr); - EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_INTEGER), attr->typeMask); - EXPECT_EQ(10, attr->minInt); - EXPECT_EQ(23, attr->maxInt); + EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_INTEGER), attr->type_mask); + EXPECT_EQ(10, attr->min_int); + EXPECT_EQ(23, attr->max_int); } TEST_F(ResourceParserTest, FailParseAttrWithMinMaxButNotInteger) { std::string input = "<attr name=\"foo\" min=\"10\" max=\"23\" format=\"string\"/>"; - ASSERT_FALSE(testParse(input)); + ASSERT_FALSE(TestParse(input)); } TEST_F(ResourceParserTest, ParseUseAndDeclOfAttr) { @@ -232,11 +235,11 @@ TEST_F(ResourceParserTest, ParseUseAndDeclOfAttr) { " <attr name=\"foo\" />\n" "</declare-styleable>\n" "<attr name=\"foo\" format=\"string\"/>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo"); + Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo"); ASSERT_NE(nullptr, attr); - EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask); + EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->type_mask); } TEST_F(ResourceParserTest, ParseDoubleUseOfAttr) { @@ -247,11 +250,11 @@ TEST_F(ResourceParserTest, ParseDoubleUseOfAttr) { "<declare-styleable name=\"Window\">\n" " <attr name=\"foo\" format=\"boolean\"/>\n" "</declare-styleable>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo"); + Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo"); ASSERT_NE(nullptr, attr); - EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_BOOLEAN), attr->typeMask); + EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_BOOLEAN), attr->type_mask); } TEST_F(ResourceParserTest, ParseEnumAttr) { @@ -261,24 +264,24 @@ TEST_F(ResourceParserTest, ParseEnumAttr) { " <enum name=\"bat\" value=\"1\"/>\n" " <enum name=\"baz\" value=\"2\"/>\n" "</attr>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Attribute* enumAttr = test::getValue<Attribute>(&mTable, "attr/foo"); - ASSERT_NE(enumAttr, nullptr); - EXPECT_EQ(enumAttr->typeMask, android::ResTable_map::TYPE_ENUM); - ASSERT_EQ(enumAttr->symbols.size(), 3u); + Attribute* enum_attr = test::GetValue<Attribute>(&table_, "attr/foo"); + ASSERT_NE(enum_attr, nullptr); + EXPECT_EQ(enum_attr->type_mask, android::ResTable_map::TYPE_ENUM); + ASSERT_EQ(enum_attr->symbols.size(), 3u); - AAPT_ASSERT_TRUE(enumAttr->symbols[0].symbol.name); - EXPECT_EQ(enumAttr->symbols[0].symbol.name.value().entry, "bar"); - EXPECT_EQ(enumAttr->symbols[0].value, 0u); + AAPT_ASSERT_TRUE(enum_attr->symbols[0].symbol.name); + EXPECT_EQ(enum_attr->symbols[0].symbol.name.value().entry, "bar"); + EXPECT_EQ(enum_attr->symbols[0].value, 0u); - AAPT_ASSERT_TRUE(enumAttr->symbols[1].symbol.name); - EXPECT_EQ(enumAttr->symbols[1].symbol.name.value().entry, "bat"); - EXPECT_EQ(enumAttr->symbols[1].value, 1u); + AAPT_ASSERT_TRUE(enum_attr->symbols[1].symbol.name); + EXPECT_EQ(enum_attr->symbols[1].symbol.name.value().entry, "bat"); + EXPECT_EQ(enum_attr->symbols[1].value, 1u); - AAPT_ASSERT_TRUE(enumAttr->symbols[2].symbol.name); - EXPECT_EQ(enumAttr->symbols[2].symbol.name.value().entry, "baz"); - EXPECT_EQ(enumAttr->symbols[2].value, 2u); + AAPT_ASSERT_TRUE(enum_attr->symbols[2].symbol.name); + EXPECT_EQ(enum_attr->symbols[2].symbol.name.value().entry, "baz"); + EXPECT_EQ(enum_attr->symbols[2].value, 2u); } TEST_F(ResourceParserTest, ParseFlagAttr) { @@ -288,29 +291,29 @@ TEST_F(ResourceParserTest, ParseFlagAttr) { " <flag name=\"bat\" value=\"1\"/>\n" " <flag name=\"baz\" value=\"2\"/>\n" "</attr>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Attribute* flagAttr = test::getValue<Attribute>(&mTable, "attr/foo"); - ASSERT_NE(nullptr, flagAttr); - EXPECT_EQ(flagAttr->typeMask, android::ResTable_map::TYPE_FLAGS); - ASSERT_EQ(flagAttr->symbols.size(), 3u); + Attribute* flag_attr = test::GetValue<Attribute>(&table_, "attr/foo"); + ASSERT_NE(nullptr, flag_attr); + EXPECT_EQ(flag_attr->type_mask, android::ResTable_map::TYPE_FLAGS); + ASSERT_EQ(flag_attr->symbols.size(), 3u); - AAPT_ASSERT_TRUE(flagAttr->symbols[0].symbol.name); - EXPECT_EQ(flagAttr->symbols[0].symbol.name.value().entry, "bar"); - EXPECT_EQ(flagAttr->symbols[0].value, 0u); + AAPT_ASSERT_TRUE(flag_attr->symbols[0].symbol.name); + EXPECT_EQ(flag_attr->symbols[0].symbol.name.value().entry, "bar"); + EXPECT_EQ(flag_attr->symbols[0].value, 0u); - AAPT_ASSERT_TRUE(flagAttr->symbols[1].symbol.name); - EXPECT_EQ(flagAttr->symbols[1].symbol.name.value().entry, "bat"); - EXPECT_EQ(flagAttr->symbols[1].value, 1u); + AAPT_ASSERT_TRUE(flag_attr->symbols[1].symbol.name); + EXPECT_EQ(flag_attr->symbols[1].symbol.name.value().entry, "bat"); + EXPECT_EQ(flag_attr->symbols[1].value, 1u); - AAPT_ASSERT_TRUE(flagAttr->symbols[2].symbol.name); - EXPECT_EQ(flagAttr->symbols[2].symbol.name.value().entry, "baz"); - EXPECT_EQ(flagAttr->symbols[2].value, 2u); + AAPT_ASSERT_TRUE(flag_attr->symbols[2].symbol.name); + EXPECT_EQ(flag_attr->symbols[2].symbol.name.value().entry, "baz"); + EXPECT_EQ(flag_attr->symbols[2].value, 2u); - std::unique_ptr<BinaryPrimitive> flagValue = - ResourceUtils::tryParseFlagSymbol(flagAttr, "baz|bat"); - ASSERT_NE(nullptr, flagValue); - EXPECT_EQ(flagValue->value.data, 1u | 2u); + std::unique_ptr<BinaryPrimitive> flag_value = + ResourceUtils::TryParseFlagSymbol(flag_attr, "baz|bat"); + ASSERT_NE(nullptr, flag_value); + EXPECT_EQ(flag_value->value.data, 1u | 2u); } TEST_F(ResourceParserTest, FailToParseEnumAttrWithNonUniqueKeys) { @@ -320,7 +323,7 @@ TEST_F(ResourceParserTest, FailToParseEnumAttrWithNonUniqueKeys) { " <enum name=\"bat\" value=\"1\"/>\n" " <enum name=\"bat\" value=\"2\"/>\n" "</attr>"; - ASSERT_FALSE(testParse(input)); + ASSERT_FALSE(TestParse(input)); } TEST_F(ResourceParserTest, ParseStyle) { @@ -330,38 +333,38 @@ TEST_F(ResourceParserTest, ParseStyle) { " <item name=\"bat\">@string/hey</item>\n" " <item name=\"baz\"><b>hey</b></item>\n" "</style>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Style* style = test::getValue<Style>(&mTable, "style/foo"); + Style* style = test::GetValue<Style>(&table_, "style/foo"); ASSERT_NE(nullptr, style); AAPT_ASSERT_TRUE(style->parent); AAPT_ASSERT_TRUE(style->parent.value().name); - EXPECT_EQ(test::parseNameOrDie("style/fu"), + EXPECT_EQ(test::ParseNameOrDie("style/fu"), style->parent.value().name.value()); ASSERT_EQ(3u, style->entries.size()); AAPT_ASSERT_TRUE(style->entries[0].key.name); - EXPECT_EQ(test::parseNameOrDie("attr/bar"), + EXPECT_EQ(test::ParseNameOrDie("attr/bar"), style->entries[0].key.name.value()); AAPT_ASSERT_TRUE(style->entries[1].key.name); - EXPECT_EQ(test::parseNameOrDie("attr/bat"), + EXPECT_EQ(test::ParseNameOrDie("attr/bat"), style->entries[1].key.name.value()); AAPT_ASSERT_TRUE(style->entries[2].key.name); - EXPECT_EQ(test::parseNameOrDie("attr/baz"), + EXPECT_EQ(test::ParseNameOrDie("attr/baz"), style->entries[2].key.name.value()); } TEST_F(ResourceParserTest, ParseStyleWithShorthandParent) { std::string input = "<style name=\"foo\" parent=\"com.app:Theme\"/>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Style* style = test::getValue<Style>(&mTable, "style/foo"); + Style* style = test::GetValue<Style>(&table_, "style/foo"); ASSERT_NE(nullptr, style); AAPT_ASSERT_TRUE(style->parent); AAPT_ASSERT_TRUE(style->parent.value().name); - EXPECT_EQ(test::parseNameOrDie("com.app:style/Theme"), + EXPECT_EQ(test::ParseNameOrDie("com.app:style/Theme"), style->parent.value().name.value()); } @@ -369,13 +372,13 @@ TEST_F(ResourceParserTest, ParseStyleWithPackageAliasedParent) { std::string input = "<style xmlns:app=\"http://schemas.android.com/apk/res/android\"\n" " name=\"foo\" parent=\"app:Theme\"/>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Style* style = test::getValue<Style>(&mTable, "style/foo"); + Style* style = test::GetValue<Style>(&table_, "style/foo"); ASSERT_NE(nullptr, style); AAPT_ASSERT_TRUE(style->parent); AAPT_ASSERT_TRUE(style->parent.value().name); - EXPECT_EQ(test::parseNameOrDie("android:style/Theme"), + EXPECT_EQ(test::ParseNameOrDie("android:style/Theme"), style->parent.value().name.value()); } @@ -385,55 +388,55 @@ TEST_F(ResourceParserTest, ParseStyleWithPackageAliasedItems) { "name=\"foo\">\n" " <item name=\"app:bar\">0</item>\n" "</style>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Style* style = test::getValue<Style>(&mTable, "style/foo"); + Style* style = test::GetValue<Style>(&table_, "style/foo"); ASSERT_NE(nullptr, style); ASSERT_EQ(1u, style->entries.size()); - EXPECT_EQ(test::parseNameOrDie("android:attr/bar"), + EXPECT_EQ(test::ParseNameOrDie("android:attr/bar"), style->entries[0].key.name.value()); } TEST_F(ResourceParserTest, ParseStyleWithInferredParent) { std::string input = "<style name=\"foo.bar\"/>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Style* style = test::getValue<Style>(&mTable, "style/foo.bar"); + Style* style = test::GetValue<Style>(&table_, "style/foo.bar"); ASSERT_NE(nullptr, style); AAPT_ASSERT_TRUE(style->parent); AAPT_ASSERT_TRUE(style->parent.value().name); EXPECT_EQ(style->parent.value().name.value(), - test::parseNameOrDie("style/foo")); - EXPECT_TRUE(style->parentInferred); + test::ParseNameOrDie("style/foo")); + EXPECT_TRUE(style->parent_inferred); } TEST_F(ResourceParserTest, ParseStyleWithInferredParentOverridenByEmptyParentAttribute) { std::string input = "<style name=\"foo.bar\" parent=\"\"/>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Style* style = test::getValue<Style>(&mTable, "style/foo.bar"); + Style* style = test::GetValue<Style>(&table_, "style/foo.bar"); ASSERT_NE(nullptr, style); AAPT_EXPECT_FALSE(style->parent); - EXPECT_FALSE(style->parentInferred); + EXPECT_FALSE(style->parent_inferred); } TEST_F(ResourceParserTest, ParseStyleWithPrivateParentReference) { std::string input = R"EOF(<style name="foo" parent="*android:style/bar" />)EOF"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Style* style = test::getValue<Style>(&mTable, "style/foo"); + Style* style = test::GetValue<Style>(&table_, "style/foo"); ASSERT_NE(nullptr, style); AAPT_ASSERT_TRUE(style->parent); - EXPECT_TRUE(style->parent.value().privateReference); + EXPECT_TRUE(style->parent.value().private_reference); } TEST_F(ResourceParserTest, ParseAutoGeneratedIdReference) { std::string input = "<string name=\"foo\">@+id/bar</string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Id* id = test::getValue<Id>(&mTable, "id/bar"); + Id* id = test::GetValue<Id>(&table_, "id/bar"); ASSERT_NE(id, nullptr); } @@ -446,35 +449,35 @@ TEST_F(ResourceParserTest, ParseAttributesDeclareStyleable) { " <enum name=\"foo\" value=\"1\"/>\n" " </attr>\n" "</declare-styleable>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); Maybe<ResourceTable::SearchResult> result = - mTable.findResource(test::parseNameOrDie("styleable/foo")); + table_.FindResource(test::ParseNameOrDie("styleable/foo")); AAPT_ASSERT_TRUE(result); - EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbolStatus.state); + EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbol_status.state); - Attribute* attr = test::getValue<Attribute>(&mTable, "attr/bar"); + Attribute* attr = test::GetValue<Attribute>(&table_, "attr/bar"); ASSERT_NE(attr, nullptr); - EXPECT_TRUE(attr->isWeak()); + EXPECT_TRUE(attr->IsWeak()); - attr = test::getValue<Attribute>(&mTable, "attr/bat"); + attr = test::GetValue<Attribute>(&table_, "attr/bat"); ASSERT_NE(attr, nullptr); - EXPECT_TRUE(attr->isWeak()); + EXPECT_TRUE(attr->IsWeak()); - attr = test::getValue<Attribute>(&mTable, "attr/baz"); + attr = test::GetValue<Attribute>(&table_, "attr/baz"); ASSERT_NE(attr, nullptr); - EXPECT_TRUE(attr->isWeak()); + EXPECT_TRUE(attr->IsWeak()); EXPECT_EQ(1u, attr->symbols.size()); - EXPECT_NE(nullptr, test::getValue<Id>(&mTable, "id/foo")); + EXPECT_NE(nullptr, test::GetValue<Id>(&table_, "id/foo")); - Styleable* styleable = test::getValue<Styleable>(&mTable, "styleable/foo"); + Styleable* styleable = test::GetValue<Styleable>(&table_, "styleable/foo"); ASSERT_NE(styleable, nullptr); ASSERT_EQ(3u, styleable->entries.size()); - EXPECT_EQ(test::parseNameOrDie("attr/bar"), + EXPECT_EQ(test::ParseNameOrDie("attr/bar"), styleable->entries[0].name.value()); - EXPECT_EQ(test::parseNameOrDie("attr/bat"), + EXPECT_EQ(test::ParseNameOrDie("attr/bat"), styleable->entries[1].name.value()); } @@ -485,16 +488,16 @@ TEST_F(ResourceParserTest, ParsePrivateAttributesDeclareStyleable) { " <attr name=\"*android:bar\" />\n" " <attr name=\"privAndroid:bat\" />\n" "</declare-styleable>"; - ASSERT_TRUE(testParse(input)); - Styleable* styleable = test::getValue<Styleable>(&mTable, "styleable/foo"); + ASSERT_TRUE(TestParse(input)); + Styleable* styleable = test::GetValue<Styleable>(&table_, "styleable/foo"); ASSERT_NE(nullptr, styleable); ASSERT_EQ(2u, styleable->entries.size()); - EXPECT_TRUE(styleable->entries[0].privateReference); + EXPECT_TRUE(styleable->entries[0].private_reference); AAPT_ASSERT_TRUE(styleable->entries[0].name); EXPECT_EQ(std::string("android"), styleable->entries[0].name.value().package); - EXPECT_TRUE(styleable->entries[1].privateReference); + EXPECT_TRUE(styleable->entries[1].private_reference); AAPT_ASSERT_TRUE(styleable->entries[1].name); EXPECT_EQ(std::string("android"), styleable->entries[1].name.value().package); } @@ -506,15 +509,15 @@ TEST_F(ResourceParserTest, ParseArray) { " <item>hey</item>\n" " <item>23</item>\n" "</array>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Array* array = test::getValue<Array>(&mTable, "array/foo"); + Array* array = test::GetValue<Array>(&table_, "array/foo"); ASSERT_NE(array, nullptr); ASSERT_EQ(3u, array->items.size()); - EXPECT_NE(nullptr, valueCast<Reference>(array->items[0].get())); - EXPECT_NE(nullptr, valueCast<String>(array->items[1].get())); - EXPECT_NE(nullptr, valueCast<BinaryPrimitive>(array->items[2].get())); + EXPECT_NE(nullptr, ValueCast<Reference>(array->items[0].get())); + EXPECT_NE(nullptr, ValueCast<String>(array->items[1].get())); + EXPECT_NE(nullptr, ValueCast<BinaryPrimitive>(array->items[2].get())); } TEST_F(ResourceParserTest, ParseStringArray) { @@ -522,8 +525,8 @@ TEST_F(ResourceParserTest, ParseStringArray) { "<string-array name=\"foo\">\n" " <item>\"Werk\"</item>\n" "</string-array>\n"; - ASSERT_TRUE(testParse(input)); - EXPECT_NE(nullptr, test::getValue<Array>(&mTable, "array/foo")); + ASSERT_TRUE(TestParse(input)); + EXPECT_NE(nullptr, test::GetValue<Array>(&table_, "array/foo")); } TEST_F(ResourceParserTest, ParsePlural) { @@ -532,18 +535,18 @@ TEST_F(ResourceParserTest, ParsePlural) { " <item quantity=\"other\">apples</item>\n" " <item quantity=\"one\">apple</item>\n" "</plurals>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); } TEST_F(ResourceParserTest, ParseCommentsWithResource) { std::string input = "<!--This is a comment-->\n" "<string name=\"foo\">Hi</string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - String* value = test::getValue<String>(&mTable, "string/foo"); + String* value = test::GetValue<String>(&table_, "string/foo"); ASSERT_NE(nullptr, value); - EXPECT_EQ(value->getComment(), "This is a comment"); + EXPECT_EQ(value->GetComment(), "This is a comment"); } TEST_F(ResourceParserTest, DoNotCombineMultipleComments) { @@ -552,11 +555,11 @@ TEST_F(ResourceParserTest, DoNotCombineMultipleComments) { "<!--Two-->\n" "<string name=\"foo\">Hi</string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - String* value = test::getValue<String>(&mTable, "string/foo"); + String* value = test::GetValue<String>(&table_, "string/foo"); ASSERT_NE(nullptr, value); - EXPECT_EQ(value->getComment(), "Two"); + EXPECT_EQ(value->GetComment(), "Two"); } TEST_F(ResourceParserTest, IgnoreCommentBeforeEndTag) { @@ -567,11 +570,11 @@ TEST_F(ResourceParserTest, IgnoreCommentBeforeEndTag) { "<!--Two-->\n" "</string>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - String* value = test::getValue<String>(&mTable, "string/foo"); + String* value = test::GetValue<String>(&table_, "string/foo"); ASSERT_NE(nullptr, value); - EXPECT_EQ(value->getComment(), "One"); + EXPECT_EQ(value->GetComment(), "One"); } TEST_F(ResourceParserTest, ParseNestedComments) { @@ -588,21 +591,21 @@ TEST_F(ResourceParserTest, ParseNestedComments) { <!-- The very first --> <enum name="one" value="1" /> </attr>)EOF"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Styleable* styleable = test::getValue<Styleable>(&mTable, "styleable/foo"); + Styleable* styleable = test::GetValue<Styleable>(&table_, "styleable/foo"); ASSERT_NE(nullptr, styleable); ASSERT_EQ(1u, styleable->entries.size()); EXPECT_EQ(StringPiece("The name of the bar"), - styleable->entries.front().getComment()); + styleable->entries.front().GetComment()); - Attribute* attr = test::getValue<Attribute>(&mTable, "attr/foo"); + Attribute* attr = test::GetValue<Attribute>(&table_, "attr/foo"); ASSERT_NE(nullptr, attr); ASSERT_EQ(1u, attr->symbols.size()); EXPECT_EQ(StringPiece("The very first"), - attr->symbols.front().symbol.getComment()); + attr->symbols.front().symbol.GetComment()); } /* @@ -611,9 +614,9 @@ TEST_F(ResourceParserTest, ParseNestedComments) { */ TEST_F(ResourceParserTest, ParsePublicIdAsDefinition) { std::string input = "<public type=\"id\" name=\"foo\"/>"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); - Id* id = test::getValue<Id>(&mTable, "id/foo"); + Id* id = test::GetValue<Id>(&table_, "id/foo"); ASSERT_NE(nullptr, id); } @@ -626,26 +629,26 @@ TEST_F(ResourceParserTest, KeepAllProducts) { <string name="bit" product="phablet">hoot</string> <string name="bot" product="default">yes</string> )EOF"; - ASSERT_TRUE(testParse(input)); - - EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>( - &mTable, "string/foo", - ConfigDescription::defaultConfig(), "phone")); - EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>( - &mTable, "string/foo", - ConfigDescription::defaultConfig(), "no-sdcard")); + ASSERT_TRUE(TestParse(input)); + + EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<String>( + &table_, "string/foo", + ConfigDescription::DefaultConfig(), "phone")); + EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<String>( + &table_, "string/foo", + ConfigDescription::DefaultConfig(), "no-sdcard")); EXPECT_NE(nullptr, - test::getValueForConfigAndProduct<String>( - &mTable, "string/bar", ConfigDescription::defaultConfig(), "")); + test::GetValueForConfigAndProduct<String>( + &table_, "string/bar", ConfigDescription::DefaultConfig(), "")); EXPECT_NE(nullptr, - test::getValueForConfigAndProduct<String>( - &mTable, "string/baz", ConfigDescription::defaultConfig(), "")); - EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>( - &mTable, "string/bit", - ConfigDescription::defaultConfig(), "phablet")); - EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>( - &mTable, "string/bot", - ConfigDescription::defaultConfig(), "default")); + test::GetValueForConfigAndProduct<String>( + &table_, "string/baz", ConfigDescription::DefaultConfig(), "")); + EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<String>( + &table_, "string/bit", + ConfigDescription::DefaultConfig(), "phablet")); + EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<String>( + &table_, "string/bot", + ConfigDescription::DefaultConfig(), "default")); } TEST_F(ResourceParserTest, AutoIncrementIdsInPublicGroup) { @@ -654,61 +657,61 @@ TEST_F(ResourceParserTest, AutoIncrementIdsInPublicGroup) { <public name="foo" /> <public name="bar" /> </public-group>)EOF"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); Maybe<ResourceTable::SearchResult> result = - mTable.findResource(test::parseNameOrDie("attr/foo")); + table_.FindResource(test::ParseNameOrDie("attr/foo")); AAPT_ASSERT_TRUE(result); AAPT_ASSERT_TRUE(result.value().package->id); AAPT_ASSERT_TRUE(result.value().type->id); AAPT_ASSERT_TRUE(result.value().entry->id); - ResourceId actualId(result.value().package->id.value(), - result.value().type->id.value(), - result.value().entry->id.value()); - EXPECT_EQ(ResourceId(0x01010040), actualId); + ResourceId actual_id(result.value().package->id.value(), + result.value().type->id.value(), + result.value().entry->id.value()); + EXPECT_EQ(ResourceId(0x01010040), actual_id); - result = mTable.findResource(test::parseNameOrDie("attr/bar")); + result = table_.FindResource(test::ParseNameOrDie("attr/bar")); AAPT_ASSERT_TRUE(result); AAPT_ASSERT_TRUE(result.value().package->id); AAPT_ASSERT_TRUE(result.value().type->id); AAPT_ASSERT_TRUE(result.value().entry->id); - actualId = ResourceId(result.value().package->id.value(), - result.value().type->id.value(), - result.value().entry->id.value()); - EXPECT_EQ(ResourceId(0x01010041), actualId); + actual_id = ResourceId(result.value().package->id.value(), + result.value().type->id.value(), + result.value().entry->id.value()); + EXPECT_EQ(ResourceId(0x01010041), actual_id); } TEST_F(ResourceParserTest, ExternalTypesShouldOnlyBeReferences) { std::string input = R"EOF(<item type="layout" name="foo">@layout/bar</item>)EOF"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); input = R"EOF(<item type="layout" name="bar">"this is a string"</item>)EOF"; - ASSERT_FALSE(testParse(input)); + ASSERT_FALSE(TestParse(input)); } TEST_F(ResourceParserTest, AddResourcesElementShouldAddEntryWithUndefinedSymbol) { std::string input = R"EOF(<add-resource name="bar" type="string" />)EOF"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); Maybe<ResourceTable::SearchResult> result = - mTable.findResource(test::parseNameOrDie("string/bar")); + table_.FindResource(test::ParseNameOrDie("string/bar")); AAPT_ASSERT_TRUE(result); const ResourceEntry* entry = result.value().entry; ASSERT_NE(nullptr, entry); - EXPECT_EQ(SymbolState::kUndefined, entry->symbolStatus.state); + EXPECT_EQ(SymbolState::kUndefined, entry->symbol_status.state); } TEST_F(ResourceParserTest, ParseItemElementWithFormat) { std::string input = R"EOF(<item name="foo" type="integer" format="float">0.3</item>)EOF"; - ASSERT_TRUE(testParse(input)); + ASSERT_TRUE(TestParse(input)); BinaryPrimitive* val = - test::getValue<BinaryPrimitive>(&mTable, "integer/foo"); + test::GetValue<BinaryPrimitive>(&table_, "integer/foo"); ASSERT_NE(nullptr, val); EXPECT_EQ(uint32_t(android::Res_value::TYPE_FLOAT), val->value.dataType); diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp index c52c91c0832f..4e6a50ae149b 100644 --- a/tools/aapt2/ResourceTable.cpp +++ b/tools/aapt2/ResourceTable.cpp @@ -21,6 +21,7 @@ #include "ValueVisitor.h" #include "util/Util.h" +#include <android-base/logging.h> #include <androidfw/ResourceTypes.h> #include <algorithm> #include <memory> @@ -29,28 +30,29 @@ namespace aapt { -static bool lessThanType(const std::unique_ptr<ResourceTableType>& lhs, - ResourceType rhs) { +static bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs, + ResourceType rhs) { return lhs->type < rhs; } template <typename T> -static bool lessThanStructWithName(const std::unique_ptr<T>& lhs, - const StringPiece& rhs) { +static bool less_than_struct_with_name(const std::unique_ptr<T>& lhs, + const StringPiece& rhs) { return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0; } -ResourceTablePackage* ResourceTable::findPackage(const StringPiece& name) { +ResourceTablePackage* ResourceTable::FindPackage(const StringPiece& name) { const auto last = packages.end(); - auto iter = std::lower_bound(packages.begin(), last, name, - lessThanStructWithName<ResourceTablePackage>); + auto iter = + std::lower_bound(packages.begin(), last, name, + less_than_struct_with_name<ResourceTablePackage>); if (iter != last && name == (*iter)->name) { return iter->get(); } return nullptr; } -ResourceTablePackage* ResourceTable::findPackageById(uint8_t id) { +ResourceTablePackage* ResourceTable::FindPackageById(uint8_t id) { for (auto& package : packages) { if (package->id && package->id.value() == id) { return package.get(); @@ -59,9 +61,9 @@ ResourceTablePackage* ResourceTable::findPackageById(uint8_t id) { return nullptr; } -ResourceTablePackage* ResourceTable::createPackage(const StringPiece& name, +ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name, Maybe<uint8_t> id) { - ResourceTablePackage* package = findOrCreatePackage(name); + ResourceTablePackage* package = FindOrCreatePackage(name); if (id && !package->id) { package->id = id; return package; @@ -73,61 +75,62 @@ ResourceTablePackage* ResourceTable::createPackage(const StringPiece& name, return package; } -ResourceTablePackage* ResourceTable::findOrCreatePackage( +ResourceTablePackage* ResourceTable::FindOrCreatePackage( const StringPiece& name) { const auto last = packages.end(); - auto iter = std::lower_bound(packages.begin(), last, name, - lessThanStructWithName<ResourceTablePackage>); + auto iter = + std::lower_bound(packages.begin(), last, name, + less_than_struct_with_name<ResourceTablePackage>); if (iter != last && name == (*iter)->name) { return iter->get(); } - std::unique_ptr<ResourceTablePackage> newPackage = + std::unique_ptr<ResourceTablePackage> new_package = util::make_unique<ResourceTablePackage>(); - newPackage->name = name.toString(); - return packages.emplace(iter, std::move(newPackage))->get(); + new_package->name = name.ToString(); + return packages.emplace(iter, std::move(new_package))->get(); } -ResourceTableType* ResourceTablePackage::findType(ResourceType type) { +ResourceTableType* ResourceTablePackage::FindType(ResourceType type) { const auto last = types.end(); - auto iter = std::lower_bound(types.begin(), last, type, lessThanType); + auto iter = std::lower_bound(types.begin(), last, type, less_than_type); if (iter != last && (*iter)->type == type) { return iter->get(); } return nullptr; } -ResourceTableType* ResourceTablePackage::findOrCreateType(ResourceType type) { +ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type) { const auto last = types.end(); - auto iter = std::lower_bound(types.begin(), last, type, lessThanType); + auto iter = std::lower_bound(types.begin(), last, type, less_than_type); if (iter != last && (*iter)->type == type) { return iter->get(); } return types.emplace(iter, new ResourceTableType(type))->get(); } -ResourceEntry* ResourceTableType::findEntry(const StringPiece& name) { +ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name) { const auto last = entries.end(); auto iter = std::lower_bound(entries.begin(), last, name, - lessThanStructWithName<ResourceEntry>); + less_than_struct_with_name<ResourceEntry>); if (iter != last && name == (*iter)->name) { return iter->get(); } return nullptr; } -ResourceEntry* ResourceTableType::findOrCreateEntry(const StringPiece& name) { +ResourceEntry* ResourceTableType::FindOrCreateEntry(const StringPiece& name) { auto last = entries.end(); auto iter = std::lower_bound(entries.begin(), last, name, - lessThanStructWithName<ResourceEntry>); + less_than_struct_with_name<ResourceEntry>); if (iter != last && name == (*iter)->name) { return iter->get(); } return entries.emplace(iter, new ResourceEntry(name))->get(); } -ResourceConfigValue* ResourceEntry::findValue(const ConfigDescription& config) { - return findValue(config, StringPiece()); +ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config) { + return FindValue(config, StringPiece()); } struct ConfigKey { @@ -144,7 +147,7 @@ bool ltConfigKeyRef(const std::unique_ptr<ResourceConfigValue>& lhs, return cmp < 0; } -ResourceConfigValue* ResourceEntry::findValue(const ConfigDescription& config, +ResourceConfigValue* ResourceEntry::FindValue(const ConfigDescription& config, const StringPiece& product) { auto iter = std::lower_bound(values.begin(), values.end(), ConfigKey{&config, product}, ltConfigKeyRef); @@ -157,7 +160,7 @@ ResourceConfigValue* ResourceEntry::findValue(const ConfigDescription& config, return nullptr; } -ResourceConfigValue* ResourceEntry::findOrCreateValue( +ResourceConfigValue* ResourceEntry::FindOrCreateValue( const ConfigDescription& config, const StringPiece& product) { auto iter = std::lower_bound(values.begin(), values.end(), ConfigKey{&config, product}, ltConfigKeyRef); @@ -197,7 +200,7 @@ std::vector<ResourceConfigValue*> ResourceEntry::findAllValues( return results; } -std::vector<ResourceConfigValue*> ResourceEntry::findValuesIf( +std::vector<ResourceConfigValue*> ResourceEntry::FindValuesIf( const std::function<bool(ResourceConfigValue*)>& f) { std::vector<ResourceConfigValue*> results; for (auto& configValue : values) { @@ -232,16 +235,16 @@ std::vector<ResourceConfigValue*> ResourceEntry::findValuesIf( * format for there to be * no error. */ -ResourceTable::CollisionResult ResourceTable::resolveValueCollision( +ResourceTable::CollisionResult ResourceTable::ResolveValueCollision( Value* existing, Value* incoming) { - Attribute* existingAttr = valueCast<Attribute>(existing); - Attribute* incomingAttr = valueCast<Attribute>(incoming); - if (!incomingAttr) { - if (incoming->isWeak()) { + Attribute* existing_attr = ValueCast<Attribute>(existing); + Attribute* incoming_attr = ValueCast<Attribute>(incoming); + if (!incoming_attr) { + if (incoming->IsWeak()) { // We're trying to add a weak resource but a resource // already exists. Keep the existing. return CollisionResult::kKeepOriginal; - } else if (existing->isWeak()) { + } else if (existing->IsWeak()) { // Override the weak resource with the new strong resource. return CollisionResult::kTakeNew; } @@ -250,8 +253,8 @@ ResourceTable::CollisionResult ResourceTable::resolveValueCollision( return CollisionResult::kConflict; } - if (!existingAttr) { - if (existing->isWeak()) { + if (!existing_attr) { + if (existing->IsWeak()) { // The existing value is not an attribute and it is weak, // so take the incoming attribute value. return CollisionResult::kTakeNew; @@ -261,7 +264,7 @@ ResourceTable::CollisionResult ResourceTable::resolveValueCollision( return CollisionResult::kConflict; } - assert(incomingAttr && existingAttr); + CHECK(incoming_attr != nullptr && existing_attr != nullptr); // // Attribute specific handling. At this point we know both @@ -269,22 +272,22 @@ ResourceTable::CollisionResult ResourceTable::resolveValueCollision( // attributes all-over, we do special handling to see // which definition sticks. // - if (existingAttr->typeMask == incomingAttr->typeMask) { + if (existing_attr->type_mask == incoming_attr->type_mask) { // The two attributes are both DECLs, but they are plain attributes // with the same formats. // Keep the strongest one. - return existingAttr->isWeak() ? CollisionResult::kTakeNew - : CollisionResult::kKeepOriginal; + return existing_attr->IsWeak() ? CollisionResult::kTakeNew + : CollisionResult::kKeepOriginal; } - if (existingAttr->isWeak() && - existingAttr->typeMask == android::ResTable_map::TYPE_ANY) { + if (existing_attr->IsWeak() && + existing_attr->type_mask == android::ResTable_map::TYPE_ANY) { // Any incoming attribute is better than this. return CollisionResult::kTakeNew; } - if (incomingAttr->isWeak() && - incomingAttr->typeMask == android::ResTable_map::TYPE_ANY) { + if (incoming_attr->IsWeak() && + incoming_attr->type_mask == android::ResTable_map::TYPE_ANY) { // The incoming attribute may be a USE instead of a DECL. // Keep the existing attribute. return CollisionResult::kKeepOriginal; @@ -295,138 +298,139 @@ ResourceTable::CollisionResult ResourceTable::resolveValueCollision( static constexpr const char* kValidNameChars = "._-"; static constexpr const char* kValidNameMangledChars = "._-$"; -bool ResourceTable::addResource(const ResourceNameRef& name, +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); + return AddResourceImpl(name, {}, config, product, std::move(value), + kValidNameChars, ResolveValueCollision, diag); } -bool ResourceTable::addResource(const ResourceNameRef& name, - const ResourceId& resId, +bool ResourceTable::AddResource(const ResourceNameRef& name, + const ResourceId& res_id, const ConfigDescription& config, const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag) { - return addResourceImpl(name, resId, config, product, std::move(value), - kValidNameChars, resolveValueCollision, diag); + return AddResourceImpl(name, res_id, config, product, std::move(value), + kValidNameChars, ResolveValueCollision, diag); } -bool ResourceTable::addFileReference(const ResourceNameRef& name, +bool ResourceTable::AddFileReference(const ResourceNameRef& name, const ConfigDescription& config, const Source& source, const StringPiece& path, IDiagnostics* diag) { - return addFileReferenceImpl(name, config, source, path, nullptr, + return AddFileReferenceImpl(name, config, source, path, nullptr, kValidNameChars, diag); } -bool ResourceTable::addFileReferenceAllowMangled( +bool ResourceTable::AddFileReferenceAllowMangled( const ResourceNameRef& name, const ConfigDescription& config, const Source& source, const StringPiece& path, io::IFile* file, IDiagnostics* diag) { - return addFileReferenceImpl(name, config, source, path, file, + return AddFileReferenceImpl(name, config, source, path, file, kValidNameMangledChars, diag); } -bool ResourceTable::addFileReferenceImpl( +bool ResourceTable::AddFileReferenceImpl( const ResourceNameRef& name, const ConfigDescription& config, const Source& source, const StringPiece& path, io::IFile* file, - const char* validChars, IDiagnostics* diag) { + const char* valid_chars, IDiagnostics* diag) { std::unique_ptr<FileReference> fileRef = - util::make_unique<FileReference>(stringPool.makeRef(path)); - fileRef->setSource(source); + util::make_unique<FileReference>(string_pool.MakeRef(path)); + fileRef->SetSource(source); fileRef->file = file; - return addResourceImpl(name, ResourceId{}, config, StringPiece{}, - std::move(fileRef), validChars, resolveValueCollision, + return AddResourceImpl(name, ResourceId{}, config, StringPiece{}, + std::move(fileRef), valid_chars, ResolveValueCollision, diag); } -bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name, +bool ResourceTable::AddResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config, const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag) { - return addResourceImpl(name, ResourceId{}, config, product, std::move(value), - kValidNameMangledChars, resolveValueCollision, diag); + return AddResourceImpl(name, ResourceId{}, config, product, std::move(value), + kValidNameMangledChars, ResolveValueCollision, diag); } -bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name, +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, product, std::move(value), - kValidNameMangledChars, resolveValueCollision, diag); + return AddResourceImpl(name, id, config, product, std::move(value), + kValidNameMangledChars, ResolveValueCollision, diag); } -bool ResourceTable::addResourceImpl( - const ResourceNameRef& name, const ResourceId& resId, +bool ResourceTable::AddResourceImpl( + const ResourceNameRef& name, const ResourceId& res_id, const ConfigDescription& config, const StringPiece& product, - std::unique_ptr<Value> value, const char* validChars, + std::unique_ptr<Value> value, const char* valid_chars, const CollisionResolverFunc& conflictResolver, IDiagnostics* diag) { - assert(value && "value can't be nullptr"); - assert(diag && "diagnostics can't be nullptr"); + CHECK(value != nullptr); + CHECK(diag != nullptr); - auto badCharIter = - util::findNonAlphaNumericAndNotInSet(name.entry, validChars); - if (badCharIter != name.entry.end()) { - diag->error(DiagMessage(value->getSource()) + auto bad_char_iter = + util::FindNonAlphaNumericAndNotInSet(name.entry, valid_chars); + if (bad_char_iter != name.entry.end()) { + diag->Error(DiagMessage(value->GetSource()) << "resource '" << name << "' has invalid entry name '" << name.entry << "'. Invalid character '" - << StringPiece(badCharIter, 1) << "'"); + << StringPiece(bad_char_iter, 1) << "'"); return false; } - ResourceTablePackage* package = findOrCreatePackage(name.package); - if (resId.isValid() && package->id && - package->id.value() != resId.packageId()) { - diag->error(DiagMessage(value->getSource()) - << "trying to add resource '" << name << "' with ID " << resId + ResourceTablePackage* package = FindOrCreatePackage(name.package); + if (res_id.is_valid() && package->id && + package->id.value() != res_id.package_id()) { + diag->Error(DiagMessage(value->GetSource()) + << "trying to add resource '" << name << "' with ID " << res_id << " but package '" << package->name << "' already has ID " << std::hex << (int)package->id.value() << std::dec); return false; } - ResourceTableType* type = package->findOrCreateType(name.type); - if (resId.isValid() && type->id && type->id.value() != resId.typeId()) { - diag->error(DiagMessage(value->getSource()) - << "trying to add resource '" << name << "' with ID " << resId + ResourceTableType* type = package->FindOrCreateType(name.type); + if (res_id.is_valid() && type->id && type->id.value() != res_id.type_id()) { + diag->Error(DiagMessage(value->GetSource()) + << "trying to add resource '" << name << "' with ID " << res_id << " but type '" << type->type << "' already has ID " << std::hex << (int)type->id.value() << std::dec); return false; } - ResourceEntry* entry = type->findOrCreateEntry(name.entry); - if (resId.isValid() && entry->id && entry->id.value() != resId.entryId()) { - diag->error(DiagMessage(value->getSource()) - << "trying to add resource '" << name << "' with ID " << resId + ResourceEntry* entry = type->FindOrCreateEntry(name.entry); + if (res_id.is_valid() && entry->id && + entry->id.value() != res_id.entry_id()) { + diag->Error(DiagMessage(value->GetSource()) + << "trying to add resource '" << name << "' with ID " << res_id << " but resource already has ID " << ResourceId(package->id.value(), type->id.value(), entry->id.value())); return false; } - ResourceConfigValue* configValue = entry->findOrCreateValue(config, product); - if (!configValue->value) { + ResourceConfigValue* config_value = entry->FindOrCreateValue(config, product); + if (!config_value->value) { // Resource does not exist, add it now. - configValue->value = std::move(value); + config_value->value = std::move(value); } else { - switch (conflictResolver(configValue->value.get(), value.get())) { + switch (conflictResolver(config_value->value.get(), value.get())) { case CollisionResult::kTakeNew: // Take the incoming value. - configValue->value = std::move(value); + config_value->value = std::move(value); break; case CollisionResult::kConflict: - diag->error(DiagMessage(value->getSource()) + diag->Error(DiagMessage(value->GetSource()) << "duplicate value for resource '" << name << "' " << "with config '" << config << "'"); - diag->error(DiagMessage(configValue->value->getSource()) + diag->Error(DiagMessage(config_value->value->GetSource()) << "resource previously defined here"); return false; @@ -435,113 +439,114 @@ bool ResourceTable::addResourceImpl( } } - if (resId.isValid()) { - package->id = resId.packageId(); - type->id = resId.typeId(); - entry->id = resId.entryId(); + if (res_id.is_valid()) { + package->id = res_id.package_id(); + type->id = res_id.type_id(); + entry->id = res_id.entry_id(); } return true; } -bool ResourceTable::setSymbolState(const ResourceNameRef& name, - const ResourceId& resId, +bool ResourceTable::SetSymbolState(const ResourceNameRef& name, + const ResourceId& res_id, const Symbol& symbol, IDiagnostics* diag) { - return setSymbolStateImpl(name, resId, symbol, kValidNameChars, diag); + return SetSymbolStateImpl(name, res_id, symbol, kValidNameChars, diag); } -bool ResourceTable::setSymbolStateAllowMangled(const ResourceNameRef& name, - const ResourceId& resId, +bool ResourceTable::SetSymbolStateAllowMangled(const ResourceNameRef& name, + const ResourceId& res_id, const Symbol& symbol, IDiagnostics* diag) { - return setSymbolStateImpl(name, resId, symbol, kValidNameMangledChars, diag); + return SetSymbolStateImpl(name, res_id, symbol, kValidNameMangledChars, diag); } -bool ResourceTable::setSymbolStateImpl(const ResourceNameRef& name, - const ResourceId& resId, +bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name, + const ResourceId& res_id, const Symbol& symbol, - const char* validChars, + const char* valid_chars, IDiagnostics* diag) { - assert(diag && "diagnostics can't be nullptr"); + CHECK(diag != nullptr); - auto badCharIter = - util::findNonAlphaNumericAndNotInSet(name.entry, validChars); - if (badCharIter != name.entry.end()) { - diag->error(DiagMessage(symbol.source) + auto bad_char_iter = + util::FindNonAlphaNumericAndNotInSet(name.entry, valid_chars); + if (bad_char_iter != name.entry.end()) { + diag->Error(DiagMessage(symbol.source) << "resource '" << name << "' has invalid entry name '" << name.entry << "'. Invalid character '" - << StringPiece(badCharIter, 1) << "'"); + << StringPiece(bad_char_iter, 1) << "'"); return false; } - ResourceTablePackage* package = findOrCreatePackage(name.package); - if (resId.isValid() && package->id && - package->id.value() != resId.packageId()) { - diag->error(DiagMessage(symbol.source) - << "trying to add resource '" << name << "' with ID " << resId + ResourceTablePackage* package = FindOrCreatePackage(name.package); + if (res_id.is_valid() && package->id && + package->id.value() != res_id.package_id()) { + diag->Error(DiagMessage(symbol.source) + << "trying to add resource '" << name << "' with ID " << res_id << " but package '" << package->name << "' already has ID " << std::hex << (int)package->id.value() << std::dec); return false; } - ResourceTableType* type = package->findOrCreateType(name.type); - if (resId.isValid() && type->id && type->id.value() != resId.typeId()) { - diag->error(DiagMessage(symbol.source) - << "trying to add resource '" << name << "' with ID " << resId + ResourceTableType* type = package->FindOrCreateType(name.type); + if (res_id.is_valid() && type->id && type->id.value() != res_id.type_id()) { + diag->Error(DiagMessage(symbol.source) + << "trying to add resource '" << name << "' with ID " << res_id << " but type '" << type->type << "' already has ID " << std::hex << (int)type->id.value() << std::dec); return false; } - ResourceEntry* entry = type->findOrCreateEntry(name.entry); - if (resId.isValid() && entry->id && entry->id.value() != resId.entryId()) { - diag->error(DiagMessage(symbol.source) - << "trying to add resource '" << name << "' with ID " << resId + ResourceEntry* entry = type->FindOrCreateEntry(name.entry); + if (res_id.is_valid() && entry->id && + entry->id.value() != res_id.entry_id()) { + diag->Error(DiagMessage(symbol.source) + << "trying to add resource '" << name << "' with ID " << res_id << " but resource already has ID " << ResourceId(package->id.value(), type->id.value(), entry->id.value())); return false; } - if (resId.isValid()) { - package->id = resId.packageId(); - type->id = resId.typeId(); - entry->id = resId.entryId(); + if (res_id.is_valid()) { + package->id = res_id.package_id(); + type->id = res_id.type_id(); + entry->id = res_id.entry_id(); } // Only mark the type state as public, it doesn't care about being private. if (symbol.state == SymbolState::kPublic) { - type->symbolStatus.state = SymbolState::kPublic; + type->symbol_status.state = SymbolState::kPublic; } if (symbol.state == SymbolState::kUndefined && - entry->symbolStatus.state != SymbolState::kUndefined) { + entry->symbol_status.state != SymbolState::kUndefined) { // We can't undefine a symbol (remove its visibility). Ignore. return true; } if (symbol.state == SymbolState::kPrivate && - entry->symbolStatus.state == SymbolState::kPublic) { + entry->symbol_status.state == SymbolState::kPublic) { // We can't downgrade public to private. Ignore. return true; } - entry->symbolStatus = std::move(symbol); + entry->symbol_status = std::move(symbol); return true; } -Maybe<ResourceTable::SearchResult> ResourceTable::findResource( +Maybe<ResourceTable::SearchResult> ResourceTable::FindResource( const ResourceNameRef& name) { - ResourceTablePackage* package = findPackage(name.package); + ResourceTablePackage* package = FindPackage(name.package); if (!package) { return {}; } - ResourceTableType* type = package->findType(name.type); + ResourceTableType* type = package->FindType(name.type); if (!type) { return {}; } - ResourceEntry* entry = type->findEntry(name.entry); + ResourceEntry* entry = type->FindEntry(name.entry); if (!entry) { return {}; } diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h index ebaad41eac6e..a0c3217df610 100644 --- a/tools/aapt2/ResourceTable.h +++ b/tools/aapt2/ResourceTable.h @@ -70,7 +70,7 @@ class ResourceConfigValue { ResourceConfigValue(const ConfigDescription& config, const StringPiece& product) - : config(config), product(product.toString()) {} + : config(config), product(product.ToString()) {} private: DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue); @@ -98,23 +98,23 @@ class ResourceEntry { * Whether this resource is public (and must maintain the same entry ID across * builds). */ - Symbol symbolStatus; + Symbol symbol_status; /** * The resource's values for each configuration. */ std::vector<std::unique_ptr<ResourceConfigValue>> values; - explicit ResourceEntry(const StringPiece& name) : name(name.toString()) {} + explicit ResourceEntry(const StringPiece& name) : name(name.ToString()) {} - ResourceConfigValue* findValue(const ConfigDescription& config); - ResourceConfigValue* findValue(const ConfigDescription& config, + ResourceConfigValue* FindValue(const ConfigDescription& config); + ResourceConfigValue* FindValue(const ConfigDescription& config, const StringPiece& product); - ResourceConfigValue* findOrCreateValue(const ConfigDescription& config, + ResourceConfigValue* FindOrCreateValue(const ConfigDescription& config, const StringPiece& product); std::vector<ResourceConfigValue*> findAllValues( const ConfigDescription& config); - std::vector<ResourceConfigValue*> findValuesIf( + std::vector<ResourceConfigValue*> FindValuesIf( const std::function<bool(ResourceConfigValue*)>& f); private: @@ -141,7 +141,7 @@ class ResourceTableType { * Whether this type is public (and must maintain the same * type ID across builds). */ - Symbol symbolStatus; + Symbol symbol_status; /** * List of resources for this type. @@ -150,8 +150,8 @@ class ResourceTableType { explicit ResourceTableType(const ResourceType type) : type(type) {} - ResourceEntry* findEntry(const StringPiece& name); - ResourceEntry* findOrCreateEntry(const StringPiece& name); + ResourceEntry* FindEntry(const StringPiece& name); + ResourceEntry* FindOrCreateEntry(const StringPiece& name); private: DISALLOW_COPY_AND_ASSIGN(ResourceTableType); @@ -168,8 +168,8 @@ class ResourceTablePackage { std::vector<std::unique_ptr<ResourceTableType>> types; ResourceTablePackage() = default; - ResourceTableType* findType(ResourceType type); - ResourceTableType* findOrCreateType(const ResourceType type); + ResourceTableType* FindType(ResourceType type); + ResourceTableType* FindOrCreateType(const ResourceType type); private: DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage); @@ -191,53 +191,53 @@ class ResourceTable { * When a collision of resources occurs, this method decides which value to * keep. */ - static CollisionResult resolveValueCollision(Value* existing, + static CollisionResult ResolveValueCollision(Value* existing, Value* incoming); - bool addResource(const ResourceNameRef& name, const ConfigDescription& config, + 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, + bool AddResource(const ResourceNameRef& name, const ResourceId& res_id, const ConfigDescription& config, const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag); - bool addFileReference(const ResourceNameRef& name, + bool AddFileReference(const ResourceNameRef& name, const ConfigDescription& config, const Source& source, const StringPiece& path, IDiagnostics* diag); - bool addFileReferenceAllowMangled(const ResourceNameRef& name, + bool AddFileReferenceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config, const Source& source, const StringPiece& path, io::IFile* file, IDiagnostics* diag); /** - * Same as addResource, but doesn't verify the validity of the name. This is + * 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, + bool AddResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config, const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag); - bool addResourceAllowMangled(const ResourceNameRef& name, + 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, + bool SetSymbolState(const ResourceNameRef& name, const ResourceId& res_id, const Symbol& symbol, IDiagnostics* diag); - bool setSymbolStateAllowMangled(const ResourceNameRef& name, - const ResourceId& resId, const Symbol& symbol, - IDiagnostics* diag); + bool SetSymbolStateAllowMangled(const ResourceNameRef& name, + const ResourceId& res_id, + const Symbol& symbol, IDiagnostics* diag); struct SearchResult { ResourceTablePackage* package; @@ -245,21 +245,21 @@ class ResourceTable { ResourceEntry* entry; }; - Maybe<SearchResult> findResource(const ResourceNameRef& name); + 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 + * NOTE: `string_pool` must come before `packages` so that it is destroyed * after. - * When `string pool` references are destroyed (as they will be when + * 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; + StringPool string_pool; /** * The list of packages in this table, sorted alphabetically by package name. @@ -273,31 +273,31 @@ class ResourceTable { * represent the * 'current' package before it is known to the ResourceTable. */ - ResourceTablePackage* findPackage(const StringPiece& name); + ResourceTablePackage* FindPackage(const StringPiece& name); - ResourceTablePackage* findPackageById(uint8_t id); + ResourceTablePackage* FindPackageById(uint8_t id); - ResourceTablePackage* createPackage(const StringPiece& name, + ResourceTablePackage* CreatePackage(const StringPiece& name, Maybe<uint8_t> id = {}); private: - ResourceTablePackage* findOrCreatePackage(const StringPiece& name); + ResourceTablePackage* FindOrCreatePackage(const StringPiece& name); - bool addResourceImpl(const ResourceNameRef& name, const ResourceId& resId, + bool AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id, const ConfigDescription& config, const StringPiece& product, std::unique_ptr<Value> value, - const char* validChars, - const CollisionResolverFunc& conflictResolver, + const char* valid_chars, + const CollisionResolverFunc& conflict_resolver, IDiagnostics* diag); - bool addFileReferenceImpl(const ResourceNameRef& name, + bool AddFileReferenceImpl(const ResourceNameRef& name, const ConfigDescription& config, const Source& source, const StringPiece& path, - io::IFile* file, const char* validChars, + io::IFile* file, const char* valid_chars, IDiagnostics* diag); - bool setSymbolStateImpl(const ResourceNameRef& name, const ResourceId& resId, - const Symbol& symbol, const char* validChars, + bool SetSymbolStateImpl(const ResourceNameRef& name, const ResourceId& res_id, + const Symbol& symbol, const char* valid_chars, IDiagnostics* diag); DISALLOW_COPY_AND_ASSIGN(ResourceTable); diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp index a64ad3eb639a..cb3699a00f75 100644 --- a/tools/aapt2/ResourceTable_test.cpp +++ b/tools/aapt2/ResourceTable_test.cpp @@ -29,108 +29,108 @@ namespace aapt { TEST(ResourceTableTest, FailToAddResourceWithBadName) { ResourceTable table; - EXPECT_FALSE(table.addResource( - test::parseNameOrDie("android:id/hey,there"), ConfigDescription{}, "", - test::ValueBuilder<Id>().setSource("test.xml", 21u).build(), - test::getDiagnostics())); - - EXPECT_FALSE(table.addResource( - test::parseNameOrDie("android:id/hey:there"), ConfigDescription{}, "", - test::ValueBuilder<Id>().setSource("test.xml", 21u).build(), - test::getDiagnostics())); + EXPECT_FALSE(table.AddResource( + test::ParseNameOrDie("android:id/hey,there"), ConfigDescription{}, "", + test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(), + test::GetDiagnostics())); + + EXPECT_FALSE(table.AddResource( + test::ParseNameOrDie("android:id/hey:there"), ConfigDescription{}, "", + test::ValueBuilder<Id>().SetSource("test.xml", 21u).Build(), + test::GetDiagnostics())); } TEST(ResourceTableTest, AddOneResource) { ResourceTable table; - EXPECT_TRUE(table.addResource( - test::parseNameOrDie("android:attr/id"), ConfigDescription{}, "", - test::ValueBuilder<Id>().setSource("test/path/file.xml", 23u).build(), - test::getDiagnostics())); + EXPECT_TRUE(table.AddResource( + test::ParseNameOrDie("android:attr/id"), ConfigDescription{}, "", + test::ValueBuilder<Id>().SetSource("test/path/file.xml", 23u).Build(), + test::GetDiagnostics())); - ASSERT_NE(nullptr, test::getValue<Id>(&table, "android:attr/id")); + ASSERT_NE(nullptr, test::GetValue<Id>(&table, "android:attr/id")); } TEST(ResourceTableTest, AddMultipleResources) { ResourceTable table; ConfigDescription config; - ConfigDescription languageConfig; - memcpy(languageConfig.language, "pl", sizeof(languageConfig.language)); - - EXPECT_TRUE(table.addResource( - test::parseNameOrDie("android:attr/layout_width"), config, "", - test::ValueBuilder<Id>().setSource("test/path/file.xml", 10u).build(), - test::getDiagnostics())); - - EXPECT_TRUE(table.addResource( - test::parseNameOrDie("android:attr/id"), config, "", - test::ValueBuilder<Id>().setSource("test/path/file.xml", 12u).build(), - test::getDiagnostics())); - - EXPECT_TRUE(table.addResource( - test::parseNameOrDie("android:string/ok"), config, "", - test::ValueBuilder<Id>().setSource("test/path/file.xml", 14u).build(), - test::getDiagnostics())); - - EXPECT_TRUE(table.addResource( - test::parseNameOrDie("android:string/ok"), languageConfig, "", + ConfigDescription language_config; + memcpy(language_config.language, "pl", sizeof(language_config.language)); + + EXPECT_TRUE(table.AddResource( + test::ParseNameOrDie("android:attr/layout_width"), config, "", + test::ValueBuilder<Id>().SetSource("test/path/file.xml", 10u).Build(), + test::GetDiagnostics())); + + EXPECT_TRUE(table.AddResource( + test::ParseNameOrDie("android:attr/id"), config, "", + test::ValueBuilder<Id>().SetSource("test/path/file.xml", 12u).Build(), + test::GetDiagnostics())); + + EXPECT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/ok"), config, "", + test::ValueBuilder<Id>().SetSource("test/path/file.xml", 14u).Build(), + test::GetDiagnostics())); + + EXPECT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/ok"), language_config, "", test::ValueBuilder<BinaryPrimitive>(android::Res_value{}) - .setSource("test/path/file.xml", 20u) - .build(), - test::getDiagnostics())); - - ASSERT_NE(nullptr, test::getValue<Id>(&table, "android:attr/layout_width")); - ASSERT_NE(nullptr, test::getValue<Id>(&table, "android:attr/id")); - ASSERT_NE(nullptr, test::getValue<Id>(&table, "android:string/ok")); - ASSERT_NE(nullptr, test::getValueForConfig<BinaryPrimitive>( - &table, "android:string/ok", languageConfig)); + .SetSource("test/path/file.xml", 20u) + .Build(), + test::GetDiagnostics())); + + ASSERT_NE(nullptr, test::GetValue<Id>(&table, "android:attr/layout_width")); + ASSERT_NE(nullptr, test::GetValue<Id>(&table, "android:attr/id")); + ASSERT_NE(nullptr, test::GetValue<Id>(&table, "android:string/ok")); + ASSERT_NE(nullptr, test::GetValueForConfig<BinaryPrimitive>( + &table, "android:string/ok", language_config)); } TEST(ResourceTableTest, OverrideWeakResourceValue) { ResourceTable table; - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:attr/foo"), ConfigDescription{}, "", - util::make_unique<Attribute>(true), test::getDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "", + util::make_unique<Attribute>(true), test::GetDiagnostics())); - Attribute* attr = test::getValue<Attribute>(&table, "android:attr/foo"); + Attribute* attr = test::GetValue<Attribute>(&table, "android:attr/foo"); ASSERT_NE(nullptr, attr); - EXPECT_TRUE(attr->isWeak()); + EXPECT_TRUE(attr->IsWeak()); - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:attr/foo"), ConfigDescription{}, "", - util::make_unique<Attribute>(false), test::getDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "", + util::make_unique<Attribute>(false), test::GetDiagnostics())); - attr = test::getValue<Attribute>(&table, "android:attr/foo"); + attr = test::GetValue<Attribute>(&table, "android:attr/foo"); ASSERT_NE(nullptr, attr); - EXPECT_FALSE(attr->isWeak()); + EXPECT_FALSE(attr->IsWeak()); } TEST(ResourceTableTest, ProductVaryingValues) { ResourceTable table; - EXPECT_TRUE(table.addResource(test::parseNameOrDie("android:string/foo"), - test::parseConfigOrDie("land"), "tablet", + EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"), + test::ParseConfigOrDie("land"), "tablet", util::make_unique<Id>(), - test::getDiagnostics())); - EXPECT_TRUE(table.addResource(test::parseNameOrDie("android:string/foo"), - test::parseConfigOrDie("land"), "phone", + test::GetDiagnostics())); + EXPECT_TRUE(table.AddResource(test::ParseNameOrDie("android:string/foo"), + test::ParseConfigOrDie("land"), "phone", util::make_unique<Id>(), - test::getDiagnostics())); + test::GetDiagnostics())); - EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>( + EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>( &table, "android:string/foo", - test::parseConfigOrDie("land"), "tablet")); - EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>( + test::ParseConfigOrDie("land"), "tablet")); + EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>( &table, "android:string/foo", - test::parseConfigOrDie("land"), "phone")); + test::ParseConfigOrDie("land"), "phone")); Maybe<ResourceTable::SearchResult> sr = - table.findResource(test::parseNameOrDie("android:string/foo")); + table.FindResource(test::ParseNameOrDie("android:string/foo")); AAPT_ASSERT_TRUE(sr); std::vector<ResourceConfigValue*> values = - sr.value().entry->findAllValues(test::parseConfigOrDie("land")); + sr.value().entry->findAllValues(test::ParseConfigOrDie("land")); ASSERT_EQ(2u, values.size()); EXPECT_EQ(std::string("phone"), values[0]->product); EXPECT_EQ(std::string("tablet"), values[1]->product); diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp index b41be4bab0b8..fce9b338d726 100644 --- a/tools/aapt2/ResourceUtils.cpp +++ b/tools/aapt2/ResourceUtils.cpp @@ -15,34 +15,36 @@ */ #include "ResourceUtils.h" + +#include <sstream> + +#include "androidfw/ResourceTypes.h" + #include "NameMangler.h" #include "SdkConstants.h" #include "flatten/ResourceTypeExtensions.h" #include "util/Files.h" #include "util/Util.h" -#include <androidfw/ResourceTypes.h> -#include <sstream> - namespace aapt { namespace ResourceUtils { -Maybe<ResourceName> toResourceName( - const android::ResTable::resource_name& nameIn) { - ResourceName nameOut; - if (!nameIn.package) { +Maybe<ResourceName> ToResourceName( + const android::ResTable::resource_name& name_in) { + ResourceName name_out; + if (!name_in.package) { return {}; } - nameOut.package = - util::utf16ToUtf8(StringPiece16(nameIn.package, nameIn.packageLen)); + name_out.package = + util::Utf16ToUtf8(StringPiece16(name_in.package, name_in.packageLen)); const ResourceType* type; - if (nameIn.type) { - type = parseResourceType( - util::utf16ToUtf8(StringPiece16(nameIn.type, nameIn.typeLen))); - } else if (nameIn.type8) { - type = parseResourceType(StringPiece(nameIn.type8, nameIn.typeLen)); + if (name_in.type) { + type = ParseResourceType( + util::Utf16ToUtf8(StringPiece16(name_in.type, name_in.typeLen))); + } else if (name_in.type8) { + type = ParseResourceType(StringPiece(name_in.type8, name_in.typeLen)); } else { return {}; } @@ -51,46 +53,46 @@ Maybe<ResourceName> toResourceName( return {}; } - nameOut.type = *type; + name_out.type = *type; - if (nameIn.name) { - nameOut.entry = - util::utf16ToUtf8(StringPiece16(nameIn.name, nameIn.nameLen)); - } else if (nameIn.name8) { - nameOut.entry = StringPiece(nameIn.name8, nameIn.nameLen).toString(); + if (name_in.name) { + name_out.entry = + util::Utf16ToUtf8(StringPiece16(name_in.name, name_in.nameLen)); + } else if (name_in.name8) { + name_out.entry = StringPiece(name_in.name8, name_in.nameLen).ToString(); } else { return {}; } - return nameOut; + return name_out; } -bool extractResourceName(const StringPiece& str, StringPiece* outPackage, - StringPiece* outType, StringPiece* outEntry) { - bool hasPackageSeparator = false; - bool hasTypeSeparator = false; +bool ExtractResourceName(const StringPiece& str, StringPiece* out_package, + StringPiece* out_type, StringPiece* out_entry) { + bool has_package_separator = false; + bool has_type_separator = false; const char* start = str.data(); const char* end = start + str.size(); const char* current = start; while (current != end) { - if (outType->size() == 0 && *current == '/') { - hasTypeSeparator = true; - outType->assign(start, current - start); + if (out_type->size() == 0 && *current == '/') { + has_type_separator = true; + out_type->assign(start, current - start); start = current + 1; - } else if (outPackage->size() == 0 && *current == ':') { - hasPackageSeparator = true; - outPackage->assign(start, current - start); + } else if (out_package->size() == 0 && *current == ':') { + has_package_separator = true; + out_package->assign(start, current - start); start = current + 1; } current++; } - outEntry->assign(start, end - start); + out_entry->assign(start, end - start); - return !(hasPackageSeparator && outPackage->empty()) && - !(hasTypeSeparator && outType->empty()); + return !(has_package_separator && out_package->empty()) && + !(has_type_separator && out_type->empty()); } -bool parseResourceName(const StringPiece& str, ResourceNameRef* outRef, - bool* outPrivate) { +bool ParseResourceName(const StringPiece& str, ResourceNameRef* out_ref, + bool* out_private) { if (str.empty()) { return false; } @@ -105,13 +107,13 @@ bool parseResourceName(const StringPiece& str, ResourceNameRef* outRef, StringPiece package; StringPiece type; StringPiece entry; - if (!extractResourceName(str.substr(offset, str.size() - offset), &package, + if (!ExtractResourceName(str.substr(offset, str.size() - offset), &package, &type, &entry)) { return false; } - const ResourceType* parsedType = parseResourceType(type); - if (!parsedType) { + const ResourceType* parsed_type = ParseResourceType(type); + if (!parsed_type) { return false; } @@ -119,37 +121,37 @@ bool parseResourceName(const StringPiece& str, ResourceNameRef* outRef, return false; } - if (outRef) { - outRef->package = package; - outRef->type = *parsedType; - outRef->entry = entry; + if (out_ref) { + out_ref->package = package; + out_ref->type = *parsed_type; + out_ref->entry = entry; } - if (outPrivate) { - *outPrivate = priv; + if (out_private) { + *out_private = priv; } return true; } -bool parseReference(const StringPiece& str, ResourceNameRef* outRef, - bool* outCreate, bool* outPrivate) { - StringPiece trimmedStr(util::trimWhitespace(str)); - if (trimmedStr.empty()) { +bool ParseReference(const StringPiece& str, ResourceNameRef* out_ref, + bool* out_create, bool* out_private) { + StringPiece trimmed_str(util::TrimWhitespace(str)); + if (trimmed_str.empty()) { return false; } bool create = false; bool priv = false; - if (trimmedStr.data()[0] == '@') { + if (trimmed_str.data()[0] == '@') { size_t offset = 1; - if (trimmedStr.data()[1] == '+') { + if (trimmed_str.data()[1] == '+') { create = true; offset += 1; } ResourceNameRef name; - if (!parseResourceName( - trimmedStr.substr(offset, trimmedStr.size() - offset), &name, + if (!ParseResourceName( + trimmed_str.substr(offset, trimmed_str.size() - offset), &name, &priv)) { return false; } @@ -162,37 +164,37 @@ bool parseReference(const StringPiece& str, ResourceNameRef* outRef, return false; } - if (outRef) { - *outRef = name; + if (out_ref) { + *out_ref = name; } - if (outCreate) { - *outCreate = create; + if (out_create) { + *out_create = create; } - if (outPrivate) { - *outPrivate = priv; + if (out_private) { + *out_private = priv; } return true; } return false; } -bool isReference(const StringPiece& str) { - return parseReference(str, nullptr, nullptr, nullptr); +bool IsReference(const StringPiece& str) { + return ParseReference(str, nullptr, nullptr, nullptr); } -bool parseAttributeReference(const StringPiece& str, ResourceNameRef* outRef) { - StringPiece trimmedStr(util::trimWhitespace(str)); - if (trimmedStr.empty()) { +bool ParseAttributeReference(const StringPiece& str, ResourceNameRef* out_ref) { + StringPiece trimmed_str(util::TrimWhitespace(str)); + if (trimmed_str.empty()) { return false; } - if (*trimmedStr.data() == '?') { + if (*trimmed_str.data() == '?') { StringPiece package; StringPiece type; StringPiece entry; - if (!extractResourceName(trimmedStr.substr(1, trimmedStr.size() - 1), + if (!ExtractResourceName(trimmed_str.substr(1, trimmed_str.size() - 1), &package, &type, &entry)) { return false; } @@ -205,18 +207,18 @@ bool parseAttributeReference(const StringPiece& str, ResourceNameRef* outRef) { return false; } - if (outRef) { - outRef->package = package; - outRef->type = ResourceType::kAttr; - outRef->entry = entry; + if (out_ref) { + out_ref->package = package; + out_ref->type = ResourceType::kAttr; + out_ref->entry = entry; } return true; } return false; } -bool isAttributeReference(const StringPiece& str) { - return parseAttributeReference(str, nullptr); +bool IsAttributeReference(const StringPiece& str) { + return ParseAttributeReference(str, nullptr); } /* @@ -227,65 +229,65 @@ bool isAttributeReference(const StringPiece& str) { * <[*]package>:[style/]<entry> * [[*]package:style/]<entry> */ -Maybe<Reference> parseStyleParentReference(const StringPiece& str, - std::string* outError) { +Maybe<Reference> ParseStyleParentReference(const StringPiece& str, + std::string* out_error) { if (str.empty()) { return {}; } StringPiece name = str; - bool hasLeadingIdentifiers = false; - bool privateRef = false; + bool has_leading_identifiers = false; + bool private_ref = false; // Skip over these identifiers. A style's parent is a normal reference. if (name.data()[0] == '@' || name.data()[0] == '?') { - hasLeadingIdentifiers = true; + has_leading_identifiers = true; name = name.substr(1, name.size() - 1); } if (name.data()[0] == '*') { - privateRef = true; + private_ref = true; name = name.substr(1, name.size() - 1); } ResourceNameRef ref; ref.type = ResourceType::kStyle; - StringPiece typeStr; - extractResourceName(name, &ref.package, &typeStr, &ref.entry); - if (!typeStr.empty()) { + StringPiece type_str; + ExtractResourceName(name, &ref.package, &type_str, &ref.entry); + if (!type_str.empty()) { // If we have a type, make sure it is a Style. - const ResourceType* parsedType = parseResourceType(typeStr); - if (!parsedType || *parsedType != ResourceType::kStyle) { + const ResourceType* parsed_type = ParseResourceType(type_str); + if (!parsed_type || *parsed_type != ResourceType::kStyle) { std::stringstream err; - err << "invalid resource type '" << typeStr << "' for parent of style"; - *outError = err.str(); + err << "invalid resource type '" << type_str << "' for parent of style"; + *out_error = err.str(); return {}; } } - if (!hasLeadingIdentifiers && ref.package.empty() && !typeStr.empty()) { + if (!has_leading_identifiers && ref.package.empty() && !type_str.empty()) { std::stringstream err; err << "invalid parent reference '" << str << "'"; - *outError = err.str(); + *out_error = err.str(); return {}; } Reference result(ref); - result.privateReference = privateRef; + result.private_reference = private_ref; return result; } -Maybe<Reference> parseXmlAttributeName(const StringPiece& str) { - StringPiece trimmedStr = util::trimWhitespace(str); - const char* start = trimmedStr.data(); - const char* const end = start + trimmedStr.size(); +Maybe<Reference> ParseXmlAttributeName(const StringPiece& str) { + StringPiece trimmed_str = util::TrimWhitespace(str); + const char* start = trimmed_str.data(); + const char* const end = start + trimmed_str.size(); const char* p = start; Reference ref; if (p != end && *p == '*') { - ref.privateReference = true; + ref.private_reference = true; start++; p++; } @@ -302,38 +304,38 @@ Maybe<Reference> parseXmlAttributeName(const StringPiece& str) { } ref.name = - ResourceName(package.toString(), ResourceType::kAttr, - name.empty() ? trimmedStr.toString() : name.toString()); + ResourceName(package.ToString(), ResourceType::kAttr, + name.empty() ? trimmed_str.ToString() : name.ToString()); return Maybe<Reference>(std::move(ref)); } -std::unique_ptr<Reference> tryParseReference(const StringPiece& str, - bool* outCreate) { +std::unique_ptr<Reference> TryParseReference(const StringPiece& str, + bool* out_create) { ResourceNameRef ref; - bool privateRef = false; - if (parseReference(str, &ref, outCreate, &privateRef)) { + bool private_ref = false; + if (ParseReference(str, &ref, out_create, &private_ref)) { std::unique_ptr<Reference> value = util::make_unique<Reference>(ref); - value->privateReference = privateRef; + value->private_reference = private_ref; return value; } - if (parseAttributeReference(str, &ref)) { - if (outCreate) { - *outCreate = false; + if (ParseAttributeReference(str, &ref)) { + if (out_create) { + *out_create = false; } return util::make_unique<Reference>(ref, Reference::Type::kAttribute); } return {}; } -std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece& str) { - StringPiece trimmedStr(util::trimWhitespace(str)); +std::unique_ptr<BinaryPrimitive> TryParseNullOrEmpty(const StringPiece& str) { + StringPiece trimmed_str(util::TrimWhitespace(str)); android::Res_value value = {}; - if (trimmedStr == "@null") { + if (trimmed_str == "@null") { // TYPE_NULL with data set to 0 is interpreted by the runtime as an error. // Instead we set the data type to TYPE_REFERENCE with a value of 0. value.dataType = android::Res_value::TYPE_REFERENCE; - } else if (trimmedStr == "@empty") { + } else if (trimmed_str == "@empty") { // TYPE_NULL with value of DATA_NULL_EMPTY is handled fine by the runtime. value.dataType = android::Res_value::TYPE_NULL; value.data = android::Res_value::DATA_NULL_EMPTY; @@ -343,14 +345,14 @@ std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece& str) { return util::make_unique<BinaryPrimitive>(value); } -std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute* enumAttr, +std::unique_ptr<BinaryPrimitive> TryParseEnumSymbol(const Attribute* enum_attr, const StringPiece& str) { - StringPiece trimmedStr(util::trimWhitespace(str)); - for (const Attribute::Symbol& symbol : enumAttr->symbols) { + StringPiece trimmed_str(util::TrimWhitespace(str)); + for (const Attribute::Symbol& symbol : enum_attr->symbols) { // Enum symbols are stored as @package:id/symbol resources, // so we need to match against the 'entry' part of the identifier. - const ResourceName& enumSymbolResourceName = symbol.symbol.name.value(); - if (trimmedStr == enumSymbolResourceName.entry) { + const ResourceName& enum_symbol_resource_name = symbol.symbol.name.value(); + if (trimmed_str == enum_symbol_resource_name.entry) { android::Res_value value = {}; value.dataType = android::Res_value::TYPE_INT_DEC; value.data = symbol.value; @@ -360,40 +362,41 @@ std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute* enumAttr, return {}; } -std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute* flagAttr, +std::unique_ptr<BinaryPrimitive> TryParseFlagSymbol(const Attribute* flag_attr, const StringPiece& str) { android::Res_value flags = {}; flags.dataType = android::Res_value::TYPE_INT_HEX; flags.data = 0u; - if (util::trimWhitespace(str).empty()) { + if (util::TrimWhitespace(str).empty()) { // Empty string is a valid flag (0). return util::make_unique<BinaryPrimitive>(flags); } - for (StringPiece part : util::tokenize(str, '|')) { - StringPiece trimmedPart = util::trimWhitespace(part); + for (StringPiece part : util::Tokenize(str, '|')) { + StringPiece trimmed_part = util::TrimWhitespace(part); - bool flagSet = false; - for (const Attribute::Symbol& symbol : flagAttr->symbols) { + bool flag_set = false; + for (const Attribute::Symbol& symbol : flag_attr->symbols) { // Flag symbols are stored as @package:id/symbol resources, // so we need to match against the 'entry' part of the identifier. - const ResourceName& flagSymbolResourceName = symbol.symbol.name.value(); - if (trimmedPart == flagSymbolResourceName.entry) { + const ResourceName& flag_symbol_resource_name = + symbol.symbol.name.value(); + if (trimmed_part == flag_symbol_resource_name.entry) { flags.data |= symbol.value; - flagSet = true; + flag_set = true; break; } } - if (!flagSet) { + if (!flag_set) { return {}; } } return util::make_unique<BinaryPrimitive>(flags); } -static uint32_t parseHex(char c, bool* outError) { +static uint32_t ParseHex(char c, bool* out_error) { if (c >= '0' && c <= '9') { return c - '0'; } else if (c >= 'a' && c <= 'f') { @@ -401,15 +404,15 @@ static uint32_t parseHex(char c, bool* outError) { } else if (c >= 'A' && c <= 'F') { return c - 'A' + 0xa; } else { - *outError = true; + *out_error = true; return 0xffffffffu; } } -std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece& str) { - StringPiece colorStr(util::trimWhitespace(str)); - const char* start = colorStr.data(); - const size_t len = colorStr.size(); +std::unique_ptr<BinaryPrimitive> TryParseColor(const StringPiece& str) { + StringPiece color_str(util::TrimWhitespace(str)); + const char* start = color_str.data(); + const size_t len = color_str.size(); if (len == 0 || start[0] != '#') { return {}; } @@ -419,41 +422,41 @@ std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece& str) { if (len == 4) { value.dataType = android::Res_value::TYPE_INT_COLOR_RGB4; value.data = 0xff000000u; - value.data |= parseHex(start[1], &error) << 20; - value.data |= parseHex(start[1], &error) << 16; - value.data |= parseHex(start[2], &error) << 12; - value.data |= parseHex(start[2], &error) << 8; - value.data |= parseHex(start[3], &error) << 4; - value.data |= parseHex(start[3], &error); + value.data |= ParseHex(start[1], &error) << 20; + value.data |= ParseHex(start[1], &error) << 16; + value.data |= ParseHex(start[2], &error) << 12; + value.data |= ParseHex(start[2], &error) << 8; + value.data |= ParseHex(start[3], &error) << 4; + value.data |= ParseHex(start[3], &error); } else if (len == 5) { value.dataType = android::Res_value::TYPE_INT_COLOR_ARGB4; - value.data |= parseHex(start[1], &error) << 28; - value.data |= parseHex(start[1], &error) << 24; - value.data |= parseHex(start[2], &error) << 20; - value.data |= parseHex(start[2], &error) << 16; - value.data |= parseHex(start[3], &error) << 12; - value.data |= parseHex(start[3], &error) << 8; - value.data |= parseHex(start[4], &error) << 4; - value.data |= parseHex(start[4], &error); + value.data |= ParseHex(start[1], &error) << 28; + value.data |= ParseHex(start[1], &error) << 24; + value.data |= ParseHex(start[2], &error) << 20; + value.data |= ParseHex(start[2], &error) << 16; + value.data |= ParseHex(start[3], &error) << 12; + value.data |= ParseHex(start[3], &error) << 8; + value.data |= ParseHex(start[4], &error) << 4; + value.data |= ParseHex(start[4], &error); } else if (len == 7) { value.dataType = android::Res_value::TYPE_INT_COLOR_RGB8; value.data = 0xff000000u; - value.data |= parseHex(start[1], &error) << 20; - value.data |= parseHex(start[2], &error) << 16; - value.data |= parseHex(start[3], &error) << 12; - value.data |= parseHex(start[4], &error) << 8; - value.data |= parseHex(start[5], &error) << 4; - value.data |= parseHex(start[6], &error); + value.data |= ParseHex(start[1], &error) << 20; + value.data |= ParseHex(start[2], &error) << 16; + value.data |= ParseHex(start[3], &error) << 12; + value.data |= ParseHex(start[4], &error) << 8; + value.data |= ParseHex(start[5], &error) << 4; + value.data |= ParseHex(start[6], &error); } else if (len == 9) { value.dataType = android::Res_value::TYPE_INT_COLOR_ARGB8; - value.data |= parseHex(start[1], &error) << 28; - value.data |= parseHex(start[2], &error) << 24; - value.data |= parseHex(start[3], &error) << 20; - value.data |= parseHex(start[4], &error) << 16; - value.data |= parseHex(start[5], &error) << 12; - value.data |= parseHex(start[6], &error) << 8; - value.data |= parseHex(start[7], &error) << 4; - value.data |= parseHex(start[8], &error); + value.data |= ParseHex(start[1], &error) << 28; + value.data |= ParseHex(start[2], &error) << 24; + value.data |= ParseHex(start[3], &error) << 20; + value.data |= ParseHex(start[4], &error) << 16; + value.data |= ParseHex(start[5], &error) << 12; + value.data |= ParseHex(start[6], &error) << 8; + value.data |= ParseHex(start[7], &error) << 4; + value.data |= ParseHex(start[8], &error); } else { return {}; } @@ -461,19 +464,19 @@ std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece& str) { : util::make_unique<BinaryPrimitive>(value); } -Maybe<bool> parseBool(const StringPiece& str) { - StringPiece trimmedStr(util::trimWhitespace(str)); - if (trimmedStr == "true" || trimmedStr == "TRUE" || trimmedStr == "True") { +Maybe<bool> ParseBool(const StringPiece& str) { + StringPiece trimmed_str(util::TrimWhitespace(str)); + if (trimmed_str == "true" || trimmed_str == "TRUE" || trimmed_str == "True") { return Maybe<bool>(true); - } else if (trimmedStr == "false" || trimmedStr == "FALSE" || - trimmedStr == "False") { + } else if (trimmed_str == "false" || trimmed_str == "FALSE" || + trimmed_str == "False") { return Maybe<bool>(false); } return {}; } -Maybe<uint32_t> parseInt(const StringPiece& str) { - std::u16string str16 = util::utf8ToUtf16(str); +Maybe<uint32_t> ParseInt(const StringPiece& str) { + std::u16string str16 = util::Utf8ToUtf16(str); android::Res_value value; if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) { return value.data; @@ -481,15 +484,15 @@ Maybe<uint32_t> parseInt(const StringPiece& str) { return {}; } -Maybe<ResourceId> parseResourceId(const StringPiece& str) { - StringPiece trimmedStr(util::trimWhitespace(str)); +Maybe<ResourceId> ParseResourceId(const StringPiece& str) { + StringPiece trimmed_str(util::TrimWhitespace(str)); - std::u16string str16 = util::utf8ToUtf16(trimmedStr); + std::u16string str16 = util::Utf8ToUtf16(trimmed_str); android::Res_value value; if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) { if (value.dataType == android::Res_value::TYPE_INT_HEX) { ResourceId id(value.data); - if (id.isValid()) { + if (id.is_valid()) { return id; } } @@ -497,29 +500,29 @@ Maybe<ResourceId> parseResourceId(const StringPiece& str) { return {}; } -Maybe<int> parseSdkVersion(const StringPiece& str) { - StringPiece trimmedStr(util::trimWhitespace(str)); +Maybe<int> ParseSdkVersion(const StringPiece& str) { + StringPiece trimmed_str(util::TrimWhitespace(str)); - std::u16string str16 = util::utf8ToUtf16(trimmedStr); + std::u16string str16 = util::Utf8ToUtf16(trimmed_str); android::Res_value value; if (android::ResTable::stringToInt(str16.data(), str16.size(), &value)) { return static_cast<int>(value.data); } // Try parsing the code name. - std::pair<StringPiece, int> entry = getDevelopmentSdkCodeNameAndVersion(); - if (entry.first == trimmedStr) { + std::pair<StringPiece, int> entry = GetDevelopmentSdkCodeNameAndVersion(); + if (entry.first == trimmed_str) { return entry.second; } return {}; } -std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece& str) { - if (Maybe<bool> maybeResult = parseBool(str)) { +std::unique_ptr<BinaryPrimitive> TryParseBool(const StringPiece& str) { + if (Maybe<bool> maybe_result = ParseBool(str)) { android::Res_value value = {}; value.dataType = android::Res_value::TYPE_INT_BOOLEAN; - if (maybeResult.value()) { + if (maybe_result.value()) { value.data = 0xffffffffu; } else { value.data = 0; @@ -529,8 +532,8 @@ std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece& str) { return {}; } -std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece& str) { - std::u16string str16 = util::utf8ToUtf16(str); +std::unique_ptr<BinaryPrimitive> TryParseInt(const StringPiece& str) { + std::u16string str16 = util::Utf8ToUtf16(str); android::Res_value value; if (!android::ResTable::stringToInt(str16.data(), str16.size(), &value)) { return {}; @@ -538,8 +541,8 @@ std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece& str) { return util::make_unique<BinaryPrimitive>(value); } -std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece& str) { - std::u16string str16 = util::utf8ToUtf16(str); +std::unique_ptr<BinaryPrimitive> TryParseFloat(const StringPiece& str) { + std::u16string str16 = util::Utf8ToUtf16(str); android::Res_value value; if (!android::ResTable::stringToFloat(str16.data(), str16.size(), &value)) { return {}; @@ -547,7 +550,7 @@ std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece& str) { return util::make_unique<BinaryPrimitive>(value); } -uint32_t androidTypeToAttributeTypeMask(uint16_t type) { +uint32_t AndroidTypeToAttributeTypeMask(uint16_t type) { switch (type) { case android::Res_value::TYPE_NULL: case android::Res_value::TYPE_REFERENCE: @@ -587,57 +590,57 @@ uint32_t androidTypeToAttributeTypeMask(uint16_t type) { }; } -std::unique_ptr<Item> tryParseItemForAttribute( - const StringPiece& value, uint32_t typeMask, - const std::function<void(const ResourceName&)>& onCreateReference) { - std::unique_ptr<BinaryPrimitive> nullOrEmpty = tryParseNullOrEmpty(value); - if (nullOrEmpty) { - return std::move(nullOrEmpty); +std::unique_ptr<Item> TryParseItemForAttribute( + const StringPiece& value, uint32_t type_mask, + const std::function<void(const ResourceName&)>& on_create_reference) { + std::unique_ptr<BinaryPrimitive> null_or_empty = TryParseNullOrEmpty(value); + if (null_or_empty) { + return std::move(null_or_empty); } bool create = false; - std::unique_ptr<Reference> reference = tryParseReference(value, &create); + std::unique_ptr<Reference> reference = TryParseReference(value, &create); if (reference) { - if (create && onCreateReference) { - onCreateReference(reference->name.value()); + if (create && on_create_reference) { + on_create_reference(reference->name.value()); } return std::move(reference); } - if (typeMask & android::ResTable_map::TYPE_COLOR) { + if (type_mask & android::ResTable_map::TYPE_COLOR) { // Try parsing this as a color. - std::unique_ptr<BinaryPrimitive> color = tryParseColor(value); + std::unique_ptr<BinaryPrimitive> color = TryParseColor(value); if (color) { return std::move(color); } } - if (typeMask & android::ResTable_map::TYPE_BOOLEAN) { + if (type_mask & android::ResTable_map::TYPE_BOOLEAN) { // Try parsing this as a boolean. - std::unique_ptr<BinaryPrimitive> boolean = tryParseBool(value); + std::unique_ptr<BinaryPrimitive> boolean = TryParseBool(value); if (boolean) { return std::move(boolean); } } - if (typeMask & android::ResTable_map::TYPE_INTEGER) { + if (type_mask & android::ResTable_map::TYPE_INTEGER) { // Try parsing this as an integer. - std::unique_ptr<BinaryPrimitive> integer = tryParseInt(value); + std::unique_ptr<BinaryPrimitive> integer = TryParseInt(value); if (integer) { return std::move(integer); } } - const uint32_t floatMask = android::ResTable_map::TYPE_FLOAT | - android::ResTable_map::TYPE_DIMENSION | - android::ResTable_map::TYPE_FRACTION; - if (typeMask & floatMask) { + const uint32_t float_mask = android::ResTable_map::TYPE_FLOAT | + android::ResTable_map::TYPE_DIMENSION | + android::ResTable_map::TYPE_FRACTION; + if (type_mask & float_mask) { // Try parsing this as a float. - std::unique_ptr<BinaryPrimitive> floatingPoint = tryParseFloat(value); - if (floatingPoint) { - if (typeMask & - androidTypeToAttributeTypeMask(floatingPoint->value.dataType)) { - return std::move(floatingPoint); + std::unique_ptr<BinaryPrimitive> floating_point = TryParseFloat(value); + if (floating_point) { + if (type_mask & + AndroidTypeToAttributeTypeMask(floating_point->value.dataType)) { + return std::move(floating_point); } } } @@ -648,49 +651,49 @@ std::unique_ptr<Item> tryParseItemForAttribute( * We successively try to parse the string as a resource type that the Attribute * allows. */ -std::unique_ptr<Item> tryParseItemForAttribute( +std::unique_ptr<Item> TryParseItemForAttribute( const StringPiece& str, const Attribute* attr, - const std::function<void(const ResourceName&)>& onCreateReference) { - const uint32_t typeMask = attr->typeMask; + const std::function<void(const ResourceName&)>& on_create_reference) { + const uint32_t type_mask = attr->type_mask; std::unique_ptr<Item> value = - tryParseItemForAttribute(str, typeMask, onCreateReference); + TryParseItemForAttribute(str, type_mask, on_create_reference); if (value) { return value; } - if (typeMask & android::ResTable_map::TYPE_ENUM) { + if (type_mask & android::ResTable_map::TYPE_ENUM) { // Try parsing this as an enum. - std::unique_ptr<BinaryPrimitive> enumValue = tryParseEnumSymbol(attr, str); - if (enumValue) { - return std::move(enumValue); + std::unique_ptr<BinaryPrimitive> enum_value = TryParseEnumSymbol(attr, str); + if (enum_value) { + return std::move(enum_value); } } - if (typeMask & android::ResTable_map::TYPE_FLAGS) { + if (type_mask & android::ResTable_map::TYPE_FLAGS) { // Try parsing this as a flag. - std::unique_ptr<BinaryPrimitive> flagValue = tryParseFlagSymbol(attr, str); - if (flagValue) { - return std::move(flagValue); + std::unique_ptr<BinaryPrimitive> flag_value = TryParseFlagSymbol(attr, str); + if (flag_value) { + return std::move(flag_value); } } return {}; } -std::string buildResourceFileName(const ResourceFile& resFile, +std::string BuildResourceFileName(const ResourceFile& res_file, const NameMangler* mangler) { std::stringstream out; - out << "res/" << resFile.name.type; - if (resFile.config != ConfigDescription{}) { - out << "-" << resFile.config; + out << "res/" << res_file.name.type; + if (res_file.config != ConfigDescription{}) { + out << "-" << res_file.config; } out << "/"; - if (mangler && mangler->shouldMangle(resFile.name.package)) { - out << NameMangler::mangleEntry(resFile.name.package, resFile.name.entry); + if (mangler && mangler->ShouldMangle(res_file.name.package)) { + out << NameMangler::MangleEntry(res_file.name.package, res_file.name.entry); } else { - out << resFile.name.entry; + out << res_file.name.entry; } - out << file::getExtension(resFile.source.path); + out << file::GetExtension(res_file.source.path); return out.str(); } diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h index cebe47cee3a7..9766f6a7b2fa 100644 --- a/tools/aapt2/ResourceUtils.h +++ b/tools/aapt2/ResourceUtils.h @@ -17,14 +17,14 @@ #ifndef AAPT_RESOURCEUTILS_H #define AAPT_RESOURCEUTILS_H +#include <functional> +#include <memory> + #include "NameMangler.h" #include "Resource.h" #include "ResourceValues.h" #include "util/StringPiece.h" -#include <functional> -#include <memory> - namespace aapt { namespace ResourceUtils { @@ -37,76 +37,75 @@ namespace ResourceUtils { * individual extracted piece to verify that the pieces are valid. * Returns false if there was no package but a ':' was present. */ -bool extractResourceName(const StringPiece& str, StringPiece* outPackage, - StringPiece* outType, StringPiece* outEntry); +bool ExtractResourceName(const StringPiece& str, StringPiece* out_package, + StringPiece* out_type, StringPiece* out_entry); /** * Returns true if the string was parsed as a resource name * ([*][package:]type/name), with - * `outResource` set to the parsed resource name and `outPrivate` set to true if - * a '*' prefix - * was present. + * `out_resource` set to the parsed resource name and `out_private` set to true + * if a '*' prefix was present. */ -bool parseResourceName(const StringPiece& str, ResourceNameRef* outResource, - bool* outPrivate = nullptr); +bool ParseResourceName(const StringPiece& str, ResourceNameRef* out_resource, + bool* out_private = nullptr); /* * Returns true if the string was parsed as a reference * (@[+][package:]type/name), with - * `outReference` set to the parsed reference. + * `out_reference` set to the parsed reference. * - * If '+' was present in the reference, `outCreate` is set to true. - * If '*' was present in the reference, `outPrivate` is set to true. + * If '+' was present in the reference, `out_create` is set to true. + * If '*' was present in the reference, `out_private` is set to true. */ -bool parseReference(const StringPiece& str, ResourceNameRef* outReference, - bool* outCreate = nullptr, bool* outPrivate = nullptr); +bool ParseReference(const StringPiece& str, ResourceNameRef* out_reference, + bool* out_create = nullptr, bool* out_private = nullptr); /* * Returns true if the string is in the form of a resource reference * (@[+][package:]type/name). */ -bool isReference(const StringPiece& str); +bool IsReference(const StringPiece& str); /* * Returns true if the string was parsed as an attribute reference * (?[package:][type/]name), - * with `outReference` set to the parsed reference. + * with `out_reference` set to the parsed reference. */ -bool parseAttributeReference(const StringPiece& str, - ResourceNameRef* outReference); +bool ParseAttributeReference(const StringPiece& str, + ResourceNameRef* out_reference); /** * Returns true if the string is in the form of an attribute * reference(?[package:][type/]name). */ -bool isAttributeReference(const StringPiece& str); +bool IsAttributeReference(const StringPiece& str); /** * Convert an android::ResTable::resource_name to an aapt::ResourceName struct. */ -Maybe<ResourceName> toResourceName( +Maybe<ResourceName> ToResourceName( const android::ResTable::resource_name& name); /** * Returns a boolean value if the string is equal to TRUE, true, True, FALSE, * false, or False. */ -Maybe<bool> parseBool(const StringPiece& str); +Maybe<bool> ParseBool(const StringPiece& str); /** * Returns a uint32_t if the string is an integer. */ -Maybe<uint32_t> parseInt(const StringPiece& str); +Maybe<uint32_t> ParseInt(const StringPiece& str); /** * Returns an ID if it the string represented a valid ID. */ -Maybe<ResourceId> parseResourceId(const StringPiece& str); +Maybe<ResourceId> ParseResourceId(const StringPiece& str); /** * Parses an SDK version, which can be an integer, or a letter from A-Z. */ -Maybe<int> parseSdkVersion(const StringPiece& str); +Maybe<int> ParseSdkVersion(const StringPiece& str); /* * Returns a Reference, or None Maybe instance if the string `str` was parsed as @@ -119,8 +118,8 @@ Maybe<int> parseSdkVersion(const StringPiece& str); * ?[package:]style/<entry> or * <package>:[style/]<entry> */ -Maybe<Reference> parseStyleParentReference(const StringPiece& str, - std::string* outError); +Maybe<Reference> ParseStyleParentReference(const StringPiece& str, + std::string* out_error); /* * Returns a Reference if the string `str` was parsed as a valid XML attribute @@ -129,7 +128,7 @@ Maybe<Reference> parseStyleParentReference(const StringPiece& str, * * package:entry */ -Maybe<Reference> parseXmlAttributeName(const StringPiece& str); +Maybe<Reference> ParseXmlAttributeName(const StringPiece& str); /* * Returns a Reference object if the string was parsed as a resource or @@ -138,73 +137,68 @@ Maybe<Reference> parseXmlAttributeName(const StringPiece& str); * if * the '+' was present in the string. */ -std::unique_ptr<Reference> tryParseReference(const StringPiece& str, - bool* outCreate = nullptr); +std::unique_ptr<Reference> TryParseReference(const StringPiece& str, + bool* out_create = nullptr); /* * Returns a BinaryPrimitve object representing @null or @empty if the string - * was parsed - * as one. + * was parsed as one. */ -std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece& str); +std::unique_ptr<BinaryPrimitive> TryParseNullOrEmpty(const StringPiece& str); /* * Returns a BinaryPrimitve object representing a color if the string was parsed * as one. */ -std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece& str); +std::unique_ptr<BinaryPrimitive> TryParseColor(const StringPiece& str); /* * Returns a BinaryPrimitve object representing a boolean if the string was - * parsed - * as one. + * parsed as one. */ -std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece& str); +std::unique_ptr<BinaryPrimitive> TryParseBool(const StringPiece& str); /* * Returns a BinaryPrimitve object representing an integer if the string was - * parsed - * as one. + * parsed as one. */ -std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece& str); +std::unique_ptr<BinaryPrimitive> TryParseInt(const StringPiece& str); /* * Returns a BinaryPrimitve object representing a floating point number * (float, dimension, etc) if the string was parsed as one. */ -std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece& str); +std::unique_ptr<BinaryPrimitive> TryParseFloat(const StringPiece& str); /* * Returns a BinaryPrimitve object representing an enum symbol if the string was - * parsed - * as one. + * parsed as one. */ -std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute* enumAttr, +std::unique_ptr<BinaryPrimitive> TryParseEnumSymbol(const Attribute* enum_attr, const StringPiece& str); /* * Returns a BinaryPrimitve object representing a flag symbol if the string was - * parsed - * as one. + * parsed as one. */ -std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute* enumAttr, +std::unique_ptr<BinaryPrimitive> TryParseFlagSymbol(const Attribute* enum_attr, const StringPiece& str); /* * Try to convert a string to an Item for the given attribute. The attribute * will * restrict what values the string can be converted to. - * The callback function onCreateReference is called when the parsed item is a + * The callback function on_create_reference is called when the parsed item is a * reference to an ID that must be created (@+id/foo). */ -std::unique_ptr<Item> tryParseItemForAttribute( +std::unique_ptr<Item> TryParseItemForAttribute( const StringPiece& value, const Attribute* attr, - const std::function<void(const ResourceName&)>& onCreateReference = {}); + const std::function<void(const ResourceName&)>& on_create_reference = {}); -std::unique_ptr<Item> tryParseItemForAttribute( - const StringPiece& value, uint32_t typeMask, - const std::function<void(const ResourceName&)>& onCreateReference = {}); +std::unique_ptr<Item> TryParseItemForAttribute( + const StringPiece& value, uint32_t type_mask, + const std::function<void(const ResourceName&)>& on_create_reference = {}); -uint32_t androidTypeToAttributeTypeMask(uint16_t type); +uint32_t AndroidTypeToAttributeTypeMask(uint16_t type); /** * Returns a string path suitable for use within an APK. The path will look @@ -216,8 +210,8 @@ uint32_t androidTypeToAttributeTypeMask(uint16_t type); * the package * requires mangling. */ -std::string buildResourceFileName(const ResourceFile& resFile, - const NameMangler* mangler); +std::string BuildResourceFileName(const ResourceFile& res_file, + const NameMangler* mangler = nullptr); } // namespace ResourceUtils } // namespace aapt diff --git a/tools/aapt2/ResourceUtils_test.cpp b/tools/aapt2/ResourceUtils_test.cpp index eb62b1b0f4fa..f9c500b42c13 100644 --- a/tools/aapt2/ResourceUtils_test.cpp +++ b/tools/aapt2/ResourceUtils_test.cpp @@ -15,128 +15,129 @@ */ #include "ResourceUtils.h" + #include "Resource.h" #include "test/Test.h" namespace aapt { TEST(ResourceUtilsTest, ParseBool) { - EXPECT_EQ(Maybe<bool>(true), ResourceUtils::parseBool("true")); - EXPECT_EQ(Maybe<bool>(true), ResourceUtils::parseBool("TRUE")); - EXPECT_EQ(Maybe<bool>(true), ResourceUtils::parseBool("True")); - EXPECT_EQ(Maybe<bool>(false), ResourceUtils::parseBool("false")); - EXPECT_EQ(Maybe<bool>(false), ResourceUtils::parseBool("FALSE")); - EXPECT_EQ(Maybe<bool>(false), ResourceUtils::parseBool("False")); + EXPECT_EQ(Maybe<bool>(true), ResourceUtils::ParseBool("true")); + EXPECT_EQ(Maybe<bool>(true), ResourceUtils::ParseBool("TRUE")); + EXPECT_EQ(Maybe<bool>(true), ResourceUtils::ParseBool("True")); + EXPECT_EQ(Maybe<bool>(false), ResourceUtils::ParseBool("false")); + EXPECT_EQ(Maybe<bool>(false), ResourceUtils::ParseBool("FALSE")); + EXPECT_EQ(Maybe<bool>(false), ResourceUtils::ParseBool("False")); } TEST(ResourceUtilsTest, ParseResourceName) { ResourceNameRef actual; - bool actualPriv = false; - EXPECT_TRUE(ResourceUtils::parseResourceName("android:color/foo", &actual, - &actualPriv)); + bool actual_priv = false; + EXPECT_TRUE(ResourceUtils::ParseResourceName("android:color/foo", &actual, + &actual_priv)); EXPECT_EQ(ResourceNameRef("android", ResourceType::kColor, "foo"), actual); - EXPECT_FALSE(actualPriv); + EXPECT_FALSE(actual_priv); EXPECT_TRUE( - ResourceUtils::parseResourceName("color/foo", &actual, &actualPriv)); + ResourceUtils::ParseResourceName("color/foo", &actual, &actual_priv)); EXPECT_EQ(ResourceNameRef({}, ResourceType::kColor, "foo"), actual); - EXPECT_FALSE(actualPriv); + EXPECT_FALSE(actual_priv); - EXPECT_TRUE(ResourceUtils::parseResourceName("*android:color/foo", &actual, - &actualPriv)); + EXPECT_TRUE(ResourceUtils::ParseResourceName("*android:color/foo", &actual, + &actual_priv)); EXPECT_EQ(ResourceNameRef("android", ResourceType::kColor, "foo"), actual); - EXPECT_TRUE(actualPriv); + EXPECT_TRUE(actual_priv); EXPECT_FALSE( - ResourceUtils::parseResourceName(StringPiece(), &actual, &actualPriv)); + ResourceUtils::ParseResourceName(StringPiece(), &actual, &actual_priv)); } TEST(ResourceUtilsTest, ParseReferenceWithNoPackage) { ResourceNameRef expected({}, ResourceType::kColor, "foo"); ResourceNameRef actual; bool create = false; - bool privateRef = false; - EXPECT_TRUE(ResourceUtils::parseReference("@color/foo", &actual, &create, - &privateRef)); + bool private_ref = false; + EXPECT_TRUE(ResourceUtils::ParseReference("@color/foo", &actual, &create, + &private_ref)); EXPECT_EQ(expected, actual); EXPECT_FALSE(create); - EXPECT_FALSE(privateRef); + EXPECT_FALSE(private_ref); } TEST(ResourceUtilsTest, ParseReferenceWithPackage) { ResourceNameRef expected("android", ResourceType::kColor, "foo"); ResourceNameRef actual; bool create = false; - bool privateRef = false; - EXPECT_TRUE(ResourceUtils::parseReference("@android:color/foo", &actual, - &create, &privateRef)); + bool private_ref = false; + EXPECT_TRUE(ResourceUtils::ParseReference("@android:color/foo", &actual, + &create, &private_ref)); EXPECT_EQ(expected, actual); EXPECT_FALSE(create); - EXPECT_FALSE(privateRef); + EXPECT_FALSE(private_ref); } TEST(ResourceUtilsTest, ParseReferenceWithSurroundingWhitespace) { ResourceNameRef expected("android", ResourceType::kColor, "foo"); ResourceNameRef actual; bool create = false; - bool privateRef = false; - EXPECT_TRUE(ResourceUtils::parseReference("\t @android:color/foo\n \n\t", - &actual, &create, &privateRef)); + bool private_ref = false; + EXPECT_TRUE(ResourceUtils::ParseReference("\t @android:color/foo\n \n\t", + &actual, &create, &private_ref)); EXPECT_EQ(expected, actual); EXPECT_FALSE(create); - EXPECT_FALSE(privateRef); + EXPECT_FALSE(private_ref); } TEST(ResourceUtilsTest, ParseAutoCreateIdReference) { ResourceNameRef expected("android", ResourceType::kId, "foo"); ResourceNameRef actual; bool create = false; - bool privateRef = false; - EXPECT_TRUE(ResourceUtils::parseReference("@+android:id/foo", &actual, - &create, &privateRef)); + bool private_ref = false; + EXPECT_TRUE(ResourceUtils::ParseReference("@+android:id/foo", &actual, + &create, &private_ref)); EXPECT_EQ(expected, actual); EXPECT_TRUE(create); - EXPECT_FALSE(privateRef); + EXPECT_FALSE(private_ref); } TEST(ResourceUtilsTest, ParsePrivateReference) { ResourceNameRef expected("android", ResourceType::kId, "foo"); ResourceNameRef actual; bool create = false; - bool privateRef = false; - EXPECT_TRUE(ResourceUtils::parseReference("@*android:id/foo", &actual, - &create, &privateRef)); + bool private_ref = false; + EXPECT_TRUE(ResourceUtils::ParseReference("@*android:id/foo", &actual, + &create, &private_ref)); EXPECT_EQ(expected, actual); EXPECT_FALSE(create); - EXPECT_TRUE(privateRef); + EXPECT_TRUE(private_ref); } TEST(ResourceUtilsTest, FailToParseAutoCreateNonIdReference) { bool create = false; - bool privateRef = false; + bool private_ref = false; ResourceNameRef actual; - EXPECT_FALSE(ResourceUtils::parseReference("@+android:color/foo", &actual, - &create, &privateRef)); + EXPECT_FALSE(ResourceUtils::ParseReference("@+android:color/foo", &actual, + &create, &private_ref)); } TEST(ResourceUtilsTest, ParseAttributeReferences) { - EXPECT_TRUE(ResourceUtils::isAttributeReference("?android")); - EXPECT_TRUE(ResourceUtils::isAttributeReference("?android:foo")); - EXPECT_TRUE(ResourceUtils::isAttributeReference("?attr/foo")); - EXPECT_TRUE(ResourceUtils::isAttributeReference("?android:attr/foo")); + EXPECT_TRUE(ResourceUtils::IsAttributeReference("?android")); + EXPECT_TRUE(ResourceUtils::IsAttributeReference("?android:foo")); + EXPECT_TRUE(ResourceUtils::IsAttributeReference("?attr/foo")); + EXPECT_TRUE(ResourceUtils::IsAttributeReference("?android:attr/foo")); } TEST(ResourceUtilsTest, FailParseIncompleteReference) { - EXPECT_FALSE(ResourceUtils::isAttributeReference("?style/foo")); - EXPECT_FALSE(ResourceUtils::isAttributeReference("?android:style/foo")); - EXPECT_FALSE(ResourceUtils::isAttributeReference("?android:")); - EXPECT_FALSE(ResourceUtils::isAttributeReference("?android:attr/")); - EXPECT_FALSE(ResourceUtils::isAttributeReference("?:attr/")); - EXPECT_FALSE(ResourceUtils::isAttributeReference("?:attr/foo")); - EXPECT_FALSE(ResourceUtils::isAttributeReference("?:/")); - EXPECT_FALSE(ResourceUtils::isAttributeReference("?:/foo")); - EXPECT_FALSE(ResourceUtils::isAttributeReference("?attr/")); - EXPECT_FALSE(ResourceUtils::isAttributeReference("?/foo")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?style/foo")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?android:style/foo")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?android:")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?android:attr/")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:attr/")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:attr/foo")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:/")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?:/foo")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?attr/")); + EXPECT_FALSE(ResourceUtils::IsAttributeReference("?/foo")); } TEST(ResourceUtilsTest, ParseStyleParentReference) { @@ -144,56 +145,58 @@ TEST(ResourceUtilsTest, ParseStyleParentReference) { "foo"); const ResourceName kStyleFooName({}, ResourceType::kStyle, "foo"); - std::string errStr; + std::string err_str; Maybe<Reference> ref = - ResourceUtils::parseStyleParentReference("@android:style/foo", &errStr); + ResourceUtils::ParseStyleParentReference("@android:style/foo", &err_str); AAPT_ASSERT_TRUE(ref); EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); - ref = ResourceUtils::parseStyleParentReference("@style/foo", &errStr); + ref = ResourceUtils::ParseStyleParentReference("@style/foo", &err_str); AAPT_ASSERT_TRUE(ref); EXPECT_EQ(ref.value().name.value(), kStyleFooName); - ref = ResourceUtils::parseStyleParentReference("?android:style/foo", &errStr); + ref = + ResourceUtils::ParseStyleParentReference("?android:style/foo", &err_str); AAPT_ASSERT_TRUE(ref); EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); - ref = ResourceUtils::parseStyleParentReference("?style/foo", &errStr); + ref = ResourceUtils::ParseStyleParentReference("?style/foo", &err_str); AAPT_ASSERT_TRUE(ref); EXPECT_EQ(ref.value().name.value(), kStyleFooName); - ref = ResourceUtils::parseStyleParentReference("android:style/foo", &errStr); + ref = ResourceUtils::ParseStyleParentReference("android:style/foo", &err_str); AAPT_ASSERT_TRUE(ref); EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); - ref = ResourceUtils::parseStyleParentReference("android:foo", &errStr); + ref = ResourceUtils::ParseStyleParentReference("android:foo", &err_str); AAPT_ASSERT_TRUE(ref); EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); - ref = ResourceUtils::parseStyleParentReference("@android:foo", &errStr); + ref = ResourceUtils::ParseStyleParentReference("@android:foo", &err_str); AAPT_ASSERT_TRUE(ref); EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); - ref = ResourceUtils::parseStyleParentReference("foo", &errStr); + ref = ResourceUtils::ParseStyleParentReference("foo", &err_str); AAPT_ASSERT_TRUE(ref); EXPECT_EQ(ref.value().name.value(), kStyleFooName); - ref = ResourceUtils::parseStyleParentReference("*android:style/foo", &errStr); + ref = + ResourceUtils::ParseStyleParentReference("*android:style/foo", &err_str); AAPT_ASSERT_TRUE(ref); EXPECT_EQ(ref.value().name.value(), kAndroidStyleFooName); - EXPECT_TRUE(ref.value().privateReference); + EXPECT_TRUE(ref.value().private_reference); } TEST(ResourceUtilsTest, ParseEmptyFlag) { std::unique_ptr<Attribute> attr = test::AttributeBuilder(false) - .setTypeMask(android::ResTable_map::TYPE_FLAGS) - .addItem("one", 0x01) - .addItem("two", 0x02) - .build(); + .SetTypeMask(android::ResTable_map::TYPE_FLAGS) + .AddItem("one", 0x01) + .AddItem("two", 0x02) + .Build(); std::unique_ptr<BinaryPrimitive> result = - ResourceUtils::tryParseFlagSymbol(attr.get(), ""); + ResourceUtils::TryParseFlagSymbol(attr.get(), ""); ASSERT_NE(nullptr, result); EXPECT_EQ(0u, result->value.data); } diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp index 60590b6026b5..7956ad826acd 100644 --- a/tools/aapt2/ResourceValues.cpp +++ b/tools/aapt2/ResourceValues.cpp @@ -15,94 +15,95 @@ */ #include "ResourceValues.h" -#include "Resource.h" -#include "ResourceUtils.h" -#include "ValueVisitor.h" -#include "util/Util.h" -#include <androidfw/ResourceTypes.h> #include <algorithm> #include <limits> #include <set> +#include "androidfw/ResourceTypes.h" + +#include "Resource.h" +#include "ResourceUtils.h" +#include "ValueVisitor.h" +#include "util/Util.h" + namespace aapt { template <typename Derived> -void BaseValue<Derived>::accept(RawValueVisitor* visitor) { - visitor->visit(static_cast<Derived*>(this)); +void BaseValue<Derived>::Accept(RawValueVisitor* visitor) { + visitor->Visit(static_cast<Derived*>(this)); } template <typename Derived> -void BaseItem<Derived>::accept(RawValueVisitor* visitor) { - visitor->visit(static_cast<Derived*>(this)); +void BaseItem<Derived>::Accept(RawValueVisitor* visitor) { + visitor->Visit(static_cast<Derived*>(this)); } RawString::RawString(const StringPool::Ref& ref) : value(ref) {} -bool RawString::equals(const Value* value) const { - const RawString* other = valueCast<RawString>(value); +bool RawString::Equals(const Value* value) const { + const RawString* other = ValueCast<RawString>(value); if (!other) { return false; } return *this->value == *other->value; } -RawString* RawString::clone(StringPool* newPool) const { - RawString* rs = new RawString(newPool->makeRef(*value)); - rs->mComment = mComment; - rs->mSource = mSource; +RawString* RawString::Clone(StringPool* new_pool) const { + RawString* rs = new RawString(new_pool->MakeRef(*value)); + rs->comment_ = comment_; + rs->source_ = source_; return rs; } -bool RawString::flatten(android::Res_value* outValue) const { - outValue->dataType = android::Res_value::TYPE_STRING; - outValue->data = - util::hostToDevice32(static_cast<uint32_t>(value.getIndex())); +bool RawString::Flatten(android::Res_value* out_value) const { + out_value->dataType = android::Res_value::TYPE_STRING; + out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index())); return true; } -void RawString::print(std::ostream* out) const { +void RawString::Print(std::ostream* out) const { *out << "(raw string) " << *value; } -Reference::Reference() : referenceType(Type::kResource) {} +Reference::Reference() : reference_type(Type::kResource) {} Reference::Reference(const ResourceNameRef& n, Type t) - : name(n.toResourceName()), referenceType(t) {} + : name(n.ToResourceName()), reference_type(t) {} Reference::Reference(const ResourceId& i, Type type) - : id(i), referenceType(type) {} + : id(i), reference_type(type) {} Reference::Reference(const ResourceNameRef& n, const ResourceId& i) - : name(n.toResourceName()), id(i), referenceType(Type::kResource) {} + : name(n.ToResourceName()), id(i), reference_type(Type::kResource) {} -bool Reference::equals(const Value* value) const { - const Reference* other = valueCast<Reference>(value); +bool Reference::Equals(const Value* value) const { + const Reference* other = ValueCast<Reference>(value); if (!other) { return false; } - return referenceType == other->referenceType && - privateReference == other->privateReference && id == other->id && + return reference_type == other->reference_type && + private_reference == other->private_reference && id == other->id && name == other->name; } -bool Reference::flatten(android::Res_value* outValue) const { - outValue->dataType = (referenceType == Reference::Type::kResource) - ? android::Res_value::TYPE_REFERENCE - : android::Res_value::TYPE_ATTRIBUTE; - outValue->data = util::hostToDevice32(id ? id.value().id : 0); +bool Reference::Flatten(android::Res_value* out_value) const { + out_value->dataType = (reference_type == Reference::Type::kResource) + ? android::Res_value::TYPE_REFERENCE + : android::Res_value::TYPE_ATTRIBUTE; + out_value->data = util::HostToDevice32(id ? id.value().id : 0); return true; } -Reference* Reference::clone(StringPool* /*newPool*/) const { +Reference* Reference::Clone(StringPool* /*new_pool*/) const { return new Reference(*this); } -void Reference::print(std::ostream* out) const { +void Reference::Print(std::ostream* out) const { *out << "(reference) "; - if (referenceType == Reference::Type::kResource) { + if (reference_type == Reference::Type::kResource) { *out << "@"; - if (privateReference) { + if (private_reference) { *out << "*"; } } else { @@ -118,128 +119,127 @@ void Reference::print(std::ostream* out) const { } } -bool Id::equals(const Value* value) const { - return valueCast<Id>(value) != nullptr; +bool Id::Equals(const Value* value) const { + return ValueCast<Id>(value) != nullptr; } -bool Id::flatten(android::Res_value* out) const { +bool Id::Flatten(android::Res_value* out) const { out->dataType = android::Res_value::TYPE_INT_BOOLEAN; - out->data = util::hostToDevice32(0); + out->data = util::HostToDevice32(0); return true; } -Id* Id::clone(StringPool* /*newPool*/) const { return new Id(*this); } +Id* Id::Clone(StringPool* /*new_pool*/) const { return new Id(*this); } -void Id::print(std::ostream* out) const { *out << "(id)"; } +void Id::Print(std::ostream* out) const { *out << "(id)"; } String::String(const StringPool::Ref& ref) : value(ref) {} -bool String::equals(const Value* value) const { - const String* other = valueCast<String>(value); +bool String::Equals(const Value* value) const { + const String* other = ValueCast<String>(value); if (!other) { return false; } return *this->value == *other->value; } -bool String::flatten(android::Res_value* outValue) const { +bool String::Flatten(android::Res_value* out_value) const { // Verify that our StringPool index is within encode-able limits. - if (value.getIndex() > std::numeric_limits<uint32_t>::max()) { + if (value.index() > std::numeric_limits<uint32_t>::max()) { return false; } - outValue->dataType = android::Res_value::TYPE_STRING; - outValue->data = - util::hostToDevice32(static_cast<uint32_t>(value.getIndex())); + out_value->dataType = android::Res_value::TYPE_STRING; + out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index())); return true; } -String* String::clone(StringPool* newPool) const { - String* str = new String(newPool->makeRef(*value)); - str->mComment = mComment; - str->mSource = mSource; +String* String::Clone(StringPool* new_pool) const { + String* str = new String(new_pool->MakeRef(*value)); + str->comment_ = comment_; + str->source_ = source_; return str; } -void String::print(std::ostream* out) const { +void String::Print(std::ostream* out) const { *out << "(string) \"" << *value << "\""; } StyledString::StyledString(const StringPool::StyleRef& ref) : value(ref) {} -bool StyledString::equals(const Value* value) const { - const StyledString* other = valueCast<StyledString>(value); +bool StyledString::Equals(const Value* value) const { + const StyledString* other = ValueCast<StyledString>(value); if (!other) { return false; } if (*this->value->str == *other->value->str) { - const std::vector<StringPool::Span>& spansA = this->value->spans; - const std::vector<StringPool::Span>& spansB = other->value->spans; + const std::vector<StringPool::Span>& spans_a = this->value->spans; + const std::vector<StringPool::Span>& spans_b = other->value->spans; return std::equal( - spansA.begin(), spansA.end(), spansB.begin(), + spans_a.begin(), spans_a.end(), spans_b.begin(), [](const StringPool::Span& a, const StringPool::Span& b) -> bool { - return *a.name == *b.name && a.firstChar == b.firstChar && - a.lastChar == b.lastChar; + return *a.name == *b.name && a.first_char == b.first_char && + a.last_char == b.last_char; }); } return false; } -bool StyledString::flatten(android::Res_value* outValue) const { - if (value.getIndex() > std::numeric_limits<uint32_t>::max()) { +bool StyledString::Flatten(android::Res_value* out_value) const { + if (value.index() > std::numeric_limits<uint32_t>::max()) { return false; } - outValue->dataType = android::Res_value::TYPE_STRING; - outValue->data = - util::hostToDevice32(static_cast<uint32_t>(value.getIndex())); + out_value->dataType = android::Res_value::TYPE_STRING; + out_value->data = util::HostToDevice32(static_cast<uint32_t>(value.index())); return true; } -StyledString* StyledString::clone(StringPool* newPool) const { - StyledString* str = new StyledString(newPool->makeRef(value)); - str->mComment = mComment; - str->mSource = mSource; +StyledString* StyledString::Clone(StringPool* new_pool) const { + StyledString* str = new StyledString(new_pool->MakeRef(value)); + str->comment_ = comment_; + str->source_ = source_; return str; } -void StyledString::print(std::ostream* out) const { +void StyledString::Print(std::ostream* out) const { *out << "(styled string) \"" << *value->str << "\""; for (const StringPool::Span& span : value->spans) { - *out << " " << *span.name << ":" << span.firstChar << "," << span.lastChar; + *out << " " << *span.name << ":" << span.first_char << "," + << span.last_char; } } FileReference::FileReference(const StringPool::Ref& _path) : path(_path) {} -bool FileReference::equals(const Value* value) const { - const FileReference* other = valueCast<FileReference>(value); +bool FileReference::Equals(const Value* value) const { + const FileReference* other = ValueCast<FileReference>(value); if (!other) { return false; } return *path == *other->path; } -bool FileReference::flatten(android::Res_value* outValue) const { - if (path.getIndex() > std::numeric_limits<uint32_t>::max()) { +bool FileReference::Flatten(android::Res_value* out_value) const { + if (path.index() > std::numeric_limits<uint32_t>::max()) { return false; } - outValue->dataType = android::Res_value::TYPE_STRING; - outValue->data = util::hostToDevice32(static_cast<uint32_t>(path.getIndex())); + out_value->dataType = android::Res_value::TYPE_STRING; + out_value->data = util::HostToDevice32(static_cast<uint32_t>(path.index())); return true; } -FileReference* FileReference::clone(StringPool* newPool) const { - FileReference* fr = new FileReference(newPool->makeRef(*path)); +FileReference* FileReference::Clone(StringPool* new_pool) const { + FileReference* fr = new FileReference(new_pool->MakeRef(*path)); fr->file = file; - fr->mComment = mComment; - fr->mSource = mSource; + fr->comment_ = comment_; + fr->source_ = source_; return fr; } -void FileReference::print(std::ostream* out) const { +void FileReference::Print(std::ostream* out) const { *out << "(file) " << *path; } @@ -250,8 +250,8 @@ BinaryPrimitive::BinaryPrimitive(uint8_t dataType, uint32_t data) { value.data = data; } -bool BinaryPrimitive::equals(const Value* value) const { - const BinaryPrimitive* other = valueCast<BinaryPrimitive>(value); +bool BinaryPrimitive::Equals(const Value* value) const { + const BinaryPrimitive* other = ValueCast<BinaryPrimitive>(value); if (!other) { return false; } @@ -259,17 +259,17 @@ bool BinaryPrimitive::equals(const Value* value) const { this->value.data == other->value.data; } -bool BinaryPrimitive::flatten(android::Res_value* outValue) const { - outValue->dataType = value.dataType; - outValue->data = util::hostToDevice32(value.data); +bool BinaryPrimitive::Flatten(android::Res_value* out_value) const { + out_value->dataType = value.dataType; + out_value->data = util::HostToDevice32(value.data); return true; } -BinaryPrimitive* BinaryPrimitive::clone(StringPool* /*newPool*/) const { +BinaryPrimitive* BinaryPrimitive::Clone(StringPool* /*new_pool*/) const { return new BinaryPrimitive(*this); } -void BinaryPrimitive::print(std::ostream* out) const { +void BinaryPrimitive::Print(std::ostream* out) const { switch (value.dataType) { case android::Res_value::TYPE_NULL: *out << "(null)"; @@ -297,10 +297,10 @@ void BinaryPrimitive::print(std::ostream* out) const { } Attribute::Attribute(bool w, uint32_t t) - : typeMask(t), - minInt(std::numeric_limits<int32_t>::min()), - maxInt(std::numeric_limits<int32_t>::max()) { - mWeak = w; + : type_mask(t), + min_int(std::numeric_limits<int32_t>::min()), + max_int(std::numeric_limits<int32_t>::max()) { + weak_ = w; } template <typename T> @@ -308,8 +308,8 @@ T* addPointer(T& val) { return &val; } -bool Attribute::equals(const Value* value) const { - const Attribute* other = valueCast<Attribute>(value); +bool Attribute::Equals(const Value* value) const { + const Attribute* other = ValueCast<Attribute>(value); if (!other) { return false; } @@ -318,46 +318,46 @@ bool Attribute::equals(const Value* value) const { return false; } - if (typeMask != other->typeMask || minInt != other->minInt || - maxInt != other->maxInt) { + if (type_mask != other->type_mask || min_int != other->min_int || + max_int != other->max_int) { return false; } - std::vector<const Symbol*> sortedA; - std::transform(symbols.begin(), symbols.end(), std::back_inserter(sortedA), + std::vector<const Symbol*> sorted_a; + std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a), addPointer<const Symbol>); - std::sort(sortedA.begin(), sortedA.end(), + std::sort(sorted_a.begin(), sorted_a.end(), [](const Symbol* a, const Symbol* b) -> bool { return a->symbol.name < b->symbol.name; }); - std::vector<const Symbol*> sortedB; + std::vector<const Symbol*> sorted_b; std::transform(other->symbols.begin(), other->symbols.end(), - std::back_inserter(sortedB), addPointer<const Symbol>); - std::sort(sortedB.begin(), sortedB.end(), + std::back_inserter(sorted_b), addPointer<const Symbol>); + std::sort(sorted_b.begin(), sorted_b.end(), [](const Symbol* a, const Symbol* b) -> bool { return a->symbol.name < b->symbol.name; }); - return std::equal(sortedA.begin(), sortedA.end(), sortedB.begin(), + return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(), [](const Symbol* a, const Symbol* b) -> bool { - return a->symbol.equals(&b->symbol) && + return a->symbol.Equals(&b->symbol) && a->value == b->value; }); } -Attribute* Attribute::clone(StringPool* /*newPool*/) const { +Attribute* Attribute::Clone(StringPool* /*new_pool*/) const { return new Attribute(*this); } -void Attribute::printMask(std::ostream* out) const { - if (typeMask == android::ResTable_map::TYPE_ANY) { +void Attribute::PrintMask(std::ostream* out) const { + if (type_mask == android::ResTable_map::TYPE_ANY) { *out << "any"; return; } bool set = false; - if ((typeMask & android::ResTable_map::TYPE_REFERENCE) != 0) { + if ((type_mask & android::ResTable_map::TYPE_REFERENCE) != 0) { if (!set) { set = true; } else { @@ -366,7 +366,7 @@ void Attribute::printMask(std::ostream* out) const { *out << "reference"; } - if ((typeMask & android::ResTable_map::TYPE_STRING) != 0) { + if ((type_mask & android::ResTable_map::TYPE_STRING) != 0) { if (!set) { set = true; } else { @@ -375,7 +375,7 @@ void Attribute::printMask(std::ostream* out) const { *out << "string"; } - if ((typeMask & android::ResTable_map::TYPE_INTEGER) != 0) { + if ((type_mask & android::ResTable_map::TYPE_INTEGER) != 0) { if (!set) { set = true; } else { @@ -384,7 +384,7 @@ void Attribute::printMask(std::ostream* out) const { *out << "integer"; } - if ((typeMask & android::ResTable_map::TYPE_BOOLEAN) != 0) { + if ((type_mask & android::ResTable_map::TYPE_BOOLEAN) != 0) { if (!set) { set = true; } else { @@ -393,7 +393,7 @@ void Attribute::printMask(std::ostream* out) const { *out << "boolean"; } - if ((typeMask & android::ResTable_map::TYPE_COLOR) != 0) { + if ((type_mask & android::ResTable_map::TYPE_COLOR) != 0) { if (!set) { set = true; } else { @@ -402,7 +402,7 @@ void Attribute::printMask(std::ostream* out) const { *out << "color"; } - if ((typeMask & android::ResTable_map::TYPE_FLOAT) != 0) { + if ((type_mask & android::ResTable_map::TYPE_FLOAT) != 0) { if (!set) { set = true; } else { @@ -411,7 +411,7 @@ void Attribute::printMask(std::ostream* out) const { *out << "float"; } - if ((typeMask & android::ResTable_map::TYPE_DIMENSION) != 0) { + if ((type_mask & android::ResTable_map::TYPE_DIMENSION) != 0) { if (!set) { set = true; } else { @@ -420,7 +420,7 @@ void Attribute::printMask(std::ostream* out) const { *out << "dimension"; } - if ((typeMask & android::ResTable_map::TYPE_FRACTION) != 0) { + if ((type_mask & android::ResTable_map::TYPE_FRACTION) != 0) { if (!set) { set = true; } else { @@ -429,7 +429,7 @@ void Attribute::printMask(std::ostream* out) const { *out << "fraction"; } - if ((typeMask & android::ResTable_map::TYPE_ENUM) != 0) { + if ((type_mask & android::ResTable_map::TYPE_ENUM) != 0) { if (!set) { set = true; } else { @@ -438,7 +438,7 @@ void Attribute::printMask(std::ostream* out) const { *out << "enum"; } - if ((typeMask & android::ResTable_map::TYPE_FLAGS) != 0) { + if ((type_mask & android::ResTable_map::TYPE_FLAGS) != 0) { if (!set) { set = true; } else { @@ -448,96 +448,96 @@ void Attribute::printMask(std::ostream* out) const { } } -void Attribute::print(std::ostream* out) const { +void Attribute::Print(std::ostream* out) const { *out << "(attr) "; - printMask(out); + PrintMask(out); if (!symbols.empty()) { - *out << " [" << util::joiner(symbols, ", ") << "]"; + *out << " [" << util::Joiner(symbols, ", ") << "]"; } - if (minInt != std::numeric_limits<int32_t>::min()) { - *out << " min=" << minInt; + if (min_int != std::numeric_limits<int32_t>::min()) { + *out << " min=" << min_int; } - if (maxInt != std::numeric_limits<int32_t>::max()) { - *out << " max=" << maxInt; + if (max_int != std::numeric_limits<int32_t>::max()) { + *out << " max=" << max_int; } - if (isWeak()) { + if (IsWeak()) { *out << " [weak]"; } } -static void buildAttributeMismatchMessage(DiagMessage* msg, +static void BuildAttributeMismatchMessage(DiagMessage* msg, const Attribute* attr, const Item* value) { *msg << "expected"; - if (attr->typeMask & android::ResTable_map::TYPE_BOOLEAN) { + if (attr->type_mask & android::ResTable_map::TYPE_BOOLEAN) { *msg << " boolean"; } - if (attr->typeMask & android::ResTable_map::TYPE_COLOR) { + if (attr->type_mask & android::ResTable_map::TYPE_COLOR) { *msg << " color"; } - if (attr->typeMask & android::ResTable_map::TYPE_DIMENSION) { + if (attr->type_mask & android::ResTable_map::TYPE_DIMENSION) { *msg << " dimension"; } - if (attr->typeMask & android::ResTable_map::TYPE_ENUM) { + if (attr->type_mask & android::ResTable_map::TYPE_ENUM) { *msg << " enum"; } - if (attr->typeMask & android::ResTable_map::TYPE_FLAGS) { + if (attr->type_mask & android::ResTable_map::TYPE_FLAGS) { *msg << " flags"; } - if (attr->typeMask & android::ResTable_map::TYPE_FLOAT) { + if (attr->type_mask & android::ResTable_map::TYPE_FLOAT) { *msg << " float"; } - if (attr->typeMask & android::ResTable_map::TYPE_FRACTION) { + if (attr->type_mask & android::ResTable_map::TYPE_FRACTION) { *msg << " fraction"; } - if (attr->typeMask & android::ResTable_map::TYPE_INTEGER) { + if (attr->type_mask & android::ResTable_map::TYPE_INTEGER) { *msg << " integer"; } - if (attr->typeMask & android::ResTable_map::TYPE_REFERENCE) { + if (attr->type_mask & android::ResTable_map::TYPE_REFERENCE) { *msg << " reference"; } - if (attr->typeMask & android::ResTable_map::TYPE_STRING) { + if (attr->type_mask & android::ResTable_map::TYPE_STRING) { *msg << " string"; } *msg << " but got " << *value; } -bool Attribute::matches(const Item* item, DiagMessage* outMsg) const { +bool Attribute::Matches(const Item* item, DiagMessage* out_msg) const { android::Res_value val = {}; - item->flatten(&val); + item->Flatten(&val); // Always allow references. - const uint32_t mask = typeMask | android::ResTable_map::TYPE_REFERENCE; - if (!(mask & ResourceUtils::androidTypeToAttributeTypeMask(val.dataType))) { - if (outMsg) { - buildAttributeMismatchMessage(outMsg, this, item); + const uint32_t mask = type_mask | android::ResTable_map::TYPE_REFERENCE; + if (!(mask & ResourceUtils::AndroidTypeToAttributeTypeMask(val.dataType))) { + if (out_msg) { + BuildAttributeMismatchMessage(out_msg, this, item); } return false; - } else if (ResourceUtils::androidTypeToAttributeTypeMask(val.dataType) & + } else if (ResourceUtils::AndroidTypeToAttributeTypeMask(val.dataType) & android::ResTable_map::TYPE_INTEGER) { - if (static_cast<int32_t>(util::deviceToHost32(val.data)) < minInt) { - if (outMsg) { - *outMsg << *item << " is less than minimum integer " << minInt; + if (static_cast<int32_t>(util::DeviceToHost32(val.data)) < min_int) { + if (out_msg) { + *out_msg << *item << " is less than minimum integer " << min_int; } return false; - } else if (static_cast<int32_t>(util::deviceToHost32(val.data)) > maxInt) { - if (outMsg) { - *outMsg << *item << " is greater than maximum integer " << maxInt; + } else if (static_cast<int32_t>(util::DeviceToHost32(val.data)) > max_int) { + if (out_msg) { + *out_msg << *item << " is greater than maximum integer " << max_int; } return false; } @@ -545,14 +545,14 @@ bool Attribute::matches(const Item* item, DiagMessage* outMsg) const { return true; } -bool Style::equals(const Value* value) const { - const Style* other = valueCast<Style>(value); +bool Style::Equals(const Value* value) const { + const Style* other = ValueCast<Style>(value); if (!other) { return false; } if (bool(parent) != bool(other->parent) || (parent && other->parent && - !parent.value().equals(&other->parent.value()))) { + !parent.value().Equals(&other->parent.value()))) { return false; } @@ -560,51 +560,51 @@ bool Style::equals(const Value* value) const { return false; } - std::vector<const Entry*> sortedA; - std::transform(entries.begin(), entries.end(), std::back_inserter(sortedA), + std::vector<const Entry*> sorted_a; + std::transform(entries.begin(), entries.end(), std::back_inserter(sorted_a), addPointer<const Entry>); - std::sort(sortedA.begin(), sortedA.end(), + std::sort(sorted_a.begin(), sorted_a.end(), [](const Entry* a, const Entry* b) -> bool { return a->key.name < b->key.name; }); - std::vector<const Entry*> sortedB; + std::vector<const Entry*> sorted_b; std::transform(other->entries.begin(), other->entries.end(), - std::back_inserter(sortedB), addPointer<const Entry>); - std::sort(sortedB.begin(), sortedB.end(), + std::back_inserter(sorted_b), addPointer<const Entry>); + std::sort(sorted_b.begin(), sorted_b.end(), [](const Entry* a, const Entry* b) -> bool { return a->key.name < b->key.name; }); - return std::equal(sortedA.begin(), sortedA.end(), sortedB.begin(), + return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(), [](const Entry* a, const Entry* b) -> bool { - return a->key.equals(&b->key) && - a->value->equals(b->value.get()); + return a->key.Equals(&b->key) && + a->value->Equals(b->value.get()); }); } -Style* Style::clone(StringPool* newPool) const { +Style* Style::Clone(StringPool* new_pool) const { Style* style = new Style(); style->parent = parent; - style->parentInferred = parentInferred; - style->mComment = mComment; - style->mSource = mSource; + style->parent_inferred = parent_inferred; + style->comment_ = comment_; + style->source_ = source_; for (auto& entry : entries) { style->entries.push_back( - Entry{entry.key, std::unique_ptr<Item>(entry.value->clone(newPool))}); + Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))}); } return style; } -void Style::print(std::ostream* out) const { +void Style::Print(std::ostream* out) const { *out << "(style) "; if (parent && parent.value().name) { - if (parent.value().privateReference) { + if (parent.value().private_reference) { *out << "*"; } *out << parent.value().name.value(); } - *out << " [" << util::joiner(entries, ", ") << "]"; + *out << " [" << util::Joiner(entries, ", ") << "]"; } static ::std::ostream& operator<<(::std::ostream& out, @@ -617,12 +617,12 @@ static ::std::ostream& operator<<(::std::ostream& out, out << "???"; } out << " = "; - value.value->print(&out); + value.value->Print(&out); return out; } -bool Array::equals(const Value* value) const { - const Array* other = valueCast<Array>(value); +bool Array::Equals(const Value* value) const { + const Array* other = ValueCast<Array>(value); if (!other) { return false; } @@ -634,26 +634,26 @@ bool Array::equals(const Value* value) const { return std::equal(items.begin(), items.end(), other->items.begin(), [](const std::unique_ptr<Item>& a, const std::unique_ptr<Item>& b) -> bool { - return a->equals(b.get()); + return a->Equals(b.get()); }); } -Array* Array::clone(StringPool* newPool) const { +Array* Array::Clone(StringPool* new_pool) const { Array* array = new Array(); - array->mComment = mComment; - array->mSource = mSource; + array->comment_ = comment_; + array->source_ = source_; for (auto& item : items) { - array->items.emplace_back(std::unique_ptr<Item>(item->clone(newPool))); + array->items.emplace_back(std::unique_ptr<Item>(item->Clone(new_pool))); } return array; } -void Array::print(std::ostream* out) const { - *out << "(array) [" << util::joiner(items, ", ") << "]"; +void Array::Print(std::ostream* out) const { + *out << "(array) [" << util::Joiner(items, ", ") << "]"; } -bool Plural::equals(const Value* value) const { - const Plural* other = valueCast<Plural>(value); +bool Plural::Equals(const Value* value) const { + const Plural* other = ValueCast<Plural>(value); if (!other) { return false; } @@ -668,24 +668,24 @@ bool Plural::equals(const Value* value) const { if (bool(a) != bool(b)) { return false; } - return bool(a) == bool(b) || a->equals(b.get()); + return bool(a) == bool(b) || a->Equals(b.get()); }); } -Plural* Plural::clone(StringPool* newPool) const { +Plural* Plural::Clone(StringPool* new_pool) const { Plural* p = new Plural(); - p->mComment = mComment; - p->mSource = mSource; + p->comment_ = comment_; + p->source_ = source_; const size_t count = values.size(); for (size_t i = 0; i < count; i++) { if (values[i]) { - p->values[i] = std::unique_ptr<Item>(values[i]->clone(newPool)); + p->values[i] = std::unique_ptr<Item>(values[i]->Clone(new_pool)); } } return p; } -void Plural::print(std::ostream* out) const { +void Plural::Print(std::ostream* out) const { *out << "(plural)"; if (values[Zero]) { *out << " zero=" << *values[Zero]; @@ -713,8 +713,8 @@ static ::std::ostream& operator<<(::std::ostream& out, return out << *item; } -bool Styleable::equals(const Value* value) const { - const Styleable* other = valueCast<Styleable>(value); +bool Styleable::Equals(const Value* value) const { + const Styleable* other = ValueCast<Styleable>(value); if (!other) { return false; } @@ -725,21 +725,21 @@ bool Styleable::equals(const Value* value) const { return std::equal(entries.begin(), entries.end(), other->entries.begin(), [](const Reference& a, const Reference& b) -> bool { - return a.equals(&b); + return a.Equals(&b); }); } -Styleable* Styleable::clone(StringPool* /*newPool*/) const { +Styleable* Styleable::Clone(StringPool* /*new_pool*/) const { return new Styleable(*this); } -void Styleable::print(std::ostream* out) const { +void Styleable::Print(std::ostream* out) const { *out << "(styleable) " - << " [" << util::joiner(entries, ", ") << "]"; + << " [" << util::Joiner(entries, ", ") << "]"; } bool operator<(const Reference& a, const Reference& b) { - int cmp = a.name.valueOrDefault({}).compare(b.name.valueOrDefault({})); + int cmp = a.name.value_or_default({}).compare(b.name.value_or_default({})); if (cmp != 0) return cmp < 0; return a.id < b.id; } @@ -758,7 +758,7 @@ struct NameOnlyComparator { } }; -void Styleable::mergeWith(Styleable* other) { +void Styleable::MergeWith(Styleable* other) { // Compare only names, because some References may already have their IDs // assigned // (framework IDs that don't change). diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h index a28ffe5aff0f..ea73615e372a 100644 --- a/tools/aapt2/ResourceValues.h +++ b/tools/aapt2/ResourceValues.h @@ -17,17 +17,18 @@ #ifndef AAPT_RESOURCE_VALUES_H #define AAPT_RESOURCE_VALUES_H +#include <array> +#include <ostream> +#include <vector> + +#include "androidfw/ResourceTypes.h" + #include "Diagnostics.h" #include "Resource.h" #include "StringPool.h" #include "io/File.h" #include "util/Maybe.h" -#include <androidfw/ResourceTypes.h> -#include <array> -#include <ostream> -#include <vector> - namespace aapt { struct RawValueVisitor; @@ -46,58 +47,59 @@ struct Value { * Whether this value is weak and can be overridden without * warning or error. Default is false. */ - bool isWeak() const { return mWeak; } + bool IsWeak() const { return weak_; } - void setWeak(bool val) { mWeak = val; } + void SetWeak(bool val) { weak_ = val; } // Whether the value is marked as translateable. // This does not persist when flattened. // It is only used during compilation phase. - void setTranslateable(bool val) { mTranslateable = val; } + void SetTranslateable(bool val) { translateable_ = val; } // Default true. - bool isTranslateable() const { return mTranslateable; } + bool IsTranslateable() const { return translateable_; } /** * Returns the source where this value was defined. */ - const Source& getSource() const { return mSource; } + const Source& GetSource() const { return source_; } - void setSource(const Source& source) { mSource = source; } + void SetSource(const Source& source) { source_ = source; } - void setSource(Source&& source) { mSource = std::move(source); } + void SetSource(Source&& source) { source_ = std::move(source); } /** * Returns the comment that was associated with this resource. */ - const std::string& getComment() const { return mComment; } + const std::string& GetComment() const { return comment_; } - void setComment(const StringPiece& str) { mComment = str.toString(); } + void SetComment(const StringPiece& str) { comment_ = str.ToString(); } - void setComment(std::string&& str) { mComment = std::move(str); } + void SetComment(std::string&& str) { comment_ = std::move(str); } - virtual bool equals(const Value* value) const = 0; + virtual bool Equals(const Value* value) const = 0; /** * Calls the appropriate overload of ValueVisitor. */ - virtual void accept(RawValueVisitor* visitor) = 0; + virtual void Accept(RawValueVisitor* visitor) = 0; /** - * Clone the value. + * Clone the value. new_pool is the new StringPool that + * any resources with strings should use when copying their string. */ - virtual Value* clone(StringPool* newPool) const = 0; + virtual Value* Clone(StringPool* new_pool) const = 0; /** * Human readable printout of this value. */ - virtual void print(std::ostream* out) const = 0; + virtual void Print(std::ostream* out) const = 0; protected: - Source mSource; - std::string mComment; - bool mWeak = false; - bool mTranslateable = true; + Source source_; + std::string comment_; + bool weak_ = false; + bool translateable_ = true; }; /** @@ -105,7 +107,7 @@ struct Value { */ template <typename Derived> struct BaseValue : public Value { - void accept(RawValueVisitor* visitor) override; + void Accept(RawValueVisitor* visitor) override; }; /** @@ -115,14 +117,14 @@ struct Item : public Value { /** * Clone the Item. */ - virtual Item* clone(StringPool* newPool) const override = 0; + virtual Item* Clone(StringPool* new_pool) const override = 0; /** * Fills in an android::Res_value structure with this Item's binary * representation. * Returns false if an error occurred. */ - virtual bool flatten(android::Res_value* outValue) const = 0; + virtual bool Flatten(android::Res_value* out_value) const = 0; }; /** @@ -130,7 +132,7 @@ struct Item : public Value { */ template <typename Derived> struct BaseItem : public Item { - void accept(RawValueVisitor* visitor) override; + void Accept(RawValueVisitor* visitor) override; }; /** @@ -149,18 +151,18 @@ struct Reference : public BaseItem<Reference> { Maybe<ResourceName> name; Maybe<ResourceId> id; - Reference::Type referenceType; - bool privateReference = false; + Reference::Type reference_type; + bool private_reference = false; Reference(); explicit Reference(const ResourceNameRef& n, Type type = Type::kResource); explicit Reference(const ResourceId& i, Type type = Type::kResource); - explicit Reference(const ResourceNameRef& n, const ResourceId& i); + Reference(const ResourceNameRef& n, const ResourceId& i); - bool equals(const Value* value) const override; - bool flatten(android::Res_value* outValue) const override; - Reference* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + bool Equals(const Value* value) const override; + bool Flatten(android::Res_value* out_value) const override; + Reference* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; bool operator<(const Reference&, const Reference&); @@ -170,11 +172,11 @@ bool operator==(const Reference&, const Reference&); * An ID resource. Has no real value, just a place holder. */ struct Id : public BaseItem<Id> { - Id() { mWeak = true; } - bool equals(const Value* value) const override; - bool flatten(android::Res_value* out) const override; - Id* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + Id() { weak_ = true; } + bool Equals(const Value* value) const override; + bool Flatten(android::Res_value* out) const override; + Id* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; /** @@ -187,10 +189,10 @@ struct RawString : public BaseItem<RawString> { explicit RawString(const StringPool::Ref& ref); - bool equals(const Value* value) const override; - bool flatten(android::Res_value* outValue) const override; - RawString* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + bool Equals(const Value* value) const override; + bool Flatten(android::Res_value* out_value) const override; + RawString* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; struct String : public BaseItem<String> { @@ -198,10 +200,10 @@ struct String : public BaseItem<String> { explicit String(const StringPool::Ref& ref); - bool equals(const Value* value) const override; - bool flatten(android::Res_value* outValue) const override; - String* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + bool Equals(const Value* value) const override; + bool Flatten(android::Res_value* out_value) const override; + String* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; struct StyledString : public BaseItem<StyledString> { @@ -209,10 +211,10 @@ struct StyledString : public BaseItem<StyledString> { explicit StyledString(const StringPool::StyleRef& ref); - bool equals(const Value* value) const override; - bool flatten(android::Res_value* outValue) const override; - StyledString* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + bool Equals(const Value* value) const override; + bool Flatten(android::Res_value* out_value) const override; + StyledString* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; struct FileReference : public BaseItem<FileReference> { @@ -226,10 +228,10 @@ struct FileReference : public BaseItem<FileReference> { FileReference() = default; explicit FileReference(const StringPool::Ref& path); - bool equals(const Value* value) const override; - bool flatten(android::Res_value* outValue) const override; - FileReference* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + bool Equals(const Value* value) const override; + bool Flatten(android::Res_value* out_value) const override; + FileReference* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; /** @@ -242,10 +244,10 @@ struct BinaryPrimitive : public BaseItem<BinaryPrimitive> { explicit BinaryPrimitive(const android::Res_value& val); BinaryPrimitive(uint8_t dataType, uint32_t data); - bool equals(const Value* value) const override; - bool flatten(android::Res_value* outValue) const override; - BinaryPrimitive* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + bool Equals(const Value* value) const override; + bool Flatten(android::Res_value* out_value) const override; + BinaryPrimitive* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; struct Attribute : public BaseValue<Attribute> { @@ -254,18 +256,18 @@ struct Attribute : public BaseValue<Attribute> { uint32_t value; }; - uint32_t typeMask; - int32_t minInt; - int32_t maxInt; + uint32_t type_mask; + int32_t min_int; + int32_t max_int; std::vector<Symbol> symbols; explicit Attribute(bool w, uint32_t t = 0u); - bool equals(const Value* value) const override; - Attribute* clone(StringPool* newPool) const override; - void printMask(std::ostream* out) const; - void print(std::ostream* out) const override; - bool matches(const Item* item, DiagMessage* outMsg) const; + bool Equals(const Value* value) const override; + Attribute* Clone(StringPool* new_pool) const override; + void PrintMask(std::ostream* out) const; + void Print(std::ostream* out) const override; + bool Matches(const Item* item, DiagMessage* out_msg) const; }; struct Style : public BaseValue<Style> { @@ -280,21 +282,21 @@ struct Style : public BaseValue<Style> { * If set to true, the parent was auto inferred from the * style's name. */ - bool parentInferred = false; + bool parent_inferred = false; std::vector<Entry> entries; - bool equals(const Value* value) const override; - Style* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + bool Equals(const Value* value) const override; + Style* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; struct Array : public BaseValue<Array> { std::vector<std::unique_ptr<Item>> items; - bool equals(const Value* value) const override; - Array* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + bool Equals(const Value* value) const override; + Array* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; struct Plural : public BaseValue<Plural> { @@ -302,25 +304,25 @@ struct Plural : public BaseValue<Plural> { std::array<std::unique_ptr<Item>, Count> values; - bool equals(const Value* value) const override; - Plural* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; + bool Equals(const Value* value) const override; + Plural* Clone(StringPool* new_pool) const override; + void Print(std::ostream* out) const override; }; struct Styleable : public BaseValue<Styleable> { std::vector<Reference> entries; - bool equals(const Value* value) const override; - Styleable* clone(StringPool* newPool) const override; - void print(std::ostream* out) const override; - void mergeWith(Styleable* styleable); + bool Equals(const Value* value) const override; + Styleable* Clone(StringPool* newPool) const override; + void Print(std::ostream* out) const override; + void MergeWith(Styleable* styleable); }; /** * Stream operator for printing Value objects. */ inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) { - value.print(&out); + value.Print(&out); return out; } diff --git a/tools/aapt2/Resource_test.cpp b/tools/aapt2/Resource_test.cpp index 4b6b122f984e..720ab91c5740 100644 --- a/tools/aapt2/Resource_test.cpp +++ b/tools/aapt2/Resource_test.cpp @@ -15,100 +15,101 @@ */ #include "Resource.h" + #include "test/Test.h" namespace aapt { TEST(ResourceTypeTest, ParseResourceTypes) { - const ResourceType* type = parseResourceType("anim"); + const ResourceType* type = ParseResourceType("anim"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kAnim); - type = parseResourceType("animator"); + type = ParseResourceType("animator"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kAnimator); - type = parseResourceType("array"); + type = ParseResourceType("array"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kArray); - type = parseResourceType("attr"); + type = ParseResourceType("attr"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kAttr); - type = parseResourceType("^attr-private"); + type = ParseResourceType("^attr-private"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kAttrPrivate); - type = parseResourceType("bool"); + type = ParseResourceType("bool"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kBool); - type = parseResourceType("color"); + type = ParseResourceType("color"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kColor); - type = parseResourceType("dimen"); + type = ParseResourceType("dimen"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kDimen); - type = parseResourceType("drawable"); + type = ParseResourceType("drawable"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kDrawable); - type = parseResourceType("fraction"); + type = ParseResourceType("fraction"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kFraction); - type = parseResourceType("id"); + type = ParseResourceType("id"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kId); - type = parseResourceType("integer"); + type = ParseResourceType("integer"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kInteger); - type = parseResourceType("interpolator"); + type = ParseResourceType("interpolator"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kInterpolator); - type = parseResourceType("layout"); + type = ParseResourceType("layout"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kLayout); - type = parseResourceType("menu"); + type = ParseResourceType("menu"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kMenu); - type = parseResourceType("mipmap"); + type = ParseResourceType("mipmap"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kMipmap); - type = parseResourceType("plurals"); + type = ParseResourceType("plurals"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kPlurals); - type = parseResourceType("raw"); + type = ParseResourceType("raw"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kRaw); - type = parseResourceType("string"); + type = ParseResourceType("string"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kString); - type = parseResourceType("style"); + type = ParseResourceType("style"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kStyle); - type = parseResourceType("transition"); + type = ParseResourceType("transition"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kTransition); - type = parseResourceType("xml"); + type = ParseResourceType("xml"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kXml); - type = parseResourceType("blahaha"); + type = ParseResourceType("blahaha"); EXPECT_EQ(type, nullptr); } diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp index 75375da33458..c7f920ac6c58 100644 --- a/tools/aapt2/SdkConstants.cpp +++ b/tools/aapt2/SdkConstants.cpp @@ -48,17 +48,17 @@ static const std::vector<std::pair<uint16_t, size_t>> sAttrIdMap = { {0x04ce, SDK_LOLLIPOP}, }; -static bool lessEntryId(const std::pair<uint16_t, size_t>& p, +static bool less_entry_id(const std::pair<uint16_t, size_t>& p, uint16_t entryId) { return p.first < entryId; } -size_t findAttributeSdkLevel(const ResourceId& id) { - if (id.packageId() != 0x01 && id.typeId() != 0x01) { +size_t FindAttributeSdkLevel(const ResourceId& id) { + if (id.package_id() != 0x01 && id.type_id() != 0x01) { return 0; } auto iter = std::lower_bound(sAttrIdMap.begin(), sAttrIdMap.end(), - id.entryId(), lessEntryId); + id.entry_id(), less_entry_id); if (iter == sAttrIdMap.end()) { return SDK_LOLLIPOP_MR1; } @@ -727,7 +727,7 @@ static const std::unordered_map<std::string, size_t> sAttrMap = { {"windowActivityTransitions", 21}, {"colorEdgeEffect", 21}}; -size_t findAttributeSdkLevel(const ResourceName& name) { +size_t FindAttributeSdkLevel(const ResourceName& name) { if (name.package != "android" && name.type != ResourceType::kAttr) { return 0; } @@ -739,7 +739,7 @@ size_t findAttributeSdkLevel(const ResourceName& name) { return SDK_LOLLIPOP_MR1; } -std::pair<StringPiece, int> getDevelopmentSdkCodeNameAndVersion() { +std::pair<StringPiece, int> GetDevelopmentSdkCodeNameAndVersion() { return std::make_pair(StringPiece(sDevelopmentSdkCodeName), sDevelopmentSdkLevel); } diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h index bd17fe499618..9b38ecbeae99 100644 --- a/tools/aapt2/SdkConstants.h +++ b/tools/aapt2/SdkConstants.h @@ -17,10 +17,10 @@ #ifndef AAPT_SDK_CONSTANTS_H #define AAPT_SDK_CONSTANTS_H -#include "Resource.h" - #include <utility> +#include "Resource.h" + namespace aapt { enum { @@ -47,9 +47,9 @@ enum { SDK_MARSHMALLOW = 23, }; -size_t findAttributeSdkLevel(const ResourceId& id); -size_t findAttributeSdkLevel(const ResourceName& name); -std::pair<StringPiece, int> getDevelopmentSdkCodeNameAndVersion(); +size_t FindAttributeSdkLevel(const ResourceId& id); +size_t FindAttributeSdkLevel(const ResourceName& name); +std::pair<StringPiece, int> GetDevelopmentSdkCodeNameAndVersion(); } // namespace aapt diff --git a/tools/aapt2/SdkConstants_test.cpp b/tools/aapt2/SdkConstants_test.cpp index 3b70acb7c610..716d922fb5a0 100644 --- a/tools/aapt2/SdkConstants_test.cpp +++ b/tools/aapt2/SdkConstants_test.cpp @@ -16,23 +16,23 @@ #include "SdkConstants.h" -#include <gtest/gtest.h> +#include "gtest/gtest.h" namespace aapt { TEST(SdkConstantsTest, FirstAttributeIsSdk1) { - EXPECT_EQ(1u, findAttributeSdkLevel(ResourceId(0x01010000))); + EXPECT_EQ(1u, FindAttributeSdkLevel(ResourceId(0x01010000))); } TEST(SdkConstantsTest, AllAttributesAfterLollipopAreLollipopMR1) { - EXPECT_EQ(SDK_LOLLIPOP, findAttributeSdkLevel(ResourceId(0x010103f7))); - EXPECT_EQ(SDK_LOLLIPOP, findAttributeSdkLevel(ResourceId(0x010104ce))); + EXPECT_EQ(SDK_LOLLIPOP, FindAttributeSdkLevel(ResourceId(0x010103f7))); + EXPECT_EQ(SDK_LOLLIPOP, FindAttributeSdkLevel(ResourceId(0x010104ce))); - EXPECT_EQ(SDK_LOLLIPOP_MR1, findAttributeSdkLevel(ResourceId(0x010104cf))); - EXPECT_EQ(SDK_LOLLIPOP_MR1, findAttributeSdkLevel(ResourceId(0x010104d8))); + EXPECT_EQ(SDK_LOLLIPOP_MR1, FindAttributeSdkLevel(ResourceId(0x010104cf))); + EXPECT_EQ(SDK_LOLLIPOP_MR1, FindAttributeSdkLevel(ResourceId(0x010104d8))); - EXPECT_EQ(SDK_LOLLIPOP_MR1, findAttributeSdkLevel(ResourceId(0x010104d9))); - EXPECT_EQ(SDK_LOLLIPOP_MR1, findAttributeSdkLevel(ResourceId(0x0101ffff))); + EXPECT_EQ(SDK_LOLLIPOP_MR1, FindAttributeSdkLevel(ResourceId(0x010104d9))); + EXPECT_EQ(SDK_LOLLIPOP_MR1, FindAttributeSdkLevel(ResourceId(0x0101ffff))); } } // namespace aapt diff --git a/tools/aapt2/Source.h b/tools/aapt2/Source.h index 422b36112660..459a8e603b6b 100644 --- a/tools/aapt2/Source.h +++ b/tools/aapt2/Source.h @@ -17,12 +17,12 @@ #ifndef AAPT_SOURCE_H #define AAPT_SOURCE_H -#include "util/Maybe.h" -#include "util/StringPiece.h" - #include <ostream> #include <string> +#include "util/Maybe.h" +#include "util/StringPiece.h" + namespace aapt { /** @@ -36,13 +36,13 @@ struct Source { Source() = default; inline Source(const StringPiece& path) - : path(path.toString()) { // NOLINT(implicit) + : path(path.ToString()) { // NOLINT(implicit) } inline Source(const StringPiece& path, size_t line) - : path(path.toString()), line(line) {} + : path(path.ToString()), line(line) {} - inline Source withLine(size_t line) const { return Source(path, line); } + inline Source WithLine(size_t line) const { return Source(path, line); } }; // diff --git a/tools/aapt2/StringPool.cpp b/tools/aapt2/StringPool.cpp index a167a6aec802..30328299bb84 100644 --- a/tools/aapt2/StringPool.cpp +++ b/tools/aapt2/StringPool.cpp @@ -15,263 +15,266 @@ */ #include "StringPool.h" -#include "util/BigBuffer.h" -#include "util/StringPiece.h" -#include "util/Util.h" -#include <androidfw/ResourceTypes.h> #include <algorithm> #include <memory> #include <string> +#include "android-base/logging.h" +#include "androidfw/ResourceTypes.h" + +#include "util/BigBuffer.h" +#include "util/StringPiece.h" +#include "util/Util.h" + namespace aapt { -StringPool::Ref::Ref() : mEntry(nullptr) {} +StringPool::Ref::Ref() : entry_(nullptr) {} -StringPool::Ref::Ref(const StringPool::Ref& rhs) : mEntry(rhs.mEntry) { - if (mEntry != nullptr) { - mEntry->ref++; +StringPool::Ref::Ref(const StringPool::Ref& rhs) : entry_(rhs.entry_) { + if (entry_ != nullptr) { + entry_->ref_++; } } -StringPool::Ref::Ref(StringPool::Entry* entry) : mEntry(entry) { - if (mEntry != nullptr) { - mEntry->ref++; +StringPool::Ref::Ref(StringPool::Entry* entry) : entry_(entry) { + if (entry_ != nullptr) { + entry_->ref_++; } } StringPool::Ref::~Ref() { - if (mEntry != nullptr) { - mEntry->ref--; + if (entry_ != nullptr) { + entry_->ref_--; } } StringPool::Ref& StringPool::Ref::operator=(const StringPool::Ref& rhs) { - if (rhs.mEntry != nullptr) { - rhs.mEntry->ref++; + if (rhs.entry_ != nullptr) { + rhs.entry_->ref_++; } - if (mEntry != nullptr) { - mEntry->ref--; + if (entry_ != nullptr) { + entry_->ref_--; } - mEntry = rhs.mEntry; + entry_ = rhs.entry_; return *this; } const std::string* StringPool::Ref::operator->() const { - return &mEntry->value; + return &entry_->value; } -const std::string& StringPool::Ref::operator*() const { return mEntry->value; } +const std::string& StringPool::Ref::operator*() const { return entry_->value; } -size_t StringPool::Ref::getIndex() const { return mEntry->index; } +size_t StringPool::Ref::index() const { return entry_->index; } -const StringPool::Context& StringPool::Ref::getContext() const { - return mEntry->context; +const StringPool::Context& StringPool::Ref::GetContext() const { + return entry_->context; } -StringPool::StyleRef::StyleRef() : mEntry(nullptr) {} +StringPool::StyleRef::StyleRef() : entry_(nullptr) {} StringPool::StyleRef::StyleRef(const StringPool::StyleRef& rhs) - : mEntry(rhs.mEntry) { - if (mEntry != nullptr) { - mEntry->ref++; + : entry_(rhs.entry_) { + if (entry_ != nullptr) { + entry_->ref_++; } } -StringPool::StyleRef::StyleRef(StringPool::StyleEntry* entry) : mEntry(entry) { - if (mEntry != nullptr) { - mEntry->ref++; +StringPool::StyleRef::StyleRef(StringPool::StyleEntry* entry) : entry_(entry) { + if (entry_ != nullptr) { + entry_->ref_++; } } StringPool::StyleRef::~StyleRef() { - if (mEntry != nullptr) { - mEntry->ref--; + if (entry_ != nullptr) { + entry_->ref_--; } } StringPool::StyleRef& StringPool::StyleRef::operator=( const StringPool::StyleRef& rhs) { - if (rhs.mEntry != nullptr) { - rhs.mEntry->ref++; + if (rhs.entry_ != nullptr) { + rhs.entry_->ref_++; } - if (mEntry != nullptr) { - mEntry->ref--; + if (entry_ != nullptr) { + entry_->ref_--; } - mEntry = rhs.mEntry; + entry_ = rhs.entry_; return *this; } const StringPool::StyleEntry* StringPool::StyleRef::operator->() const { - return mEntry; + return entry_; } const StringPool::StyleEntry& StringPool::StyleRef::operator*() const { - return *mEntry; + return *entry_; } -size_t StringPool::StyleRef::getIndex() const { return mEntry->str.getIndex(); } +size_t StringPool::StyleRef::index() const { return entry_->str.index(); } -const StringPool::Context& StringPool::StyleRef::getContext() const { - return mEntry->str.getContext(); +const StringPool::Context& StringPool::StyleRef::GetContext() const { + return entry_->str.GetContext(); } -StringPool::Ref StringPool::makeRef(const StringPiece& str) { - return makeRefImpl(str, Context{}, true); +StringPool::Ref StringPool::MakeRef(const StringPiece& str) { + return MakeRefImpl(str, Context{}, true); } -StringPool::Ref StringPool::makeRef(const StringPiece& str, +StringPool::Ref StringPool::MakeRef(const StringPiece& str, const Context& context) { - return makeRefImpl(str, context, true); + return MakeRefImpl(str, context, true); } -StringPool::Ref StringPool::makeRefImpl(const StringPiece& str, +StringPool::Ref StringPool::MakeRefImpl(const StringPiece& str, const Context& context, bool unique) { if (unique) { - auto iter = mIndexedStrings.find(str); - if (iter != std::end(mIndexedStrings)) { + auto iter = indexed_strings_.find(str); + if (iter != std::end(indexed_strings_)) { return Ref(iter->second); } } Entry* entry = new Entry(); - entry->value = str.toString(); + entry->value = str.ToString(); entry->context = context; - entry->index = mStrings.size(); - entry->ref = 0; - mStrings.emplace_back(entry); - mIndexedStrings.insert(std::make_pair(StringPiece(entry->value), entry)); + entry->index = strings_.size(); + entry->ref_ = 0; + strings_.emplace_back(entry); + indexed_strings_.insert(std::make_pair(StringPiece(entry->value), entry)); return Ref(entry); } -StringPool::StyleRef StringPool::makeRef(const StyleString& str) { - return makeRef(str, Context{}); +StringPool::StyleRef StringPool::MakeRef(const StyleString& str) { + return MakeRef(str, Context{}); } -StringPool::StyleRef StringPool::makeRef(const StyleString& str, +StringPool::StyleRef StringPool::MakeRef(const StyleString& str, const Context& context) { Entry* entry = new Entry(); entry->value = str.str; entry->context = context; - entry->index = mStrings.size(); - entry->ref = 0; - mStrings.emplace_back(entry); - mIndexedStrings.insert(std::make_pair(StringPiece(entry->value), entry)); + entry->index = strings_.size(); + entry->ref_ = 0; + strings_.emplace_back(entry); + indexed_strings_.insert(std::make_pair(StringPiece(entry->value), entry)); - StyleEntry* styleEntry = new StyleEntry(); - styleEntry->str = Ref(entry); + StyleEntry* style_entry = new StyleEntry(); + style_entry->str = Ref(entry); for (const aapt::Span& span : str.spans) { - styleEntry->spans.emplace_back( - Span{makeRef(span.name), span.firstChar, span.lastChar}); + style_entry->spans.emplace_back( + Span{MakeRef(span.name), span.first_char, span.last_char}); } - styleEntry->ref = 0; - mStyles.emplace_back(styleEntry); - return StyleRef(styleEntry); + style_entry->ref_ = 0; + styles_.emplace_back(style_entry); + return StyleRef(style_entry); } -StringPool::StyleRef StringPool::makeRef(const StyleRef& ref) { +StringPool::StyleRef StringPool::MakeRef(const StyleRef& ref) { Entry* entry = new Entry(); - entry->value = *ref.mEntry->str; - entry->context = ref.mEntry->str.mEntry->context; - entry->index = mStrings.size(); - entry->ref = 0; - mStrings.emplace_back(entry); - mIndexedStrings.insert(std::make_pair(StringPiece(entry->value), entry)); - - StyleEntry* styleEntry = new StyleEntry(); - styleEntry->str = Ref(entry); - for (const Span& span : ref.mEntry->spans) { - styleEntry->spans.emplace_back( - Span{makeRef(*span.name), span.firstChar, span.lastChar}); + entry->value = *ref.entry_->str; + entry->context = ref.entry_->str.entry_->context; + entry->index = strings_.size(); + entry->ref_ = 0; + strings_.emplace_back(entry); + indexed_strings_.insert(std::make_pair(StringPiece(entry->value), entry)); + + StyleEntry* style_entry = new StyleEntry(); + style_entry->str = Ref(entry); + for (const Span& span : ref.entry_->spans) { + style_entry->spans.emplace_back( + Span{MakeRef(*span.name), span.first_char, span.last_char}); } - styleEntry->ref = 0; - mStyles.emplace_back(styleEntry); - return StyleRef(styleEntry); + style_entry->ref_ = 0; + styles_.emplace_back(style_entry); + return StyleRef(style_entry); } -void StringPool::merge(StringPool&& pool) { - mIndexedStrings.insert(pool.mIndexedStrings.begin(), - pool.mIndexedStrings.end()); - pool.mIndexedStrings.clear(); - std::move(pool.mStrings.begin(), pool.mStrings.end(), - std::back_inserter(mStrings)); - pool.mStrings.clear(); - std::move(pool.mStyles.begin(), pool.mStyles.end(), - std::back_inserter(mStyles)); - pool.mStyles.clear(); +void StringPool::Merge(StringPool&& pool) { + indexed_strings_.insert(pool.indexed_strings_.begin(), + pool.indexed_strings_.end()); + pool.indexed_strings_.clear(); + std::move(pool.strings_.begin(), pool.strings_.end(), + std::back_inserter(strings_)); + pool.strings_.clear(); + std::move(pool.styles_.begin(), pool.styles_.end(), + std::back_inserter(styles_)); + pool.styles_.clear(); // Assign the indices. - const size_t len = mStrings.size(); + const size_t len = strings_.size(); for (size_t index = 0; index < len; index++) { - mStrings[index]->index = index; + strings_[index]->index = index; } } -void StringPool::hintWillAdd(size_t stringCount, size_t styleCount) { - mStrings.reserve(mStrings.size() + stringCount); - mStyles.reserve(mStyles.size() + styleCount); +void StringPool::HintWillAdd(size_t stringCount, size_t styleCount) { + strings_.reserve(strings_.size() + stringCount); + styles_.reserve(styles_.size() + styleCount); } -void StringPool::prune() { - const auto iterEnd = std::end(mIndexedStrings); - auto indexIter = std::begin(mIndexedStrings); - while (indexIter != iterEnd) { - if (indexIter->second->ref <= 0) { - indexIter = mIndexedStrings.erase(indexIter); +void StringPool::Prune() { + const auto iter_end = indexed_strings_.end(); + auto index_iter = indexed_strings_.begin(); + while (index_iter != iter_end) { + if (index_iter->second->ref_ <= 0) { + index_iter = indexed_strings_.erase(index_iter); } else { - ++indexIter; + ++index_iter; } } - auto endIter2 = - std::remove_if(std::begin(mStrings), std::end(mStrings), + auto end_iter2 = + std::remove_if(strings_.begin(), strings_.end(), [](const std::unique_ptr<Entry>& entry) -> bool { - return entry->ref <= 0; + return entry->ref_ <= 0; }); - auto endIter3 = - std::remove_if(std::begin(mStyles), std::end(mStyles), + auto end_iter3 = + std::remove_if(styles_.begin(), styles_.end(), [](const std::unique_ptr<StyleEntry>& entry) -> bool { - return entry->ref <= 0; + return entry->ref_ <= 0; }); // Remove the entries at the end or else we'll be accessing // a deleted string from the StyleEntry. - mStrings.erase(endIter2, std::end(mStrings)); - mStyles.erase(endIter3, std::end(mStyles)); + strings_.erase(end_iter2, strings_.end()); + styles_.erase(end_iter3, styles_.end()); // Reassign the indices. - const size_t len = mStrings.size(); + const size_t len = strings_.size(); for (size_t index = 0; index < len; index++) { - mStrings[index]->index = index; + strings_[index]->index = index; } } -void StringPool::sort( +void StringPool::Sort( const std::function<bool(const Entry&, const Entry&)>& cmp) { std::sort( - std::begin(mStrings), std::end(mStrings), + strings_.begin(), strings_.end(), [&cmp](const std::unique_ptr<Entry>& a, const std::unique_ptr<Entry>& b) -> bool { return cmp(*a, *b); }); // Assign the indices. - const size_t len = mStrings.size(); + const size_t len = strings_.size(); for (size_t index = 0; index < len; index++) { - mStrings[index]->index = index; + strings_[index]->index = index; } // Reorder the styles. - std::sort(std::begin(mStyles), std::end(mStyles), + std::sort(styles_.begin(), styles_.end(), [](const std::unique_ptr<StyleEntry>& lhs, const std::unique_ptr<StyleEntry>& rhs) -> bool { - return lhs->str.getIndex() < rhs->str.getIndex(); + return lhs->str.index() < rhs->str.index(); }); } template <typename T> -static T* encodeLength(T* data, size_t length) { +static T* EncodeLength(T* data, size_t length) { static_assert(std::is_integral<T>::value, "wat."); constexpr size_t kMask = 1 << ((sizeof(T) * 8) - 1); @@ -284,7 +287,7 @@ static T* encodeLength(T* data, size_t length) { } template <typename T> -static size_t encodedLengthUnits(size_t length) { +static size_t EncodedLengthUnits(size_t length) { static_assert(std::is_integral<T>::value, "wat."); constexpr size_t kMask = 1 << ((sizeof(T) * 8) - 1); @@ -292,10 +295,10 @@ static size_t encodedLengthUnits(size_t length) { return length > kMaxSize ? 2 : 1; } -bool StringPool::flatten(BigBuffer* out, const StringPool& pool, bool utf8) { - const size_t startIndex = out->size(); +bool StringPool::Flatten(BigBuffer* out, const StringPool& pool, bool utf8) { + const size_t start_index = out->size(); android::ResStringPool_header* header = - out->nextBlock<android::ResStringPool_header>(); + out->NextBlock<android::ResStringPool_header>(); header->header.type = android::RES_STRING_POOL_TYPE; header->header.headerSize = sizeof(*header); header->stringCount = pool.size(); @@ -304,92 +307,90 @@ bool StringPool::flatten(BigBuffer* out, const StringPool& pool, bool utf8) { } uint32_t* indices = - pool.size() != 0 ? out->nextBlock<uint32_t>(pool.size()) : nullptr; + pool.size() != 0 ? out->NextBlock<uint32_t>(pool.size()) : nullptr; - uint32_t* styleIndices = nullptr; - if (!pool.mStyles.empty()) { - header->styleCount = pool.mStyles.back()->str.getIndex() + 1; - styleIndices = out->nextBlock<uint32_t>(header->styleCount); + uint32_t* style_indices = nullptr; + if (!pool.styles_.empty()) { + header->styleCount = pool.styles_.back()->str.index() + 1; + style_indices = out->NextBlock<uint32_t>(header->styleCount); } - const size_t beforeStringsIndex = out->size(); - header->stringsStart = beforeStringsIndex - startIndex; + const size_t before_strings_index = out->size(); + header->stringsStart = before_strings_index - start_index; for (const auto& entry : pool) { - *indices = out->size() - beforeStringsIndex; + *indices = out->size() - before_strings_index; indices++; if (utf8) { const std::string& encoded = entry->value; - const ssize_t utf16Length = utf8_to_utf16_length( + const ssize_t utf16_length = utf8_to_utf16_length( reinterpret_cast<const uint8_t*>(entry->value.data()), entry->value.size()); - assert(utf16Length >= 0); + CHECK(utf16_length >= 0); - const size_t totalSize = encodedLengthUnits<char>(utf16Length) + - encodedLengthUnits<char>(encoded.length()) + - encoded.size() + 1; + const size_t total_size = EncodedLengthUnits<char>(utf16_length) + + EncodedLengthUnits<char>(encoded.length()) + + encoded.size() + 1; - char* data = out->nextBlock<char>(totalSize); + char* data = out->NextBlock<char>(total_size); // First encode the UTF16 string length. - data = encodeLength(data, utf16Length); + data = EncodeLength(data, utf16_length); // Now encode the size of the real UTF8 string. - data = encodeLength(data, encoded.length()); + data = EncodeLength(data, encoded.length()); strncpy(data, encoded.data(), encoded.size()); } else { - const std::u16string encoded = util::utf8ToUtf16(entry->value); - const ssize_t utf16Length = encoded.size(); + const std::u16string encoded = util::Utf8ToUtf16(entry->value); + const ssize_t utf16_length = encoded.size(); // Total number of 16-bit words to write. - const size_t totalSize = - encodedLengthUnits<char16_t>(utf16Length) + encoded.size() + 1; + const size_t total_size = + EncodedLengthUnits<char16_t>(utf16_length) + encoded.size() + 1; - char16_t* data = out->nextBlock<char16_t>(totalSize); + char16_t* data = out->NextBlock<char16_t>(total_size); // Encode the actual UTF16 string length. - data = encodeLength(data, utf16Length); - const size_t byteLength = encoded.size() * sizeof(char16_t); + data = EncodeLength(data, utf16_length); + const size_t byte_length = encoded.size() * sizeof(char16_t); // NOTE: For some reason, strncpy16(data, entry->value.data(), - // entry->value.size()) - // truncates the string. - memcpy(data, encoded.data(), byteLength); + // entry->value.size()) truncates the string. + memcpy(data, encoded.data(), byte_length); // The null-terminating character is already here due to the block of data - // being set - // to 0s on allocation. + // being set to 0s on allocation. } } - out->align4(); + out->Align4(); - if (!pool.mStyles.empty()) { - const size_t beforeStylesIndex = out->size(); - header->stylesStart = beforeStylesIndex - startIndex; + if (!pool.styles_.empty()) { + const size_t before_styles_index = out->size(); + header->stylesStart = before_styles_index - start_index; - size_t currentIndex = 0; - for (const auto& entry : pool.mStyles) { - while (entry->str.getIndex() > currentIndex) { - styleIndices[currentIndex++] = out->size() - beforeStylesIndex; + size_t current_index = 0; + for (const auto& entry : pool.styles_) { + while (entry->str.index() > current_index) { + style_indices[current_index++] = out->size() - before_styles_index; - uint32_t* spanOffset = out->nextBlock<uint32_t>(); - *spanOffset = android::ResStringPool_span::END; + uint32_t* span_offset = out->NextBlock<uint32_t>(); + *span_offset = android::ResStringPool_span::END; } - styleIndices[currentIndex++] = out->size() - beforeStylesIndex; + style_indices[current_index++] = out->size() - before_styles_index; android::ResStringPool_span* span = - out->nextBlock<android::ResStringPool_span>(entry->spans.size()); + out->NextBlock<android::ResStringPool_span>(entry->spans.size()); for (const auto& s : entry->spans) { - span->name.index = s.name.getIndex(); - span->firstChar = s.firstChar; - span->lastChar = s.lastChar; + span->name.index = s.name.index(); + span->firstChar = s.first_char; + span->lastChar = s.last_char; span++; } - uint32_t* spanEnd = out->nextBlock<uint32_t>(); + uint32_t* spanEnd = out->NextBlock<uint32_t>(); *spanEnd = android::ResStringPool_span::END; } @@ -397,22 +398,22 @@ bool StringPool::flatten(BigBuffer* out, const StringPool& pool, bool utf8) { // ResStringPool_span structure worth of 0xFFFFFFFF at the end // of the style block, so fill in the remaining 2 32bit words // with 0xFFFFFFFF. - const size_t paddingLength = sizeof(android::ResStringPool_span) - - sizeof(android::ResStringPool_span::name); - uint8_t* padding = out->nextBlock<uint8_t>(paddingLength); - memset(padding, 0xff, paddingLength); - out->align4(); + const size_t padding_length = sizeof(android::ResStringPool_span) - + sizeof(android::ResStringPool_span::name); + uint8_t* padding = out->NextBlock<uint8_t>(padding_length); + memset(padding, 0xff, padding_length); + out->Align4(); } - header->header.size = out->size() - startIndex; + header->header.size = out->size() - start_index; return true; } -bool StringPool::flattenUtf8(BigBuffer* out, const StringPool& pool) { - return flatten(out, pool, true); +bool StringPool::FlattenUtf8(BigBuffer* out, const StringPool& pool) { + return Flatten(out, pool, true); } -bool StringPool::flattenUtf16(BigBuffer* out, const StringPool& pool) { - return flatten(out, pool, false); +bool StringPool::FlattenUtf16(BigBuffer* out, const StringPool& pool) { + return Flatten(out, pool, false); } } // namespace aapt diff --git a/tools/aapt2/StringPool.h b/tools/aapt2/StringPool.h index 6e0d646cae12..a4f556ca52e4 100644 --- a/tools/aapt2/StringPool.h +++ b/tools/aapt2/StringPool.h @@ -17,22 +17,22 @@ #ifndef AAPT_STRING_POOL_H #define AAPT_STRING_POOL_H -#include "ConfigDescription.h" -#include "util/BigBuffer.h" -#include "util/StringPiece.h" - #include <functional> #include <memory> #include <string> #include <unordered_map> #include <vector> +#include "ConfigDescription.h" +#include "util/BigBuffer.h" +#include "util/StringPiece.h" + namespace aapt { struct Span { std::string name; - uint32_t firstChar; - uint32_t lastChar; + uint32_t first_char; + uint32_t last_char; }; struct StyleString { @@ -72,15 +72,15 @@ class StringPool { const std::string* operator->() const; const std::string& operator*() const; - size_t getIndex() const; - const Context& getContext() const; + size_t index() const; + const Context& GetContext() const; private: friend class StringPool; explicit Ref(Entry* entry); - Entry* mEntry; + Entry* entry_; }; class StyleEntry; @@ -95,15 +95,15 @@ class StringPool { const StyleEntry* operator->() const; const StyleEntry& operator*() const; - size_t getIndex() const; - const Context& getContext() const; + size_t index() const; + const Context& GetContext() const; private: friend class StringPool; explicit StyleRef(StyleEntry* entry); - StyleEntry* mEntry; + StyleEntry* entry_; }; class Entry { @@ -116,13 +116,13 @@ class StringPool { friend class StringPool; friend class Ref; - int ref; + int ref_; }; struct Span { Ref name; - uint32_t firstChar; - uint32_t lastChar; + uint32_t first_char; + uint32_t last_char; }; class StyleEntry { @@ -134,13 +134,13 @@ class StringPool { friend class StringPool; friend class StyleRef; - int ref; + int ref_; }; using const_iterator = std::vector<std::unique_ptr<Entry>>::const_iterator; - static bool flattenUtf8(BigBuffer* out, const StringPool& pool); - static bool flattenUtf16(BigBuffer* out, const StringPool& pool); + static bool FlattenUtf8(BigBuffer* out, const StringPool& pool); + static bool FlattenUtf16(BigBuffer* out, const StringPool& pool); StringPool() = default; StringPool(const StringPool&) = delete; @@ -149,84 +149,84 @@ class StringPool { * Adds a string to the pool, unless it already exists. Returns * a reference to the string in the pool. */ - Ref makeRef(const StringPiece& str); + Ref MakeRef(const StringPiece& str); /** * Adds a string to the pool, unless it already exists, with a context * object that can be used when sorting the string pool. Returns * a reference to the string in the pool. */ - Ref makeRef(const StringPiece& str, const Context& context); + Ref MakeRef(const StringPiece& str, const Context& context); /** * Adds a style to the string pool and returns a reference to it. */ - StyleRef makeRef(const StyleString& str); + StyleRef MakeRef(const StyleString& str); /** * Adds a style to the string pool with a context object that * can be used when sorting the string pool. Returns a reference * to the style in the string pool. */ - StyleRef makeRef(const StyleString& str, const Context& context); + StyleRef MakeRef(const StyleString& str, const Context& context); /** * Adds a style from another string pool. Returns a reference to the * style in the string pool. */ - StyleRef makeRef(const StyleRef& ref); + StyleRef MakeRef(const StyleRef& ref); /** * Moves pool into this one without coalescing strings. When this * function returns, pool will be empty. */ - void merge(StringPool&& pool); + void Merge(StringPool&& pool); /** - * Retuns the number of strings in the table. + * Returns the number of strings in the table. */ inline size_t size() const; /** * Reserves space for strings and styles as an optimization. */ - void hintWillAdd(size_t stringCount, size_t styleCount); + void HintWillAdd(size_t string_count, size_t style_count); /** * Sorts the strings according to some comparison function. */ - void sort(const std::function<bool(const Entry&, const Entry&)>& cmp); + void Sort(const std::function<bool(const Entry&, const Entry&)>& cmp); /** * Removes any strings that have no references. */ - void prune(); + void Prune(); private: friend const_iterator begin(const StringPool& pool); friend const_iterator end(const StringPool& pool); - static bool flatten(BigBuffer* out, const StringPool& pool, bool utf8); + static bool Flatten(BigBuffer* out, const StringPool& pool, bool utf8); - Ref makeRefImpl(const StringPiece& str, const Context& context, bool unique); + Ref MakeRefImpl(const StringPiece& str, const Context& context, bool unique); - std::vector<std::unique_ptr<Entry>> mStrings; - std::vector<std::unique_ptr<StyleEntry>> mStyles; - std::unordered_multimap<StringPiece, Entry*> mIndexedStrings; + std::vector<std::unique_ptr<Entry>> strings_; + std::vector<std::unique_ptr<StyleEntry>> styles_; + std::unordered_multimap<StringPiece, Entry*> indexed_strings_; }; // // Inline implementation // -inline size_t StringPool::size() const { return mStrings.size(); } +inline size_t StringPool::size() const { return strings_.size(); } inline StringPool::const_iterator begin(const StringPool& pool) { - return pool.mStrings.begin(); + return pool.strings_.begin(); } inline StringPool::const_iterator end(const StringPool& pool) { - return pool.mStrings.end(); + return pool.strings_.end(); } } // namespace aapt diff --git a/tools/aapt2/StringPool_test.cpp b/tools/aapt2/StringPool_test.cpp index 2a7e1dd6a231..e1394fc0221f 100644 --- a/tools/aapt2/StringPool_test.cpp +++ b/tools/aapt2/StringPool_test.cpp @@ -15,25 +15,26 @@ */ #include "StringPool.h" -#include "test/Test.h" -#include "util/Util.h" #include <string> +#include "test/Test.h" +#include "util/Util.h" + namespace aapt { TEST(StringPoolTest, InsertOneString) { StringPool pool; - StringPool::Ref ref = pool.makeRef("wut"); + StringPool::Ref ref = pool.MakeRef("wut"); EXPECT_EQ(*ref, "wut"); } TEST(StringPoolTest, InsertTwoUniqueStrings) { StringPool pool; - StringPool::Ref ref = pool.makeRef("wut"); - StringPool::Ref ref2 = pool.makeRef("hey"); + StringPool::Ref ref = pool.MakeRef("wut"); + StringPool::Ref ref2 = pool.MakeRef("hey"); EXPECT_EQ(*ref, "wut"); EXPECT_EQ(*ref2, "hey"); @@ -42,8 +43,8 @@ TEST(StringPoolTest, InsertTwoUniqueStrings) { TEST(StringPoolTest, DoNotInsertNewDuplicateString) { StringPool pool; - StringPool::Ref ref = pool.makeRef("wut"); - StringPool::Ref ref2 = pool.makeRef("wut"); + StringPool::Ref ref = pool.MakeRef("wut"); + StringPool::Ref ref2 = pool.MakeRef("wut"); EXPECT_EQ(*ref, "wut"); EXPECT_EQ(*ref2, "wut"); @@ -53,28 +54,28 @@ TEST(StringPoolTest, DoNotInsertNewDuplicateString) { TEST(StringPoolTest, MaintainInsertionOrderIndex) { StringPool pool; - StringPool::Ref ref = pool.makeRef("z"); - StringPool::Ref ref2 = pool.makeRef("a"); - StringPool::Ref ref3 = pool.makeRef("m"); + StringPool::Ref ref = pool.MakeRef("z"); + StringPool::Ref ref2 = pool.MakeRef("a"); + StringPool::Ref ref3 = pool.MakeRef("m"); - EXPECT_EQ(0u, ref.getIndex()); - EXPECT_EQ(1u, ref2.getIndex()); - EXPECT_EQ(2u, ref3.getIndex()); + EXPECT_EQ(0u, ref.index()); + EXPECT_EQ(1u, ref2.index()); + EXPECT_EQ(2u, ref3.index()); } TEST(StringPoolTest, PruneStringsWithNoReferences) { StringPool pool; - StringPool::Ref refA = pool.makeRef("foo"); + StringPool::Ref refA = pool.MakeRef("foo"); { - StringPool::Ref ref = pool.makeRef("wut"); + StringPool::Ref ref = pool.MakeRef("wut"); EXPECT_EQ(*ref, "wut"); EXPECT_EQ(2u, pool.size()); } - StringPool::Ref refB = pool.makeRef("bar"); + StringPool::Ref refB = pool.MakeRef("bar"); EXPECT_EQ(3u, pool.size()); - pool.prune(); + pool.Prune(); EXPECT_EQ(2u, pool.size()); StringPool::const_iterator iter = begin(pool); EXPECT_EQ((*iter)->value, "foo"); @@ -87,51 +88,51 @@ TEST(StringPoolTest, PruneStringsWithNoReferences) { TEST(StringPoolTest, SortAndMaintainIndexesInReferences) { StringPool pool; - StringPool::Ref ref = pool.makeRef("z"); - StringPool::StyleRef ref2 = pool.makeRef(StyleString{{"a"}}); - StringPool::Ref ref3 = pool.makeRef("m"); + StringPool::Ref ref = pool.MakeRef("z"); + StringPool::StyleRef ref2 = pool.MakeRef(StyleString{{"a"}}); + StringPool::Ref ref3 = pool.MakeRef("m"); EXPECT_EQ(*ref, "z"); - EXPECT_EQ(0u, ref.getIndex()); + EXPECT_EQ(0u, ref.index()); EXPECT_EQ(*(ref2->str), "a"); - EXPECT_EQ(1u, ref2.getIndex()); + EXPECT_EQ(1u, ref2.index()); EXPECT_EQ(*ref3, "m"); - EXPECT_EQ(2u, ref3.getIndex()); + EXPECT_EQ(2u, ref3.index()); - pool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { + pool.Sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { return a.value < b.value; }); EXPECT_EQ(*ref, "z"); - EXPECT_EQ(2u, ref.getIndex()); + EXPECT_EQ(2u, ref.index()); EXPECT_EQ(*(ref2->str), "a"); - EXPECT_EQ(0u, ref2.getIndex()); + EXPECT_EQ(0u, ref2.index()); EXPECT_EQ(*ref3, "m"); - EXPECT_EQ(1u, ref3.getIndex()); + EXPECT_EQ(1u, ref3.index()); } TEST(StringPoolTest, SortAndStillDedupe) { StringPool pool; - StringPool::Ref ref = pool.makeRef("z"); - StringPool::Ref ref2 = pool.makeRef("a"); - StringPool::Ref ref3 = pool.makeRef("m"); + StringPool::Ref ref = pool.MakeRef("z"); + StringPool::Ref ref2 = pool.MakeRef("a"); + StringPool::Ref ref3 = pool.MakeRef("m"); - pool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { + pool.Sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { return a.value < b.value; }); - StringPool::Ref ref4 = pool.makeRef("z"); - StringPool::Ref ref5 = pool.makeRef("a"); - StringPool::Ref ref6 = pool.makeRef("m"); + StringPool::Ref ref4 = pool.MakeRef("z"); + StringPool::Ref ref5 = pool.MakeRef("a"); + StringPool::Ref ref6 = pool.MakeRef("m"); - EXPECT_EQ(ref4.getIndex(), ref.getIndex()); - EXPECT_EQ(ref5.getIndex(), ref2.getIndex()); - EXPECT_EQ(ref6.getIndex(), ref3.getIndex()); + EXPECT_EQ(ref4.index(), ref.index()); + EXPECT_EQ(ref5.index(), ref2.index()); + EXPECT_EQ(ref6.index(), ref3.index()); } TEST(StringPoolTest, AddStyles) { @@ -139,27 +140,27 @@ TEST(StringPoolTest, AddStyles) { StyleString str{{"android"}, {Span{{"b"}, 2, 6}}}; - StringPool::StyleRef ref = pool.makeRef(str); + StringPool::StyleRef ref = pool.MakeRef(str); - EXPECT_EQ(0u, ref.getIndex()); + EXPECT_EQ(0u, ref.index()); EXPECT_EQ(std::string("android"), *(ref->str)); ASSERT_EQ(1u, ref->spans.size()); const StringPool::Span& span = ref->spans.front(); EXPECT_EQ(*(span.name), "b"); - EXPECT_EQ(2u, span.firstChar); - EXPECT_EQ(6u, span.lastChar); + EXPECT_EQ(2u, span.first_char); + EXPECT_EQ(6u, span.last_char); } TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) { StringPool pool; - StringPool::Ref ref = pool.makeRef("android"); + StringPool::Ref ref = pool.MakeRef("android"); StyleString str{{"android"}}; - StringPool::StyleRef styleRef = pool.makeRef(str); + StringPool::StyleRef styleRef = pool.MakeRef(str); - EXPECT_NE(ref.getIndex(), styleRef.getIndex()); + EXPECT_NE(ref.index(), styleRef.index()); } TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) { @@ -167,9 +168,9 @@ TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) { StringPool pool; BigBuffer buffer(1024); - StringPool::flattenUtf8(&buffer, pool); + StringPool::FlattenUtf8(&buffer, pool); - std::unique_ptr<uint8_t[]> data = util::copy(buffer); + std::unique_ptr<uint8_t[]> data = util::Copy(buffer); ResStringPool test; ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR); } @@ -178,11 +179,11 @@ TEST(StringPoolTest, FlattenOddCharactersUtf16) { using namespace android; // For NO_ERROR on Windows. StringPool pool; - pool.makeRef("\u093f"); + pool.MakeRef("\u093f"); BigBuffer buffer(1024); - StringPool::flattenUtf16(&buffer, pool); + StringPool::FlattenUtf16(&buffer, pool); - std::unique_ptr<uint8_t[]> data = util::copy(buffer); + std::unique_ptr<uint8_t[]> data = util::Copy(buffer); ResStringPool test; ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR); size_t len = 0; @@ -204,58 +205,58 @@ TEST(StringPoolTest, Flatten) { StringPool pool; - StringPool::Ref ref1 = pool.makeRef("hello"); - StringPool::Ref ref2 = pool.makeRef("goodbye"); - StringPool::Ref ref3 = pool.makeRef(sLongString); - StringPool::Ref ref4 = pool.makeRef(""); - StringPool::StyleRef ref5 = pool.makeRef( + StringPool::Ref ref1 = pool.MakeRef("hello"); + StringPool::Ref ref2 = pool.MakeRef("goodbye"); + StringPool::Ref ref3 = pool.MakeRef(sLongString); + StringPool::Ref ref4 = pool.MakeRef(""); + StringPool::StyleRef ref5 = pool.MakeRef( StyleString{{"style"}, {Span{{"b"}, 0, 1}, Span{{"i"}, 2, 3}}}); - EXPECT_EQ(0u, ref1.getIndex()); - EXPECT_EQ(1u, ref2.getIndex()); - EXPECT_EQ(2u, ref3.getIndex()); - EXPECT_EQ(3u, ref4.getIndex()); - EXPECT_EQ(4u, ref5.getIndex()); + EXPECT_EQ(0u, ref1.index()); + EXPECT_EQ(1u, ref2.index()); + EXPECT_EQ(2u, ref3.index()); + EXPECT_EQ(3u, ref4.index()); + EXPECT_EQ(4u, ref5.index()); BigBuffer buffers[2] = {BigBuffer(1024), BigBuffer(1024)}; - StringPool::flattenUtf8(&buffers[0], pool); - StringPool::flattenUtf16(&buffers[1], pool); + StringPool::FlattenUtf8(&buffers[0], pool); + StringPool::FlattenUtf16(&buffers[1], pool); // Test both UTF-8 and UTF-16 buffers. for (const BigBuffer& buffer : buffers) { - std::unique_ptr<uint8_t[]> data = util::copy(buffer); + std::unique_ptr<uint8_t[]> data = util::Copy(buffer); ResStringPool test; ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR); - EXPECT_EQ(std::string("hello"), util::getString(test, 0)); - EXPECT_EQ(StringPiece16(u"hello"), util::getString16(test, 0)); + EXPECT_EQ(std::string("hello"), util::GetString(test, 0)); + EXPECT_EQ(StringPiece16(u"hello"), util::GetString16(test, 0)); - EXPECT_EQ(std::string("goodbye"), util::getString(test, 1)); - EXPECT_EQ(StringPiece16(u"goodbye"), util::getString16(test, 1)); + EXPECT_EQ(std::string("goodbye"), util::GetString(test, 1)); + EXPECT_EQ(StringPiece16(u"goodbye"), util::GetString16(test, 1)); - EXPECT_EQ(StringPiece(sLongString), util::getString(test, 2)); - EXPECT_EQ(util::utf8ToUtf16(sLongString), - util::getString16(test, 2).toString()); + EXPECT_EQ(StringPiece(sLongString), util::GetString(test, 2)); + EXPECT_EQ(util::Utf8ToUtf16(sLongString), + util::GetString16(test, 2).ToString()); size_t len; EXPECT_TRUE(test.stringAt(3, &len) != nullptr || test.string8At(3, &len) != nullptr); - EXPECT_EQ(std::string("style"), util::getString(test, 4)); - EXPECT_EQ(StringPiece16(u"style"), util::getString16(test, 4)); + EXPECT_EQ(std::string("style"), util::GetString(test, 4)); + EXPECT_EQ(StringPiece16(u"style"), util::GetString16(test, 4)); const ResStringPool_span* span = test.styleAt(4); ASSERT_NE(nullptr, span); - EXPECT_EQ(std::string("b"), util::getString(test, span->name.index)); - EXPECT_EQ(StringPiece16(u"b"), util::getString16(test, span->name.index)); + EXPECT_EQ(std::string("b"), util::GetString(test, span->name.index)); + EXPECT_EQ(StringPiece16(u"b"), util::GetString16(test, span->name.index)); EXPECT_EQ(0u, span->firstChar); EXPECT_EQ(1u, span->lastChar); span++; ASSERT_NE(ResStringPool_span::END, span->name.index); - EXPECT_EQ(std::string("i"), util::getString(test, span->name.index)); - EXPECT_EQ(StringPiece16(u"i"), util::getString16(test, span->name.index)); + EXPECT_EQ(std::string("i"), util::GetString(test, span->name.index)); + EXPECT_EQ(StringPiece16(u"i"), util::GetString16(test, span->name.index)); EXPECT_EQ(2u, span->firstChar); EXPECT_EQ(3u, span->lastChar); span++; diff --git a/tools/aapt2/ValueVisitor.h b/tools/aapt2/ValueVisitor.h index 121c33709eef..1cb6aa13f336 100644 --- a/tools/aapt2/ValueVisitor.h +++ b/tools/aapt2/ValueVisitor.h @@ -24,32 +24,31 @@ namespace aapt { /** * Visits a value and invokes the appropriate method based on its type. Does not - * traverse - * into compound types. Use ValueVisitor for that. + * traverse into compound types. Use ValueVisitor for that. */ struct RawValueVisitor { virtual ~RawValueVisitor() = default; - virtual void visitItem(Item* value) {} - virtual void visit(Reference* value) { visitItem(value); } - virtual void visit(RawString* value) { visitItem(value); } - virtual void visit(String* value) { visitItem(value); } - virtual void visit(StyledString* value) { visitItem(value); } - virtual void visit(FileReference* value) { visitItem(value); } - virtual void visit(Id* value) { visitItem(value); } - virtual void visit(BinaryPrimitive* value) { visitItem(value); } - - virtual void visit(Attribute* value) {} - virtual void visit(Style* value) {} - virtual void visit(Array* value) {} - virtual void visit(Plural* value) {} - virtual void visit(Styleable* value) {} + virtual void VisitItem(Item* value) {} + virtual void Visit(Reference* value) { VisitItem(value); } + virtual void Visit(RawString* value) { VisitItem(value); } + virtual void Visit(String* value) { VisitItem(value); } + virtual void Visit(StyledString* value) { VisitItem(value); } + virtual void Visit(FileReference* value) { VisitItem(value); } + virtual void Visit(Id* value) { VisitItem(value); } + virtual void Visit(BinaryPrimitive* value) { VisitItem(value); } + + virtual void Visit(Attribute* value) {} + virtual void Visit(Style* value) {} + virtual void Visit(Array* value) {} + virtual void Visit(Plural* value) {} + virtual void Visit(Styleable* value) {} }; // NOLINT, do not add parentheses around T. -#define DECL_VISIT_COMPOUND_VALUE(T) \ - virtual void visit(T* value) { /* NOLINT */ \ - visitSubValues(value); \ +#define DECL_VISIT_COMPOUND_VALUE(T) \ + virtual void Visit(T* value) override { /* NOLINT */ \ + VisitSubValues(value); \ } /** @@ -59,44 +58,43 @@ struct RawValueVisitor { struct ValueVisitor : public RawValueVisitor { // The compiler will think we're hiding an overload, when we actually intend // to call into RawValueVisitor. This will expose the visit methods in the - // super - // class so the compiler knows we are trying to call them. - using RawValueVisitor::visit; + // super class so the compiler knows we are trying to call them. + using RawValueVisitor::Visit; - void visitSubValues(Attribute* attribute) { + void VisitSubValues(Attribute* attribute) { for (Attribute::Symbol& symbol : attribute->symbols) { - visit(&symbol.symbol); + Visit(&symbol.symbol); } } - void visitSubValues(Style* style) { + void VisitSubValues(Style* style) { if (style->parent) { - visit(&style->parent.value()); + Visit(&style->parent.value()); } for (Style::Entry& entry : style->entries) { - visit(&entry.key); - entry.value->accept(this); + Visit(&entry.key); + entry.value->Accept(this); } } - void visitSubValues(Array* array) { + void VisitSubValues(Array* array) { for (std::unique_ptr<Item>& item : array->items) { - item->accept(this); + item->Accept(this); } } - void visitSubValues(Plural* plural) { + void VisitSubValues(Plural* plural) { for (std::unique_ptr<Item>& item : plural->values) { if (item) { - item->accept(this); + item->Accept(this); } } } - void visitSubValues(Styleable* styleable) { + void VisitSubValues(Styleable* styleable) { for (Reference& reference : styleable->entries) { - visit(&reference); + Visit(&reference); } } @@ -114,7 +112,7 @@ template <typename T> struct DynCastVisitor : public RawValueVisitor { T* value = nullptr; - void visit(T* v) override { value = v; } + void Visit(T* v) override { value = v; } }; /** @@ -124,12 +122,12 @@ template <> struct DynCastVisitor<Item> : public RawValueVisitor { Item* value = nullptr; - void visitItem(Item* item) override { value = item; } + void VisitItem(Item* item) override { value = item; } }; template <typename T> -const T* valueCast(const Value* value) { - return valueCast<T>(const_cast<Value*>(value)); +const T* ValueCast(const Value* value) { + return ValueCast<T>(const_cast<Value*>(value)); } /** @@ -137,30 +135,30 @@ const T* valueCast(const Value* value) { * Otherwise, returns nullptr. */ template <typename T> -T* valueCast(Value* value) { +T* ValueCast(Value* value) { if (!value) { return nullptr; } DynCastVisitor<T> visitor; - value->accept(&visitor); + value->Accept(&visitor); return visitor.value; } -inline void visitAllValuesInPackage(ResourceTablePackage* pkg, +inline void VisitAllValuesInPackage(ResourceTablePackage* pkg, RawValueVisitor* visitor) { for (auto& type : pkg->types) { for (auto& entry : type->entries) { - for (auto& configValue : entry->values) { - configValue->value->accept(visitor); + for (auto& config_value : entry->values) { + config_value->value->Accept(visitor); } } } } -inline void visitAllValuesInTable(ResourceTable* table, +inline void VisitAllValuesInTable(ResourceTable* table, RawValueVisitor* visitor) { for (auto& pkg : table->packages) { - visitAllValuesInPackage(pkg.get(), visitor); + VisitAllValuesInPackage(pkg.get(), visitor); } } diff --git a/tools/aapt2/ValueVisitor_test.cpp b/tools/aapt2/ValueVisitor_test.cpp index ed9c7f6c8050..eb75b102e427 100644 --- a/tools/aapt2/ValueVisitor_test.cpp +++ b/tools/aapt2/ValueVisitor_test.cpp @@ -15,40 +15,41 @@ */ #include "ValueVisitor.h" + +#include <string> + #include "ResourceValues.h" #include "test/Test.h" #include "util/Util.h" -#include <string> - namespace aapt { struct SingleReferenceVisitor : public ValueVisitor { - using ValueVisitor::visit; + using ValueVisitor::Visit; Reference* visited = nullptr; - void visit(Reference* ref) override { visited = ref; } + void Visit(Reference* ref) override { visited = ref; } }; struct StyleVisitor : public ValueVisitor { - using ValueVisitor::visit; + using ValueVisitor::Visit; - std::list<Reference*> visitedRefs; - Style* visitedStyle = nullptr; + std::list<Reference*> visited_refs; + Style* visited_style = nullptr; - void visit(Reference* ref) override { visitedRefs.push_back(ref); } + void Visit(Reference* ref) override { visited_refs.push_back(ref); } - void visit(Style* style) override { - visitedStyle = style; - ValueVisitor::visit(style); + void Visit(Style* style) override { + visited_style = style; + ValueVisitor::Visit(style); } }; TEST(ValueVisitorTest, VisitsReference) { Reference ref(ResourceName{"android", ResourceType::kAttr, "foo"}); SingleReferenceVisitor visitor; - ref.accept(&visitor); + ref.Accept(&visitor); EXPECT_EQ(visitor.visited, &ref); } @@ -56,31 +57,31 @@ TEST(ValueVisitorTest, VisitsReference) { TEST(ValueVisitorTest, VisitsReferencesInStyle) { std::unique_ptr<Style> style = test::StyleBuilder() - .setParent("android:style/foo") - .addItem("android:attr/one", test::buildReference("android:id/foo")) - .build(); + .SetParent("android:style/foo") + .AddItem("android:attr/one", test::BuildReference("android:id/foo")) + .Build(); StyleVisitor visitor; - style->accept(&visitor); + style->Accept(&visitor); - ASSERT_EQ(style.get(), visitor.visitedStyle); + ASSERT_EQ(style.get(), visitor.visited_style); // Entry attribute references, plus the parent reference, plus one value // reference. - ASSERT_EQ(style->entries.size() + 2, visitor.visitedRefs.size()); + ASSERT_EQ(style->entries.size() + 2, visitor.visited_refs.size()); } TEST(ValueVisitorTest, ValueCast) { - std::unique_ptr<Reference> ref = test::buildReference("android:color/white"); - EXPECT_NE(valueCast<Reference>(ref.get()), nullptr); + std::unique_ptr<Reference> ref = test::BuildReference("android:color/white"); + EXPECT_NE(ValueCast<Reference>(ref.get()), nullptr); std::unique_ptr<Style> style = test::StyleBuilder() - .addItem("android:attr/foo", - test::buildReference("android:color/black")) - .build(); - EXPECT_NE(valueCast<Style>(style.get()), nullptr); - EXPECT_EQ(valueCast<Reference>(style.get()), nullptr); + .AddItem("android:attr/foo", + test::BuildReference("android:color/black")) + .Build(); + EXPECT_NE(ValueCast<Style>(style.get()), nullptr); + EXPECT_EQ(ValueCast<Reference>(style.get()), nullptr); } } // namespace aapt diff --git a/tools/aapt2/compile/Compile.cpp b/tools/aapt2/compile/Compile.cpp index 2ea63d02b754..a06140cff542 100644 --- a/tools/aapt2/compile/Compile.cpp +++ b/tools/aapt2/compile/Compile.cpp @@ -14,6 +14,11 @@ * limitations under the License. */ +#include <dirent.h> + +#include <fstream> +#include <string> + #include "ConfigDescription.h" #include "Diagnostics.h" #include "Flags.h" @@ -33,14 +38,10 @@ #include "xml/XmlDom.h" #include "xml/XmlPullParser.h" -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl_lite.h> - -#include <android-base/errors.h> -#include <android-base/file.h> -#include <dirent.h> -#include <fstream> -#include <string> +#include "android-base/errors.h" +#include "android-base/file.h" +#include "google/protobuf/io/coded_stream.h" +#include "google/protobuf/io/zero_copy_stream_impl_lite.h" using google::protobuf::io::CopyingOutputStreamAdaptor; using google::protobuf::io::ZeroCopyOutputStream; @@ -49,7 +50,7 @@ namespace aapt { struct ResourcePathData { Source source; - std::string resourceDir; + std::string resource_dir; std::string name; std::string extension; @@ -58,7 +59,7 @@ struct ResourcePathData { // version qualifiers. We want to preserve the original input so the output is // easily // computed before hand. - std::string configStr; + std::string config_str; ConfigDescription config; }; @@ -66,60 +67,60 @@ struct ResourcePathData { * Resource file paths are expected to look like: * [--/res/]type[-config]/name */ -static Maybe<ResourcePathData> extractResourcePathData(const std::string& path, - std::string* outError) { - std::vector<std::string> parts = util::split(path, file::sDirSep); +static Maybe<ResourcePathData> ExtractResourcePathData(const std::string& path, + std::string* out_error) { + std::vector<std::string> parts = util::Split(path, file::sDirSep); if (parts.size() < 2) { - if (outError) *outError = "bad resource path"; + if (out_error) *out_error = "bad resource path"; return {}; } std::string& dir = parts[parts.size() - 2]; - StringPiece dirStr = dir; + StringPiece dir_str = dir; - StringPiece configStr; + StringPiece config_str; ConfigDescription config; - size_t dashPos = dir.find('-'); - if (dashPos != std::string::npos) { - configStr = dirStr.substr(dashPos + 1, dir.size() - (dashPos + 1)); - if (!ConfigDescription::parse(configStr, &config)) { - if (outError) { - std::stringstream errStr; - errStr << "invalid configuration '" << configStr << "'"; - *outError = errStr.str(); + size_t dash_pos = dir.find('-'); + if (dash_pos != std::string::npos) { + config_str = dir_str.substr(dash_pos + 1, dir.size() - (dash_pos + 1)); + if (!ConfigDescription::Parse(config_str, &config)) { + if (out_error) { + std::stringstream err_str; + err_str << "invalid configuration '" << config_str << "'"; + *out_error = err_str.str(); } return {}; } - dirStr = dirStr.substr(0, dashPos); + dir_str = dir_str.substr(0, dash_pos); } std::string& filename = parts[parts.size() - 1]; StringPiece name = filename; StringPiece extension; - size_t dotPos = filename.find('.'); - if (dotPos != std::string::npos) { - extension = name.substr(dotPos + 1, filename.size() - (dotPos + 1)); - name = name.substr(0, dotPos); + size_t dot_pos = filename.find('.'); + if (dot_pos != std::string::npos) { + extension = name.substr(dot_pos + 1, filename.size() - (dot_pos + 1)); + name = name.substr(0, dot_pos); } - return ResourcePathData{Source(path), dirStr.toString(), - name.toString(), extension.toString(), - configStr.toString(), config}; + return ResourcePathData{Source(path), dir_str.ToString(), + name.ToString(), extension.ToString(), + config_str.ToString(), config}; } struct CompileOptions { - std::string outputPath; - Maybe<std::string> resDir; + std::string output_path; + Maybe<std::string> res_dir; bool pseudolocalize = false; - bool legacyMode = false; + bool legacy_mode = false; bool verbose = false; }; -static std::string buildIntermediateFilename(const ResourcePathData& data) { +static std::string BuildIntermediateFilename(const ResourcePathData& data) { std::stringstream name; - name << data.resourceDir; - if (!data.configStr.empty()) { - name << "-" << data.configStr; + name << data.resource_dir; + if (!data.config_str.empty()) { + name << "-" << data.config_str; } name << "_" << data.name; if (!data.extension.empty()) { @@ -129,92 +130,93 @@ static std::string buildIntermediateFilename(const ResourcePathData& data) { return name.str(); } -static bool isHidden(const StringPiece& filename) { - return util::stringStartsWith(filename, "."); +static bool IsHidden(const StringPiece& filename) { + return util::StartsWith(filename, "."); } /** * Walks the res directory structure, looking for resource files. */ -static bool loadInputFilesFromDir(IAaptContext* context, - const CompileOptions& options, - std::vector<ResourcePathData>* outPathData) { - const std::string& rootDir = options.resDir.value(); - std::unique_ptr<DIR, decltype(closedir)*> d(opendir(rootDir.data()), +static bool LoadInputFilesFromDir( + IAaptContext* context, const CompileOptions& options, + std::vector<ResourcePathData>* out_path_data) { + const std::string& root_dir = options.res_dir.value(); + std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()), closedir); if (!d) { - context->getDiagnostics()->error(DiagMessage() << strerror(errno)); + context->GetDiagnostics()->Error(DiagMessage() << strerror(errno)); return false; } while (struct dirent* entry = readdir(d.get())) { - if (isHidden(entry->d_name)) { + if (IsHidden(entry->d_name)) { continue; } - std::string prefixPath = rootDir; - file::appendPath(&prefixPath, entry->d_name); + std::string prefix_path = root_dir; + file::AppendPath(&prefix_path, entry->d_name); - if (file::getFileType(prefixPath) != file::FileType::kDirectory) { + if (file::GetFileType(prefix_path) != file::FileType::kDirectory) { continue; } - std::unique_ptr<DIR, decltype(closedir)*> subDir(opendir(prefixPath.data()), - closedir); - if (!subDir) { - context->getDiagnostics()->error(DiagMessage() << strerror(errno)); + std::unique_ptr<DIR, decltype(closedir)*> subdir( + opendir(prefix_path.data()), closedir); + if (!subdir) { + context->GetDiagnostics()->Error(DiagMessage() << strerror(errno)); return false; } - while (struct dirent* leafEntry = readdir(subDir.get())) { - if (isHidden(leafEntry->d_name)) { + while (struct dirent* leaf_entry = readdir(subdir.get())) { + if (IsHidden(leaf_entry->d_name)) { continue; } - std::string fullPath = prefixPath; - file::appendPath(&fullPath, leafEntry->d_name); + std::string full_path = prefix_path; + file::AppendPath(&full_path, leaf_entry->d_name); - std::string errStr; - Maybe<ResourcePathData> pathData = - extractResourcePathData(fullPath, &errStr); - if (!pathData) { - context->getDiagnostics()->error(DiagMessage() << errStr); + std::string err_str; + Maybe<ResourcePathData> path_data = + ExtractResourcePathData(full_path, &err_str); + if (!path_data) { + context->GetDiagnostics()->Error(DiagMessage() << err_str); return false; } - outPathData->push_back(std::move(pathData.value())); + out_path_data->push_back(std::move(path_data.value())); } } return true; } -static bool compileTable(IAaptContext* context, const CompileOptions& options, - const ResourcePathData& pathData, +static bool CompileTable(IAaptContext* context, const CompileOptions& options, + const ResourcePathData& path_data, IArchiveWriter* writer, - const std::string& outputPath) { + const std::string& output_path) { ResourceTable table; { - std::ifstream fin(pathData.source.path, std::ifstream::binary); + std::ifstream fin(path_data.source.path, std::ifstream::binary); if (!fin) { - context->getDiagnostics()->error(DiagMessage(pathData.source) + context->GetDiagnostics()->Error(DiagMessage(path_data.source) << strerror(errno)); return false; } // Parse the values file from XML. - xml::XmlPullParser xmlParser(fin); + xml::XmlPullParser xml_parser(fin); - ResourceParserOptions parserOptions; - parserOptions.errorOnPositionalArguments = !options.legacyMode; + ResourceParserOptions parser_options; + parser_options.error_on_positional_arguments = !options.legacy_mode; // If the filename includes donottranslate, then the default translatable is // false. - parserOptions.translatable = - pathData.name.find("donottranslate") == std::string::npos; + parser_options.translatable = + path_data.name.find("donottranslate") == std::string::npos; - ResourceParser resParser(context->getDiagnostics(), &table, pathData.source, - pathData.config, parserOptions); - if (!resParser.parse(&xmlParser)) { + ResourceParser res_parser(context->GetDiagnostics(), &table, + path_data.source, path_data.config, + parser_options); + if (!res_parser.Parse(&xml_parser)) { return false; } @@ -226,242 +228,241 @@ static bool compileTable(IAaptContext* context, const CompileOptions& options, // These are created as weak symbols, and are only generated from default // configuration // strings and plurals. - PseudolocaleGenerator pseudolocaleGenerator; - if (!pseudolocaleGenerator.consume(context, &table)) { + PseudolocaleGenerator pseudolocale_generator; + if (!pseudolocale_generator.Consume(context, &table)) { return false; } } // Ensure we have the compilation package at least. - table.createPackage(context->getCompilationPackage()); + table.CreatePackage(context->GetCompilationPackage()); // Assign an ID to any package that has resources. for (auto& pkg : table.packages) { if (!pkg->id) { // If no package ID was set while parsing (public identifiers), auto // assign an ID. - pkg->id = context->getPackageId(); + pkg->id = context->GetPackageId(); } } // Create the file/zip entry. - if (!writer->startEntry(outputPath, 0)) { - context->getDiagnostics()->error(DiagMessage(outputPath) + if (!writer->StartEntry(output_path, 0)) { + context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to open"); return false; } // Make sure CopyingOutputStreamAdaptor is deleted before we call - // writer->finishEntry(). + // writer->FinishEntry(). { // Wrap our IArchiveWriter with an adaptor that implements the // ZeroCopyOutputStream // interface. - CopyingOutputStreamAdaptor copyingAdaptor(writer); + CopyingOutputStreamAdaptor copying_adaptor(writer); - std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(&table); - if (!pbTable->SerializeToZeroCopyStream(©ingAdaptor)) { - context->getDiagnostics()->error(DiagMessage(outputPath) + std::unique_ptr<pb::ResourceTable> pb_table = SerializeTableToPb(&table); + if (!pb_table->SerializeToZeroCopyStream(©ing_adaptor)) { + context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to write"); return false; } } - if (!writer->finishEntry()) { - context->getDiagnostics()->error(DiagMessage(outputPath) + if (!writer->FinishEntry()) { + context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to finish entry"); return false; } return true; } -static bool writeHeaderAndBufferToWriter(const StringPiece& outputPath, +static bool WriteHeaderAndBufferToWriter(const StringPiece& output_path, const ResourceFile& file, const BigBuffer& buffer, IArchiveWriter* writer, IDiagnostics* diag) { // Start the entry so we can write the header. - if (!writer->startEntry(outputPath, 0)) { - diag->error(DiagMessage(outputPath) << "failed to open file"); + if (!writer->StartEntry(output_path, 0)) { + diag->Error(DiagMessage(output_path) << "failed to open file"); return false; } // Make sure CopyingOutputStreamAdaptor is deleted before we call - // writer->finishEntry(). + // writer->FinishEntry(). { // Wrap our IArchiveWriter with an adaptor that implements the // ZeroCopyOutputStream // interface. - CopyingOutputStreamAdaptor copyingAdaptor(writer); - CompiledFileOutputStream outputStream(©ingAdaptor); + CopyingOutputStreamAdaptor copying_adaptor(writer); + CompiledFileOutputStream output_stream(©ing_adaptor); // Number of CompiledFiles. - outputStream.WriteLittleEndian32(1); + output_stream.WriteLittleEndian32(1); - std::unique_ptr<pb::CompiledFile> compiledFile = - serializeCompiledFileToPb(file); - outputStream.WriteCompiledFile(compiledFile.get()); - outputStream.WriteData(&buffer); + std::unique_ptr<pb::CompiledFile> compiled_file = + SerializeCompiledFileToPb(file); + output_stream.WriteCompiledFile(compiled_file.get()); + output_stream.WriteData(&buffer); - if (outputStream.HadError()) { - diag->error(DiagMessage(outputPath) << "failed to write data"); + if (output_stream.HadError()) { + diag->Error(DiagMessage(output_path) << "failed to write data"); return false; } } - if (!writer->finishEntry()) { - diag->error(DiagMessage(outputPath) << "failed to finish writing data"); + if (!writer->FinishEntry()) { + diag->Error(DiagMessage(output_path) << "failed to finish writing data"); return false; } return true; } -static bool writeHeaderAndMmapToWriter(const StringPiece& outputPath, +static bool WriteHeaderAndMmapToWriter(const StringPiece& output_path, const ResourceFile& file, const android::FileMap& map, IArchiveWriter* writer, IDiagnostics* diag) { // Start the entry so we can write the header. - if (!writer->startEntry(outputPath, 0)) { - diag->error(DiagMessage(outputPath) << "failed to open file"); + if (!writer->StartEntry(output_path, 0)) { + diag->Error(DiagMessage(output_path) << "failed to open file"); return false; } // Make sure CopyingOutputStreamAdaptor is deleted before we call - // writer->finishEntry(). + // writer->FinishEntry(). { // Wrap our IArchiveWriter with an adaptor that implements the - // ZeroCopyOutputStream - // interface. - CopyingOutputStreamAdaptor copyingAdaptor(writer); - CompiledFileOutputStream outputStream(©ingAdaptor); + // ZeroCopyOutputStream interface. + CopyingOutputStreamAdaptor copying_adaptor(writer); + CompiledFileOutputStream output_stream(©ing_adaptor); // Number of CompiledFiles. - outputStream.WriteLittleEndian32(1); + output_stream.WriteLittleEndian32(1); - std::unique_ptr<pb::CompiledFile> compiledFile = - serializeCompiledFileToPb(file); - outputStream.WriteCompiledFile(compiledFile.get()); - outputStream.WriteData(map.getDataPtr(), map.getDataLength()); + std::unique_ptr<pb::CompiledFile> compiled_file = + SerializeCompiledFileToPb(file); + output_stream.WriteCompiledFile(compiled_file.get()); + output_stream.WriteData(map.getDataPtr(), map.getDataLength()); - if (outputStream.HadError()) { - diag->error(DiagMessage(outputPath) << "failed to write data"); + if (output_stream.HadError()) { + diag->Error(DiagMessage(output_path) << "failed to write data"); return false; } } - if (!writer->finishEntry()) { - diag->error(DiagMessage(outputPath) << "failed to finish writing data"); + if (!writer->FinishEntry()) { + diag->Error(DiagMessage(output_path) << "failed to finish writing data"); return false; } return true; } -static bool flattenXmlToOutStream(IAaptContext* context, - const StringPiece& outputPath, - xml::XmlResource* xmlRes, +static bool FlattenXmlToOutStream(IAaptContext* context, + const StringPiece& output_path, + xml::XmlResource* xmlres, CompiledFileOutputStream* out) { BigBuffer buffer(1024); - XmlFlattenerOptions xmlFlattenerOptions; - xmlFlattenerOptions.keepRawValues = true; - XmlFlattener flattener(&buffer, xmlFlattenerOptions); - if (!flattener.consume(context, xmlRes)) { + XmlFlattenerOptions xml_flattener_options; + xml_flattener_options.keep_raw_values = true; + XmlFlattener flattener(&buffer, xml_flattener_options); + if (!flattener.Consume(context, xmlres)) { return false; } - std::unique_ptr<pb::CompiledFile> pbCompiledFile = - serializeCompiledFileToPb(xmlRes->file); - out->WriteCompiledFile(pbCompiledFile.get()); + std::unique_ptr<pb::CompiledFile> pb_compiled_file = + SerializeCompiledFileToPb(xmlres->file); + out->WriteCompiledFile(pb_compiled_file.get()); out->WriteData(&buffer); if (out->HadError()) { - context->getDiagnostics()->error(DiagMessage(outputPath) + context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to write data"); return false; } return true; } -static bool compileXml(IAaptContext* context, const CompileOptions& options, - const ResourcePathData& pathData, IArchiveWriter* writer, - const std::string& outputPath) { - if (context->verbose()) { - context->getDiagnostics()->note(DiagMessage(pathData.source) +static bool CompileXml(IAaptContext* context, const CompileOptions& options, + const ResourcePathData& path_data, + IArchiveWriter* writer, const std::string& output_path) { + if (context->IsVerbose()) { + context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling XML"); } - std::unique_ptr<xml::XmlResource> xmlRes; + std::unique_ptr<xml::XmlResource> xmlres; { - std::ifstream fin(pathData.source.path, std::ifstream::binary); + std::ifstream fin(path_data.source.path, std::ifstream::binary); if (!fin) { - context->getDiagnostics()->error(DiagMessage(pathData.source) + context->GetDiagnostics()->Error(DiagMessage(path_data.source) << strerror(errno)); return false; } - xmlRes = xml::inflate(&fin, context->getDiagnostics(), pathData.source); + xmlres = xml::Inflate(&fin, context->GetDiagnostics(), path_data.source); fin.close(); } - if (!xmlRes) { + if (!xmlres) { return false; } - xmlRes->file.name = - ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name); - xmlRes->file.config = pathData.config; - xmlRes->file.source = pathData.source; + xmlres->file.name = ResourceName( + {}, *ParseResourceType(path_data.resource_dir), path_data.name); + xmlres->file.config = path_data.config; + xmlres->file.source = path_data.source; // Collect IDs that are defined here. XmlIdCollector collector; - if (!collector.consume(context, xmlRes.get())) { + if (!collector.Consume(context, xmlres.get())) { return false; } // Look for and process any <aapt:attr> tags and create sub-documents. - InlineXmlFormatParser inlineXmlFormatParser; - if (!inlineXmlFormatParser.consume(context, xmlRes.get())) { + InlineXmlFormatParser inline_xml_format_parser; + if (!inline_xml_format_parser.Consume(context, xmlres.get())) { return false; } // Start the entry so we can write the header. - if (!writer->startEntry(outputPath, 0)) { - context->getDiagnostics()->error(DiagMessage(outputPath) + if (!writer->StartEntry(output_path, 0)) { + context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to open file"); return false; } // Make sure CopyingOutputStreamAdaptor is deleted before we call - // writer->finishEntry(). + // writer->FinishEntry(). { // Wrap our IArchiveWriter with an adaptor that implements the // ZeroCopyOutputStream // interface. - CopyingOutputStreamAdaptor copyingAdaptor(writer); - CompiledFileOutputStream outputStream(©ingAdaptor); + CopyingOutputStreamAdaptor copying_adaptor(writer); + CompiledFileOutputStream output_stream(©ing_adaptor); - std::vector<std::unique_ptr<xml::XmlResource>>& inlineDocuments = - inlineXmlFormatParser.getExtractedInlineXmlDocuments(); + std::vector<std::unique_ptr<xml::XmlResource>>& inline_documents = + inline_xml_format_parser.GetExtractedInlineXmlDocuments(); // Number of CompiledFiles. - outputStream.WriteLittleEndian32(1 + inlineDocuments.size()); + output_stream.WriteLittleEndian32(1 + inline_documents.size()); - if (!flattenXmlToOutStream(context, outputPath, xmlRes.get(), - &outputStream)) { + if (!FlattenXmlToOutStream(context, output_path, xmlres.get(), + &output_stream)) { return false; } - for (auto& inlineXmlDoc : inlineDocuments) { - if (!flattenXmlToOutStream(context, outputPath, inlineXmlDoc.get(), - &outputStream)) { + for (auto& inline_xml_doc : inline_documents) { + if (!FlattenXmlToOutStream(context, output_path, inline_xml_doc.get(), + &output_stream)) { return false; } } } - if (!writer->finishEntry()) { - context->getDiagnostics()->error(DiagMessage(outputPath) + if (!writer->FinishEntry()) { + context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to finish writing data"); return false; } @@ -470,69 +471,69 @@ static bool compileXml(IAaptContext* context, const CompileOptions& options, class BigBufferOutputStream : public io::OutputStream { public: - explicit BigBufferOutputStream(BigBuffer* buffer) : mBuffer(buffer) {} + explicit BigBufferOutputStream(BigBuffer* buffer) : buffer_(buffer) {} bool Next(void** data, int* len) override { size_t count; - *data = mBuffer->nextBlock(&count); + *data = buffer_->NextBlock(&count); *len = static_cast<int>(count); return true; } - void BackUp(int count) override { mBuffer->backUp(count); } + void BackUp(int count) override { buffer_->BackUp(count); } - int64_t ByteCount() const override { return mBuffer->size(); } + int64_t ByteCount() const override { return buffer_->size(); } bool HadError() const override { return false; } private: - BigBuffer* mBuffer; + BigBuffer* buffer_; DISALLOW_COPY_AND_ASSIGN(BigBufferOutputStream); }; -static bool compilePng(IAaptContext* context, const CompileOptions& options, - const ResourcePathData& pathData, IArchiveWriter* writer, - const std::string& outputPath) { - if (context->verbose()) { - context->getDiagnostics()->note(DiagMessage(pathData.source) +static bool CompilePng(IAaptContext* context, const CompileOptions& options, + const ResourcePathData& path_data, + IArchiveWriter* writer, const std::string& output_path) { + if (context->IsVerbose()) { + context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling PNG"); } BigBuffer buffer(4096); - ResourceFile resFile; - resFile.name = - ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name); - resFile.config = pathData.config; - resFile.source = pathData.source; + ResourceFile res_file; + res_file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir), + path_data.name); + res_file.config = path_data.config; + res_file.source = path_data.source; { std::string content; - if (!android::base::ReadFileToString(pathData.source.path, &content)) { - context->getDiagnostics()->error( - DiagMessage(pathData.source) + if (!android::base::ReadFileToString(path_data.source.path, &content)) { + context->GetDiagnostics()->Error( + DiagMessage(path_data.source) << android::base::SystemErrorCodeToString(errno)); return false; } - BigBuffer crunchedPngBuffer(4096); - BigBufferOutputStream crunchedPngBufferOut(&crunchedPngBuffer); + BigBuffer crunched_png_buffer(4096); + BigBufferOutputStream crunched_png_buffer_out(&crunched_png_buffer); // Ensure that we only keep the chunks we care about if we end up // using the original PNG instead of the crunched one. - PngChunkFilter pngChunkFilter(content); - std::unique_ptr<Image> image = readPng(context, &pngChunkFilter); + PngChunkFilter png_chunk_filter(content); + std::unique_ptr<Image> image = ReadPng(context, &png_chunk_filter); if (!image) { return false; } - std::unique_ptr<NinePatch> ninePatch; - if (pathData.extension == "9.png") { + std::unique_ptr<NinePatch> nine_patch; + if (path_data.extension == "9.png") { std::string err; - ninePatch = NinePatch::create(image->rows.get(), image->width, - image->height, &err); - if (!ninePatch) { - context->getDiagnostics()->error(DiagMessage() << err); + nine_patch = NinePatch::Create(image->rows.get(), image->width, + image->height, &err); + if (!nine_patch) { + context->GetDiagnostics()->Error(DiagMessage() << err); return false; } @@ -549,89 +550,91 @@ static bool compilePng(IAaptContext* context, const CompileOptions& options, memmove(image->rows[h], image->rows[h] + 4, image->width * 4); } - if (context->verbose()) { - context->getDiagnostics()->note(DiagMessage(pathData.source) - << "9-patch: " << *ninePatch); + if (context->IsVerbose()) { + context->GetDiagnostics()->Note(DiagMessage(path_data.source) + << "9-patch: " << *nine_patch); } } // Write the crunched PNG. - if (!writePng(context, image.get(), ninePatch.get(), &crunchedPngBufferOut, - {})) { + if (!WritePng(context, image.get(), nine_patch.get(), + &crunched_png_buffer_out, {})) { return false; } - if (ninePatch != nullptr || - crunchedPngBufferOut.ByteCount() <= pngChunkFilter.ByteCount()) { + if (nine_patch != nullptr || + crunched_png_buffer_out.ByteCount() <= png_chunk_filter.ByteCount()) { // No matter what, we must use the re-encoded PNG, even if it is larger. // 9-patch images must be re-encoded since their borders are stripped. - buffer.appendBuffer(std::move(crunchedPngBuffer)); + buffer.AppendBuffer(std::move(crunched_png_buffer)); } else { // The re-encoded PNG is larger than the original, and there is // no mandatory transformation. Use the original. - if (context->verbose()) { - context->getDiagnostics()->note( - DiagMessage(pathData.source) + if (context->IsVerbose()) { + context->GetDiagnostics()->Note( + DiagMessage(path_data.source) << "original PNG is smaller than crunched PNG" << ", using original"); } - PngChunkFilter pngChunkFilterAgain(content); - BigBuffer filteredPngBuffer(4096); - BigBufferOutputStream filteredPngBufferOut(&filteredPngBuffer); - io::copy(&filteredPngBufferOut, &pngChunkFilterAgain); - buffer.appendBuffer(std::move(filteredPngBuffer)); + PngChunkFilter png_chunk_filter_again(content); + BigBuffer filtered_png_buffer(4096); + BigBufferOutputStream filtered_png_buffer_out(&filtered_png_buffer); + io::Copy(&filtered_png_buffer_out, &png_chunk_filter_again); + buffer.AppendBuffer(std::move(filtered_png_buffer)); } - if (context->verbose()) { + if (context->IsVerbose()) { // For debugging only, use the legacy PNG cruncher and compare the // resulting file sizes. // This will help catch exotic cases where the new code may generate // larger PNGs. - std::stringstream legacyStream(content); - BigBuffer legacyBuffer(4096); - Png png(context->getDiagnostics()); - if (!png.process(pathData.source, &legacyStream, &legacyBuffer, {})) { + std::stringstream legacy_stream(content); + BigBuffer legacy_buffer(4096); + Png png(context->GetDiagnostics()); + if (!png.process(path_data.source, &legacy_stream, &legacy_buffer, {})) { return false; } - context->getDiagnostics()->note(DiagMessage(pathData.source) - << "legacy=" << legacyBuffer.size() + context->GetDiagnostics()->Note(DiagMessage(path_data.source) + << "legacy=" << legacy_buffer.size() << " new=" << buffer.size()); } } - if (!writeHeaderAndBufferToWriter(outputPath, resFile, buffer, writer, - context->getDiagnostics())) { + if (!WriteHeaderAndBufferToWriter(output_path, res_file, buffer, writer, + context->GetDiagnostics())) { return false; } return true; } -static bool compileFile(IAaptContext* context, const CompileOptions& options, - const ResourcePathData& pathData, - IArchiveWriter* writer, const std::string& outputPath) { - if (context->verbose()) { - context->getDiagnostics()->note(DiagMessage(pathData.source) +static bool CompileFile(IAaptContext* context, const CompileOptions& options, + const ResourcePathData& path_data, + IArchiveWriter* writer, + const std::string& output_path) { + if (context->IsVerbose()) { + context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling file"); } BigBuffer buffer(256); - ResourceFile resFile; - resFile.name = - ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name); - resFile.config = pathData.config; - resFile.source = pathData.source; - - std::string errorStr; - Maybe<android::FileMap> f = file::mmapPath(pathData.source.path, &errorStr); + ResourceFile res_file; + res_file.name = ResourceName({}, *ParseResourceType(path_data.resource_dir), + path_data.name); + res_file.config = path_data.config; + res_file.source = path_data.source; + + std::string error_str; + Maybe<android::FileMap> f = file::MmapPath(path_data.source.path, &error_str); if (!f) { - context->getDiagnostics()->error(DiagMessage(pathData.source) << errorStr); + context->GetDiagnostics()->Error(DiagMessage(path_data.source) + << error_str); return false; } - if (!writeHeaderAndMmapToWriter(outputPath, resFile, f.value(), writer, - context->getDiagnostics())) { + if (!WriteHeaderAndMmapToWriter(output_path, res_file, f.value(), writer, + context->GetDiagnostics())) { return false; } return true; @@ -639,155 +642,156 @@ static bool compileFile(IAaptContext* context, const CompileOptions& options, class CompileContext : public IAaptContext { public: - void setVerbose(bool val) { mVerbose = val; } + void SetVerbose(bool val) { verbose_ = val; } - bool verbose() override { return mVerbose; } + bool IsVerbose() override { return verbose_; } - IDiagnostics* getDiagnostics() override { return &mDiagnostics; } + IDiagnostics* GetDiagnostics() override { return &diagnostics_; } - NameMangler* getNameMangler() override { + NameMangler* GetNameMangler() override { abort(); return nullptr; } - const std::string& getCompilationPackage() override { + const std::string& GetCompilationPackage() override { static std::string empty; return empty; } - uint8_t getPackageId() override { return 0x0; } + uint8_t GetPackageId() override { return 0x0; } - SymbolTable* getExternalSymbols() override { + SymbolTable* GetExternalSymbols() override { abort(); return nullptr; } - int getMinSdkVersion() override { return 0; } + int GetMinSdkVersion() override { return 0; } private: - StdErrDiagnostics mDiagnostics; - bool mVerbose = false; + StdErrDiagnostics diagnostics_; + bool verbose_ = false; }; /** * Entry point for compilation phase. Parses arguments and dispatches to the * correct steps. */ -int compile(const std::vector<StringPiece>& args) { +int Compile(const std::vector<StringPiece>& args) { CompileContext context; CompileOptions options; bool verbose = false; Flags flags = Flags() - .requiredFlag("-o", "Output path", &options.outputPath) - .optionalFlag("--dir", "Directory to scan for resources", - &options.resDir) - .optionalSwitch("--pseudo-localize", + .RequiredFlag("-o", "Output path", &options.output_path) + .OptionalFlag("--dir", "Directory to scan for resources", + &options.res_dir) + .OptionalSwitch("--pseudo-localize", "Generate resources for pseudo-locales " "(en-XA and ar-XB)", &options.pseudolocalize) - .optionalSwitch( + .OptionalSwitch( "--legacy", "Treat errors that used to be valid in AAPT as warnings", - &options.legacyMode) - .optionalSwitch("-v", "Enables verbose logging", &verbose); - if (!flags.parse("aapt2 compile", args, &std::cerr)) { + &options.legacy_mode) + .OptionalSwitch("-v", "Enables verbose logging", &verbose); + if (!flags.Parse("aapt2 compile", args, &std::cerr)) { return 1; } - context.setVerbose(verbose); + context.SetVerbose(verbose); - std::unique_ptr<IArchiveWriter> archiveWriter; + std::unique_ptr<IArchiveWriter> archive_writer; - std::vector<ResourcePathData> inputData; - if (options.resDir) { - if (!flags.getArgs().empty()) { + std::vector<ResourcePathData> input_data; + if (options.res_dir) { + if (!flags.GetArgs().empty()) { // Can't have both files and a resource directory. - context.getDiagnostics()->error(DiagMessage() + context.GetDiagnostics()->Error(DiagMessage() << "files given but --dir specified"); - flags.usage("aapt2 compile", &std::cerr); + flags.Usage("aapt2 compile", &std::cerr); return 1; } - if (!loadInputFilesFromDir(&context, options, &inputData)) { + if (!LoadInputFilesFromDir(&context, options, &input_data)) { return 1; } - archiveWriter = createZipFileArchiveWriter(context.getDiagnostics(), - options.outputPath); + archive_writer = CreateZipFileArchiveWriter(context.GetDiagnostics(), + options.output_path); } else { - inputData.reserve(flags.getArgs().size()); + input_data.reserve(flags.GetArgs().size()); // Collect data from the path for each input file. - for (const std::string& arg : flags.getArgs()) { - std::string errorStr; - if (Maybe<ResourcePathData> pathData = - extractResourcePathData(arg, &errorStr)) { - inputData.push_back(std::move(pathData.value())); + for (const std::string& arg : flags.GetArgs()) { + std::string error_str; + if (Maybe<ResourcePathData> path_data = + ExtractResourcePathData(arg, &error_str)) { + input_data.push_back(std::move(path_data.value())); } else { - context.getDiagnostics()->error(DiagMessage() << errorStr << " (" << arg - << ")"); + context.GetDiagnostics()->Error(DiagMessage() << error_str << " (" + << arg << ")"); return 1; } } - archiveWriter = createDirectoryArchiveWriter(context.getDiagnostics(), - options.outputPath); + archive_writer = CreateDirectoryArchiveWriter(context.GetDiagnostics(), + options.output_path); } - if (!archiveWriter) { + if (!archive_writer) { return 1; } bool error = false; - for (ResourcePathData& pathData : inputData) { + for (ResourcePathData& path_data : input_data) { if (options.verbose) { - context.getDiagnostics()->note(DiagMessage(pathData.source) + context.GetDiagnostics()->Note(DiagMessage(path_data.source) << "processing"); } - if (pathData.resourceDir == "values") { + if (path_data.resource_dir == "values") { // Overwrite the extension. - pathData.extension = "arsc"; + path_data.extension = "arsc"; - const std::string outputFilename = buildIntermediateFilename(pathData); - if (!compileTable(&context, options, pathData, archiveWriter.get(), - outputFilename)) { + const std::string output_filename = BuildIntermediateFilename(path_data); + if (!CompileTable(&context, options, path_data, archive_writer.get(), + output_filename)) { error = true; } } else { - const std::string outputFilename = buildIntermediateFilename(pathData); - if (const ResourceType* type = parseResourceType(pathData.resourceDir)) { + const std::string output_filename = BuildIntermediateFilename(path_data); + if (const ResourceType* type = + ParseResourceType(path_data.resource_dir)) { if (*type != ResourceType::kRaw) { - if (pathData.extension == "xml") { - if (!compileXml(&context, options, pathData, archiveWriter.get(), - outputFilename)) { + if (path_data.extension == "xml") { + if (!CompileXml(&context, options, path_data, archive_writer.get(), + output_filename)) { error = true; } - } else if (pathData.extension == "png" || - pathData.extension == "9.png") { - if (!compilePng(&context, options, pathData, archiveWriter.get(), - outputFilename)) { + } else if (path_data.extension == "png" || + path_data.extension == "9.png") { + if (!CompilePng(&context, options, path_data, archive_writer.get(), + output_filename)) { error = true; } } else { - if (!compileFile(&context, options, pathData, archiveWriter.get(), - outputFilename)) { + if (!CompileFile(&context, options, path_data, archive_writer.get(), + output_filename)) { error = true; } } } else { - if (!compileFile(&context, options, pathData, archiveWriter.get(), - outputFilename)) { + if (!CompileFile(&context, options, path_data, archive_writer.get(), + output_filename)) { error = true; } } } else { - context.getDiagnostics()->error( - DiagMessage() << "invalid file path '" << pathData.source << "'"); + context.GetDiagnostics()->Error( + DiagMessage() << "invalid file path '" << path_data.source << "'"); error = true; } } diff --git a/tools/aapt2/compile/IdAssigner.cpp b/tools/aapt2/compile/IdAssigner.cpp index 73eb066b04d1..17c22c5aac6b 100644 --- a/tools/aapt2/compile/IdAssigner.cpp +++ b/tools/aapt2/compile/IdAssigner.cpp @@ -15,13 +15,15 @@ */ #include "compile/IdAssigner.h" + +#include <map> + +#include "android-base/logging.h" + #include "ResourceTable.h" #include "process/IResourceTableConsumer.h" #include "util/Util.h" -#include <cassert> -#include <map> - namespace aapt { /** @@ -29,44 +31,44 @@ namespace aapt { * ResourceEntry, * as long as there is no existing ID or the ID is the same. */ -static bool assignId(IDiagnostics* diag, const ResourceId& id, +static bool AssignId(IDiagnostics* diag, const ResourceId& id, const ResourceName& name, ResourceTablePackage* pkg, ResourceTableType* type, ResourceEntry* entry) { - if (pkg->id.value() == id.packageId()) { - if (!type->id || type->id.value() == id.typeId()) { - type->id = id.typeId(); + if (pkg->id.value() == id.package_id()) { + if (!type->id || type->id.value() == id.type_id()) { + type->id = id.type_id(); - if (!entry->id || entry->id.value() == id.entryId()) { - entry->id = id.entryId(); + if (!entry->id || entry->id.value() == id.entry_id()) { + entry->id = id.entry_id(); return true; } } } - const ResourceId existingId(pkg->id.value(), type->id ? type->id.value() : 0, - entry->id ? entry->id.value() : 0); - diag->error(DiagMessage() << "can't assign ID " << id << " to resource " - << name << " with conflicting ID " << existingId); + const ResourceId existing_id(pkg->id.value(), type->id ? type->id.value() : 0, + entry->id ? entry->id.value() : 0); + diag->Error(DiagMessage() << "can't assign ID " << id << " to resource " + << name << " with conflicting ID " << existing_id); return false; } -bool IdAssigner::consume(IAaptContext* context, ResourceTable* table) { - std::map<ResourceId, ResourceName> assignedIds; +bool IdAssigner::Consume(IAaptContext* context, ResourceTable* table) { + std::map<ResourceId, ResourceName> assigned_ids; for (auto& package : table->packages) { - assert(package->id && "packages must have manually assigned IDs"); + CHECK(bool(package->id)) << "packages must have manually assigned IDs"; for (auto& type : package->types) { for (auto& entry : type->entries) { const ResourceName name(package->name, type->type, entry->name); - if (mAssignedIdMap) { + if (assigned_id_map_) { // Assign the pre-assigned stable ID meant for this resource. - const auto iter = mAssignedIdMap->find(name); - if (iter != mAssignedIdMap->end()) { - const ResourceId assignedId = iter->second; + const auto iter = assigned_id_map_->find(name); + if (iter != assigned_id_map_->end()) { + const ResourceId assigned_id = iter->second; const bool result = - assignId(context->getDiagnostics(), assignedId, name, + AssignId(context->GetDiagnostics(), assigned_id, name, package.get(), type.get(), entry.get()); if (!result) { return false; @@ -76,14 +78,14 @@ bool IdAssigner::consume(IAaptContext* context, ResourceTable* table) { if (package->id && type->id && entry->id) { // If the ID is set for this resource, then reserve it. - ResourceId resourceId(package->id.value(), type->id.value(), - entry->id.value()); - auto result = assignedIds.insert({resourceId, name}); - const ResourceName& existingName = result.first->second; + ResourceId resource_id(package->id.value(), type->id.value(), + entry->id.value()); + auto result = assigned_ids.insert({resource_id, name}); + const ResourceName& existing_name = result.first->second; if (!result.second) { - context->getDiagnostics()->error( + context->GetDiagnostics()->Error( DiagMessage() << "resource " << name << " has same ID " - << resourceId << " as " << existingName); + << resource_id << " as " << existing_name); return false; } } @@ -91,20 +93,20 @@ bool IdAssigner::consume(IAaptContext* context, ResourceTable* table) { } } - if (mAssignedIdMap) { + if (assigned_id_map_) { // Reserve all the IDs mentioned in the stable ID map. That way we won't // assign // IDs that were listed in the map if they don't exist in the table. - for (const auto& stableIdEntry : *mAssignedIdMap) { - const ResourceName& preAssignedName = stableIdEntry.first; - const ResourceId& preAssignedId = stableIdEntry.second; - auto result = assignedIds.insert({preAssignedId, preAssignedName}); - const ResourceName& existingName = result.first->second; - if (!result.second && existingName != preAssignedName) { - context->getDiagnostics()->error( - DiagMessage() << "stable ID " << preAssignedId << " for resource " - << preAssignedName << " is already taken by resource " - << existingName); + for (const auto& stable_id_entry : *assigned_id_map_) { + const ResourceName& pre_assigned_name = stable_id_entry.first; + const ResourceId& pre_assigned_id = stable_id_entry.second; + auto result = assigned_ids.insert({pre_assigned_id, pre_assigned_name}); + const ResourceName& existing_name = result.first->second; + if (!result.second && existing_name != pre_assigned_name) { + context->GetDiagnostics()->Error( + DiagMessage() << "stable ID " << pre_assigned_id << " for resource " + << pre_assigned_name + << " is already taken by resource " << existing_name); return false; } } @@ -114,21 +116,21 @@ bool IdAssigner::consume(IAaptContext* context, ResourceTable* table) { // if possible, // unless those IDs have been reserved. - const auto assignedIdsIterEnd = assignedIds.end(); + const auto assigned_ids_iter_end = assigned_ids.end(); for (auto& package : table->packages) { - assert(package->id && "packages must have manually assigned IDs"); + CHECK(bool(package->id)) << "packages must have manually assigned IDs"; // Build a half filled ResourceId object, which will be used to find the // closest matching // reserved ID in the assignedId map. From that point the next available // type ID can be // found. - ResourceId resourceId(package->id.value(), 0, 0); - uint8_t nextExpectedTypeId = 1; + ResourceId resource_id(package->id.value(), 0, 0); + uint8_t next_expected_type_id = 1; // Find the closest matching ResourceId that is <= the one with only the // package set. - auto nextTypeIter = assignedIds.lower_bound(resourceId); + auto next_type_iter = assigned_ids.lower_bound(resource_id); for (auto& type : package->types) { if (!type->id) { // We need to assign a type ID. Iterate over the reserved IDs until we @@ -136,41 +138,41 @@ bool IdAssigner::consume(IAaptContext* context, ResourceTable* table) { // some type ID that is a distance of 2 greater than the last one we've // seen. // That means there is an available type ID between these reserved IDs. - while (nextTypeIter != assignedIdsIterEnd) { - if (nextTypeIter->first.packageId() != package->id.value()) { + while (next_type_iter != assigned_ids_iter_end) { + if (next_type_iter->first.package_id() != package->id.value()) { break; } - const uint8_t typeId = nextTypeIter->first.typeId(); - if (typeId > nextExpectedTypeId) { + const uint8_t type_id = next_type_iter->first.type_id(); + if (type_id > next_expected_type_id) { // There is a gap in the type IDs, so use the missing one. - type->id = nextExpectedTypeId++; + type->id = next_expected_type_id++; break; } // Set our expectation to be the next type ID after the reserved one // we // just saw. - nextExpectedTypeId = typeId + 1; + next_expected_type_id = type_id + 1; // Move to the next reserved ID. - ++nextTypeIter; + ++next_type_iter; } if (!type->id) { // We must have hit the end of the reserved IDs and not found a gap. // That means the next ID is available. - type->id = nextExpectedTypeId++; + type->id = next_expected_type_id++; } } - resourceId = ResourceId(package->id.value(), type->id.value(), 0); - uint16_t nextExpectedEntryId = 0; + resource_id = ResourceId(package->id.value(), type->id.value(), 0); + uint16_t next_expected_entry_id = 0; // Find the closest matching ResourceId that is <= the one with only the // package // and type set. - auto nextEntryIter = assignedIds.lower_bound(resourceId); + auto next_entry_iter = assigned_ids.lower_bound(resource_id); for (auto& entry : type->entries) { if (!entry->id) { // We need to assign an entry ID. Iterate over the reserved IDs until @@ -179,32 +181,32 @@ bool IdAssigner::consume(IAaptContext* context, ResourceTable* table) { // we've seen. // That means there is an available entry ID between these reserved // IDs. - while (nextEntryIter != assignedIdsIterEnd) { - if (nextEntryIter->first.packageId() != package->id.value() || - nextEntryIter->first.typeId() != type->id.value()) { + while (next_entry_iter != assigned_ids_iter_end) { + if (next_entry_iter->first.package_id() != package->id.value() || + next_entry_iter->first.type_id() != type->id.value()) { break; } - const uint16_t entryId = nextEntryIter->first.entryId(); - if (entryId > nextExpectedEntryId) { + const uint16_t entry_id = next_entry_iter->first.entry_id(); + if (entry_id > next_expected_entry_id) { // There is a gap in the entry IDs, so use the missing one. - entry->id = nextExpectedEntryId++; + entry->id = next_expected_entry_id++; break; } // Set our expectation to be the next type ID after the reserved one // we // just saw. - nextExpectedEntryId = entryId + 1; + next_expected_entry_id = entry_id + 1; // Move to the next reserved entry ID. - ++nextEntryIter; + ++next_entry_iter; } if (!entry->id) { // We must have hit the end of the reserved IDs and not found a gap. // That means the next ID is available. - entry->id = nextExpectedEntryId++; + entry->id = next_expected_entry_id++; } } } diff --git a/tools/aapt2/compile/IdAssigner.h b/tools/aapt2/compile/IdAssigner.h index d3990641abf5..371ec01818cd 100644 --- a/tools/aapt2/compile/IdAssigner.h +++ b/tools/aapt2/compile/IdAssigner.h @@ -17,11 +17,12 @@ #ifndef AAPT_COMPILE_IDASSIGNER_H #define AAPT_COMPILE_IDASSIGNER_H +#include <unordered_map> + #include "Resource.h" #include "process/IResourceTableConsumer.h" -#include <android-base/macros.h> -#include <unordered_map> +#include "android-base/macros.h" namespace aapt { @@ -34,12 +35,13 @@ class IdAssigner : public IResourceTableConsumer { public: IdAssigner() = default; explicit IdAssigner(const std::unordered_map<ResourceName, ResourceId>* map) - : mAssignedIdMap(map) {} + : assigned_id_map_(map) {} - bool consume(IAaptContext* context, ResourceTable* table) override; + bool Consume(IAaptContext* context, ResourceTable* table) override; private: - const std::unordered_map<ResourceName, ResourceId>* mAssignedIdMap = nullptr; + const std::unordered_map<ResourceName, ResourceId>* assigned_id_map_ = + nullptr; }; } // namespace aapt diff --git a/tools/aapt2/compile/IdAssigner_test.cpp b/tools/aapt2/compile/IdAssigner_test.cpp index ff7bf5ce7195..d465091d224e 100644 --- a/tools/aapt2/compile/IdAssigner_test.cpp +++ b/tools/aapt2/compile/IdAssigner_test.cpp @@ -15,128 +15,129 @@ */ #include "compile/IdAssigner.h" + #include "test/Test.h" namespace aapt { -::testing::AssertionResult verifyIds(ResourceTable* table); +::testing::AssertionResult VerifyIds(ResourceTable* table); TEST(IdAssignerTest, AssignIds) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addSimple("android:attr/foo") - .addSimple("android:attr/bar") - .addSimple("android:id/foo") - .setPackageId("android", 0x01) - .build(); + .AddSimple("android:attr/foo") + .AddSimple("android:attr/bar") + .AddSimple("android:id/foo") + .SetPackageId("android", 0x01) + .Build(); - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); IdAssigner assigner; - ASSERT_TRUE(assigner.consume(context.get(), table.get())); - ASSERT_TRUE(verifyIds(table.get())); + ASSERT_TRUE(assigner.Consume(context.get(), table.get())); + ASSERT_TRUE(VerifyIds(table.get())); } TEST(IdAssignerTest, AssignIdsWithReservedIds) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addSimple("android:id/foo", ResourceId(0x01010000)) - .addSimple("android:dimen/two") - .addSimple("android:integer/three") - .addSimple("android:string/five") - .addSimple("android:attr/fun", ResourceId(0x01040000)) - .addSimple("android:attr/foo", ResourceId(0x01040006)) - .addSimple("android:attr/bar") - .addSimple("android:attr/baz") - .addSimple("app:id/biz") - .setPackageId("android", 0x01) - .setPackageId("app", 0x7f) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + .AddSimple("android:id/foo", ResourceId(0x01010000)) + .AddSimple("android:dimen/two") + .AddSimple("android:integer/three") + .AddSimple("android:string/five") + .AddSimple("android:attr/fun", ResourceId(0x01040000)) + .AddSimple("android:attr/foo", ResourceId(0x01040006)) + .AddSimple("android:attr/bar") + .AddSimple("android:attr/baz") + .AddSimple("app:id/biz") + .SetPackageId("android", 0x01) + .SetPackageId("app", 0x7f) + .Build(); + + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); IdAssigner assigner; - ASSERT_TRUE(assigner.consume(context.get(), table.get())); - ASSERT_TRUE(verifyIds(table.get())); + ASSERT_TRUE(assigner.Consume(context.get(), table.get())); + ASSERT_TRUE(VerifyIds(table.get())); - Maybe<ResourceTable::SearchResult> maybeResult; + Maybe<ResourceTable::SearchResult> maybe_result; // Expect to fill in the gaps between 0x0101XXXX and 0x0104XXXX. - maybeResult = table->findResource(test::parseNameOrDie("android:dimen/two")); - AAPT_ASSERT_TRUE(maybeResult); - EXPECT_EQ(make_value<uint8_t>(2), maybeResult.value().type->id); + maybe_result = table->FindResource(test::ParseNameOrDie("android:dimen/two")); + AAPT_ASSERT_TRUE(maybe_result); + EXPECT_EQ(make_value<uint8_t>(2), maybe_result.value().type->id); - maybeResult = - table->findResource(test::parseNameOrDie("android:integer/three")); - AAPT_ASSERT_TRUE(maybeResult); - EXPECT_EQ(make_value<uint8_t>(3), maybeResult.value().type->id); + maybe_result = + table->FindResource(test::ParseNameOrDie("android:integer/three")); + AAPT_ASSERT_TRUE(maybe_result); + EXPECT_EQ(make_value<uint8_t>(3), maybe_result.value().type->id); // Expect to bypass the reserved 0x0104XXXX IDs and use the next 0x0105XXXX // IDs. - maybeResult = - table->findResource(test::parseNameOrDie("android:string/five")); - AAPT_ASSERT_TRUE(maybeResult); - EXPECT_EQ(make_value<uint8_t>(5), maybeResult.value().type->id); + maybe_result = + table->FindResource(test::ParseNameOrDie("android:string/five")); + AAPT_ASSERT_TRUE(maybe_result); + EXPECT_EQ(make_value<uint8_t>(5), maybe_result.value().type->id); // Expect to fill in the gaps between 0x01040000 and 0x01040006. - maybeResult = table->findResource(test::parseNameOrDie("android:attr/bar")); - AAPT_ASSERT_TRUE(maybeResult); - EXPECT_EQ(make_value<uint16_t>(1), maybeResult.value().entry->id); + maybe_result = table->FindResource(test::ParseNameOrDie("android:attr/bar")); + AAPT_ASSERT_TRUE(maybe_result); + EXPECT_EQ(make_value<uint16_t>(1), maybe_result.value().entry->id); - maybeResult = table->findResource(test::parseNameOrDie("android:attr/baz")); - AAPT_ASSERT_TRUE(maybeResult); - EXPECT_EQ(make_value<uint16_t>(2), maybeResult.value().entry->id); + maybe_result = table->FindResource(test::ParseNameOrDie("android:attr/baz")); + AAPT_ASSERT_TRUE(maybe_result); + EXPECT_EQ(make_value<uint16_t>(2), maybe_result.value().entry->id); } TEST(IdAssignerTest, FailWhenNonUniqueIdsAssigned) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addSimple("android:attr/foo", ResourceId(0x01040006)) - .addSimple("android:attr/bar", ResourceId(0x01040006)) - .setPackageId("android", 0x01) - .setPackageId("app", 0x7f) - .build(); + .AddSimple("android:attr/foo", ResourceId(0x01040006)) + .AddSimple("android:attr/bar", ResourceId(0x01040006)) + .SetPackageId("android", 0x01) + .SetPackageId("app", 0x7f) + .Build(); - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); IdAssigner assigner; - ASSERT_FALSE(assigner.consume(context.get(), table.get())); + ASSERT_FALSE(assigner.Consume(context.get(), table.get())); } TEST(IdAssignerTest, AssignIdsWithIdMap) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addSimple("android:attr/foo") - .addSimple("android:attr/bar") - .setPackageId("android", 0x01) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); - std::unordered_map<ResourceName, ResourceId> idMap = { - {test::parseNameOrDie("android:attr/foo"), ResourceId(0x01010002)}}; - IdAssigner assigner(&idMap); - ASSERT_TRUE(assigner.consume(context.get(), table.get())); - ASSERT_TRUE(verifyIds(table.get())); + .AddSimple("android:attr/foo") + .AddSimple("android:attr/bar") + .SetPackageId("android", 0x01) + .Build(); + + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unordered_map<ResourceName, ResourceId> id_map = { + {test::ParseNameOrDie("android:attr/foo"), ResourceId(0x01010002)}}; + IdAssigner assigner(&id_map); + ASSERT_TRUE(assigner.Consume(context.get(), table.get())); + ASSERT_TRUE(VerifyIds(table.get())); Maybe<ResourceTable::SearchResult> result = - table->findResource(test::parseNameOrDie("android:attr/foo")); + table->FindResource(test::ParseNameOrDie("android:attr/foo")); AAPT_ASSERT_TRUE(result); - const ResourceTable::SearchResult& searchResult = result.value(); - EXPECT_EQ(make_value<uint8_t>(0x01), searchResult.package->id); - EXPECT_EQ(make_value<uint8_t>(0x01), searchResult.type->id); - EXPECT_EQ(make_value<uint16_t>(0x0002), searchResult.entry->id); + const ResourceTable::SearchResult& search_result = result.value(); + EXPECT_EQ(make_value<uint8_t>(0x01), search_result.package->id); + EXPECT_EQ(make_value<uint8_t>(0x01), search_result.type->id); + EXPECT_EQ(make_value<uint16_t>(0x0002), search_result.entry->id); } -::testing::AssertionResult verifyIds(ResourceTable* table) { - std::set<uint8_t> packageIds; +::testing::AssertionResult VerifyIds(ResourceTable* table) { + std::set<uint8_t> package_ids; for (auto& package : table->packages) { if (!package->id) { return ::testing::AssertionFailure() << "package " << package->name << " has no ID"; } - if (!packageIds.insert(package->id.value()).second) { + if (!package_ids.insert(package->id.value()).second) { return ::testing::AssertionFailure() << "package " << package->name << " has non-unique ID " << std::hex << (int)package->id.value() << std::dec; @@ -144,7 +145,7 @@ TEST(IdAssignerTest, AssignIdsWithIdMap) { } for (auto& package : table->packages) { - std::set<uint8_t> typeIds; + std::set<uint8_t> type_ids; for (auto& type : package->types) { if (!type->id) { return ::testing::AssertionFailure() << "type " << type->type @@ -152,7 +153,7 @@ TEST(IdAssignerTest, AssignIdsWithIdMap) { << " has no ID"; } - if (!typeIds.insert(type->id.value()).second) { + if (!type_ids.insert(type->id.value()).second) { return ::testing::AssertionFailure() << "type " << type->type << " of package " << package->name << " has non-unique ID " << std::hex << (int)type->id.value() @@ -161,7 +162,7 @@ TEST(IdAssignerTest, AssignIdsWithIdMap) { } for (auto& type : package->types) { - std::set<uint16_t> entryIds; + std::set<uint16_t> entry_ids; for (auto& entry : type->entries) { if (!entry->id) { return ::testing::AssertionFailure() @@ -169,7 +170,7 @@ TEST(IdAssignerTest, AssignIdsWithIdMap) { << " of package " << package->name << " has no ID"; } - if (!entryIds.insert(entry->id.value()).second) { + if (!entry_ids.insert(entry->id.value()).second) { return ::testing::AssertionFailure() << "entry " << entry->name << " of type " << type->type << " of package " << package->name << " has non-unique ID " diff --git a/tools/aapt2/compile/Image.h b/tools/aapt2/compile/Image.h index 4cf2ea788b5c..db0b945e1f18 100644 --- a/tools/aapt2/compile/Image.h +++ b/tools/aapt2/compile/Image.h @@ -17,12 +17,13 @@ #ifndef AAPT_COMPILE_IMAGE_H #define AAPT_COMPILE_IMAGE_H -#include <android-base/macros.h> #include <cstdint> #include <memory> #include <string> #include <vector> +#include "android-base/macros.h" + namespace aapt { /** @@ -113,15 +114,15 @@ inline bool operator==(const Bounds& left, const Bounds& right) { */ class NinePatch { public: - static std::unique_ptr<NinePatch> create(uint8_t** rows, const int32_t width, + static std::unique_ptr<NinePatch> Create(uint8_t** rows, const int32_t width, const int32_t height, - std::string* errOut); + std::string* err_out); /** * Packs the RGBA_8888 data pointed to by pixel into a uint32_t * with format 0xAARRGGBB (the way 9-patch expects it). */ - static uint32_t packRGBA(const uint8_t* pixel); + static uint32_t PackRGBA(const uint8_t* pixel); /** * 9-patch content padding/insets. All positions are relative to the 9-patch @@ -136,7 +137,7 @@ class NinePatch { * See * https://developer.android.com/about/versions/android-4.3.html#OpticalBounds */ - Bounds layoutBounds; + Bounds layout_bounds; /** * Outline of the image, calculated based on opacity. @@ -147,51 +148,51 @@ class NinePatch { * The computed radius of the outline. If non-zero, the outline is a * rounded-rect. */ - float outlineRadius = 0.0f; + float outline_radius = 0.0f; /** * The largest alpha value within the outline. */ - uint32_t outlineAlpha = 0x000000ffu; + uint32_t outline_alpha = 0x000000ffu; /** * Horizontal regions of the image that are stretchable. * All positions are relative to the 9-patch * NOT including the 1px thick source border. */ - std::vector<Range> horizontalStretchRegions; + std::vector<Range> horizontal_stretch_regions; /** * Vertical regions of the image that are stretchable. * All positions are relative to the 9-patch * NOT including the 1px thick source border. */ - std::vector<Range> verticalStretchRegions; + std::vector<Range> vertical_stretch_regions; /** * The colors within each region, fixed or stretchable. * For w*h regions, the color of region (x,y) is addressable * via index y*w + x. */ - std::vector<uint32_t> regionColors; + std::vector<uint32_t> region_colors; /** * Returns serialized data containing the original basic 9-patch meta data. * Optical layout bounds and round rect outline data must be serialized - * separately using serializeOpticalLayoutBounds() and - * serializeRoundedRectOutline(). + * separately using SerializeOpticalLayoutBounds() and + * SerializeRoundedRectOutline(). */ - std::unique_ptr<uint8_t[]> serializeBase(size_t* outLen) const; + std::unique_ptr<uint8_t[]> SerializeBase(size_t* out_len) const; /** * Serializes the layout bounds. */ - std::unique_ptr<uint8_t[]> serializeLayoutBounds(size_t* outLen) const; + std::unique_ptr<uint8_t[]> SerializeLayoutBounds(size_t* out_len) const; /** * Serializes the rounded-rect outline. */ - std::unique_ptr<uint8_t[]> serializeRoundedRectOutline(size_t* outLen) const; + std::unique_ptr<uint8_t[]> SerializeRoundedRectOutline(size_t* out_len) const; private: explicit NinePatch() = default; @@ -201,7 +202,7 @@ class NinePatch { ::std::ostream& operator<<(::std::ostream& out, const Range& range); ::std::ostream& operator<<(::std::ostream& out, const Bounds& bounds); -::std::ostream& operator<<(::std::ostream& out, const NinePatch& ninePatch); +::std::ostream& operator<<(::std::ostream& out, const NinePatch& nine_patch); } // namespace aapt diff --git a/tools/aapt2/compile/InlineXmlFormatParser.cpp b/tools/aapt2/compile/InlineXmlFormatParser.cpp index 56f72b54ab7e..786494b6ad1c 100644 --- a/tools/aapt2/compile/InlineXmlFormatParser.cpp +++ b/tools/aapt2/compile/InlineXmlFormatParser.cpp @@ -15,16 +15,18 @@ */ #include "compile/InlineXmlFormatParser.h" + +#include <sstream> +#include <string> + +#include "android-base/macros.h" + #include "Debug.h" #include "ResourceUtils.h" #include "util/Util.h" #include "xml/XmlDom.h" #include "xml/XmlUtil.h" -#include <android-base/macros.h> -#include <sstream> -#include <string> - namespace aapt { namespace { @@ -34,38 +36,38 @@ namespace { */ class Visitor : public xml::PackageAwareVisitor { public: - using xml::PackageAwareVisitor::visit; + using xml::PackageAwareVisitor::Visit; struct InlineDeclaration { xml::Element* el; - std::string attrNamespaceUri; - std::string attrName; + std::string attr_namespace_uri; + std::string attr_name; }; - explicit Visitor(IAaptContext* context, xml::XmlResource* xmlResource) - : mContext(context), mXmlResource(xmlResource) {} + explicit Visitor(IAaptContext* context, xml::XmlResource* xml_resource) + : context_(context), xml_resource_(xml_resource) {} - void visit(xml::Element* el) override { - if (el->namespaceUri != xml::kSchemaAapt || el->name != "attr") { - xml::PackageAwareVisitor::visit(el); + void Visit(xml::Element* el) override { + if (el->namespace_uri != xml::kSchemaAapt || el->name != "attr") { + xml::PackageAwareVisitor::Visit(el); return; } - const Source& src = mXmlResource->file.source.withLine(el->lineNumber); + const Source& src = xml_resource_->file.source.WithLine(el->line_number); - xml::Attribute* attr = el->findAttribute({}, "name"); + xml::Attribute* attr = el->FindAttribute({}, "name"); if (!attr) { - mContext->getDiagnostics()->error(DiagMessage(src) + context_->GetDiagnostics()->Error(DiagMessage(src) << "missing 'name' attribute"); - mError = true; + error_ = true; return; } - Maybe<Reference> ref = ResourceUtils::parseXmlAttributeName(attr->value); + Maybe<Reference> ref = ResourceUtils::ParseXmlAttributeName(attr->value); if (!ref) { - mContext->getDiagnostics()->error( + context_->GetDiagnostics()->Error( DiagMessage(src) << "invalid XML attribute '" << attr->value << "'"); - mError = true; + error_ = true; return; } @@ -76,63 +78,63 @@ class Visitor : public xml::PackageAwareVisitor { // the local package if the user specified name="style" or something. This // should just // be the default namespace. - Maybe<xml::ExtractedPackage> maybePkg = - transformPackageAlias(name.package, {}); - if (!maybePkg) { - mContext->getDiagnostics()->error(DiagMessage(src) + Maybe<xml::ExtractedPackage> maybe_pkg = + TransformPackageAlias(name.package, {}); + if (!maybe_pkg) { + context_->GetDiagnostics()->Error(DiagMessage(src) << "invalid namespace prefix '" << name.package << "'"); - mError = true; + error_ = true; return; } - const xml::ExtractedPackage& pkg = maybePkg.value(); - const bool privateNamespace = - pkg.privateNamespace || ref.value().privateReference; + const xml::ExtractedPackage& pkg = maybe_pkg.value(); + const bool private_namespace = + pkg.private_namespace || ref.value().private_reference; InlineDeclaration decl; decl.el = el; - decl.attrName = name.entry; + decl.attr_name = name.entry; if (!pkg.package.empty()) { - decl.attrNamespaceUri = - xml::buildPackageNamespace(pkg.package, privateNamespace); + decl.attr_namespace_uri = + xml::BuildPackageNamespace(pkg.package, private_namespace); } - mInlineDeclarations.push_back(std::move(decl)); + inline_declarations_.push_back(std::move(decl)); } - const std::vector<InlineDeclaration>& getInlineDeclarations() const { - return mInlineDeclarations; + const std::vector<InlineDeclaration>& GetInlineDeclarations() const { + return inline_declarations_; } - bool hasError() const { return mError; } + bool HasError() const { return error_; } private: DISALLOW_COPY_AND_ASSIGN(Visitor); - IAaptContext* mContext; - xml::XmlResource* mXmlResource; - std::vector<InlineDeclaration> mInlineDeclarations; - bool mError = false; + IAaptContext* context_; + xml::XmlResource* xml_resource_; + std::vector<InlineDeclaration> inline_declarations_; + bool error_ = false; }; } // namespace -bool InlineXmlFormatParser::consume(IAaptContext* context, +bool InlineXmlFormatParser::Consume(IAaptContext* context, xml::XmlResource* doc) { Visitor visitor(context, doc); - doc->root->accept(&visitor); - if (visitor.hasError()) { + doc->root->Accept(&visitor); + if (visitor.HasError()) { return false; } - size_t nameSuffixCounter = 0; + size_t name_suffix_counter = 0; for (const Visitor::InlineDeclaration& decl : - visitor.getInlineDeclarations()) { - auto newDoc = util::make_unique<xml::XmlResource>(); - newDoc->file.config = doc->file.config; - newDoc->file.source = doc->file.source.withLine(decl.el->lineNumber); - newDoc->file.name = doc->file.name; + visitor.GetInlineDeclarations()) { + auto new_doc = util::make_unique<xml::XmlResource>(); + new_doc->file.config = doc->file.config; + new_doc->file.source = doc->file.source.WithLine(decl.el->line_number); + new_doc->file.name = doc->file.name; // Modify the new entry name. We need to suffix the entry with a number to // avoid @@ -140,63 +142,64 @@ bool InlineXmlFormatParser::consume(IAaptContext* context, // won't show up // in R.java. - newDoc->file.name.entry = NameMangler::mangleEntry( - {}, newDoc->file.name.entry + "__" + std::to_string(nameSuffixCounter)); + new_doc->file.name.entry = + NameMangler::MangleEntry({}, new_doc->file.name.entry + "__" + + std::to_string(name_suffix_counter)); // Extracted elements must be the only child of <aapt:attr>. // Make sure there is one root node in the children (ignore empty text). for (auto& child : decl.el->children) { - const Source childSource = doc->file.source.withLine(child->lineNumber); - if (xml::Text* t = xml::nodeCast<xml::Text>(child.get())) { - if (!util::trimWhitespace(t->text).empty()) { - context->getDiagnostics()->error( - DiagMessage(childSource) + const Source child_source = doc->file.source.WithLine(child->line_number); + if (xml::Text* t = xml::NodeCast<xml::Text>(child.get())) { + if (!util::TrimWhitespace(t->text).empty()) { + context->GetDiagnostics()->Error( + DiagMessage(child_source) << "can't extract text into its own resource"); return false; } - } else if (newDoc->root) { - context->getDiagnostics()->error( - DiagMessage(childSource) + } else if (new_doc->root) { + context->GetDiagnostics()->Error( + DiagMessage(child_source) << "inline XML resources must have a single root"); return false; } else { - newDoc->root = std::move(child); - newDoc->root->parent = nullptr; + new_doc->root = std::move(child); + new_doc->root->parent = nullptr; } } // Walk up and find the parent element. xml::Node* node = decl.el; - xml::Element* parentEl = nullptr; + xml::Element* parent_el = nullptr; while (node->parent && - (parentEl = xml::nodeCast<xml::Element>(node->parent)) == nullptr) { + (parent_el = xml::NodeCast<xml::Element>(node->parent)) == nullptr) { node = node->parent; } - if (!parentEl) { - context->getDiagnostics()->error( - DiagMessage(newDoc->file.source) + if (!parent_el) { + context->GetDiagnostics()->Error( + DiagMessage(new_doc->file.source) << "no suitable parent for inheriting attribute"); return false; } // Add the inline attribute to the parent. - parentEl->attributes.push_back( - xml::Attribute{decl.attrNamespaceUri, decl.attrName, - "@" + newDoc->file.name.toString()}); + parent_el->attributes.push_back( + xml::Attribute{decl.attr_namespace_uri, decl.attr_name, + "@" + new_doc->file.name.ToString()}); // Delete the subtree. - for (auto iter = parentEl->children.begin(); - iter != parentEl->children.end(); ++iter) { + for (auto iter = parent_el->children.begin(); + iter != parent_el->children.end(); ++iter) { if (iter->get() == node) { - parentEl->children.erase(iter); + parent_el->children.erase(iter); break; } } - mQueue.push_back(std::move(newDoc)); + queue_.push_back(std::move(new_doc)); - nameSuffixCounter++; + name_suffix_counter++; } return true; } diff --git a/tools/aapt2/compile/InlineXmlFormatParser.h b/tools/aapt2/compile/InlineXmlFormatParser.h index cd8794ba9cc3..1a658fd6a180 100644 --- a/tools/aapt2/compile/InlineXmlFormatParser.h +++ b/tools/aapt2/compile/InlineXmlFormatParser.h @@ -17,12 +17,13 @@ #ifndef AAPT_COMPILE_INLINEXMLFORMATPARSER_H #define AAPT_COMPILE_INLINEXMLFORMATPARSER_H -#include "process/IResourceTableConsumer.h" - -#include <android-base/macros.h> #include <memory> #include <vector> +#include "android-base/macros.h" + +#include "process/IResourceTableConsumer.h" + namespace aapt { /** @@ -50,17 +51,17 @@ class InlineXmlFormatParser : public IXmlResourceConsumer { public: explicit InlineXmlFormatParser() = default; - bool consume(IAaptContext* context, xml::XmlResource* doc) override; + bool Consume(IAaptContext* context, xml::XmlResource* doc) override; std::vector<std::unique_ptr<xml::XmlResource>>& - getExtractedInlineXmlDocuments() { - return mQueue; + GetExtractedInlineXmlDocuments() { + return queue_; } private: DISALLOW_COPY_AND_ASSIGN(InlineXmlFormatParser); - std::vector<std::unique_ptr<xml::XmlResource>> mQueue; + std::vector<std::unique_ptr<xml::XmlResource>> queue_; }; } // namespace aapt diff --git a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp index 4adb21cf9830..348796c98c22 100644 --- a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp +++ b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp @@ -15,13 +15,14 @@ */ #include "compile/InlineXmlFormatParser.h" + #include "test/Test.h" namespace aapt { TEST(InlineXmlFormatParserTest, PassThrough) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); - std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF( + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android"> <View android:text="hey"> <View android:id="hi" /> @@ -29,13 +30,13 @@ TEST(InlineXmlFormatParserTest, PassThrough) { </View>)EOF"); InlineXmlFormatParser parser; - ASSERT_TRUE(parser.consume(context.get(), doc.get())); - EXPECT_EQ(0u, parser.getExtractedInlineXmlDocuments().size()); + ASSERT_TRUE(parser.Consume(context.get(), doc.get())); + EXPECT_EQ(0u, parser.GetExtractedInlineXmlDocuments().size()); } TEST(InlineXmlFormatParserTest, ExtractOneXmlResource) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); - std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF( + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( <View1 xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> <aapt:attr name="android:text"> @@ -45,48 +46,48 @@ TEST(InlineXmlFormatParserTest, ExtractOneXmlResource) { </aapt:attr> </View1>)EOF"); - doc->file.name = test::parseNameOrDie("layout/main"); + doc->file.name = test::ParseNameOrDie("layout/main"); InlineXmlFormatParser parser; - ASSERT_TRUE(parser.consume(context.get(), doc.get())); + ASSERT_TRUE(parser.Consume(context.get(), doc.get())); // One XML resource should have been extracted. - EXPECT_EQ(1u, parser.getExtractedInlineXmlDocuments().size()); + EXPECT_EQ(1u, parser.GetExtractedInlineXmlDocuments().size()); - xml::Element* el = xml::findRootElement(doc.get()); + xml::Element* el = xml::FindRootElement(doc.get()); ASSERT_NE(nullptr, el); EXPECT_EQ("View1", el->name); // The <aapt:attr> tag should be extracted. - EXPECT_EQ(nullptr, el->findChild(xml::kSchemaAapt, "attr")); + EXPECT_EQ(nullptr, el->FindChild(xml::kSchemaAapt, "attr")); // The 'android:text' attribute should be set with a reference. - xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, "text"); + xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "text"); ASSERT_NE(nullptr, attr); - ResourceNameRef nameRef; - ASSERT_TRUE(ResourceUtils::parseReference(attr->value, &nameRef)); + ResourceNameRef name_ref; + ASSERT_TRUE(ResourceUtils::ParseReference(attr->value, &name_ref)); - xml::XmlResource* extractedDoc = - parser.getExtractedInlineXmlDocuments()[0].get(); - ASSERT_NE(nullptr, extractedDoc); + xml::XmlResource* extracted_doc = + parser.GetExtractedInlineXmlDocuments()[0].get(); + ASSERT_NE(nullptr, extracted_doc); // Make sure the generated reference is correct. - EXPECT_EQ(nameRef.package, extractedDoc->file.name.package); - EXPECT_EQ(nameRef.type, extractedDoc->file.name.type); - EXPECT_EQ(nameRef.entry, extractedDoc->file.name.entry); + EXPECT_EQ(name_ref.package, extracted_doc->file.name.package); + EXPECT_EQ(name_ref.type, extracted_doc->file.name.type); + EXPECT_EQ(name_ref.entry, extracted_doc->file.name.entry); // Verify the structure of the extracted XML. - el = xml::findRootElement(extractedDoc); + el = xml::FindRootElement(extracted_doc); ASSERT_NE(nullptr, el); EXPECT_EQ("View2", el->name); - EXPECT_NE(nullptr, el->findChild({}, "View3")); + EXPECT_NE(nullptr, el->FindChild({}, "View3")); } TEST(InlineXmlFormatParserTest, ExtractTwoXmlResources) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); - std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF( + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( <View1 xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> <aapt:attr name="android:text"> @@ -100,41 +101,41 @@ TEST(InlineXmlFormatParserTest, ExtractTwoXmlResources) { </aapt:attr> </View1>)EOF"); - doc->file.name = test::parseNameOrDie("layout/main"); + doc->file.name = test::ParseNameOrDie("layout/main"); InlineXmlFormatParser parser; - ASSERT_TRUE(parser.consume(context.get(), doc.get())); - ASSERT_EQ(2u, parser.getExtractedInlineXmlDocuments().size()); + ASSERT_TRUE(parser.Consume(context.get(), doc.get())); + ASSERT_EQ(2u, parser.GetExtractedInlineXmlDocuments().size()); - xml::Element* el = xml::findRootElement(doc.get()); + xml::Element* el = xml::FindRootElement(doc.get()); ASSERT_NE(nullptr, el); EXPECT_EQ("View1", el->name); - xml::Attribute* attrText = el->findAttribute(xml::kSchemaAndroid, "text"); - ASSERT_NE(nullptr, attrText); + xml::Attribute* attr_text = el->FindAttribute(xml::kSchemaAndroid, "text"); + ASSERT_NE(nullptr, attr_text); - xml::Attribute* attrDrawable = - el->findAttribute(xml::kSchemaAndroid, "drawable"); - ASSERT_NE(nullptr, attrDrawable); + xml::Attribute* attr_drawable = + el->FindAttribute(xml::kSchemaAndroid, "drawable"); + ASSERT_NE(nullptr, attr_drawable); // The two extracted resources should have different names. - EXPECT_NE(attrText->value, attrDrawable->value); + EXPECT_NE(attr_text->value, attr_drawable->value); // The child <aapt:attr> elements should be gone. - EXPECT_EQ(nullptr, el->findChild(xml::kSchemaAapt, "attr")); + EXPECT_EQ(nullptr, el->FindChild(xml::kSchemaAapt, "attr")); - xml::XmlResource* extractedDocText = - parser.getExtractedInlineXmlDocuments()[0].get(); - ASSERT_NE(nullptr, extractedDocText); - el = xml::findRootElement(extractedDocText); + xml::XmlResource* extracted_doc_text = + parser.GetExtractedInlineXmlDocuments()[0].get(); + ASSERT_NE(nullptr, extracted_doc_text); + el = xml::FindRootElement(extracted_doc_text); ASSERT_NE(nullptr, el); EXPECT_EQ("View2", el->name); - xml::XmlResource* extractedDocDrawable = - parser.getExtractedInlineXmlDocuments()[1].get(); - ASSERT_NE(nullptr, extractedDocDrawable); - el = xml::findRootElement(extractedDocDrawable); + xml::XmlResource* extracted_doc_drawable = + parser.GetExtractedInlineXmlDocuments()[1].get(); + ASSERT_NE(nullptr, extracted_doc_drawable); + el = xml::FindRootElement(extracted_doc_drawable); ASSERT_NE(nullptr, el); EXPECT_EQ("vector", el->name); } diff --git a/tools/aapt2/compile/NinePatch.cpp b/tools/aapt2/compile/NinePatch.cpp index 8842eb70f3a0..eab5c97c437c 100644 --- a/tools/aapt2/compile/NinePatch.cpp +++ b/tools/aapt2/compile/NinePatch.cpp @@ -15,14 +15,16 @@ */ #include "compile/Image.h" -#include "util/StringPiece.h" -#include "util/Util.h" -#include <androidfw/ResourceTypes.h> #include <sstream> #include <string> #include <vector> +#include "androidfw/ResourceTypes.h" + +#include "util/StringPiece.h" +#include "util/Util.h" + namespace aapt { // Colors in the format 0xAARRGGBB (the way 9-patch expects it). @@ -36,7 +38,7 @@ constexpr static const uint32_t kSecondaryColor = kColorOpaqueRed; /** * Returns the alpha value encoded in the 0xAARRGBB encoded pixel. */ -static uint32_t getAlpha(uint32_t color); +static uint32_t get_alpha(uint32_t color); /** * Determines whether a color on an ImageLine is valid. @@ -53,19 +55,19 @@ class ColorValidator { * Returns true if the color specified is a neutral color * (no padding, stretching, or optical bounds). */ - virtual bool isNeutralColor(uint32_t color) const = 0; + virtual bool IsNeutralColor(uint32_t color) const = 0; /** * Returns true if the color is either a neutral color * or one denoting padding, stretching, or optical bounds. */ - bool isValidColor(uint32_t color) const { + bool IsValidColor(uint32_t color) const { switch (color) { case kPrimaryColor: case kSecondaryColor: return true; } - return isNeutralColor(color); + return IsNeutralColor(color); } }; @@ -81,42 +83,43 @@ class ColorValidator { // // class ImageLine { // public: -// virtual int32_t getLength() const = 0; -// virtual uint32_t getColor(int32_t idx) const = 0; +// virtual int32_t GetLength() const = 0; +// virtual uint32_t GetColor(int32_t idx) const = 0; // }; // template <typename ImageLine> -static bool fillRanges(const ImageLine* imageLine, - const ColorValidator* colorValidator, - std::vector<Range>* primaryRanges, - std::vector<Range>* secondaryRanges, std::string* err) { - const int32_t length = imageLine->getLength(); - - uint32_t lastColor = 0xffffffffu; +static bool FillRanges(const ImageLine* image_line, + const ColorValidator* color_validator, + std::vector<Range>* primary_ranges, + std::vector<Range>* secondary_ranges, + std::string* out_err) { + const int32_t length = image_line->GetLength(); + + uint32_t last_color = 0xffffffffu; for (int32_t idx = 1; idx < length - 1; idx++) { - const uint32_t color = imageLine->getColor(idx); - if (!colorValidator->isValidColor(color)) { - *err = "found an invalid color"; + const uint32_t color = image_line->GetColor(idx); + if (!color_validator->IsValidColor(color)) { + *out_err = "found an invalid color"; return false; } - if (color != lastColor) { + if (color != last_color) { // We are ending a range. Which range? // note: encode the x offset without the final 1 pixel border. - if (lastColor == kPrimaryColor) { - primaryRanges->back().end = idx - 1; - } else if (lastColor == kSecondaryColor) { - secondaryRanges->back().end = idx - 1; + if (last_color == kPrimaryColor) { + primary_ranges->back().end = idx - 1; + } else if (last_color == kSecondaryColor) { + secondary_ranges->back().end = idx - 1; } // We are starting a range. Which range? // note: encode the x offset without the final 1 pixel border. if (color == kPrimaryColor) { - primaryRanges->push_back(Range(idx - 1, length - 2)); + primary_ranges->push_back(Range(idx - 1, length - 2)); } else if (color == kSecondaryColor) { - secondaryRanges->push_back(Range(idx - 1, length - 2)); + secondary_ranges->push_back(Range(idx - 1, length - 2)); } - lastColor = color; + last_color = color; } } return true; @@ -128,19 +131,19 @@ static bool fillRanges(const ImageLine* imageLine, */ class HorizontalImageLine { public: - explicit HorizontalImageLine(uint8_t** rows, int32_t xOffset, int32_t yOffset, + explicit HorizontalImageLine(uint8_t** rows, int32_t xoffset, int32_t yoffset, int32_t length) - : mRows(rows), mXOffset(xOffset), mYOffset(yOffset), mLength(length) {} + : rows_(rows), xoffset_(xoffset), yoffset_(yoffset), length_(length) {} - inline int32_t getLength() const { return mLength; } + inline int32_t GetLength() const { return length_; } - inline uint32_t getColor(int32_t idx) const { - return NinePatch::packRGBA(mRows[mYOffset] + (idx + mXOffset) * 4); + inline uint32_t GetColor(int32_t idx) const { + return NinePatch::PackRGBA(rows_[yoffset_] + (idx + xoffset_) * 4); } private: - uint8_t** mRows; - int32_t mXOffset, mYOffset, mLength; + uint8_t** rows_; + int32_t xoffset_, yoffset_, length_; DISALLOW_COPY_AND_ASSIGN(HorizontalImageLine); }; @@ -151,179 +154,180 @@ class HorizontalImageLine { */ class VerticalImageLine { public: - explicit VerticalImageLine(uint8_t** rows, int32_t xOffset, int32_t yOffset, + explicit VerticalImageLine(uint8_t** rows, int32_t xoffset, int32_t yoffset, int32_t length) - : mRows(rows), mXOffset(xOffset), mYOffset(yOffset), mLength(length) {} + : rows_(rows), xoffset_(xoffset), yoffset_(yoffset), length_(length) {} - inline int32_t getLength() const { return mLength; } + inline int32_t GetLength() const { return length_; } - inline uint32_t getColor(int32_t idx) const { - return NinePatch::packRGBA(mRows[mYOffset + idx] + (mXOffset * 4)); + inline uint32_t GetColor(int32_t idx) const { + return NinePatch::PackRGBA(rows_[yoffset_ + idx] + (xoffset_ * 4)); } private: - uint8_t** mRows; - int32_t mXOffset, mYOffset, mLength; + uint8_t** rows_; + int32_t xoffset_, yoffset_, length_; DISALLOW_COPY_AND_ASSIGN(VerticalImageLine); }; class DiagonalImageLine { public: - explicit DiagonalImageLine(uint8_t** rows, int32_t xOffset, int32_t yOffset, - int32_t xStep, int32_t yStep, int32_t length) - : mRows(rows), - mXOffset(xOffset), - mYOffset(yOffset), - mXStep(xStep), - mYStep(yStep), - mLength(length) {} - - inline int32_t getLength() const { return mLength; } - - inline uint32_t getColor(int32_t idx) const { - return NinePatch::packRGBA(mRows[mYOffset + (idx * mYStep)] + - ((idx + mXOffset) * mXStep) * 4); + explicit DiagonalImageLine(uint8_t** rows, int32_t xoffset, int32_t yoffset, + int32_t xstep, int32_t ystep, int32_t length) + : rows_(rows), + xoffset_(xoffset), + yoffset_(yoffset), + xstep_(xstep), + ystep_(ystep), + length_(length) {} + + inline int32_t GetLength() const { return length_; } + + inline uint32_t GetColor(int32_t idx) const { + return NinePatch::PackRGBA(rows_[yoffset_ + (idx * ystep_)] + + ((idx + xoffset_) * xstep_) * 4); } private: - uint8_t** mRows; - int32_t mXOffset, mYOffset, mXStep, mYStep, mLength; + uint8_t** rows_; + int32_t xoffset_, yoffset_, xstep_, ystep_, length_; DISALLOW_COPY_AND_ASSIGN(DiagonalImageLine); }; class TransparentNeutralColorValidator : public ColorValidator { public: - bool isNeutralColor(uint32_t color) const override { - return getAlpha(color) == 0; + bool IsNeutralColor(uint32_t color) const override { + return get_alpha(color) == 0; } }; class WhiteNeutralColorValidator : public ColorValidator { public: - bool isNeutralColor(uint32_t color) const override { + bool IsNeutralColor(uint32_t color) const override { return color == kColorOpaqueWhite; } }; -inline static uint32_t getAlpha(uint32_t color) { +inline static uint32_t get_alpha(uint32_t color) { return (color & 0xff000000u) >> 24; } -static bool populateBounds(const std::vector<Range>& padding, - const std::vector<Range>& layoutBounds, - const std::vector<Range>& stretchRegions, - const int32_t length, int32_t* paddingStart, - int32_t* paddingEnd, int32_t* layoutStart, - int32_t* layoutEnd, const StringPiece& edgeName, - std::string* err) { +static bool PopulateBounds(const std::vector<Range>& padding, + const std::vector<Range>& layout_bounds, + const std::vector<Range>& stretch_regions, + const int32_t length, int32_t* padding_start, + int32_t* padding_end, int32_t* layout_start, + int32_t* layout_end, const StringPiece& edge_name, + std::string* out_err) { if (padding.size() > 1) { - std::stringstream errStream; - errStream << "too many padding sections on " << edgeName << " border"; - *err = errStream.str(); + std::stringstream err_stream; + err_stream << "too many padding sections on " << edge_name << " border"; + *out_err = err_stream.str(); return false; } - *paddingStart = 0; - *paddingEnd = 0; + *padding_start = 0; + *padding_end = 0; if (!padding.empty()) { const Range& range = padding.front(); - *paddingStart = range.start; - *paddingEnd = length - range.end; - } else if (!stretchRegions.empty()) { + *padding_start = range.start; + *padding_end = length - range.end; + } else if (!stretch_regions.empty()) { // No padding was defined. Compute the padding from the first and last // stretch regions. - *paddingStart = stretchRegions.front().start; - *paddingEnd = length - stretchRegions.back().end; + *padding_start = stretch_regions.front().start; + *padding_end = length - stretch_regions.back().end; } - if (layoutBounds.size() > 2) { - std::stringstream errStream; - errStream << "too many layout bounds sections on " << edgeName << " border"; - *err = errStream.str(); + if (layout_bounds.size() > 2) { + std::stringstream err_stream; + err_stream << "too many layout bounds sections on " << edge_name + << " border"; + *out_err = err_stream.str(); return false; } - *layoutStart = 0; - *layoutEnd = 0; - if (layoutBounds.size() >= 1) { - const Range& range = layoutBounds.front(); + *layout_start = 0; + *layout_end = 0; + if (layout_bounds.size() >= 1) { + const Range& range = layout_bounds.front(); // If there is only one layout bound segment, it might not start at 0, but // then it should // end at length. if (range.start != 0 && range.end != length) { - std::stringstream errStream; - errStream << "layout bounds on " << edgeName - << " border must start at edge"; - *err = errStream.str(); + std::stringstream err_stream; + err_stream << "layout bounds on " << edge_name + << " border must start at edge"; + *out_err = err_stream.str(); return false; } - *layoutStart = range.end; + *layout_start = range.end; - if (layoutBounds.size() >= 2) { - const Range& range = layoutBounds.back(); + if (layout_bounds.size() >= 2) { + const Range& range = layout_bounds.back(); if (range.end != length) { - std::stringstream errStream; - errStream << "layout bounds on " << edgeName - << " border must start at edge"; - *err = errStream.str(); + std::stringstream err_stream; + err_stream << "layout bounds on " << edge_name + << " border must start at edge"; + *out_err = err_stream.str(); return false; } - *layoutEnd = length - range.start; + *layout_end = length - range.start; } } return true; } -static int32_t calculateSegmentCount(const std::vector<Range>& stretchRegions, +static int32_t CalculateSegmentCount(const std::vector<Range>& stretch_regions, int32_t length) { - if (stretchRegions.size() == 0) { + if (stretch_regions.size() == 0) { return 0; } - const bool startIsFixed = stretchRegions.front().start != 0; - const bool endIsFixed = stretchRegions.back().end != length; + const bool start_is_fixed = stretch_regions.front().start != 0; + const bool end_is_fixed = stretch_regions.back().end != length; int32_t modifier = 0; - if (startIsFixed && endIsFixed) { + if (start_is_fixed && end_is_fixed) { modifier = 1; - } else if (!startIsFixed && !endIsFixed) { + } else if (!start_is_fixed && !end_is_fixed) { modifier = -1; } - return static_cast<int32_t>(stretchRegions.size()) * 2 + modifier; + return static_cast<int32_t>(stretch_regions.size()) * 2 + modifier; } -static uint32_t getRegionColor(uint8_t** rows, const Bounds& region) { +static uint32_t GetRegionColor(uint8_t** rows, const Bounds& region) { // Sample the first pixel to compare against. - const uint32_t expectedColor = - NinePatch::packRGBA(rows[region.top] + region.left * 4); + const uint32_t expected_color = + NinePatch::PackRGBA(rows[region.top] + region.left * 4); for (int32_t y = region.top; y < region.bottom; y++) { const uint8_t* row = rows[y]; for (int32_t x = region.left; x < region.right; x++) { - const uint32_t color = NinePatch::packRGBA(row + x * 4); - if (getAlpha(color) == 0) { + const uint32_t color = NinePatch::PackRGBA(row + x * 4); + if (get_alpha(color) == 0) { // The color is transparent. // If the expectedColor is not transparent, NO_COLOR. - if (getAlpha(expectedColor) != 0) { + if (get_alpha(expected_color) != 0) { return android::Res_png_9patch::NO_COLOR; } - } else if (color != expectedColor) { + } else if (color != expected_color) { return android::Res_png_9patch::NO_COLOR; } } } - if (getAlpha(expectedColor) == 0) { + if (get_alpha(expected_color) == 0) { return android::Res_png_9patch::TRANSPARENT_COLOR; } - return expectedColor; + return expected_color; } -// Fills outColors with each 9-patch section's colour. If the whole section is +// Fills out_colors with each 9-patch section's color. If the whole section is // transparent, -// it gets the special TRANSPARENT colour. If the whole section is the same -// colour, it is assigned -// that colour. Otherwise it gets the special NO_COLOR colour. +// it gets the special TRANSPARENT color. If the whole section is the same +// color, it is assigned +// that color. Otherwise it gets the special NO_COLOR color. // // Note that the rows contain the 9-patch 1px border, and the indices in the // stretch regions are @@ -332,63 +336,63 @@ static uint32_t getRegionColor(uint8_t** rows, const Bounds& region) { // the indices must be offset by 1. // // width and height also include the 9-patch 1px border. -static void calculateRegionColors( - uint8_t** rows, const std::vector<Range>& horizontalStretchRegions, - const std::vector<Range>& verticalStretchRegions, const int32_t width, - const int32_t height, std::vector<uint32_t>* outColors) { - int32_t nextTop = 0; +static void CalculateRegionColors( + uint8_t** rows, const std::vector<Range>& horizontal_stretch_regions, + const std::vector<Range>& vertical_stretch_regions, const int32_t width, + const int32_t height, std::vector<uint32_t>* out_colors) { + int32_t next_top = 0; Bounds bounds; - auto rowIter = verticalStretchRegions.begin(); - while (nextTop != height) { - if (rowIter != verticalStretchRegions.end()) { - if (nextTop != rowIter->start) { + auto row_iter = vertical_stretch_regions.begin(); + while (next_top != height) { + if (row_iter != vertical_stretch_regions.end()) { + if (next_top != row_iter->start) { // This is a fixed segment. // Offset the bounds by 1 to accommodate the border. - bounds.top = nextTop + 1; - bounds.bottom = rowIter->start + 1; - nextTop = rowIter->start; + bounds.top = next_top + 1; + bounds.bottom = row_iter->start + 1; + next_top = row_iter->start; } else { // This is a stretchy segment. // Offset the bounds by 1 to accommodate the border. - bounds.top = rowIter->start + 1; - bounds.bottom = rowIter->end + 1; - nextTop = rowIter->end; - ++rowIter; + bounds.top = row_iter->start + 1; + bounds.bottom = row_iter->end + 1; + next_top = row_iter->end; + ++row_iter; } } else { // This is the end, fixed section. // Offset the bounds by 1 to accommodate the border. - bounds.top = nextTop + 1; + bounds.top = next_top + 1; bounds.bottom = height + 1; - nextTop = height; + next_top = height; } - int32_t nextLeft = 0; - auto colIter = horizontalStretchRegions.begin(); - while (nextLeft != width) { - if (colIter != horizontalStretchRegions.end()) { - if (nextLeft != colIter->start) { + int32_t next_left = 0; + auto col_iter = horizontal_stretch_regions.begin(); + while (next_left != width) { + if (col_iter != horizontal_stretch_regions.end()) { + if (next_left != col_iter->start) { // This is a fixed segment. // Offset the bounds by 1 to accommodate the border. - bounds.left = nextLeft + 1; - bounds.right = colIter->start + 1; - nextLeft = colIter->start; + bounds.left = next_left + 1; + bounds.right = col_iter->start + 1; + next_left = col_iter->start; } else { // This is a stretchy segment. // Offset the bounds by 1 to accommodate the border. - bounds.left = colIter->start + 1; - bounds.right = colIter->end + 1; - nextLeft = colIter->end; - ++colIter; + bounds.left = col_iter->start + 1; + bounds.right = col_iter->end + 1; + next_left = col_iter->end; + ++col_iter; } } else { // This is the end, fixed section. // Offset the bounds by 1 to accommodate the border. - bounds.left = nextLeft + 1; + bounds.left = next_left + 1; bounds.right = width + 1; - nextLeft = width; + next_left = width; } - outColors->push_back(getRegionColor(rows, bounds)); + out_colors->push_back(GetRegionColor(rows, bounds)); } } } @@ -397,12 +401,12 @@ static void calculateRegionColors( // alpha value begins // (on both sides). template <typename ImageLine> -static void findOutlineInsets(const ImageLine* imageLine, int32_t* outStart, - int32_t* outEnd) { - *outStart = 0; - *outEnd = 0; +static void FindOutlineInsets(const ImageLine* image_line, int32_t* out_start, + int32_t* out_end) { + *out_start = 0; + *out_end = 0; - const int32_t length = imageLine->getLength(); + const int32_t length = image_line->GetLength(); if (length < 3) { return; } @@ -413,179 +417,181 @@ static void findOutlineInsets(const ImageLine* imageLine, int32_t* outStart, const int32_t mid2 = length / 2; const int32_t mid1 = mid2 + (length % 2); - uint32_t maxAlpha = 0; - for (int32_t i = 0; i < mid1 && maxAlpha != 0xff; i++) { - uint32_t alpha = getAlpha(imageLine->getColor(i)); - if (alpha > maxAlpha) { - maxAlpha = alpha; - *outStart = i; + uint32_t max_alpha = 0; + for (int32_t i = 0; i < mid1 && max_alpha != 0xff; i++) { + uint32_t alpha = get_alpha(image_line->GetColor(i)); + if (alpha > max_alpha) { + max_alpha = alpha; + *out_start = i; } } - maxAlpha = 0; - for (int32_t i = length - 1; i >= mid2 && maxAlpha != 0xff; i--) { - uint32_t alpha = getAlpha(imageLine->getColor(i)); - if (alpha > maxAlpha) { - maxAlpha = alpha; - *outEnd = length - (i + 1); + max_alpha = 0; + for (int32_t i = length - 1; i >= mid2 && max_alpha != 0xff; i--) { + uint32_t alpha = get_alpha(image_line->GetColor(i)); + if (alpha > max_alpha) { + max_alpha = alpha; + *out_end = length - (i + 1); } } return; } template <typename ImageLine> -static uint32_t findMaxAlpha(const ImageLine* imageLine) { - const int32_t length = imageLine->getLength(); - uint32_t maxAlpha = 0; - for (int32_t idx = 0; idx < length && maxAlpha != 0xff; idx++) { - uint32_t alpha = getAlpha(imageLine->getColor(idx)); - if (alpha > maxAlpha) { - maxAlpha = alpha; +static uint32_t FindMaxAlpha(const ImageLine* image_line) { + const int32_t length = image_line->GetLength(); + uint32_t max_alpha = 0; + for (int32_t idx = 0; idx < length && max_alpha != 0xff; idx++) { + uint32_t alpha = get_alpha(image_line->GetColor(idx)); + if (alpha > max_alpha) { + max_alpha = alpha; } } - return maxAlpha; + return max_alpha; } // Pack the pixels in as 0xAARRGGBB (as 9-patch expects it). -uint32_t NinePatch::packRGBA(const uint8_t* pixel) { +uint32_t NinePatch::PackRGBA(const uint8_t* pixel) { return (pixel[3] << 24) | (pixel[0] << 16) | (pixel[1] << 8) | pixel[2]; } -std::unique_ptr<NinePatch> NinePatch::create(uint8_t** rows, +std::unique_ptr<NinePatch> NinePatch::Create(uint8_t** rows, const int32_t width, const int32_t height, - std::string* err) { + std::string* out_err) { if (width < 3 || height < 3) { - *err = "image must be at least 3x3 (1x1 image with 1 pixel border)"; + *out_err = "image must be at least 3x3 (1x1 image with 1 pixel border)"; return {}; } - std::vector<Range> horizontalPadding; - std::vector<Range> horizontalOpticalBounds; - std::vector<Range> verticalPadding; - std::vector<Range> verticalOpticalBounds; - std::vector<Range> unexpectedRanges; - std::unique_ptr<ColorValidator> colorValidator; + std::vector<Range> horizontal_padding; + std::vector<Range> horizontal_layout_bounds; + std::vector<Range> vertical_padding; + std::vector<Range> vertical_layout_bounds; + std::vector<Range> unexpected_ranges; + std::unique_ptr<ColorValidator> color_validator; if (rows[0][3] == 0) { - colorValidator = util::make_unique<TransparentNeutralColorValidator>(); - } else if (packRGBA(rows[0]) == kColorOpaqueWhite) { - colorValidator = util::make_unique<WhiteNeutralColorValidator>(); + color_validator = util::make_unique<TransparentNeutralColorValidator>(); + } else if (PackRGBA(rows[0]) == kColorOpaqueWhite) { + color_validator = util::make_unique<WhiteNeutralColorValidator>(); } else { - *err = "top-left corner pixel must be either opaque white or transparent"; + *out_err = + "top-left corner pixel must be either opaque white or transparent"; return {}; } // Private constructor, can't use make_unique. - auto ninePatch = std::unique_ptr<NinePatch>(new NinePatch()); + auto nine_patch = std::unique_ptr<NinePatch>(new NinePatch()); - HorizontalImageLine topRow(rows, 0, 0, width); - if (!fillRanges(&topRow, colorValidator.get(), - &ninePatch->horizontalStretchRegions, &unexpectedRanges, - err)) { + HorizontalImageLine top_row(rows, 0, 0, width); + if (!FillRanges(&top_row, color_validator.get(), + &nine_patch->horizontal_stretch_regions, &unexpected_ranges, + out_err)) { return {}; } - if (!unexpectedRanges.empty()) { - const Range& range = unexpectedRanges[0]; - std::stringstream errStream; - errStream << "found unexpected optical bounds (red pixel) on top border " - << "at x=" << range.start + 1; - *err = errStream.str(); + if (!unexpected_ranges.empty()) { + const Range& range = unexpected_ranges[0]; + std::stringstream err_stream; + err_stream << "found unexpected optical bounds (red pixel) on top border " + << "at x=" << range.start + 1; + *out_err = err_stream.str(); return {}; } - VerticalImageLine leftCol(rows, 0, 0, height); - if (!fillRanges(&leftCol, colorValidator.get(), - &ninePatch->verticalStretchRegions, &unexpectedRanges, err)) { + VerticalImageLine left_col(rows, 0, 0, height); + if (!FillRanges(&left_col, color_validator.get(), + &nine_patch->vertical_stretch_regions, &unexpected_ranges, + out_err)) { return {}; } - if (!unexpectedRanges.empty()) { - const Range& range = unexpectedRanges[0]; - std::stringstream errStream; - errStream << "found unexpected optical bounds (red pixel) on left border " - << "at y=" << range.start + 1; + if (!unexpected_ranges.empty()) { + const Range& range = unexpected_ranges[0]; + std::stringstream err_stream; + err_stream << "found unexpected optical bounds (red pixel) on left border " + << "at y=" << range.start + 1; return {}; } - HorizontalImageLine bottomRow(rows, 0, height - 1, width); - if (!fillRanges(&bottomRow, colorValidator.get(), &horizontalPadding, - &horizontalOpticalBounds, err)) { + HorizontalImageLine bottom_row(rows, 0, height - 1, width); + if (!FillRanges(&bottom_row, color_validator.get(), &horizontal_padding, + &horizontal_layout_bounds, out_err)) { return {}; } - if (!populateBounds(horizontalPadding, horizontalOpticalBounds, - ninePatch->horizontalStretchRegions, width - 2, - &ninePatch->padding.left, &ninePatch->padding.right, - &ninePatch->layoutBounds.left, - &ninePatch->layoutBounds.right, "bottom", err)) { + if (!PopulateBounds(horizontal_padding, horizontal_layout_bounds, + nine_patch->horizontal_stretch_regions, width - 2, + &nine_patch->padding.left, &nine_patch->padding.right, + &nine_patch->layout_bounds.left, + &nine_patch->layout_bounds.right, "bottom", out_err)) { return {}; } - VerticalImageLine rightCol(rows, width - 1, 0, height); - if (!fillRanges(&rightCol, colorValidator.get(), &verticalPadding, - &verticalOpticalBounds, err)) { + VerticalImageLine right_col(rows, width - 1, 0, height); + if (!FillRanges(&right_col, color_validator.get(), &vertical_padding, + &vertical_layout_bounds, out_err)) { return {}; } - if (!populateBounds(verticalPadding, verticalOpticalBounds, - ninePatch->verticalStretchRegions, height - 2, - &ninePatch->padding.top, &ninePatch->padding.bottom, - &ninePatch->layoutBounds.top, - &ninePatch->layoutBounds.bottom, "right", err)) { + if (!PopulateBounds(vertical_padding, vertical_layout_bounds, + nine_patch->vertical_stretch_regions, height - 2, + &nine_patch->padding.top, &nine_patch->padding.bottom, + &nine_patch->layout_bounds.top, + &nine_patch->layout_bounds.bottom, "right", out_err)) { return {}; } // Fill the region colors of the 9-patch. - const int32_t numRows = - calculateSegmentCount(ninePatch->horizontalStretchRegions, width - 2); - const int32_t numCols = - calculateSegmentCount(ninePatch->verticalStretchRegions, height - 2); - if ((int64_t)numRows * (int64_t)numCols > 0x7f) { - *err = "too many regions in 9-patch"; + const int32_t num_rows = + CalculateSegmentCount(nine_patch->horizontal_stretch_regions, width - 2); + const int32_t num_cols = + CalculateSegmentCount(nine_patch->vertical_stretch_regions, height - 2); + if ((int64_t)num_rows * (int64_t)num_cols > 0x7f) { + *out_err = "too many regions in 9-patch"; return {}; } - ninePatch->regionColors.reserve(numRows * numCols); - calculateRegionColors(rows, ninePatch->horizontalStretchRegions, - ninePatch->verticalStretchRegions, width - 2, - height - 2, &ninePatch->regionColors); + nine_patch->region_colors.reserve(num_rows * num_cols); + CalculateRegionColors(rows, nine_patch->horizontal_stretch_regions, + nine_patch->vertical_stretch_regions, width - 2, + height - 2, &nine_patch->region_colors); // Compute the outline based on opacity. // Find left and right extent of 9-patch content on center row. - HorizontalImageLine midRow(rows, 1, height / 2, width - 2); - findOutlineInsets(&midRow, &ninePatch->outline.left, - &ninePatch->outline.right); + HorizontalImageLine mid_row(rows, 1, height / 2, width - 2); + FindOutlineInsets(&mid_row, &nine_patch->outline.left, + &nine_patch->outline.right); // Find top and bottom extent of 9-patch content on center column. - VerticalImageLine midCol(rows, width / 2, 1, height - 2); - findOutlineInsets(&midCol, &ninePatch->outline.top, - &ninePatch->outline.bottom); + VerticalImageLine mid_col(rows, width / 2, 1, height - 2); + FindOutlineInsets(&mid_col, &nine_patch->outline.top, + &nine_patch->outline.bottom); - const int32_t outlineWidth = - (width - 2) - ninePatch->outline.left - ninePatch->outline.right; - const int32_t outlineHeight = - (height - 2) - ninePatch->outline.top - ninePatch->outline.bottom; + const int32_t outline_width = + (width - 2) - nine_patch->outline.left - nine_patch->outline.right; + const int32_t outline_height = + (height - 2) - nine_patch->outline.top - nine_patch->outline.bottom; // Find the largest alpha value within the outline area. - HorizontalImageLine outlineMidRow( - rows, 1 + ninePatch->outline.left, - 1 + ninePatch->outline.top + (outlineHeight / 2), outlineWidth); - VerticalImageLine outlineMidCol( - rows, 1 + ninePatch->outline.left + (outlineWidth / 2), - 1 + ninePatch->outline.top, outlineHeight); - ninePatch->outlineAlpha = - std::max(findMaxAlpha(&outlineMidRow), findMaxAlpha(&outlineMidCol)); + HorizontalImageLine outline_mid_row( + rows, 1 + nine_patch->outline.left, + 1 + nine_patch->outline.top + (outline_height / 2), outline_width); + VerticalImageLine outline_mid_col( + rows, 1 + nine_patch->outline.left + (outline_width / 2), + 1 + nine_patch->outline.top, outline_height); + nine_patch->outline_alpha = + std::max(FindMaxAlpha(&outline_mid_row), FindMaxAlpha(&outline_mid_col)); // Assuming the image is a round rect, compute the radius by marching // diagonally from the top left corner towards the center. - DiagonalImageLine diagonal(rows, 1 + ninePatch->outline.left, - 1 + ninePatch->outline.top, 1, 1, - std::min(outlineWidth, outlineHeight)); - int32_t topLeft, bottomRight; - findOutlineInsets(&diagonal, &topLeft, &bottomRight); + DiagonalImageLine diagonal(rows, 1 + nine_patch->outline.left, + 1 + nine_patch->outline.top, 1, 1, + std::min(outline_width, outline_height)); + int32_t top_left, bottom_right; + FindOutlineInsets(&diagonal, &top_left, &bottom_right); /* Determine source radius based upon inset: * sqrt(r^2 + r^2) = sqrt(i^2 + i^2) + r @@ -593,15 +599,15 @@ std::unique_ptr<NinePatch> NinePatch::create(uint8_t** rows, * (sqrt(2) - 1) * r = sqrt(2) * i * r = sqrt(2) / (sqrt(2) - 1) * i */ - ninePatch->outlineRadius = 3.4142f * topLeft; - return ninePatch; + nine_patch->outline_radius = 3.4142f * top_left; + return nine_patch; } -std::unique_ptr<uint8_t[]> NinePatch::serializeBase(size_t* outLen) const { +std::unique_ptr<uint8_t[]> NinePatch::SerializeBase(size_t* outLen) const { android::Res_png_9patch data; - data.numXDivs = static_cast<uint8_t>(horizontalStretchRegions.size()) * 2; - data.numYDivs = static_cast<uint8_t>(verticalStretchRegions.size()) * 2; - data.numColors = static_cast<uint8_t>(regionColors.size()); + data.numXDivs = static_cast<uint8_t>(horizontal_stretch_regions.size()) * 2; + data.numYDivs = static_cast<uint8_t>(vertical_stretch_regions.size()) * 2; + data.numColors = static_cast<uint8_t>(region_colors.size()); data.paddingLeft = padding.left; data.paddingRight = padding.right; data.paddingTop = padding.top; @@ -609,8 +615,8 @@ std::unique_ptr<uint8_t[]> NinePatch::serializeBase(size_t* outLen) const { auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[data.serializedSize()]); android::Res_png_9patch::serialize( - data, (const int32_t*)horizontalStretchRegions.data(), - (const int32_t*)verticalStretchRegions.data(), regionColors.data(), + data, (const int32_t*)horizontal_stretch_regions.data(), + (const int32_t*)vertical_stretch_regions.data(), region_colors.data(), buffer.get()); // Convert to file endianness. reinterpret_cast<android::Res_png_9patch*>(buffer.get())->deviceToFile(); @@ -619,32 +625,32 @@ std::unique_ptr<uint8_t[]> NinePatch::serializeBase(size_t* outLen) const { return buffer; } -std::unique_ptr<uint8_t[]> NinePatch::serializeLayoutBounds( - size_t* outLen) const { - size_t chunkLen = sizeof(uint32_t) * 4; - auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunkLen]); +std::unique_ptr<uint8_t[]> NinePatch::SerializeLayoutBounds( + size_t* out_len) const { + size_t chunk_len = sizeof(uint32_t) * 4; + auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunk_len]); uint8_t* cursor = buffer.get(); - memcpy(cursor, &layoutBounds.left, sizeof(layoutBounds.left)); - cursor += sizeof(layoutBounds.left); + memcpy(cursor, &layout_bounds.left, sizeof(layout_bounds.left)); + cursor += sizeof(layout_bounds.left); - memcpy(cursor, &layoutBounds.top, sizeof(layoutBounds.top)); - cursor += sizeof(layoutBounds.top); + memcpy(cursor, &layout_bounds.top, sizeof(layout_bounds.top)); + cursor += sizeof(layout_bounds.top); - memcpy(cursor, &layoutBounds.right, sizeof(layoutBounds.right)); - cursor += sizeof(layoutBounds.right); + memcpy(cursor, &layout_bounds.right, sizeof(layout_bounds.right)); + cursor += sizeof(layout_bounds.right); - memcpy(cursor, &layoutBounds.bottom, sizeof(layoutBounds.bottom)); - cursor += sizeof(layoutBounds.bottom); + memcpy(cursor, &layout_bounds.bottom, sizeof(layout_bounds.bottom)); + cursor += sizeof(layout_bounds.bottom); - *outLen = chunkLen; + *out_len = chunk_len; return buffer; } -std::unique_ptr<uint8_t[]> NinePatch::serializeRoundedRectOutline( - size_t* outLen) const { - size_t chunkLen = sizeof(uint32_t) * 6; - auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunkLen]); +std::unique_ptr<uint8_t[]> NinePatch::SerializeRoundedRectOutline( + size_t* out_len) const { + size_t chunk_len = sizeof(uint32_t) * 6; + auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunk_len]); uint8_t* cursor = buffer.get(); memcpy(cursor, &outline.left, sizeof(outline.left)); @@ -659,12 +665,12 @@ std::unique_ptr<uint8_t[]> NinePatch::serializeRoundedRectOutline( memcpy(cursor, &outline.bottom, sizeof(outline.bottom)); cursor += sizeof(outline.bottom); - *((float*)cursor) = outlineRadius; - cursor += sizeof(outlineRadius); + *((float*)cursor) = outline_radius; + cursor += sizeof(outline_radius); - *((uint32_t*)cursor) = outlineAlpha; + *((uint32_t*)cursor) = outline_alpha; - *outLen = chunkLen; + *out_len = chunk_len; return buffer; } @@ -677,16 +683,16 @@ std::unique_ptr<uint8_t[]> NinePatch::serializeRoundedRectOutline( << " r=" << bounds.right << " b=" << bounds.bottom; } -::std::ostream& operator<<(::std::ostream& out, const NinePatch& ninePatch) { +::std::ostream& operator<<(::std::ostream& out, const NinePatch& nine_patch) { return out << "horizontalStretch:" - << util::joiner(ninePatch.horizontalStretchRegions, " ") + << util::Joiner(nine_patch.horizontal_stretch_regions, " ") << " verticalStretch:" - << util::joiner(ninePatch.verticalStretchRegions, " ") - << " padding: " << ninePatch.padding - << ", bounds: " << ninePatch.layoutBounds - << ", outline: " << ninePatch.outline - << " rad=" << ninePatch.outlineRadius - << " alpha=" << ninePatch.outlineAlpha; + << util::Joiner(nine_patch.vertical_stretch_regions, " ") + << " padding: " << nine_patch.padding + << ", bounds: " << nine_patch.layout_bounds + << ", outline: " << nine_patch.outline + << " rad=" << nine_patch.outline_radius + << " alpha=" << nine_patch.outline_alpha; } } // namespace aapt diff --git a/tools/aapt2/compile/NinePatch_test.cpp b/tools/aapt2/compile/NinePatch_test.cpp index b8eda09f5905..f54bb2e62842 100644 --- a/tools/aapt2/compile/NinePatch_test.cpp +++ b/tools/aapt2/compile/NinePatch_test.cpp @@ -15,6 +15,7 @@ */ #include "compile/Image.h" + #include "test/Test.h" namespace aapt { @@ -182,169 +183,168 @@ static uint8_t* kStretchAndPadding5x5[] = { TEST(NinePatchTest, Minimum3x3) { std::string err; - EXPECT_EQ(nullptr, NinePatch::create(k2x2, 2, 2, &err)); + EXPECT_EQ(nullptr, NinePatch::Create(k2x2, 2, 2, &err)); EXPECT_FALSE(err.empty()); } TEST(NinePatchTest, MixedNeutralColors) { std::string err; - EXPECT_EQ(nullptr, NinePatch::create(kMixedNeutralColor3x3, 3, 3, &err)); + EXPECT_EQ(nullptr, NinePatch::Create(kMixedNeutralColor3x3, 3, 3, &err)); EXPECT_FALSE(err.empty()); } TEST(NinePatchTest, TransparentNeutralColor) { std::string err; EXPECT_NE(nullptr, - NinePatch::create(kTransparentNeutralColor3x3, 3, 3, &err)); + NinePatch::Create(kTransparentNeutralColor3x3, 3, 3, &err)); } TEST(NinePatchTest, SingleStretchRegion) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kSingleStretch7x6, 7, 6, &err); - ASSERT_NE(nullptr, ninePatch); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kSingleStretch7x6, 7, 6, &err); + ASSERT_NE(nullptr, nine_patch); - ASSERT_EQ(1u, ninePatch->horizontalStretchRegions.size()); - ASSERT_EQ(1u, ninePatch->verticalStretchRegions.size()); + ASSERT_EQ(1u, nine_patch->horizontal_stretch_regions.size()); + ASSERT_EQ(1u, nine_patch->vertical_stretch_regions.size()); - EXPECT_EQ(Range(1, 4), ninePatch->horizontalStretchRegions.front()); - EXPECT_EQ(Range(1, 3), ninePatch->verticalStretchRegions.front()); + EXPECT_EQ(Range(1, 4), nine_patch->horizontal_stretch_regions.front()); + EXPECT_EQ(Range(1, 3), nine_patch->vertical_stretch_regions.front()); } TEST(NinePatchTest, MultipleStretchRegions) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kMultipleStretch10x7, 10, 7, &err); - ASSERT_NE(nullptr, ninePatch); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kMultipleStretch10x7, 10, 7, &err); + ASSERT_NE(nullptr, nine_patch); - ASSERT_EQ(3u, ninePatch->horizontalStretchRegions.size()); - ASSERT_EQ(2u, ninePatch->verticalStretchRegions.size()); + ASSERT_EQ(3u, nine_patch->horizontal_stretch_regions.size()); + ASSERT_EQ(2u, nine_patch->vertical_stretch_regions.size()); - EXPECT_EQ(Range(1, 2), ninePatch->horizontalStretchRegions[0]); - EXPECT_EQ(Range(3, 5), ninePatch->horizontalStretchRegions[1]); - EXPECT_EQ(Range(6, 7), ninePatch->horizontalStretchRegions[2]); + EXPECT_EQ(Range(1, 2), nine_patch->horizontal_stretch_regions[0]); + EXPECT_EQ(Range(3, 5), nine_patch->horizontal_stretch_regions[1]); + EXPECT_EQ(Range(6, 7), nine_patch->horizontal_stretch_regions[2]); - EXPECT_EQ(Range(0, 2), ninePatch->verticalStretchRegions[0]); - EXPECT_EQ(Range(3, 5), ninePatch->verticalStretchRegions[1]); + EXPECT_EQ(Range(0, 2), nine_patch->vertical_stretch_regions[0]); + EXPECT_EQ(Range(3, 5), nine_patch->vertical_stretch_regions[1]); } TEST(NinePatchTest, InferPaddingFromStretchRegions) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kMultipleStretch10x7, 10, 7, &err); - ASSERT_NE(nullptr, ninePatch); - EXPECT_EQ(Bounds(1, 0, 1, 0), ninePatch->padding); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kMultipleStretch10x7, 10, 7, &err); + ASSERT_NE(nullptr, nine_patch); + EXPECT_EQ(Bounds(1, 0, 1, 0), nine_patch->padding); } TEST(NinePatchTest, Padding) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kPadding6x5, 6, 5, &err); - ASSERT_NE(nullptr, ninePatch); - EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->padding); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kPadding6x5, 6, 5, &err); + ASSERT_NE(nullptr, nine_patch); + EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->padding); } TEST(NinePatchTest, LayoutBoundsAreOnWrongEdge) { std::string err; - EXPECT_EQ(nullptr, NinePatch::create(kLayoutBoundsWrongEdge3x3, 3, 3, &err)); + EXPECT_EQ(nullptr, NinePatch::Create(kLayoutBoundsWrongEdge3x3, 3, 3, &err)); EXPECT_FALSE(err.empty()); } TEST(NinePatchTest, LayoutBoundsMustTouchEdges) { std::string err; EXPECT_EQ(nullptr, - NinePatch::create(kLayoutBoundsNotEdgeAligned5x5, 5, 5, &err)); + NinePatch::Create(kLayoutBoundsNotEdgeAligned5x5, 5, 5, &err)); EXPECT_FALSE(err.empty()); } TEST(NinePatchTest, LayoutBounds) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kLayoutBounds5x5, 5, 5, &err); - ASSERT_NE(nullptr, ninePatch); - EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->layoutBounds); - - ninePatch = NinePatch::create(kAsymmetricLayoutBounds5x5, 5, 5, &err); - ASSERT_NE(nullptr, ninePatch); - EXPECT_EQ(Bounds(1, 1, 0, 0), ninePatch->layoutBounds); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kLayoutBounds5x5, 5, 5, &err); + ASSERT_NE(nullptr, nine_patch); + EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->layout_bounds); + + nine_patch = NinePatch::Create(kAsymmetricLayoutBounds5x5, 5, 5, &err); + ASSERT_NE(nullptr, nine_patch); + EXPECT_EQ(Bounds(1, 1, 0, 0), nine_patch->layout_bounds); } TEST(NinePatchTest, PaddingAndLayoutBounds) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kPaddingAndLayoutBounds5x5, 5, 5, &err); - ASSERT_NE(nullptr, ninePatch); - EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->padding); - EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->layoutBounds); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kPaddingAndLayoutBounds5x5, 5, 5, &err); + ASSERT_NE(nullptr, nine_patch); + EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->padding); + EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->layout_bounds); } TEST(NinePatchTest, RegionColorsAreCorrect) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kColorfulImage5x5, 5, 5, &err); - ASSERT_NE(nullptr, ninePatch); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kColorfulImage5x5, 5, 5, &err); + ASSERT_NE(nullptr, nine_patch); - std::vector<uint32_t> expectedColors = { - NinePatch::packRGBA((uint8_t*)RED), + std::vector<uint32_t> expected_colors = { + NinePatch::PackRGBA((uint8_t*)RED), (uint32_t)android::Res_png_9patch::NO_COLOR, - NinePatch::packRGBA((uint8_t*)GREEN), + NinePatch::PackRGBA((uint8_t*)GREEN), (uint32_t)android::Res_png_9patch::TRANSPARENT_COLOR, - NinePatch::packRGBA((uint8_t*)BLUE), - NinePatch::packRGBA((uint8_t*)GREEN), + NinePatch::PackRGBA((uint8_t*)BLUE), + NinePatch::PackRGBA((uint8_t*)GREEN), }; - EXPECT_EQ(expectedColors, ninePatch->regionColors); + EXPECT_EQ(expected_colors, nine_patch->region_colors); } TEST(NinePatchTest, OutlineFromOpaqueImage) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kOutlineOpaque10x10, 10, 10, &err); - ASSERT_NE(nullptr, ninePatch); - EXPECT_EQ(Bounds(2, 2, 2, 2), ninePatch->outline); - EXPECT_EQ(0x000000ffu, ninePatch->outlineAlpha); - EXPECT_EQ(0.0f, ninePatch->outlineRadius); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kOutlineOpaque10x10, 10, 10, &err); + ASSERT_NE(nullptr, nine_patch); + EXPECT_EQ(Bounds(2, 2, 2, 2), nine_patch->outline); + EXPECT_EQ(0x000000ffu, nine_patch->outline_alpha); + EXPECT_EQ(0.0f, nine_patch->outline_radius); } TEST(NinePatchTest, OutlineFromTranslucentImage) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kOutlineTranslucent10x10, 10, 10, &err); - ASSERT_NE(nullptr, ninePatch); - EXPECT_EQ(Bounds(3, 3, 3, 3), ninePatch->outline); - EXPECT_EQ(0x000000b3u, ninePatch->outlineAlpha); - EXPECT_EQ(0.0f, ninePatch->outlineRadius); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kOutlineTranslucent10x10, 10, 10, &err); + ASSERT_NE(nullptr, nine_patch); + EXPECT_EQ(Bounds(3, 3, 3, 3), nine_patch->outline); + EXPECT_EQ(0x000000b3u, nine_patch->outline_alpha); + EXPECT_EQ(0.0f, nine_patch->outline_radius); } TEST(NinePatchTest, OutlineFromOffCenterImage) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kOutlineOffsetTranslucent12x10, 12, 10, &err); - ASSERT_NE(nullptr, ninePatch); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kOutlineOffsetTranslucent12x10, 12, 10, &err); + ASSERT_NE(nullptr, nine_patch); // TODO(adamlesinski): The old AAPT algorithm searches from the outside to the - // middle - // for each inset. If the outline is shifted, the search may not find a closer - // bounds. + // middle for each inset. If the outline is shifted, the search may not find a + // closer bounds. // This check should be: // EXPECT_EQ(Bounds(5, 3, 3, 3), ninePatch->outline); - // but until I know what behaviour I'm breaking, I will leave it at the + // but until I know what behavior I'm breaking, I will leave it at the // incorrect: - EXPECT_EQ(Bounds(4, 3, 3, 3), ninePatch->outline); + EXPECT_EQ(Bounds(4, 3, 3, 3), nine_patch->outline); - EXPECT_EQ(0x000000b3u, ninePatch->outlineAlpha); - EXPECT_EQ(0.0f, ninePatch->outlineRadius); + EXPECT_EQ(0x000000b3u, nine_patch->outline_alpha); + EXPECT_EQ(0.0f, nine_patch->outline_radius); } TEST(NinePatchTest, OutlineRadius) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kOutlineRadius5x5, 5, 5, &err); - ASSERT_NE(nullptr, ninePatch); - EXPECT_EQ(Bounds(0, 0, 0, 0), ninePatch->outline); - EXPECT_EQ(3.4142f, ninePatch->outlineRadius); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kOutlineRadius5x5, 5, 5, &err); + ASSERT_NE(nullptr, nine_patch); + EXPECT_EQ(Bounds(0, 0, 0, 0), nine_patch->outline); + EXPECT_EQ(3.4142f, nine_patch->outline_radius); } -::testing::AssertionResult bigEndianOne(uint8_t* cursor) { +::testing::AssertionResult BigEndianOne(uint8_t* cursor) { if (cursor[0] == 0 && cursor[1] == 0 && cursor[2] == 0 && cursor[3] == 1) { return ::testing::AssertionSuccess(); } @@ -353,12 +353,12 @@ TEST(NinePatchTest, OutlineRadius) { TEST(NinePatchTest, SerializePngEndianness) { std::string err; - std::unique_ptr<NinePatch> ninePatch = - NinePatch::create(kStretchAndPadding5x5, 5, 5, &err); - ASSERT_NE(nullptr, ninePatch); + std::unique_ptr<NinePatch> nine_patch = + NinePatch::Create(kStretchAndPadding5x5, 5, 5, &err); + ASSERT_NE(nullptr, nine_patch); size_t len; - std::unique_ptr<uint8_t[]> data = ninePatch->serializeBase(&len); + std::unique_ptr<uint8_t[]> data = nine_patch->SerializeBase(&len); ASSERT_NE(nullptr, data); ASSERT_NE(0u, len); @@ -368,10 +368,10 @@ TEST(NinePatchTest, SerializePngEndianness) { uint8_t* cursor = data.get() + 12; // Check that padding is big-endian. Expecting value 1. - EXPECT_TRUE(bigEndianOne(cursor)); - EXPECT_TRUE(bigEndianOne(cursor + 4)); - EXPECT_TRUE(bigEndianOne(cursor + 8)); - EXPECT_TRUE(bigEndianOne(cursor + 12)); + EXPECT_TRUE(BigEndianOne(cursor)); + EXPECT_TRUE(BigEndianOne(cursor + 4)); + EXPECT_TRUE(BigEndianOne(cursor + 8)); + EXPECT_TRUE(BigEndianOne(cursor + 12)); } } // namespace aapt diff --git a/tools/aapt2/compile/Png.cpp b/tools/aapt2/compile/Png.cpp index 9b5fa7e091c2..f1bc53ee9cf7 100644 --- a/tools/aapt2/compile/Png.cpp +++ b/tools/aapt2/compile/Png.cpp @@ -89,7 +89,7 @@ static void readDataFromStream(png_structp readPtr, png_bytep data, static void writeDataToStream(png_structp writePtr, png_bytep data, png_size_t length) { BigBuffer* outBuffer = reinterpret_cast<BigBuffer*>(png_get_io_ptr(writePtr)); - png_bytep buf = outBuffer->nextBlock<png_byte>(length); + png_bytep buf = outBuffer->NextBlock<png_byte>(length); memcpy(buf, data, length); } @@ -98,13 +98,13 @@ static void flushDataToStream(png_structp /*writePtr*/) {} static void logWarning(png_structp readPtr, png_const_charp warningMessage) { IDiagnostics* diag = reinterpret_cast<IDiagnostics*>(png_get_error_ptr(readPtr)); - diag->warn(DiagMessage() << warningMessage); + diag->Warn(DiagMessage() << warningMessage); } static bool readPng(IDiagnostics* diag, png_structp readPtr, png_infop infoPtr, PngInfo* outInfo) { if (setjmp(png_jmpbuf(readPtr))) { - diag->error(DiagMessage() << "failed reading png"); + diag->Error(DiagMessage() << "failed reading png"); return false; } @@ -373,7 +373,7 @@ static void analyze_image(IDiagnostics* diag, const PngInfo& imageInfo, *colorType = PNG_COLOR_TYPE_PALETTE; } else { if (maxGrayDeviation <= grayscaleTolerance) { - diag->note(DiagMessage() << "forcing image to gray (max deviation = " + diag->Note(DiagMessage() << "forcing image to gray (max deviation = " << maxGrayDeviation << ")"); *colorType = isOpaque ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_GRAY_ALPHA; } else { @@ -424,7 +424,7 @@ static void analyze_image(IDiagnostics* diag, const PngInfo& imageInfo, static bool writePng(IDiagnostics* diag, png_structp writePtr, png_infop infoPtr, PngInfo* info, int grayScaleTolerance) { if (setjmp(png_jmpbuf(writePtr))) { - diag->error(DiagMessage() << "failed to write png"); + diag->Error(DiagMessage() << "failed to write png"); return false; } @@ -453,7 +453,7 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr, png_set_compression_level(writePtr, Z_BEST_COMPRESSION); if (kDebug) { - diag->note(DiagMessage() << "writing image: w = " << info->width + diag->Note(DiagMessage() << "writing image: w = " << info->width << ", h = " << info->height); } @@ -476,23 +476,23 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr, if (kDebug) { switch (colorType) { case PNG_COLOR_TYPE_PALETTE: - diag->note(DiagMessage() << "has " << paletteEntries << " colors" + diag->Note(DiagMessage() << "has " << paletteEntries << " colors" << (hasTransparency ? " (with alpha)" : "") << ", using PNG_COLOR_TYPE_PALLETTE"); break; case PNG_COLOR_TYPE_GRAY: - diag->note(DiagMessage() + diag->Note(DiagMessage() << "is opaque gray, using PNG_COLOR_TYPE_GRAY"); break; case PNG_COLOR_TYPE_GRAY_ALPHA: - diag->note(DiagMessage() + diag->Note(DiagMessage() << "is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA"); break; case PNG_COLOR_TYPE_RGB: - diag->note(DiagMessage() << "is opaque RGB, using PNG_COLOR_TYPE_RGB"); + diag->Note(DiagMessage() << "is opaque RGB, using PNG_COLOR_TYPE_RGB"); break; case PNG_COLOR_TYPE_RGB_ALPHA: - diag->note(DiagMessage() + diag->Note(DiagMessage() << "is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA"); break; } @@ -527,7 +527,7 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr, // base 9 patch data if (kDebug) { - diag->note(DiagMessage() << "adding 9-patch info.."); + diag->Note(DiagMessage() << "adding 9-patch info.."); } strcpy((char*)unknowns[pIndex].name, "npTc"); unknowns[pIndex].data = (png_byte*)info->serialize9Patch(); @@ -604,7 +604,7 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr, &interlaceType, &compressionType, nullptr); if (kDebug) { - diag->note(DiagMessage() << "image written: w = " << width + diag->Note(DiagMessage() << "image written: w = " << width << ", h = " << height << ", d = " << bitDepth << ", colors = " << colorType << ", inter = " << interlaceType @@ -1228,13 +1228,13 @@ bool Png::process(const Source& source, std::istream* input, // Read the PNG signature first. if (!input->read(reinterpret_cast<char*>(signature), kPngSignatureSize)) { - mDiag->error(DiagMessage() << strerror(errno)); + mDiag->Error(DiagMessage() << strerror(errno)); return false; } // If the PNG signature doesn't match, bail early. if (png_sig_cmp(signature, 0, kPngSignatureSize) != 0) { - mDiag->error(DiagMessage() << "not a valid png file"); + mDiag->Error(DiagMessage() << "not a valid png file"); return false; } @@ -1247,13 +1247,13 @@ bool Png::process(const Source& source, std::istream* input, readPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr); if (!readPtr) { - mDiag->error(DiagMessage() << "failed to allocate read ptr"); + mDiag->Error(DiagMessage() << "failed to allocate read ptr"); goto bail; } infoPtr = png_create_info_struct(readPtr); if (!infoPtr) { - mDiag->error(DiagMessage() << "failed to allocate info ptr"); + mDiag->Error(DiagMessage() << "failed to allocate info ptr"); goto bail; } @@ -1267,10 +1267,10 @@ bool Png::process(const Source& source, std::istream* input, goto bail; } - if (util::stringEndsWith(source.path, ".9.png")) { + if (util::EndsWith(source.path, ".9.png")) { std::string errorMsg; if (!do9Patch(&pngInfo, &errorMsg)) { - mDiag->error(DiagMessage() << errorMsg); + mDiag->Error(DiagMessage() << errorMsg); goto bail; } } @@ -1278,13 +1278,13 @@ bool Png::process(const Source& source, std::istream* input, writePtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr); if (!writePtr) { - mDiag->error(DiagMessage() << "failed to allocate write ptr"); + mDiag->Error(DiagMessage() << "failed to allocate write ptr"); goto bail; } writeInfoPtr = png_create_info_struct(writePtr); if (!writeInfoPtr) { - mDiag->error(DiagMessage() << "failed to allocate write info ptr"); + mDiag->Error(DiagMessage() << "failed to allocate write info ptr"); goto bail; } @@ -1295,7 +1295,7 @@ bool Png::process(const Source& source, std::istream* input, flushDataToStream); if (!writePng(mDiag, writePtr, writeInfoPtr, &pngInfo, - options.grayScaleTolerance)) { + options.grayscale_tolerance)) { goto bail; } diff --git a/tools/aapt2/compile/Png.h b/tools/aapt2/compile/Png.h index f9038afa5f9f..01c9adbc9094 100644 --- a/tools/aapt2/compile/Png.h +++ b/tools/aapt2/compile/Png.h @@ -17,6 +17,11 @@ #ifndef AAPT_PNG_H #define AAPT_PNG_H +#include <iostream> +#include <string> + +#include "android-base/macros.h" + #include "Diagnostics.h" #include "Source.h" #include "compile/Image.h" @@ -24,16 +29,15 @@ #include "process/IResourceTableConsumer.h" #include "util/BigBuffer.h" -#include <android-base/macros.h> -#include <iostream> -#include <string> - namespace aapt { struct PngOptions { - int grayScaleTolerance = 0; + int grayscale_tolerance = 0; }; +/** + * Deprecated. Removing once new PNG crunching code is proved to be correct. + */ class Png { public: explicit Png(IDiagnostics* diag) : mDiag(diag) {} @@ -59,18 +63,18 @@ class PngChunkFilter : public io::InputStream { bool Skip(int count) override; int64_t ByteCount() const override { - return static_cast<int64_t>(mWindowStart); + return static_cast<int64_t>(window_start_); } - bool HadError() const override { return mError; } + bool HadError() const override { return error_; } private: - bool consumeWindow(const void** buffer, int* len); + bool ConsumeWindow(const void** buffer, int* len); - StringPiece mData; - size_t mWindowStart = 0; - size_t mWindowEnd = 0; - bool mError = false; + StringPiece data_; + size_t window_start_ = 0; + size_t window_end_ = 0; + bool error_ = false; DISALLOW_COPY_AND_ASSIGN(PngChunkFilter); }; @@ -78,14 +82,14 @@ class PngChunkFilter : public io::InputStream { /** * Reads a PNG from the InputStream into memory as an RGBA Image. */ -std::unique_ptr<Image> readPng(IAaptContext* context, io::InputStream* in); +std::unique_ptr<Image> ReadPng(IAaptContext* context, io::InputStream* in); /** * Writes the RGBA Image, with optional 9-patch meta-data, into the OutputStream * as a PNG. */ -bool writePng(IAaptContext* context, const Image* image, - const NinePatch* ninePatch, io::OutputStream* out, +bool WritePng(IAaptContext* context, const Image* image, + const NinePatch* nine_patch, io::OutputStream* out, const PngOptions& options); } // namespace aapt diff --git a/tools/aapt2/compile/PngChunkFilter.cpp b/tools/aapt2/compile/PngChunkFilter.cpp index fb7fe9271f80..4cbefb9496ae 100644 --- a/tools/aapt2/compile/PngChunkFilter.cpp +++ b/tools/aapt2/compile/PngChunkFilter.cpp @@ -15,6 +15,7 @@ */ #include "compile/Png.h" + #include "io/Io.h" #include "util/StringPiece.h" @@ -39,7 +40,7 @@ enum PngChunkTypes { kPngChunksRGB = u32(115, 82, 71, 66), }; -static uint32_t peek32LE(const char* data) { +static uint32_t Peek32LE(const char* data) { uint32_t word = ((uint32_t)data[0]) & 0x000000ff; word <<= 8; word |= ((uint32_t)data[1]) & 0x000000ff; @@ -50,7 +51,7 @@ static uint32_t peek32LE(const char* data) { return word; } -static bool isPngChunkWhitelisted(uint32_t type) { +static bool IsPngChunkWhitelisted(uint32_t type) { switch (type) { case kPngChunkIHDR: case kPngChunkIDAT: @@ -64,93 +65,93 @@ static bool isPngChunkWhitelisted(uint32_t type) { } } -PngChunkFilter::PngChunkFilter(const StringPiece& data) : mData(data) { - if (util::stringStartsWith(mData, kPngSignature)) { - mWindowStart = 0; - mWindowEnd = strlen(kPngSignature); +PngChunkFilter::PngChunkFilter(const StringPiece& data) : data_(data) { + if (util::StartsWith(data_, kPngSignature)) { + window_start_ = 0; + window_end_ = strlen(kPngSignature); } else { - mError = true; + error_ = true; } } -bool PngChunkFilter::consumeWindow(const void** buffer, int* len) { - if (mWindowStart != mWindowEnd) { +bool PngChunkFilter::ConsumeWindow(const void** buffer, int* len) { + if (window_start_ != window_end_) { // We have bytes to give from our window. - const int bytesRead = (int)(mWindowEnd - mWindowStart); - *buffer = mData.data() + mWindowStart; - *len = bytesRead; - mWindowStart = mWindowEnd; + const int bytes_read = (int)(window_end_ - window_start_); + *buffer = data_.data() + window_start_; + *len = bytes_read; + window_start_ = window_end_; return true; } return false; } bool PngChunkFilter::Next(const void** buffer, int* len) { - if (mError) { + if (error_) { return false; } // In case BackUp was called, we must consume the window. - if (consumeWindow(buffer, len)) { + if (ConsumeWindow(buffer, len)) { return true; } // Advance the window as far as possible (until we meet a chunk that // we want to strip). - while (mWindowEnd < mData.size()) { + while (window_end_ < data_.size()) { // Chunk length (4 bytes) + type (4 bytes) + crc32 (4 bytes) = 12 bytes. const size_t kMinChunkHeaderSize = 3 * sizeof(uint32_t); // Is there enough room for a chunk header? - if (mData.size() - mWindowStart < kMinChunkHeaderSize) { - mError = true; + if (data_.size() - window_start_ < kMinChunkHeaderSize) { + error_ = true; return false; } // Verify the chunk length. - const uint32_t chunkLen = peek32LE(mData.data() + mWindowEnd); - if (((uint64_t)chunkLen) + ((uint64_t)mWindowEnd) + sizeof(uint32_t) > - mData.size()) { + const uint32_t chunk_len = Peek32LE(data_.data() + window_end_); + if (((uint64_t)chunk_len) + ((uint64_t)window_end_) + sizeof(uint32_t) > + data_.size()) { // Overflow. - mError = true; + error_ = true; return false; } // Do we strip this chunk? - const uint32_t chunkType = - peek32LE(mData.data() + mWindowEnd + sizeof(uint32_t)); - if (isPngChunkWhitelisted(chunkType)) { + const uint32_t chunk_type = + Peek32LE(data_.data() + window_end_ + sizeof(uint32_t)); + if (IsPngChunkWhitelisted(chunk_type)) { // Advance the window to include this chunk. - mWindowEnd += kMinChunkHeaderSize + chunkLen; + window_end_ += kMinChunkHeaderSize + chunk_len; } else { // We want to strip this chunk. If we accumulated a window, // we must return the window now. - if (mWindowStart != mWindowEnd) { + if (window_start_ != window_end_) { break; } // The window is empty, so we can advance past this chunk // and keep looking for the next good chunk, - mWindowEnd += kMinChunkHeaderSize + chunkLen; - mWindowStart = mWindowEnd; + window_end_ += kMinChunkHeaderSize + chunk_len; + window_start_ = window_end_; } } - if (consumeWindow(buffer, len)) { + if (ConsumeWindow(buffer, len)) { return true; } return false; } void PngChunkFilter::BackUp(int count) { - if (mError) { + if (error_) { return; } - mWindowStart -= count; + window_start_ -= count; } bool PngChunkFilter::Skip(int count) { - if (mError) { + if (error_) { return false; } diff --git a/tools/aapt2/compile/PngCrunch.cpp b/tools/aapt2/compile/PngCrunch.cpp index 4a74f7af79d8..3b46d8b4c782 100644 --- a/tools/aapt2/compile/PngCrunch.cpp +++ b/tools/aapt2/compile/PngCrunch.cpp @@ -16,14 +16,17 @@ #include "compile/Png.h" -#include <android-base/errors.h> -#include <android-base/macros.h> #include <png.h> #include <zlib.h> + #include <algorithm> #include <unordered_map> #include <unordered_set> +#include "android-base/errors.h" +#include "android-base/logging.h" +#include "android-base/macros.h" + namespace aapt { // Size in bytes of the PNG signature. @@ -34,16 +37,16 @@ constexpr size_t kPngSignatureSize = 8u; */ class PngReadStructDeleter { public: - explicit PngReadStructDeleter(png_structp readPtr, png_infop infoPtr) - : mReadPtr(readPtr), mInfoPtr(infoPtr) {} + PngReadStructDeleter(png_structp read_ptr, png_infop info_ptr) + : read_ptr_(read_ptr), info_ptr_(info_ptr) {} ~PngReadStructDeleter() { - png_destroy_read_struct(&mReadPtr, &mInfoPtr, nullptr); + png_destroy_read_struct(&read_ptr_, &info_ptr_, nullptr); } private: - png_structp mReadPtr; - png_infop mInfoPtr; + png_structp read_ptr_; + png_infop info_ptr_; DISALLOW_COPY_AND_ASSIGN(PngReadStructDeleter); }; @@ -53,226 +56,229 @@ class PngReadStructDeleter { */ class PngWriteStructDeleter { public: - explicit PngWriteStructDeleter(png_structp writePtr, png_infop infoPtr) - : mWritePtr(writePtr), mInfoPtr(infoPtr) {} + PngWriteStructDeleter(png_structp write_ptr, png_infop info_ptr) + : write_ptr_(write_ptr), info_ptr_(info_ptr) {} - ~PngWriteStructDeleter() { png_destroy_write_struct(&mWritePtr, &mInfoPtr); } + ~PngWriteStructDeleter() { + png_destroy_write_struct(&write_ptr_, &info_ptr_); + } private: - png_structp mWritePtr; - png_infop mInfoPtr; + png_structp write_ptr_; + png_infop info_ptr_; DISALLOW_COPY_AND_ASSIGN(PngWriteStructDeleter); }; // Custom warning logging method that uses IDiagnostics. -static void logWarning(png_structp pngPtr, png_const_charp warningMsg) { - IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(pngPtr); - diag->warn(DiagMessage() << warningMsg); +static void LogWarning(png_structp png_ptr, png_const_charp warning_msg) { + IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(png_ptr); + diag->Warn(DiagMessage() << warning_msg); } // Custom error logging method that uses IDiagnostics. -static void logError(png_structp pngPtr, png_const_charp errorMsg) { - IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(pngPtr); - diag->error(DiagMessage() << errorMsg); +static void LogError(png_structp png_ptr, png_const_charp error_msg) { + IDiagnostics* diag = (IDiagnostics*)png_get_error_ptr(png_ptr); + diag->Error(DiagMessage() << error_msg); } -static void readDataFromStream(png_structp pngPtr, png_bytep buffer, +static void ReadDataFromStream(png_structp png_ptr, png_bytep buffer, png_size_t len) { - io::InputStream* in = (io::InputStream*)png_get_io_ptr(pngPtr); + io::InputStream* in = (io::InputStream*)png_get_io_ptr(png_ptr); - const void* inBuffer; - int inLen; - if (!in->Next(&inBuffer, &inLen)) { + const void* in_buffer; + int in_len; + if (!in->Next(&in_buffer, &in_len)) { if (in->HadError()) { std::string err = in->GetError(); - png_error(pngPtr, err.c_str()); + png_error(png_ptr, err.c_str()); } return; } - const size_t bytesRead = std::min(static_cast<size_t>(inLen), len); - memcpy(buffer, inBuffer, bytesRead); - if (bytesRead != static_cast<size_t>(inLen)) { - in->BackUp(inLen - static_cast<int>(bytesRead)); + const size_t bytes_read = std::min(static_cast<size_t>(in_len), len); + memcpy(buffer, in_buffer, bytes_read); + if (bytes_read != static_cast<size_t>(in_len)) { + in->BackUp(in_len - static_cast<int>(bytes_read)); } } -static void writeDataToStream(png_structp pngPtr, png_bytep buffer, +static void WriteDataToStream(png_structp png_ptr, png_bytep buffer, png_size_t len) { - io::OutputStream* out = (io::OutputStream*)png_get_io_ptr(pngPtr); + io::OutputStream* out = (io::OutputStream*)png_get_io_ptr(png_ptr); - void* outBuffer; - int outLen; + void* out_buffer; + int out_len; while (len > 0) { - if (!out->Next(&outBuffer, &outLen)) { + if (!out->Next(&out_buffer, &out_len)) { if (out->HadError()) { std::string err = out->GetError(); - png_error(pngPtr, err.c_str()); + png_error(png_ptr, err.c_str()); } return; } - const size_t bytesWritten = std::min(static_cast<size_t>(outLen), len); - memcpy(outBuffer, buffer, bytesWritten); + const size_t bytes_written = std::min(static_cast<size_t>(out_len), len); + memcpy(out_buffer, buffer, bytes_written); // Advance the input buffer. - buffer += bytesWritten; - len -= bytesWritten; + buffer += bytes_written; + len -= bytes_written; // Advance the output buffer. - outLen -= static_cast<int>(bytesWritten); + out_len -= static_cast<int>(bytes_written); } // If the entire output buffer wasn't used, backup. - if (outLen > 0) { - out->BackUp(outLen); + if (out_len > 0) { + out->BackUp(out_len); } } -std::unique_ptr<Image> readPng(IAaptContext* context, io::InputStream* in) { +std::unique_ptr<Image> ReadPng(IAaptContext* context, io::InputStream* in) { // Read the first 8 bytes of the file looking for the PNG signature. // Bail early if it does not match. const png_byte* signature; - int bufferSize; - if (!in->Next((const void**)&signature, &bufferSize)) { - context->getDiagnostics()->error( + int buffer_size; + if (!in->Next((const void**)&signature, &buffer_size)) { + context->GetDiagnostics()->Error( DiagMessage() << android::base::SystemErrorCodeToString(errno)); return {}; } - if (static_cast<size_t>(bufferSize) < kPngSignatureSize || + if (static_cast<size_t>(buffer_size) < kPngSignatureSize || png_sig_cmp(signature, 0, kPngSignatureSize) != 0) { - context->getDiagnostics()->error( + context->GetDiagnostics()->Error( DiagMessage() << "file signature does not match PNG signature"); return {}; } // Start at the beginning of the first chunk. - in->BackUp(bufferSize - static_cast<int>(kPngSignatureSize)); + in->BackUp(buffer_size - static_cast<int>(kPngSignatureSize)); // Create and initialize the png_struct with the default error and warning // handlers. // The header version is also passed in to ensure that this was built against // the same // version of libpng. - png_structp readPtr = + png_structp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (readPtr == nullptr) { - context->getDiagnostics()->error( + if (read_ptr == nullptr) { + context->GetDiagnostics()->Error( DiagMessage() << "failed to create libpng read png_struct"); return {}; } // Create and initialize the memory for image header and data. - png_infop infoPtr = png_create_info_struct(readPtr); - if (infoPtr == nullptr) { - context->getDiagnostics()->error( + png_infop info_ptr = png_create_info_struct(read_ptr); + if (info_ptr == nullptr) { + context->GetDiagnostics()->Error( DiagMessage() << "failed to create libpng read png_info"); - png_destroy_read_struct(&readPtr, nullptr, nullptr); + png_destroy_read_struct(&read_ptr, nullptr, nullptr); return {}; } // Automatically release PNG resources at end of scope. - PngReadStructDeleter pngReadDeleter(readPtr, infoPtr); + PngReadStructDeleter png_read_deleter(read_ptr, info_ptr); // libpng uses longjmp to jump to an error handling routine. // setjmp will only return true if it was jumped to, aka there was // an error. - if (setjmp(png_jmpbuf(readPtr))) { + if (setjmp(png_jmpbuf(read_ptr))) { return {}; } // Handle warnings ourselves via IDiagnostics. - png_set_error_fn(readPtr, (png_voidp)context->getDiagnostics(), logError, - logWarning); + png_set_error_fn(read_ptr, (png_voidp)context->GetDiagnostics(), LogError, + LogWarning); // Set up the read functions which read from our custom data sources. - png_set_read_fn(readPtr, (png_voidp)in, readDataFromStream); + png_set_read_fn(read_ptr, (png_voidp)in, ReadDataFromStream); // Skip the signature that we already read. - png_set_sig_bytes(readPtr, kPngSignatureSize); + png_set_sig_bytes(read_ptr, kPngSignatureSize); // Read the chunk headers. - png_read_info(readPtr, infoPtr); + png_read_info(read_ptr, info_ptr); // Extract image meta-data from the various chunk headers. uint32_t width, height; - int bitDepth, colorType, interlaceMethod, compressionMethod, filterMethod; - png_get_IHDR(readPtr, infoPtr, &width, &height, &bitDepth, &colorType, - &interlaceMethod, &compressionMethod, &filterMethod); + int bit_depth, color_type, interlace_method, compression_method, + filter_method; + png_get_IHDR(read_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + &interlace_method, &compression_method, &filter_method); // When the image is read, expand it so that it is in RGBA 8888 format // so that image handling is uniform. - if (colorType == PNG_COLOR_TYPE_PALETTE) { - png_set_palette_to_rgb(readPtr); + if (color_type == PNG_COLOR_TYPE_PALETTE) { + png_set_palette_to_rgb(read_ptr); } - if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) { - png_set_expand_gray_1_2_4_to_8(readPtr); + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { + png_set_expand_gray_1_2_4_to_8(read_ptr); } - if (png_get_valid(readPtr, infoPtr, PNG_INFO_tRNS)) { - png_set_tRNS_to_alpha(readPtr); + if (png_get_valid(read_ptr, info_ptr, PNG_INFO_tRNS)) { + png_set_tRNS_to_alpha(read_ptr); } - if (bitDepth == 16) { - png_set_strip_16(readPtr); + if (bit_depth == 16) { + png_set_strip_16(read_ptr); } - if (!(colorType & PNG_COLOR_MASK_ALPHA)) { - png_set_add_alpha(readPtr, 0xFF, PNG_FILLER_AFTER); + if (!(color_type & PNG_COLOR_MASK_ALPHA)) { + png_set_add_alpha(read_ptr, 0xFF, PNG_FILLER_AFTER); } - if (colorType == PNG_COLOR_TYPE_GRAY || - colorType == PNG_COLOR_TYPE_GRAY_ALPHA) { - png_set_gray_to_rgb(readPtr); + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + png_set_gray_to_rgb(read_ptr); } - if (interlaceMethod != PNG_INTERLACE_NONE) { - png_set_interlace_handling(readPtr); + if (interlace_method != PNG_INTERLACE_NONE) { + png_set_interlace_handling(read_ptr); } // Once all the options for reading have been set, we need to flush // them to libpng. - png_read_update_info(readPtr, infoPtr); + png_read_update_info(read_ptr, info_ptr); // 9-patch uses int32_t to index images, so we cap the image dimensions to // something // that can always be represented by 9-patch. if (width > std::numeric_limits<int32_t>::max() || height > std::numeric_limits<int32_t>::max()) { - context->getDiagnostics()->error(DiagMessage() + context->GetDiagnostics()->Error(DiagMessage() << "PNG image dimensions are too large: " << width << "x" << height); return {}; } - std::unique_ptr<Image> outputImage = util::make_unique<Image>(); - outputImage->width = static_cast<int32_t>(width); - outputImage->height = static_cast<int32_t>(height); + std::unique_ptr<Image> output_image = util::make_unique<Image>(); + output_image->width = static_cast<int32_t>(width); + output_image->height = static_cast<int32_t>(height); - const size_t rowBytes = png_get_rowbytes(readPtr, infoPtr); - assert(rowBytes == 4 * width); // RGBA + const size_t row_bytes = png_get_rowbytes(read_ptr, info_ptr); + CHECK(row_bytes == 4 * width); // RGBA // Allocate one large block to hold the image. - outputImage->data = - std::unique_ptr<uint8_t[]>(new uint8_t[height * rowBytes]); + output_image->data = + std::unique_ptr<uint8_t[]>(new uint8_t[height * row_bytes]); // Create an array of rows that index into the data block. - outputImage->rows = std::unique_ptr<uint8_t* []>(new uint8_t*[height]); + output_image->rows = std::unique_ptr<uint8_t* []>(new uint8_t*[height]); for (uint32_t h = 0; h < height; h++) { - outputImage->rows[h] = outputImage->data.get() + (h * rowBytes); + output_image->rows[h] = output_image->data.get() + (h * row_bytes); } // Actually read the image pixels. - png_read_image(readPtr, outputImage->rows.get()); + png_read_image(read_ptr, output_image->rows.get()); // Finish reading. This will read any other chunks after the image data. - png_read_end(readPtr, infoPtr); + png_read_end(read_ptr, info_ptr); - return outputImage; + return output_image; } /** @@ -309,57 +315,58 @@ constexpr static const size_t kPaletteOverheadConstant = 1024u * 10u; // - Grayscale + cheap alpha // - Grayscale + alpha // -static int pickColorType(int32_t width, int32_t height, bool grayScale, - bool convertibleToGrayScale, bool hasNinePatch, - size_t colorPaletteSize, size_t alphaPaletteSize) { - const size_t paletteChunkSize = 16 + colorPaletteSize * 3; - const size_t alphaChunkSize = 16 + alphaPaletteSize; - const size_t colorAlphaDataChunkSize = 16 + 4 * width * height; - const size_t colorDataChunkSize = 16 + 3 * width * height; - const size_t grayScaleAlphaDataChunkSize = 16 + 2 * width * height; - const size_t paletteDataChunkSize = 16 + width * height; - - if (grayScale) { - if (alphaPaletteSize == 0) { +static int PickColorType(int32_t width, int32_t height, bool grayscale, + bool convertible_to_grayscale, bool has_nine_patch, + size_t color_palette_size, size_t alpha_palette_size) { + const size_t palette_chunk_size = 16 + color_palette_size * 3; + const size_t alpha_chunk_size = 16 + alpha_palette_size; + const size_t color_alpha_data_chunk_size = 16 + 4 * width * height; + const size_t color_data_chunk_size = 16 + 3 * width * height; + const size_t grayscale_alpha_data_chunk_size = 16 + 2 * width * height; + const size_t palette_data_chunk_size = 16 + width * height; + + if (grayscale) { + if (alpha_palette_size == 0) { // This is the smallest the data can be. return PNG_COLOR_TYPE_GRAY; - } else if (colorPaletteSize <= 256 && !hasNinePatch) { + } else if (color_palette_size <= 256 && !has_nine_patch) { // This grayscale has alpha and can fit within a palette. // See if it is worth fitting into a palette. - const size_t paletteThreshold = paletteChunkSize + alphaChunkSize + - paletteDataChunkSize + - kPaletteOverheadConstant; - if (grayScaleAlphaDataChunkSize > paletteThreshold) { + const size_t palette_threshold = palette_chunk_size + alpha_chunk_size + + palette_data_chunk_size + + kPaletteOverheadConstant; + if (grayscale_alpha_data_chunk_size > palette_threshold) { return PNG_COLOR_TYPE_PALETTE; } } return PNG_COLOR_TYPE_GRAY_ALPHA; } - if (colorPaletteSize <= 256 && !hasNinePatch) { + if (color_palette_size <= 256 && !has_nine_patch) { // This image can fit inside a palette. Let's see if it is worth it. - size_t totalSizeWithPalette = paletteDataChunkSize + paletteChunkSize; - size_t totalSizeWithoutPalette = colorDataChunkSize; - if (alphaPaletteSize > 0) { - totalSizeWithPalette += alphaPaletteSize; - totalSizeWithoutPalette = colorAlphaDataChunkSize; + size_t total_size_with_palette = + palette_data_chunk_size + palette_chunk_size; + size_t total_size_without_palette = color_data_chunk_size; + if (alpha_palette_size > 0) { + total_size_with_palette += alpha_palette_size; + total_size_without_palette = color_alpha_data_chunk_size; } - if (totalSizeWithoutPalette > - totalSizeWithPalette + kPaletteOverheadConstant) { + if (total_size_without_palette > + total_size_with_palette + kPaletteOverheadConstant) { return PNG_COLOR_TYPE_PALETTE; } } - if (convertibleToGrayScale) { - if (alphaPaletteSize == 0) { + if (convertible_to_grayscale) { + if (alpha_palette_size == 0) { return PNG_COLOR_TYPE_GRAY; } else { return PNG_COLOR_TYPE_GRAY_ALPHA; } } - if (alphaPaletteSize == 0) { + if (alpha_palette_size == 0) { return PNG_COLOR_TYPE_RGB; } return PNG_COLOR_TYPE_RGBA; @@ -371,11 +378,11 @@ static int pickColorType(int32_t width, int32_t height, bool grayScale, // This must be done before writing image data. // Image data must be transformed to use the indices assigned within the // palette. -static void writePalette(png_structp writePtr, png_infop writeInfoPtr, - std::unordered_map<uint32_t, int>* colorPalette, - std::unordered_set<uint32_t>* alphaPalette) { - assert(colorPalette->size() <= 256); - assert(alphaPalette->size() <= 256); +static void WritePalette(png_structp write_ptr, png_infop write_info_ptr, + std::unordered_map<uint32_t, int>* color_palette, + std::unordered_set<uint32_t>* alpha_palette) { + CHECK(color_palette->size() <= 256); + CHECK(alpha_palette->size() <= 256); // Populate the PNG palette struct and assign indices to the color // palette. @@ -384,160 +391,161 @@ static void writePalette(png_structp writePtr, png_infop writeInfoPtr, // This will ensure that we can truncate the alpha palette if it is // smaller than the color palette. int index = 0; - for (uint32_t color : *alphaPalette) { - (*colorPalette)[color] = index++; + for (uint32_t color : *alpha_palette) { + (*color_palette)[color] = index++; } // Assign the rest of the entries. - for (auto& entry : *colorPalette) { + for (auto& entry : *color_palette) { if (entry.second == -1) { entry.second = index++; } } // Create the PNG color palette struct. - auto colorPaletteBytes = - std::unique_ptr<png_color[]>(new png_color[colorPalette->size()]); + auto color_palette_bytes = + std::unique_ptr<png_color[]>(new png_color[color_palette->size()]); - std::unique_ptr<png_byte[]> alphaPaletteBytes; - if (!alphaPalette->empty()) { - alphaPaletteBytes = - std::unique_ptr<png_byte[]>(new png_byte[alphaPalette->size()]); + std::unique_ptr<png_byte[]> alpha_palette_bytes; + if (!alpha_palette->empty()) { + alpha_palette_bytes = + std::unique_ptr<png_byte[]>(new png_byte[alpha_palette->size()]); } - for (const auto& entry : *colorPalette) { + for (const auto& entry : *color_palette) { const uint32_t color = entry.first; const int index = entry.second; - assert(index >= 0); - assert(static_cast<size_t>(index) < colorPalette->size()); + CHECK(index >= 0); + CHECK(static_cast<size_t>(index) < color_palette->size()); - png_colorp slot = colorPaletteBytes.get() + index; + png_colorp slot = color_palette_bytes.get() + index; slot->red = color >> 24; slot->green = color >> 16; slot->blue = color >> 8; const png_byte alpha = color & 0x000000ff; - if (alpha != 0xff && alphaPaletteBytes) { - assert(static_cast<size_t>(index) < alphaPalette->size()); - alphaPaletteBytes[index] = alpha; + if (alpha != 0xff && alpha_palette_bytes) { + CHECK(static_cast<size_t>(index) < alpha_palette->size()); + alpha_palette_bytes[index] = alpha; } } - // The bytes get copied here, so it is safe to release colorPaletteBytes at + // The bytes get copied here, so it is safe to release color_palette_bytes at // the end of function // scope. - png_set_PLTE(writePtr, writeInfoPtr, colorPaletteBytes.get(), - colorPalette->size()); + png_set_PLTE(write_ptr, write_info_ptr, color_palette_bytes.get(), + color_palette->size()); - if (alphaPaletteBytes) { - png_set_tRNS(writePtr, writeInfoPtr, alphaPaletteBytes.get(), - alphaPalette->size(), nullptr); + if (alpha_palette_bytes) { + png_set_tRNS(write_ptr, write_info_ptr, alpha_palette_bytes.get(), + alpha_palette->size(), nullptr); } } -// Write the 9-patch custom PNG chunks to writeInfoPtr. This must be done before +// Write the 9-patch custom PNG chunks to write_info_ptr. This must be done +// before // writing image data. -static void writeNinePatch(png_structp writePtr, png_infop writeInfoPtr, - const NinePatch* ninePatch) { +static void WriteNinePatch(png_structp write_ptr, png_infop write_info_ptr, + const NinePatch* nine_patch) { // The order of the chunks is important. // 9-patch code in older platforms expects the 9-patch chunk to // be last. - png_unknown_chunk unknownChunks[3]; - memset(unknownChunks, 0, sizeof(unknownChunks)); + png_unknown_chunk unknown_chunks[3]; + memset(unknown_chunks, 0, sizeof(unknown_chunks)); size_t index = 0; - size_t chunkLen = 0; - - std::unique_ptr<uint8_t[]> serializedOutline = - ninePatch->serializeRoundedRectOutline(&chunkLen); - strcpy((char*)unknownChunks[index].name, "npOl"); - unknownChunks[index].size = chunkLen; - unknownChunks[index].data = (png_bytep)serializedOutline.get(); - unknownChunks[index].location = PNG_HAVE_PLTE; + size_t chunk_len = 0; + + std::unique_ptr<uint8_t[]> serialized_outline = + nine_patch->SerializeRoundedRectOutline(&chunk_len); + strcpy((char*)unknown_chunks[index].name, "npOl"); + unknown_chunks[index].size = chunk_len; + unknown_chunks[index].data = (png_bytep)serialized_outline.get(); + unknown_chunks[index].location = PNG_HAVE_PLTE; index++; - std::unique_ptr<uint8_t[]> serializedLayoutBounds; - if (ninePatch->layoutBounds.nonZero()) { - serializedLayoutBounds = ninePatch->serializeLayoutBounds(&chunkLen); - strcpy((char*)unknownChunks[index].name, "npLb"); - unknownChunks[index].size = chunkLen; - unknownChunks[index].data = (png_bytep)serializedLayoutBounds.get(); - unknownChunks[index].location = PNG_HAVE_PLTE; + std::unique_ptr<uint8_t[]> serialized_layout_bounds; + if (nine_patch->layout_bounds.nonZero()) { + serialized_layout_bounds = nine_patch->SerializeLayoutBounds(&chunk_len); + strcpy((char*)unknown_chunks[index].name, "npLb"); + unknown_chunks[index].size = chunk_len; + unknown_chunks[index].data = (png_bytep)serialized_layout_bounds.get(); + unknown_chunks[index].location = PNG_HAVE_PLTE; index++; } - std::unique_ptr<uint8_t[]> serializedNinePatch = - ninePatch->serializeBase(&chunkLen); - strcpy((char*)unknownChunks[index].name, "npTc"); - unknownChunks[index].size = chunkLen; - unknownChunks[index].data = (png_bytep)serializedNinePatch.get(); - unknownChunks[index].location = PNG_HAVE_PLTE; + std::unique_ptr<uint8_t[]> serialized_nine_patch = + nine_patch->SerializeBase(&chunk_len); + strcpy((char*)unknown_chunks[index].name, "npTc"); + unknown_chunks[index].size = chunk_len; + unknown_chunks[index].data = (png_bytep)serialized_nine_patch.get(); + unknown_chunks[index].location = PNG_HAVE_PLTE; index++; // Handle all unknown chunks. We are manually setting the chunks here, // so we will only ever handle our custom chunks. - png_set_keep_unknown_chunks(writePtr, PNG_HANDLE_CHUNK_ALWAYS, nullptr, 0); + png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, nullptr, 0); // Set the actual chunks here. The data gets copied, so our buffers can // safely go out of scope. - png_set_unknown_chunks(writePtr, writeInfoPtr, unknownChunks, index); + png_set_unknown_chunks(write_ptr, write_info_ptr, unknown_chunks, index); } -bool writePng(IAaptContext* context, const Image* image, - const NinePatch* ninePatch, io::OutputStream* out, +bool WritePng(IAaptContext* context, const Image* image, + const NinePatch* nine_patch, io::OutputStream* out, const PngOptions& options) { // Create and initialize the write png_struct with the default error and // warning handlers. // The header version is also passed in to ensure that this was built against // the same // version of libpng. - png_structp writePtr = + png_structp write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (writePtr == nullptr) { - context->getDiagnostics()->error( + if (write_ptr == nullptr) { + context->GetDiagnostics()->Error( DiagMessage() << "failed to create libpng write png_struct"); return false; } // Allocate memory to store image header data. - png_infop writeInfoPtr = png_create_info_struct(writePtr); - if (writeInfoPtr == nullptr) { - context->getDiagnostics()->error( + png_infop write_info_ptr = png_create_info_struct(write_ptr); + if (write_info_ptr == nullptr) { + context->GetDiagnostics()->Error( DiagMessage() << "failed to create libpng write png_info"); - png_destroy_write_struct(&writePtr, nullptr); + png_destroy_write_struct(&write_ptr, nullptr); return false; } // Automatically release PNG resources at end of scope. - PngWriteStructDeleter pngWriteDeleter(writePtr, writeInfoPtr); + PngWriteStructDeleter png_write_deleter(write_ptr, write_info_ptr); // libpng uses longjmp to jump to error handling routines. // setjmp will return true only if it was jumped to, aka, there was an error. - if (setjmp(png_jmpbuf(writePtr))) { + if (setjmp(png_jmpbuf(write_ptr))) { return false; } // Handle warnings with our IDiagnostics. - png_set_error_fn(writePtr, (png_voidp)context->getDiagnostics(), logError, - logWarning); + png_set_error_fn(write_ptr, (png_voidp)context->GetDiagnostics(), LogError, + LogWarning); // Set up the write functions which write to our custom data sources. - png_set_write_fn(writePtr, (png_voidp)out, writeDataToStream, nullptr); + png_set_write_fn(write_ptr, (png_voidp)out, WriteDataToStream, nullptr); // We want small files and can take the performance hit to achieve this goal. - png_set_compression_level(writePtr, Z_BEST_COMPRESSION); + png_set_compression_level(write_ptr, Z_BEST_COMPRESSION); // Begin analysis of the image data. // Scan the entire image and determine if: // 1. Every pixel has R == G == B (grayscale) // 2. Every pixel has A == 255 (opaque) // 3. There are no more than 256 distinct RGBA colors (palette). - std::unordered_map<uint32_t, int> colorPalette; - std::unordered_set<uint32_t> alphaPalette; - bool needsToZeroRGBChannelsOfTransparentPixels = false; - bool grayScale = true; - int maxGrayDeviation = 0; + std::unordered_map<uint32_t, int> color_palette; + std::unordered_set<uint32_t> alpha_palette; + bool needs_to_zero_rgb_channels_of_transparent_pixels = false; + bool grayscale = true; + int max_gray_deviation = 0; for (int32_t y = 0; y < image->height; y++) { const uint8_t* row = image->rows[y]; @@ -551,60 +559,60 @@ bool writePng(IAaptContext* context, const Image* image, // The color is completely transparent. // For purposes of palettes and grayscale optimization, // treat all channels as 0x00. - needsToZeroRGBChannelsOfTransparentPixels = - needsToZeroRGBChannelsOfTransparentPixels || + needs_to_zero_rgb_channels_of_transparent_pixels = + needs_to_zero_rgb_channels_of_transparent_pixels || (red != 0 || green != 0 || blue != 0); red = green = blue = 0; } // Insert the color into the color palette. const uint32_t color = red << 24 | green << 16 | blue << 8 | alpha; - colorPalette[color] = -1; + color_palette[color] = -1; // If the pixel has non-opaque alpha, insert it into the // alpha palette. if (alpha != 0xff) { - alphaPalette.insert(color); + alpha_palette.insert(color); } // Check if the image is indeed grayscale. - if (grayScale) { + if (grayscale) { if (red != green || red != blue) { - grayScale = false; + grayscale = false; } } // Calculate the gray scale deviation so that it can be compared // with the threshold. - maxGrayDeviation = std::max(std::abs(red - green), maxGrayDeviation); - maxGrayDeviation = std::max(std::abs(green - blue), maxGrayDeviation); - maxGrayDeviation = std::max(std::abs(blue - red), maxGrayDeviation); + max_gray_deviation = std::max(std::abs(red - green), max_gray_deviation); + max_gray_deviation = std::max(std::abs(green - blue), max_gray_deviation); + max_gray_deviation = std::max(std::abs(blue - red), max_gray_deviation); } } - if (context->verbose()) { + if (context->IsVerbose()) { DiagMessage msg; - msg << " paletteSize=" << colorPalette.size() - << " alphaPaletteSize=" << alphaPalette.size() - << " maxGrayDeviation=" << maxGrayDeviation - << " grayScale=" << (grayScale ? "true" : "false"); - context->getDiagnostics()->note(msg); + msg << " paletteSize=" << color_palette.size() + << " alphaPaletteSize=" << alpha_palette.size() + << " maxGrayDeviation=" << max_gray_deviation + << " grayScale=" << (grayscale ? "true" : "false"); + context->GetDiagnostics()->Note(msg); } - const bool convertibleToGrayScale = - maxGrayDeviation <= options.grayScaleTolerance; + const bool convertible_to_grayscale = + max_gray_deviation <= options.grayscale_tolerance; - const int newColorType = pickColorType( - image->width, image->height, grayScale, convertibleToGrayScale, - ninePatch != nullptr, colorPalette.size(), alphaPalette.size()); + const int new_color_type = PickColorType( + image->width, image->height, grayscale, convertible_to_grayscale, + nine_patch != nullptr, color_palette.size(), alpha_palette.size()); - if (context->verbose()) { + if (context->IsVerbose()) { DiagMessage msg; msg << "encoding PNG "; - if (ninePatch) { + if (nine_patch) { msg << "(with 9-patch) as "; } - switch (newColorType) { + switch (new_color_type) { case PNG_COLOR_TYPE_GRAY: msg << "GRAY"; break; @@ -621,137 +629,138 @@ bool writePng(IAaptContext* context, const Image* image, msg << "PALETTE"; break; default: - msg << "unknown type " << newColorType; + msg << "unknown type " << new_color_type; break; } - context->getDiagnostics()->note(msg); + context->GetDiagnostics()->Note(msg); } - png_set_IHDR(writePtr, writeInfoPtr, image->width, image->height, 8, - newColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + png_set_IHDR(write_ptr, write_info_ptr, image->width, image->height, 8, + new_color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - if (newColorType & PNG_COLOR_MASK_PALETTE) { + if (new_color_type & PNG_COLOR_MASK_PALETTE) { // Assigns indices to the palette, and writes the encoded palette to the // libpng writePtr. - writePalette(writePtr, writeInfoPtr, &colorPalette, &alphaPalette); - png_set_filter(writePtr, 0, PNG_NO_FILTERS); + WritePalette(write_ptr, write_info_ptr, &color_palette, &alpha_palette); + png_set_filter(write_ptr, 0, PNG_NO_FILTERS); } else { - png_set_filter(writePtr, 0, PNG_ALL_FILTERS); + png_set_filter(write_ptr, 0, PNG_ALL_FILTERS); } - if (ninePatch) { - writeNinePatch(writePtr, writeInfoPtr, ninePatch); + if (nine_patch) { + WriteNinePatch(write_ptr, write_info_ptr, nine_patch); } // Flush our updates to the header. - png_write_info(writePtr, writeInfoPtr); + png_write_info(write_ptr, write_info_ptr); // Write out each row of image data according to its encoding. - if (newColorType == PNG_COLOR_TYPE_PALETTE) { + if (new_color_type == PNG_COLOR_TYPE_PALETTE) { // 1 byte/pixel. - auto outRow = std::unique_ptr<png_byte[]>(new png_byte[image->width]); + auto out_row = std::unique_ptr<png_byte[]>(new png_byte[image->width]); for (int32_t y = 0; y < image->height; y++) { - png_const_bytep inRow = image->rows[y]; + png_const_bytep in_row = image->rows[y]; for (int32_t x = 0; x < image->width; x++) { - int rr = *inRow++; - int gg = *inRow++; - int bb = *inRow++; - int aa = *inRow++; + int rr = *in_row++; + int gg = *in_row++; + int bb = *in_row++; + int aa = *in_row++; if (aa == 0) { // Zero out color channels when transparent. rr = gg = bb = 0; } const uint32_t color = rr << 24 | gg << 16 | bb << 8 | aa; - const int idx = colorPalette[color]; - assert(idx != -1); - outRow[x] = static_cast<png_byte>(idx); + const int idx = color_palette[color]; + CHECK(idx != -1); + out_row[x] = static_cast<png_byte>(idx); } - png_write_row(writePtr, outRow.get()); + png_write_row(write_ptr, out_row.get()); } - } else if (newColorType == PNG_COLOR_TYPE_GRAY || - newColorType == PNG_COLOR_TYPE_GRAY_ALPHA) { - const size_t bpp = newColorType == PNG_COLOR_TYPE_GRAY ? 1 : 2; - auto outRow = std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]); + } else if (new_color_type == PNG_COLOR_TYPE_GRAY || + new_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + const size_t bpp = new_color_type == PNG_COLOR_TYPE_GRAY ? 1 : 2; + auto out_row = + std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]); for (int32_t y = 0; y < image->height; y++) { - png_const_bytep inRow = image->rows[y]; + png_const_bytep in_row = image->rows[y]; for (int32_t x = 0; x < image->width; x++) { - int rr = inRow[x * 4]; - int gg = inRow[x * 4 + 1]; - int bb = inRow[x * 4 + 2]; - int aa = inRow[x * 4 + 3]; + int rr = in_row[x * 4]; + int gg = in_row[x * 4 + 1]; + int bb = in_row[x * 4 + 2]; + int aa = in_row[x * 4 + 3]; if (aa == 0) { // Zero out the gray channel when transparent. rr = gg = bb = 0; } - if (grayScale) { + if (grayscale) { // The image was already grayscale, red == green == blue. - outRow[x * bpp] = inRow[x * 4]; + out_row[x * bpp] = in_row[x * 4]; } else { // The image is convertible to grayscale, use linear-luminance of // sRGB colorspace: // https://en.wikipedia.org/wiki/Grayscale#Colorimetric_.28luminance-preserving.29_conversion_to_grayscale - outRow[x * bpp] = + out_row[x * bpp] = (png_byte)(rr * 0.2126f + gg * 0.7152f + bb * 0.0722f); } if (bpp == 2) { // Write out alpha if we have it. - outRow[x * bpp + 1] = aa; + out_row[x * bpp + 1] = aa; } } - png_write_row(writePtr, outRow.get()); + png_write_row(write_ptr, out_row.get()); } - } else if (newColorType == PNG_COLOR_TYPE_RGB || - newColorType == PNG_COLOR_TYPE_RGBA) { - const size_t bpp = newColorType == PNG_COLOR_TYPE_RGB ? 3 : 4; - if (needsToZeroRGBChannelsOfTransparentPixels) { + } else if (new_color_type == PNG_COLOR_TYPE_RGB || + new_color_type == PNG_COLOR_TYPE_RGBA) { + const size_t bpp = new_color_type == PNG_COLOR_TYPE_RGB ? 3 : 4; + if (needs_to_zero_rgb_channels_of_transparent_pixels) { // The source RGBA data can't be used as-is, because we need to zero out // the RGB // values of transparent pixels. - auto outRow = + auto out_row = std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]); for (int32_t y = 0; y < image->height; y++) { - png_const_bytep inRow = image->rows[y]; + png_const_bytep in_row = image->rows[y]; for (int32_t x = 0; x < image->width; x++) { - int rr = *inRow++; - int gg = *inRow++; - int bb = *inRow++; - int aa = *inRow++; + int rr = *in_row++; + int gg = *in_row++; + int bb = *in_row++; + int aa = *in_row++; if (aa == 0) { // Zero out the RGB channels when transparent. rr = gg = bb = 0; } - outRow[x * bpp] = rr; - outRow[x * bpp + 1] = gg; - outRow[x * bpp + 2] = bb; + out_row[x * bpp] = rr; + out_row[x * bpp + 1] = gg; + out_row[x * bpp + 2] = bb; if (bpp == 4) { - outRow[x * bpp + 3] = aa; + out_row[x * bpp + 3] = aa; } } - png_write_row(writePtr, outRow.get()); + png_write_row(write_ptr, out_row.get()); } } else { // The source image can be used as-is, just tell libpng whether or not to // ignore // the alpha channel. - if (newColorType == PNG_COLOR_TYPE_RGB) { + if (new_color_type == PNG_COLOR_TYPE_RGB) { // Delete the extraneous alpha values that we appended to our buffer // when reading the original values. - png_set_filler(writePtr, 0, PNG_FILLER_AFTER); + png_set_filler(write_ptr, 0, PNG_FILLER_AFTER); } - png_write_image(writePtr, image->rows.get()); + png_write_image(write_ptr, image->rows.get()); } } else { - assert(false && "unreachable"); + LOG(FATAL) << "unreachable"; } - png_write_end(writePtr, writeInfoPtr); + png_write_end(write_ptr, write_info_ptr); return true; } diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp index d8ed0bba951e..055a725213b7 100644 --- a/tools/aapt2/compile/PseudolocaleGenerator.cpp +++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp @@ -15,27 +15,29 @@ */ #include "compile/PseudolocaleGenerator.h" + +#include <algorithm> + #include "ResourceTable.h" #include "ResourceValues.h" #include "ValueVisitor.h" #include "compile/Pseudolocalizer.h" -#include <algorithm> - namespace aapt { -std::unique_ptr<StyledString> pseudolocalizeStyledString( +std::unique_ptr<StyledString> PseudolocalizeStyledString( StyledString* string, Pseudolocalizer::Method method, StringPool* pool) { Pseudolocalizer localizer(method); - const StringPiece originalText = *string->value->str; + const StringPiece original_text = *string->value->str; StyleString localized; // Copy the spans. We will update their offsets when we localize. localized.spans.reserve(string->value->spans.size()); for (const StringPool::Span& span : string->value->spans) { - localized.spans.push_back(Span{*span.name, span.firstChar, span.lastChar}); + localized.spans.push_back( + Span{*span.name, span.first_char, span.last_char}); } // The ranges are all represented with a single value. This is the start of @@ -49,8 +51,8 @@ std::unique_ptr<StyledString> pseudolocalizeStyledString( // Since this struct represents the start of one range and end of another, // we have // the two pointers respectively. - uint32_t* updateStart; - uint32_t* updateEnd; + uint32_t* update_start; + uint32_t* update_end; }; auto cmp = [](const Range& r, size_t index) -> bool { @@ -64,109 +66,113 @@ std::unique_ptr<StyledString> pseudolocalizeStyledString( // std::vector<Range> ranges; ranges.push_back(Range{0}); - ranges.push_back(Range{originalText.size() - 1}); + ranges.push_back(Range{original_text.size() - 1}); for (size_t i = 0; i < string->value->spans.size(); i++) { const StringPool::Span& span = string->value->spans[i]; // Insert or update the Range marker for the start of this span. auto iter = - std::lower_bound(ranges.begin(), ranges.end(), span.firstChar, cmp); - if (iter != ranges.end() && iter->start == span.firstChar) { - iter->updateStart = &localized.spans[i].firstChar; + std::lower_bound(ranges.begin(), ranges.end(), span.first_char, cmp); + if (iter != ranges.end() && iter->start == span.first_char) { + iter->update_start = &localized.spans[i].first_char; } else { - ranges.insert( - iter, Range{span.firstChar, &localized.spans[i].firstChar, nullptr}); + ranges.insert(iter, Range{span.first_char, &localized.spans[i].first_char, + nullptr}); } // Insert or update the Range marker for the end of this span. - iter = std::lower_bound(ranges.begin(), ranges.end(), span.lastChar, cmp); - if (iter != ranges.end() && iter->start == span.lastChar) { - iter->updateEnd = &localized.spans[i].lastChar; + iter = std::lower_bound(ranges.begin(), ranges.end(), span.last_char, cmp); + if (iter != ranges.end() && iter->start == span.last_char) { + iter->update_end = &localized.spans[i].last_char; } else { ranges.insert( - iter, Range{span.lastChar, nullptr, &localized.spans[i].lastChar}); + iter, Range{span.last_char, nullptr, &localized.spans[i].last_char}); } } - localized.str += localizer.start(); + localized.str += localizer.Start(); // Iterate over the ranges and localize each section. for (size_t i = 0; i < ranges.size(); i++) { const size_t start = ranges[i].start; - size_t len = originalText.size() - start; + size_t len = original_text.size() - start; if (i + 1 < ranges.size()) { len = ranges[i + 1].start - start; } - if (ranges[i].updateStart) { - *ranges[i].updateStart = localized.str.size(); + if (ranges[i].update_start) { + *ranges[i].update_start = localized.str.size(); } - if (ranges[i].updateEnd) { - *ranges[i].updateEnd = localized.str.size(); + if (ranges[i].update_end) { + *ranges[i].update_end = localized.str.size(); } - localized.str += localizer.text(originalText.substr(start, len)); + localized.str += localizer.Text(original_text.substr(start, len)); } - localized.str += localizer.end(); + localized.str += localizer.End(); - std::unique_ptr<StyledString> localizedString = - util::make_unique<StyledString>(pool->makeRef(localized)); - localizedString->setSource(string->getSource()); - return localizedString; + std::unique_ptr<StyledString> localized_string = + util::make_unique<StyledString>(pool->MakeRef(localized)); + localized_string->SetSource(string->GetSource()); + return localized_string; } namespace { -struct Visitor : public RawValueVisitor { - StringPool* mPool; - Pseudolocalizer::Method mMethod; - Pseudolocalizer mLocalizer; - +class Visitor : public RawValueVisitor { + public: // Either value or item will be populated upon visiting the value. - std::unique_ptr<Value> mValue; - std::unique_ptr<Item> mItem; + std::unique_ptr<Value> value; + std::unique_ptr<Item> item; Visitor(StringPool* pool, Pseudolocalizer::Method method) - : mPool(pool), mMethod(method), mLocalizer(method) {} + : pool_(pool), method_(method), localizer_(method) {} - void visit(Plural* plural) override { + void Visit(Plural* plural) override { std::unique_ptr<Plural> localized = util::make_unique<Plural>(); for (size_t i = 0; i < plural->values.size(); i++) { - Visitor subVisitor(mPool, mMethod); + Visitor sub_visitor(pool_, method_); if (plural->values[i]) { - plural->values[i]->accept(&subVisitor); - if (subVisitor.mValue) { - localized->values[i] = std::move(subVisitor.mItem); + plural->values[i]->Accept(&sub_visitor); + if (sub_visitor.value) { + localized->values[i] = std::move(sub_visitor.item); } else { localized->values[i] = - std::unique_ptr<Item>(plural->values[i]->clone(mPool)); + std::unique_ptr<Item>(plural->values[i]->Clone(pool_)); } } } - localized->setSource(plural->getSource()); - localized->setWeak(true); - mValue = std::move(localized); + localized->SetSource(plural->GetSource()); + localized->SetWeak(true); + value = std::move(localized); } - void visit(String* string) override { + void Visit(String* string) override { std::string result = - mLocalizer.start() + mLocalizer.text(*string->value) + mLocalizer.end(); + localizer_.Start() + localizer_.Text(*string->value) + localizer_.End(); std::unique_ptr<String> localized = - util::make_unique<String>(mPool->makeRef(result)); - localized->setSource(string->getSource()); - localized->setWeak(true); - mItem = std::move(localized); + util::make_unique<String>(pool_->MakeRef(result)); + localized->SetSource(string->GetSource()); + localized->SetWeak(true); + item = std::move(localized); } - void visit(StyledString* string) override { - mItem = pseudolocalizeStyledString(string, mMethod, mPool); - mItem->setWeak(true); + void Visit(StyledString* string) override { + item = PseudolocalizeStyledString(string, method_, pool_); + item->SetWeak(true); } + + private: + DISALLOW_COPY_AND_ASSIGN(Visitor); + + StringPool* pool_; + Pseudolocalizer::Method method_; + Pseudolocalizer localizer_; }; -ConfigDescription modifyConfigForPseudoLocale(const ConfigDescription& base, +ConfigDescription ModifyConfigForPseudoLocale(const ConfigDescription& base, Pseudolocalizer::Method m) { ConfigDescription modified = base; switch (m) { @@ -189,31 +195,31 @@ ConfigDescription modifyConfigForPseudoLocale(const ConfigDescription& base, return modified; } -void pseudolocalizeIfNeeded(const Pseudolocalizer::Method method, - ResourceConfigValue* originalValue, +void PseudolocalizeIfNeeded(const Pseudolocalizer::Method method, + ResourceConfigValue* original_value, StringPool* pool, ResourceEntry* entry) { Visitor visitor(pool, method); - originalValue->value->accept(&visitor); + original_value->value->Accept(&visitor); - std::unique_ptr<Value> localizedValue; - if (visitor.mValue) { - localizedValue = std::move(visitor.mValue); - } else if (visitor.mItem) { - localizedValue = std::move(visitor.mItem); + std::unique_ptr<Value> localized_value; + if (visitor.value) { + localized_value = std::move(visitor.value); + } else if (visitor.item) { + localized_value = std::move(visitor.item); } - if (!localizedValue) { + if (!localized_value) { return; } - ConfigDescription configWithAccent = - modifyConfigForPseudoLocale(originalValue->config, method); + ConfigDescription config_with_accent = + ModifyConfigForPseudoLocale(original_value->config, method); - ResourceConfigValue* newConfigValue = - entry->findOrCreateValue(configWithAccent, originalValue->product); - if (!newConfigValue->value) { + ResourceConfigValue* new_config_value = + entry->FindOrCreateValue(config_with_accent, original_value->product); + if (!new_config_value->value) { // Only use auto-generated pseudo-localization if none is defined. - newConfigValue->value = std::move(localizedValue); + new_config_value->value = std::move(localized_value); } } @@ -222,29 +228,30 @@ void pseudolocalizeIfNeeded(const Pseudolocalizer::Method method, * default locale) * and is translateable. */ -static bool isPseudolocalizable(ResourceConfigValue* configValue) { - const int diff = configValue->config.diff(ConfigDescription::defaultConfig()); +static bool IsPseudolocalizable(ResourceConfigValue* config_value) { + const int diff = + config_value->config.diff(ConfigDescription::DefaultConfig()); if (diff & ConfigDescription::CONFIG_LOCALE) { return false; } - return configValue->value->isTranslateable(); + return config_value->value->IsTranslateable(); } } // namespace -bool PseudolocaleGenerator::consume(IAaptContext* context, +bool PseudolocaleGenerator::Consume(IAaptContext* context, ResourceTable* table) { for (auto& package : table->packages) { for (auto& type : package->types) { for (auto& entry : type->entries) { std::vector<ResourceConfigValue*> values = - entry->findValuesIf(isPseudolocalizable); + entry->FindValuesIf(IsPseudolocalizable); for (ResourceConfigValue* value : values) { - pseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value, - &table->stringPool, entry.get()); - pseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value, - &table->stringPool, entry.get()); + PseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value, + &table->string_pool, entry.get()); + PseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value, + &table->string_pool, entry.get()); } } } diff --git a/tools/aapt2/compile/PseudolocaleGenerator.h b/tools/aapt2/compile/PseudolocaleGenerator.h index 4e97cb989e68..ace378603f65 100644 --- a/tools/aapt2/compile/PseudolocaleGenerator.h +++ b/tools/aapt2/compile/PseudolocaleGenerator.h @@ -23,11 +23,11 @@ namespace aapt { -std::unique_ptr<StyledString> pseudolocalizeStyledString( +std::unique_ptr<StyledString> PseudolocalizeStyledString( StyledString* string, Pseudolocalizer::Method method, StringPool* pool); struct PseudolocaleGenerator : public IResourceTableConsumer { - bool consume(IAaptContext* context, ResourceTable* table) override; + bool Consume(IAaptContext* context, ResourceTable* table) override; }; } // namespace aapt diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp index 64a3e97a5aa6..5a9884d34dd1 100644 --- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp +++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp @@ -15,118 +15,119 @@ */ #include "compile/PseudolocaleGenerator.h" + #include "test/Test.h" #include "util/Util.h" -#include <androidfw/ResourceTypes.h> - namespace aapt { TEST(PseudolocaleGeneratorTest, PseudolocalizeStyledString) { StringPool pool; - StyleString originalStyle; - originalStyle.str = "Hello world!"; - originalStyle.spans = {Span{"b", 2, 3}, Span{"b", 6, 7}, Span{"i", 1, 10}}; + StyleString original_style; + original_style.str = "Hello world!"; + original_style.spans = {Span{"b", 2, 3}, Span{"b", 6, 7}, Span{"i", 1, 10}}; - std::unique_ptr<StyledString> newString = pseudolocalizeStyledString( - util::make_unique<StyledString>(pool.makeRef(originalStyle)).get(), + std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString( + util::make_unique<StyledString>(pool.MakeRef(original_style)).get(), Pseudolocalizer::Method::kNone, &pool); - EXPECT_EQ(originalStyle.str, *newString->value->str); - ASSERT_EQ(originalStyle.spans.size(), newString->value->spans.size()); + EXPECT_EQ(original_style.str, *new_string->value->str); + ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size()); - EXPECT_EQ(std::string("He").size(), newString->value->spans[0].firstChar); - EXPECT_EQ(std::string("Hel").size(), newString->value->spans[0].lastChar); - EXPECT_EQ(std::string("b"), *newString->value->spans[0].name); + EXPECT_EQ(std::string("He").size(), new_string->value->spans[0].first_char); + EXPECT_EQ(std::string("Hel").size(), new_string->value->spans[0].last_char); + EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name); - EXPECT_EQ(std::string("Hello ").size(), newString->value->spans[1].firstChar); - EXPECT_EQ(std::string("Hello w").size(), newString->value->spans[1].lastChar); - EXPECT_EQ(std::string("b"), *newString->value->spans[1].name); + EXPECT_EQ(std::string("Hello ").size(), + new_string->value->spans[1].first_char); + EXPECT_EQ(std::string("Hello w").size(), + new_string->value->spans[1].last_char); + EXPECT_EQ(std::string("b"), *new_string->value->spans[1].name); - EXPECT_EQ(std::string("H").size(), newString->value->spans[2].firstChar); + EXPECT_EQ(std::string("H").size(), new_string->value->spans[2].first_char); EXPECT_EQ(std::string("Hello worl").size(), - newString->value->spans[2].lastChar); - EXPECT_EQ(std::string("i"), *newString->value->spans[2].name); + new_string->value->spans[2].last_char); + EXPECT_EQ(std::string("i"), *new_string->value->spans[2].name); - originalStyle.spans.push_back(Span{"em", 0, 11u}); + original_style.spans.push_back(Span{"em", 0, 11u}); - newString = pseudolocalizeStyledString( - util::make_unique<StyledString>(pool.makeRef(originalStyle)).get(), + new_string = PseudolocalizeStyledString( + util::make_unique<StyledString>(pool.MakeRef(original_style)).get(), Pseudolocalizer::Method::kAccent, &pool); - EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð¡ one two]"), *newString->value->str); - ASSERT_EQ(originalStyle.spans.size(), newString->value->spans.size()); + EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð¡ one two]"), *new_string->value->str); + ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size()); - EXPECT_EQ(std::string("[Ĥé").size(), newString->value->spans[0].firstChar); - EXPECT_EQ(std::string("[Ĥéļ").size(), newString->value->spans[0].lastChar); + EXPECT_EQ(std::string("[Ĥé").size(), new_string->value->spans[0].first_char); + EXPECT_EQ(std::string("[Ĥéļ").size(), new_string->value->spans[0].last_char); EXPECT_EQ(std::string("[Ĥéļļö ").size(), - newString->value->spans[1].firstChar); + new_string->value->spans[1].first_char); EXPECT_EQ(std::string("[Ĥéļļö ŵ").size(), - newString->value->spans[1].lastChar); + new_string->value->spans[1].last_char); - EXPECT_EQ(std::string("[Ĥ").size(), newString->value->spans[2].firstChar); + EXPECT_EQ(std::string("[Ĥ").size(), new_string->value->spans[2].first_char); EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļ").size(), - newString->value->spans[2].lastChar); + new_string->value->spans[2].last_char); - EXPECT_EQ(std::string("[").size(), newString->value->spans[3].firstChar); + EXPECT_EQ(std::string("[").size(), new_string->value->spans[3].first_char); EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð").size(), - newString->value->spans[3].lastChar); + new_string->value->spans[3].last_char); } TEST(PseudolocaleGeneratorTest, PseudolocalizeOnlyDefaultConfigs) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addString("android:string/one", "one") - .addString("android:string/two", ResourceId{}, - test::parseConfigOrDie("en"), "two") - .addString("android:string/three", "three") - .addString("android:string/three", ResourceId{}, - test::parseConfigOrDie("en-rXA"), "three") - .addString("android:string/four", "four") - .build(); - - String* val = test::getValue<String>(table.get(), "android:string/four"); + .AddString("android:string/one", "one") + .AddString("android:string/two", ResourceId{}, + test::ParseConfigOrDie("en"), "two") + .AddString("android:string/three", "three") + .AddString("android:string/three", ResourceId{}, + test::ParseConfigOrDie("en-rXA"), "three") + .AddString("android:string/four", "four") + .Build(); + + String* val = test::GetValue<String>(table.get(), "android:string/four"); ASSERT_NE(nullptr, val); - val->setTranslateable(false); + val->SetTranslateable(false); - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); PseudolocaleGenerator generator; - ASSERT_TRUE(generator.consume(context.get(), table.get())); + ASSERT_TRUE(generator.Consume(context.get(), table.get())); // Normal pseudolocalization should take place. ASSERT_NE(nullptr, - test::getValueForConfig<String>(table.get(), "android:string/one", - test::parseConfigOrDie("en-rXA"))); + test::GetValueForConfig<String>(table.get(), "android:string/one", + test::ParseConfigOrDie("en-rXA"))); ASSERT_NE(nullptr, - test::getValueForConfig<String>(table.get(), "android:string/one", - test::parseConfigOrDie("ar-rXB"))); + test::GetValueForConfig<String>(table.get(), "android:string/one", + test::ParseConfigOrDie("ar-rXB"))); // No default config for android:string/two, so no pseudlocales should exist. ASSERT_EQ(nullptr, - test::getValueForConfig<String>(table.get(), "android:string/two", - test::parseConfigOrDie("en-rXA"))); + test::GetValueForConfig<String>(table.get(), "android:string/two", + test::ParseConfigOrDie("en-rXA"))); ASSERT_EQ(nullptr, - test::getValueForConfig<String>(table.get(), "android:string/two", - test::parseConfigOrDie("ar-rXB"))); + test::GetValueForConfig<String>(table.get(), "android:string/two", + test::ParseConfigOrDie("ar-rXB"))); // Check that we didn't override manual pseudolocalization. - val = test::getValueForConfig<String>(table.get(), "android:string/three", - test::parseConfigOrDie("en-rXA")); + val = test::GetValueForConfig<String>(table.get(), "android:string/three", + test::ParseConfigOrDie("en-rXA")); ASSERT_NE(nullptr, val); EXPECT_EQ(std::string("three"), *val->value); ASSERT_NE(nullptr, - test::getValueForConfig<String>(table.get(), "android:string/three", - test::parseConfigOrDie("ar-rXB"))); + test::GetValueForConfig<String>(table.get(), "android:string/three", + test::ParseConfigOrDie("ar-rXB"))); // Check that four's translateable marker was honored. ASSERT_EQ(nullptr, - test::getValueForConfig<String>(table.get(), "android:string/four", - test::parseConfigOrDie("en-rXA"))); + test::GetValueForConfig<String>(table.get(), "android:string/four", + test::ParseConfigOrDie("en-rXA"))); ASSERT_EQ(nullptr, - test::getValueForConfig<String>(table.get(), "android:string/four", - test::parseConfigOrDie("ar-rXB"))); + test::GetValueForConfig<String>(table.get(), "android:string/four", + test::ParseConfigOrDie("ar-rXB"))); } } // namespace aapt diff --git a/tools/aapt2/compile/Pseudolocalizer.cpp b/tools/aapt2/compile/Pseudolocalizer.cpp index c3aec98d89e0..f89288f73333 100644 --- a/tools/aapt2/compile/Pseudolocalizer.cpp +++ b/tools/aapt2/compile/Pseudolocalizer.cpp @@ -15,77 +15,78 @@ */ #include "compile/Pseudolocalizer.h" + #include "util/Util.h" namespace aapt { // String basis to generate expansion -static const std::string k_expansion_string = +static const std::string kExpansionString = "one two three " "four five six seven eight nine ten eleven twelve thirteen " "fourteen fiveteen sixteen seventeen nineteen twenty"; // Special unicode characters to override directionality of the words -static const std::string k_rlm = "\u200f"; -static const std::string k_rlo = "\u202e"; -static const std::string k_pdf = "\u202c"; +static const std::string kRlm = "\u200f"; +static const std::string kRlo = "\u202e"; +static const std::string kPdf = "\u202c"; // Placeholder marks -static const std::string k_placeholder_open = "\u00bb"; -static const std::string k_placeholder_close = "\u00ab"; +static const std::string kPlaceholderOpen = "\u00bb"; +static const std::string kPlaceholderClose = "\u00ab"; -static const char k_arg_start = '{'; -static const char k_arg_end = '}'; +static const char kArgStart = '{'; +static const char kArgEnd = '}'; class PseudoMethodNone : public PseudoMethodImpl { public: - std::string text(const StringPiece& text) override { return text.toString(); } - std::string placeholder(const StringPiece& text) override { - return text.toString(); + std::string Text(const StringPiece& text) override { return text.ToString(); } + std::string Placeholder(const StringPiece& text) override { + return text.ToString(); } }; class PseudoMethodBidi : public PseudoMethodImpl { public: - std::string text(const StringPiece& text) override; - std::string placeholder(const StringPiece& text) override; + std::string Text(const StringPiece& text) override; + std::string Placeholder(const StringPiece& text) override; }; class PseudoMethodAccent : public PseudoMethodImpl { public: - PseudoMethodAccent() : mDepth(0), mWordCount(0), mLength(0) {} - std::string start() override; - std::string end() override; - std::string text(const StringPiece& text) override; - std::string placeholder(const StringPiece& text) override; + PseudoMethodAccent() : depth_(0), word_count_(0), length_(0) {} + std::string Start() override; + std::string End() override; + std::string Text(const StringPiece& text) override; + std::string Placeholder(const StringPiece& text) override; private: - size_t mDepth; - size_t mWordCount; - size_t mLength; + size_t depth_; + size_t word_count_; + size_t length_; }; -Pseudolocalizer::Pseudolocalizer(Method method) : mLastDepth(0) { - setMethod(method); +Pseudolocalizer::Pseudolocalizer(Method method) : last_depth_(0) { + SetMethod(method); } -void Pseudolocalizer::setMethod(Method method) { +void Pseudolocalizer::SetMethod(Method method) { switch (method) { case Method::kNone: - mImpl = util::make_unique<PseudoMethodNone>(); + impl_ = util::make_unique<PseudoMethodNone>(); break; case Method::kAccent: - mImpl = util::make_unique<PseudoMethodAccent>(); + impl_ = util::make_unique<PseudoMethodAccent>(); break; case Method::kBidi: - mImpl = util::make_unique<PseudoMethodBidi>(); + impl_ = util::make_unique<PseudoMethodBidi>(); break; } } -std::string Pseudolocalizer::text(const StringPiece& text) { +std::string Pseudolocalizer::Text(const StringPiece& text) { std::string out; - size_t depth = mLastDepth; + size_t depth = last_depth_; size_t lastpos, pos; const size_t length = text.size(); const char* str = text.data(); @@ -101,42 +102,41 @@ std::string Pseudolocalizer::text(const StringPiece& text) { continue; } - if (c == k_arg_start) { + if (c == kArgStart) { depth++; - } else if (c == k_arg_end && depth) { + } else if (c == kArgEnd && depth) { depth--; } - if (mLastDepth != depth || pos == length - 1) { - bool pseudo = ((mLastDepth % 2) == 0); + if (last_depth_ != depth || pos == length - 1) { + bool pseudo = ((last_depth_ % 2) == 0); size_t nextpos = pos; - if (!pseudo || depth == mLastDepth) { + if (!pseudo || depth == last_depth_) { nextpos++; } size_t size = nextpos - lastpos; if (size) { - std::string chunk = text.substr(lastpos, size).toString(); + std::string chunk = text.substr(lastpos, size).ToString(); if (pseudo) { - chunk = mImpl->text(chunk); - } else if (str[lastpos] == k_arg_start && - str[nextpos - 1] == k_arg_end) { - chunk = mImpl->placeholder(chunk); + chunk = impl_->Text(chunk); + } else if (str[lastpos] == kArgStart && str[nextpos - 1] == kArgEnd) { + chunk = impl_->Placeholder(chunk); } out.append(chunk); } - if (pseudo && depth < mLastDepth) { // End of message - out.append(mImpl->end()); - } else if (!pseudo && depth > mLastDepth) { // Start of message - out.append(mImpl->start()); + if (pseudo && depth < last_depth_) { // End of message + out.append(impl_->End()); + } else if (!pseudo && depth > last_depth_) { // Start of message + out.append(impl_->Start()); } lastpos = nextpos; - mLastDepth = depth; + last_depth_ = depth; } } return out; } -static const char* pseudolocalizeChar(const char c) { +static const char* PseudolocalizeChar(const char c) { switch (c) { case 'a': return "\u00e5"; @@ -251,7 +251,7 @@ static const char* pseudolocalizeChar(const char c) { } } -static bool isPossibleNormalPlaceholderEnd(const char c) { +static bool IsPossibleNormalPlaceholderEnd(const char c) { switch (c) { case 's': return true; @@ -300,12 +300,12 @@ static bool isPossibleNormalPlaceholderEnd(const char c) { } } -static std::string pseudoGenerateExpansion(const unsigned int length) { - std::string result = k_expansion_string; +static std::string PseudoGenerateExpansion(const unsigned int length) { + std::string result = kExpansionString; const char* s = result.data(); if (result.size() < length) { result += " "; - result += pseudoGenerateExpansion(length - result.size()); + result += PseudoGenerateExpansion(length - result.size()); } else { int ext = 0; // Should contain only whole words, so looking for a space @@ -320,25 +320,25 @@ static std::string pseudoGenerateExpansion(const unsigned int length) { return result; } -std::string PseudoMethodAccent::start() { +std::string PseudoMethodAccent::Start() { std::string result; - if (mDepth == 0) { + if (depth_ == 0) { result = "["; } - mWordCount = mLength = 0; - mDepth++; + word_count_ = length_ = 0; + depth_++; return result; } -std::string PseudoMethodAccent::end() { +std::string PseudoMethodAccent::End() { std::string result; - if (mLength) { + if (length_) { result += " "; - result += pseudoGenerateExpansion(mWordCount > 3 ? mLength : mLength / 2); + result += PseudoGenerateExpansion(word_count_ > 3 ? length_ : length_ / 2); } - mWordCount = mLength = 0; - mDepth--; - if (mDepth == 0) { + word_count_ = length_ = 0; + depth_--; + if (depth_ == 0) { result += "]"; } return result; @@ -349,7 +349,7 @@ std::string PseudoMethodAccent::end() { * * Note: This leaves placeholder syntax untouched. */ -std::string PseudoMethodAccent::text(const StringPiece& source) { +std::string PseudoMethodAccent::Text(const StringPiece& source) { const char* s = source.data(); std::string result; const size_t I = source.size(); @@ -365,7 +365,7 @@ std::string PseudoMethodAccent::text(const StringPiece& source) { ++i; c = s[i]; chunk.append(&c, 1); - if (isPossibleNormalPlaceholderEnd(c)) { + if (IsPossibleNormalPlaceholderEnd(c)) { end = true; } else if (i + 1 < I && c == 't') { ++i; @@ -375,24 +375,24 @@ std::string PseudoMethodAccent::text(const StringPiece& source) { } } // Treat chunk as a placeholder unless it ends with %. - result += ((c == '%') ? chunk : placeholder(chunk)); + result += ((c == '%') ? chunk : Placeholder(chunk)); } else if (c == '<' || c == '&') { // html syntax, no need to pseudolocalize bool tag_closed = false; while (!tag_closed && i < I) { if (c == '&') { - std::string escapeText; - escapeText.append(&c, 1); + std::string escape_text; + escape_text.append(&c, 1); bool end = false; - size_t htmlCodePos = i; - while (!end && htmlCodePos < I) { - ++htmlCodePos; - c = s[htmlCodePos]; - escapeText.append(&c, 1); + size_t html_code_pos = i; + while (!end && html_code_pos < I) { + ++html_code_pos; + c = s[html_code_pos]; + escape_text.append(&c, 1); // Valid html code if (c == ';') { end = true; - i = htmlCodePos; + i = html_code_pos; } // Wrong html code else if (!((c == '#' || (c >= 'a' && c <= 'z') || @@ -400,8 +400,8 @@ std::string PseudoMethodAccent::text(const StringPiece& source) { end = true; } } - result += escapeText; - if (escapeText != "<") { + result += escape_text; + if (escape_text != "<") { tag_closed = true; } continue; @@ -417,30 +417,30 @@ std::string PseudoMethodAccent::text(const StringPiece& source) { } } else { // This is a pure text that should be pseudolocalized - const char* p = pseudolocalizeChar(c); + const char* p = PseudolocalizeChar(c); if (p != nullptr) { result += p; } else { bool space = isspace(c); if (lastspace && !space) { - mWordCount++; + word_count_++; } lastspace = space; result.append(&c, 1); } // Count only pseudolocalizable chars and delimiters - mLength++; + length_++; } } return result; } -std::string PseudoMethodAccent::placeholder(const StringPiece& source) { +std::string PseudoMethodAccent::Placeholder(const StringPiece& source) { // Surround a placeholder with brackets - return k_placeholder_open + source.toString() + k_placeholder_close; + return kPlaceholderOpen + source.ToString() + kPlaceholderClose; } -std::string PseudoMethodBidi::text(const StringPiece& source) { +std::string PseudoMethodBidi::Text(const StringPiece& source) { const char* s = source.data(); std::string result; bool lastspace = true; @@ -450,24 +450,24 @@ std::string PseudoMethodBidi::text(const StringPiece& source) { space = isspace(c); if (lastspace && !space) { // Word start - result += k_rlm + k_rlo; + result += kRlm + kRlo; } else if (!lastspace && space) { // Word end - result += k_pdf + k_rlm; + result += kPdf + kRlm; } lastspace = space; result.append(&c, 1); } if (!lastspace) { // End of last word - result += k_pdf + k_rlm; + result += kPdf + kRlm; } return result; } -std::string PseudoMethodBidi::placeholder(const StringPiece& source) { +std::string PseudoMethodBidi::Placeholder(const StringPiece& source) { // Surround a placeholder with directionality change sequence - return k_rlm + k_rlo + source.toString() + k_pdf + k_rlm; + return kRlm + kRlo + source.ToString() + kPdf + kRlm; } } // namespace aapt diff --git a/tools/aapt2/compile/Pseudolocalizer.h b/tools/aapt2/compile/Pseudolocalizer.h index a526877b4737..a6d2ad037d50 100644 --- a/tools/aapt2/compile/Pseudolocalizer.h +++ b/tools/aapt2/compile/Pseudolocalizer.h @@ -17,22 +17,23 @@ #ifndef AAPT_COMPILE_PSEUDOLOCALIZE_H #define AAPT_COMPILE_PSEUDOLOCALIZE_H +#include <memory> + +#include "android-base/macros.h" + #include "ResourceValues.h" #include "StringPool.h" #include "util/StringPiece.h" -#include <android-base/macros.h> -#include <memory> - namespace aapt { class PseudoMethodImpl { public: virtual ~PseudoMethodImpl() {} - virtual std::string start() { return {}; } - virtual std::string end() { return {}; } - virtual std::string text(const StringPiece& text) = 0; - virtual std::string placeholder(const StringPiece& text) = 0; + virtual std::string Start() { return {}; } + virtual std::string End() { return {}; } + virtual std::string Text(const StringPiece& text) = 0; + virtual std::string Placeholder(const StringPiece& text) = 0; }; class Pseudolocalizer { @@ -44,14 +45,14 @@ class Pseudolocalizer { }; explicit Pseudolocalizer(Method method); - void setMethod(Method method); - std::string start() { return mImpl->start(); } - std::string end() { return mImpl->end(); } - std::string text(const StringPiece& text); + void SetMethod(Method method); + std::string Start() { return impl_->Start(); } + std::string End() { return impl_->End(); } + std::string Text(const StringPiece& text); private: - std::unique_ptr<PseudoMethodImpl> mImpl; - size_t mLastDepth; + std::unique_ptr<PseudoMethodImpl> impl_; + size_t last_depth_; }; } // namespace aapt diff --git a/tools/aapt2/compile/Pseudolocalizer_test.cpp b/tools/aapt2/compile/Pseudolocalizer_test.cpp index a152ed6d00cf..92eb3b58515f 100644 --- a/tools/aapt2/compile/Pseudolocalizer_test.cpp +++ b/tools/aapt2/compile/Pseudolocalizer_test.cpp @@ -15,33 +15,32 @@ */ #include "compile/Pseudolocalizer.h" -#include "util/Util.h" -#include <androidfw/ResourceTypes.h> -#include <gtest/gtest.h> +#include "test/Test.h" +#include "util/Util.h" namespace aapt { // In this context, 'Axis' represents a particular field in the configuration, // such as language or density. -static ::testing::AssertionResult simpleHelper(const char* input, +static ::testing::AssertionResult SimpleHelper(const char* input, const char* expected, Pseudolocalizer::Method method) { Pseudolocalizer pseudo(method); - std::string result = pseudo.start() + pseudo.text(input) + pseudo.end(); + std::string result = pseudo.Start() + pseudo.Text(input) + pseudo.End(); if (result != expected) { return ::testing::AssertionFailure() << expected << " != " << result; } return ::testing::AssertionSuccess(); } -static ::testing::AssertionResult compoundHelper( +static ::testing::AssertionResult CompoundHelper( const char* in1, const char* in2, const char* in3, const char* expected, Pseudolocalizer::Method method) { Pseudolocalizer pseudo(method); - std::string result = pseudo.start() + pseudo.text(in1) + pseudo.text(in2) + - pseudo.text(in3) + pseudo.end(); + std::string result = pseudo.Start() + pseudo.Text(in1) + pseudo.Text(in2) + + pseudo.Text(in3) + pseudo.End(); if (result != expected) { return ::testing::AssertionFailure() << expected << " != " << result; } @@ -49,49 +48,49 @@ static ::testing::AssertionResult compoundHelper( } TEST(PseudolocalizerTest, NoPseudolocalization) { - EXPECT_TRUE(simpleHelper("", "", Pseudolocalizer::Method::kNone)); - EXPECT_TRUE(simpleHelper("Hello, world", "Hello, world", + EXPECT_TRUE(SimpleHelper("", "", Pseudolocalizer::Method::kNone)); + EXPECT_TRUE(SimpleHelper("Hello, world", "Hello, world", Pseudolocalizer::Method::kNone)); - EXPECT_TRUE(compoundHelper("Hello,", " world", "", "Hello, world", + EXPECT_TRUE(CompoundHelper("Hello,", " world", "", "Hello, world", Pseudolocalizer::Method::kNone)); } TEST(PseudolocalizerTest, PlaintextAccent) { - EXPECT_TRUE(simpleHelper("", "[]", Pseudolocalizer::Method::kAccent)); - EXPECT_TRUE(simpleHelper("Hello, world", "[Ĥéļļö, ŵöŕļð one two]", + EXPECT_TRUE(SimpleHelper("", "[]", Pseudolocalizer::Method::kAccent)); + EXPECT_TRUE(SimpleHelper("Hello, world", "[Ĥéļļö, ŵöŕļð one two]", Pseudolocalizer::Method::kAccent)); - EXPECT_TRUE(simpleHelper("Hello, %1d", "[Ĥéļļö, »%1d« one two]", + EXPECT_TRUE(SimpleHelper("Hello, %1d", "[Ĥéļļö, »%1d« one two]", Pseudolocalizer::Method::kAccent)); - EXPECT_TRUE(simpleHelper("Battery %1d%%", "[βåţţéŕý »%1d«%% one two]", + EXPECT_TRUE(SimpleHelper("Battery %1d%%", "[βåţţéŕý »%1d«%% one two]", Pseudolocalizer::Method::kAccent)); EXPECT_TRUE( - simpleHelper("^1 %", "[^1 % one]", Pseudolocalizer::Method::kAccent)); + SimpleHelper("^1 %", "[^1 % one]", Pseudolocalizer::Method::kAccent)); EXPECT_TRUE( - compoundHelper("", "", "", "[]", Pseudolocalizer::Method::kAccent)); - EXPECT_TRUE(compoundHelper("Hello,", " world", "", "[Ĥéļļö, ŵöŕļð one two]", + CompoundHelper("", "", "", "[]", Pseudolocalizer::Method::kAccent)); + EXPECT_TRUE(CompoundHelper("Hello,", " world", "", "[Ĥéļļö, ŵöŕļð one two]", Pseudolocalizer::Method::kAccent)); } TEST(PseudolocalizerTest, PlaintextBidi) { - EXPECT_TRUE(simpleHelper("", "", Pseudolocalizer::Method::kBidi)); - EXPECT_TRUE(simpleHelper( + EXPECT_TRUE(SimpleHelper("", "", Pseudolocalizer::Method::kBidi)); + EXPECT_TRUE(SimpleHelper( "word", "\xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f", Pseudolocalizer::Method::kBidi)); - EXPECT_TRUE(simpleHelper( + EXPECT_TRUE(SimpleHelper( " word ", " \xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f ", Pseudolocalizer::Method::kBidi)); - EXPECT_TRUE(simpleHelper( + EXPECT_TRUE(SimpleHelper( " word ", " \xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f ", Pseudolocalizer::Method::kBidi)); EXPECT_TRUE( - simpleHelper("hello\n world\n", + SimpleHelper("hello\n world\n", "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n" " \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n", Pseudolocalizer::Method::kBidi)); - EXPECT_TRUE(compoundHelper( + EXPECT_TRUE(CompoundHelper( "hello", "\n ", " world\n", "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n" " \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n", @@ -100,33 +99,33 @@ TEST(PseudolocalizerTest, PlaintextBidi) { TEST(PseudolocalizerTest, SimpleICU) { // Single-fragment messages - EXPECT_TRUE(simpleHelper("{placeholder}", "[»{placeholder}«]", + EXPECT_TRUE(SimpleHelper("{placeholder}", "[»{placeholder}«]", Pseudolocalizer::Method::kAccent)); - EXPECT_TRUE(simpleHelper("{USER} is offline", "[»{USER}« îš öƒƒļîñé one two]", + EXPECT_TRUE(SimpleHelper("{USER} is offline", "[»{USER}« îš öƒƒļîñé one two]", Pseudolocalizer::Method::kAccent)); - EXPECT_TRUE(simpleHelper("Copy from {path1} to {path2}", + EXPECT_TRUE(SimpleHelper("Copy from {path1} to {path2}", "[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]", Pseudolocalizer::Method::kAccent)); - EXPECT_TRUE(simpleHelper("Today is {1,date} {1,time}", + EXPECT_TRUE(SimpleHelper("Today is {1,date} {1,time}", "[Ţöðåý îš »{1,date}« »{1,time}« one two]", Pseudolocalizer::Method::kAccent)); // Multi-fragment messages - EXPECT_TRUE(compoundHelper("{USER}", " ", "is offline", + EXPECT_TRUE(CompoundHelper("{USER}", " ", "is offline", "[»{USER}« îš öƒƒļîñé one two]", Pseudolocalizer::Method::kAccent)); - EXPECT_TRUE(compoundHelper("Copy from ", "{path1}", " to {path2}", + EXPECT_TRUE(CompoundHelper("Copy from ", "{path1}", " to {path2}", "[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]", Pseudolocalizer::Method::kAccent)); } TEST(PseudolocalizerTest, ICUBidi) { // Single-fragment messages - EXPECT_TRUE(simpleHelper( + EXPECT_TRUE(SimpleHelper( "{placeholder}", "\xe2\x80\x8f\xE2\x80\xae{placeholder}\xE2\x80\xac\xe2\x80\x8f", Pseudolocalizer::Method::kBidi)); - EXPECT_TRUE(simpleHelper( + EXPECT_TRUE(SimpleHelper( "{COUNT, plural, one {one} other {other}}", "{COUNT, plural, " "one {\xe2\x80\x8f\xE2\x80\xaeone\xE2\x80\xac\xe2\x80\x8f} " @@ -136,30 +135,30 @@ TEST(PseudolocalizerTest, ICUBidi) { TEST(PseudolocalizerTest, Escaping) { // Single-fragment messages - EXPECT_TRUE(simpleHelper("'{USER'} is offline", + EXPECT_TRUE(SimpleHelper("'{USER'} is offline", "['{ÛŠÉŔ'} îš öƒƒļîñé one two three]", Pseudolocalizer::Method::kAccent)); // Multi-fragment messages - EXPECT_TRUE(compoundHelper("'{USER}", " ", "''is offline", + EXPECT_TRUE(CompoundHelper("'{USER}", " ", "''is offline", "['{ÛŠÉŔ} ''îš öƒƒļîñé one two three]", Pseudolocalizer::Method::kAccent)); } TEST(PseudolocalizerTest, PluralsAndSelects) { - EXPECT_TRUE(simpleHelper( + EXPECT_TRUE(SimpleHelper( "{COUNT, plural, one {Delete a file} other {Delete {COUNT} files}}", "[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} " "other {Ðéļéţé »{COUNT}« ƒîļéš one two}}]", Pseudolocalizer::Method::kAccent)); EXPECT_TRUE( - simpleHelper("Distance is {COUNT, plural, one {# mile} other {# miles}}", + SimpleHelper("Distance is {COUNT, plural, one {# mile} other {# miles}}", "[Ðîšţåñçé îš {COUNT, plural, one {# ḿîļé one two} " "other {# ḿîļéš one two}}]", Pseudolocalizer::Method::kAccent)); - EXPECT_TRUE(simpleHelper( + EXPECT_TRUE(SimpleHelper( "{1, select, female {{1} added you} " "male {{1} added you} other {{1} added you}}", "[{1, select, female {»{1}« åððéð ýöû one two} " @@ -167,7 +166,7 @@ TEST(PseudolocalizerTest, PluralsAndSelects) { Pseudolocalizer::Method::kAccent)); EXPECT_TRUE( - compoundHelper("{COUNT, plural, one {Delete a file} " + CompoundHelper("{COUNT, plural, one {Delete a file} " "other {Delete ", "{COUNT}", " files}}", "[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} " @@ -177,7 +176,7 @@ TEST(PseudolocalizerTest, PluralsAndSelects) { TEST(PseudolocalizerTest, NestedICU) { EXPECT_TRUE( - simpleHelper("{person, select, " + SimpleHelper("{person, select, " "female {" "{num_circles, plural," "=0{{person} didn't add you to any of her circles.}" @@ -222,9 +221,9 @@ TEST(PseudolocalizerTest, NestedICU) { TEST(PseudolocalizerTest, RedefineMethod) { Pseudolocalizer pseudo(Pseudolocalizer::Method::kAccent); - std::string result = pseudo.text("Hello, "); - pseudo.setMethod(Pseudolocalizer::Method::kNone); - result += pseudo.text("world!"); + std::string result = pseudo.Text("Hello, "); + pseudo.SetMethod(Pseudolocalizer::Method::kNone); + result += pseudo.Text("world!"); ASSERT_EQ(StringPiece("Ĥéļļö, world!"), result); } diff --git a/tools/aapt2/compile/XmlIdCollector.cpp b/tools/aapt2/compile/XmlIdCollector.cpp index aa8b1dfe8311..d61a15af0d85 100644 --- a/tools/aapt2/compile/XmlIdCollector.cpp +++ b/tools/aapt2/compile/XmlIdCollector.cpp @@ -15,55 +15,59 @@ */ #include "compile/XmlIdCollector.h" -#include "ResourceUtils.h" -#include "ResourceValues.h" -#include "xml/XmlDom.h" #include <algorithm> #include <vector> +#include "ResourceUtils.h" +#include "ResourceValues.h" +#include "xml/XmlDom.h" + namespace aapt { namespace { -static bool cmpName(const SourcedResourceName& a, const ResourceNameRef& b) { +static bool cmp_name(const SourcedResourceName& a, const ResourceNameRef& b) { return a.name < b; } struct IdCollector : public xml::Visitor { - using xml::Visitor::visit; + public: + using xml::Visitor::Visit; - std::vector<SourcedResourceName>* mOutSymbols; + explicit IdCollector(std::vector<SourcedResourceName>* out_symbols) + : out_symbols_(out_symbols) {} - explicit IdCollector(std::vector<SourcedResourceName>* outSymbols) - : mOutSymbols(outSymbols) {} - - void visit(xml::Element* element) override { + void Visit(xml::Element* element) override { for (xml::Attribute& attr : element->attributes) { ResourceNameRef name; bool create = false; - if (ResourceUtils::parseReference(attr.value, &name, &create, nullptr)) { + if (ResourceUtils::ParseReference(attr.value, &name, &create, nullptr)) { if (create && name.type == ResourceType::kId) { - auto iter = std::lower_bound(mOutSymbols->begin(), mOutSymbols->end(), - name, cmpName); - if (iter == mOutSymbols->end() || iter->name != name) { - mOutSymbols->insert(iter, SourcedResourceName{name.toResourceName(), - element->lineNumber}); + auto iter = std::lower_bound(out_symbols_->begin(), + out_symbols_->end(), name, cmp_name); + if (iter == out_symbols_->end() || iter->name != name) { + out_symbols_->insert(iter, + SourcedResourceName{name.ToResourceName(), + element->line_number}); } } } } - xml::Visitor::visit(element); + xml::Visitor::Visit(element); } + + private: + std::vector<SourcedResourceName>* out_symbols_; }; } // namespace -bool XmlIdCollector::consume(IAaptContext* context, xml::XmlResource* xmlRes) { - xmlRes->file.exportedSymbols.clear(); - IdCollector collector(&xmlRes->file.exportedSymbols); - xmlRes->root->accept(&collector); +bool XmlIdCollector::Consume(IAaptContext* context, xml::XmlResource* xmlRes) { + xmlRes->file.exported_symbols.clear(); + IdCollector collector(&xmlRes->file.exported_symbols); + xmlRes->root->Accept(&collector); return true; } diff --git a/tools/aapt2/compile/XmlIdCollector.h b/tools/aapt2/compile/XmlIdCollector.h index 8423f4892989..8febf0f250dd 100644 --- a/tools/aapt2/compile/XmlIdCollector.h +++ b/tools/aapt2/compile/XmlIdCollector.h @@ -23,7 +23,7 @@ namespace aapt { struct XmlIdCollector : public IXmlResourceConsumer { - bool consume(IAaptContext* context, xml::XmlResource* xmlRes) override; + bool Consume(IAaptContext* context, xml::XmlResource* xml_res) override; }; } // namespace aapt diff --git a/tools/aapt2/compile/XmlIdCollector_test.cpp b/tools/aapt2/compile/XmlIdCollector_test.cpp index 08ca7b1fbf9e..98da56d03ae3 100644 --- a/tools/aapt2/compile/XmlIdCollector_test.cpp +++ b/tools/aapt2/compile/XmlIdCollector_test.cpp @@ -15,18 +15,17 @@ */ #include "compile/XmlIdCollector.h" -#include "test/Builders.h" -#include "test/Context.h" -#include <gtest/gtest.h> #include <algorithm> +#include "test/Test.h" + namespace aapt { TEST(XmlIdCollectorTest, CollectsIds) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); - std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF( + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/foo" text="@+id/bar"> @@ -35,34 +34,34 @@ TEST(XmlIdCollectorTest, CollectsIds) { </View>)EOF"); XmlIdCollector collector; - ASSERT_TRUE(collector.consume(context.get(), doc.get())); + ASSERT_TRUE(collector.Consume(context.get(), doc.get())); EXPECT_EQ( - 1, std::count(doc->file.exportedSymbols.begin(), - doc->file.exportedSymbols.end(), - SourcedResourceName{test::parseNameOrDie("id/foo"), 3u})); + 1, std::count(doc->file.exported_symbols.begin(), + doc->file.exported_symbols.end(), + SourcedResourceName{test::ParseNameOrDie("id/foo"), 3u})); EXPECT_EQ( - 1, std::count(doc->file.exportedSymbols.begin(), - doc->file.exportedSymbols.end(), - SourcedResourceName{test::parseNameOrDie("id/bar"), 3u})); + 1, std::count(doc->file.exported_symbols.begin(), + doc->file.exported_symbols.end(), + SourcedResourceName{test::ParseNameOrDie("id/bar"), 3u})); EXPECT_EQ( - 1, std::count(doc->file.exportedSymbols.begin(), - doc->file.exportedSymbols.end(), - SourcedResourceName{test::parseNameOrDie("id/car"), 6u})); + 1, std::count(doc->file.exported_symbols.begin(), + doc->file.exported_symbols.end(), + SourcedResourceName{test::ParseNameOrDie("id/car"), 6u})); } TEST(XmlIdCollectorTest, DontCollectNonIds) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDom("<View foo=\"@+string/foo\"/>"); + test::BuildXmlDom("<View foo=\"@+string/foo\"/>"); XmlIdCollector collector; - ASSERT_TRUE(collector.consume(context.get(), doc.get())); + ASSERT_TRUE(collector.Consume(context.get(), doc.get())); - EXPECT_TRUE(doc->file.exportedSymbols.empty()); + EXPECT_TRUE(doc->file.exported_symbols.empty()); } } // namespace aapt diff --git a/tools/aapt2/diff/Diff.cpp b/tools/aapt2/diff/Diff.cpp index 01f45399511f..593e7ab119f1 100644 --- a/tools/aapt2/diff/Diff.cpp +++ b/tools/aapt2/diff/Diff.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "android-base/macros.h" + #include "Flags.h" #include "ResourceTable.h" #include "ValueVisitor.h" @@ -22,74 +24,72 @@ #include "process/SymbolTable.h" #include "unflatten/BinaryResourceParser.h" -#include <android-base/macros.h> - namespace aapt { class DiffContext : public IAaptContext { public: - const std::string& getCompilationPackage() override { return mEmpty; } + const std::string& GetCompilationPackage() override { return empty_; } - uint8_t getPackageId() override { return 0x0; } + uint8_t GetPackageId() override { return 0x0; } - IDiagnostics* getDiagnostics() override { return &mDiagnostics; } + IDiagnostics* GetDiagnostics() override { return &diagnostics_; } - NameMangler* getNameMangler() override { return &mNameMangler; } + NameMangler* GetNameMangler() override { return &name_mangler_; } - SymbolTable* getExternalSymbols() override { return &mSymbolTable; } + SymbolTable* GetExternalSymbols() override { return &symbol_table_; } - bool verbose() override { return false; } + bool IsVerbose() override { return false; } - int getMinSdkVersion() override { return 0; } + int GetMinSdkVersion() override { return 0; } private: - std::string mEmpty; - StdErrDiagnostics mDiagnostics; - NameMangler mNameMangler = NameMangler(NameManglerPolicy{}); - SymbolTable mSymbolTable; + std::string empty_; + StdErrDiagnostics diagnostics_; + NameMangler name_mangler_ = NameMangler(NameManglerPolicy{}); + SymbolTable symbol_table_; }; class LoadedApk { public: LoadedApk(const Source& source, std::unique_ptr<io::IFileCollection> apk, std::unique_ptr<ResourceTable> table) - : mSource(source), mApk(std::move(apk)), mTable(std::move(table)) {} + : source_(source), apk_(std::move(apk)), table_(std::move(table)) {} - io::IFileCollection* getFileCollection() { return mApk.get(); } + io::IFileCollection* GetFileCollection() { return apk_.get(); } - ResourceTable* getResourceTable() { return mTable.get(); } + ResourceTable* GetResourceTable() { return table_.get(); } - const Source& getSource() { return mSource; } + const Source& GetSource() { return source_; } private: - Source mSource; - std::unique_ptr<io::IFileCollection> mApk; - std::unique_ptr<ResourceTable> mTable; + Source source_; + std::unique_ptr<io::IFileCollection> apk_; + std::unique_ptr<ResourceTable> table_; DISALLOW_COPY_AND_ASSIGN(LoadedApk); }; -static std::unique_ptr<LoadedApk> loadApkFromPath(IAaptContext* context, +static std::unique_ptr<LoadedApk> LoadApkFromPath(IAaptContext* context, const StringPiece& path) { Source source(path); std::string error; std::unique_ptr<io::ZipFileCollection> apk = - io::ZipFileCollection::create(path, &error); + io::ZipFileCollection::Create(path, &error); if (!apk) { - context->getDiagnostics()->error(DiagMessage(source) << error); + context->GetDiagnostics()->Error(DiagMessage(source) << error); return {}; } - io::IFile* file = apk->findFile("resources.arsc"); + io::IFile* file = apk->FindFile("resources.arsc"); if (!file) { - context->getDiagnostics()->error(DiagMessage(source) + context->GetDiagnostics()->Error(DiagMessage(source) << "no resources.arsc found"); return {}; } - std::unique_ptr<io::IData> data = file->openAsData(); + std::unique_ptr<io::IData> data = file->OpenAsData(); if (!data) { - context->getDiagnostics()->error(DiagMessage(source) + context->GetDiagnostics()->Error(DiagMessage(source) << "could not open resources.arsc"); return {}; } @@ -97,276 +97,281 @@ static std::unique_ptr<LoadedApk> loadApkFromPath(IAaptContext* context, std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>(); BinaryResourceParser parser(context, table.get(), source, data->data(), data->size()); - if (!parser.parse()) { + if (!parser.Parse()) { return {}; } return util::make_unique<LoadedApk>(source, std::move(apk), std::move(table)); } -static void emitDiffLine(const Source& source, const StringPiece& message) { +static void EmitDiffLine(const Source& source, const StringPiece& message) { std::cerr << source << ": " << message << "\n"; } -static bool isSymbolVisibilityDifferent(const Symbol& symbolA, - const Symbol& symbolB) { - return symbolA.state != symbolB.state; +static bool IsSymbolVisibilityDifferent(const Symbol& symbol_a, + const Symbol& symbol_b) { + return symbol_a.state != symbol_b.state; } template <typename Id> -static bool isIdDiff(const Symbol& symbolA, const Maybe<Id>& idA, - const Symbol& symbolB, const Maybe<Id>& idB) { - if (symbolA.state == SymbolState::kPublic || - symbolB.state == SymbolState::kPublic) { - return idA != idB; +static bool IsIdDiff(const Symbol& symbol_a, const Maybe<Id>& id_a, + const Symbol& symbol_b, const Maybe<Id>& id_b) { + if (symbol_a.state == SymbolState::kPublic || + symbol_b.state == SymbolState::kPublic) { + return id_a != id_b; } return false; } -static bool emitResourceConfigValueDiff( - IAaptContext* context, LoadedApk* apkA, ResourceTablePackage* pkgA, - ResourceTableType* typeA, ResourceEntry* entryA, - ResourceConfigValue* configValueA, LoadedApk* apkB, - ResourceTablePackage* pkgB, ResourceTableType* typeB, ResourceEntry* entryB, - ResourceConfigValue* configValueB) { - Value* valueA = configValueA->value.get(); - Value* valueB = configValueB->value.get(); - if (!valueA->equals(valueB)) { - std::stringstream strStream; - strStream << "value " << pkgA->name << ":" << typeA->type << "/" - << entryA->name << " config=" << configValueA->config - << " does not match:\n"; - valueA->print(&strStream); - strStream << "\n vs \n"; - valueB->print(&strStream); - emitDiffLine(apkB->getSource(), strStream.str()); +static bool EmitResourceConfigValueDiff( + IAaptContext* context, LoadedApk* apk_a, ResourceTablePackage* pkg_a, + ResourceTableType* type_a, ResourceEntry* entry_a, + ResourceConfigValue* config_value_a, LoadedApk* apk_b, + ResourceTablePackage* pkg_b, ResourceTableType* type_b, + ResourceEntry* entry_b, ResourceConfigValue* config_value_b) { + Value* value_a = config_value_a->value.get(); + Value* value_b = config_value_b->value.get(); + if (!value_a->Equals(value_b)) { + std::stringstream str_stream; + str_stream << "value " << pkg_a->name << ":" << type_a->type << "/" + << entry_a->name << " config=" << config_value_a->config + << " does not match:\n"; + value_a->Print(&str_stream); + str_stream << "\n vs \n"; + value_b->Print(&str_stream); + EmitDiffLine(apk_b->GetSource(), str_stream.str()); return true; } return false; } -static bool emitResourceEntryDiff(IAaptContext* context, LoadedApk* apkA, - ResourceTablePackage* pkgA, - ResourceTableType* typeA, - ResourceEntry* entryA, LoadedApk* apkB, - ResourceTablePackage* pkgB, - ResourceTableType* typeB, - ResourceEntry* entryB) { +static bool EmitResourceEntryDiff(IAaptContext* context, LoadedApk* apk_a, + ResourceTablePackage* pkg_a, + ResourceTableType* type_a, + ResourceEntry* entry_a, LoadedApk* apk_b, + ResourceTablePackage* pkg_b, + ResourceTableType* type_b, + ResourceEntry* entry_b) { bool diff = false; - for (std::unique_ptr<ResourceConfigValue>& configValueA : entryA->values) { - ResourceConfigValue* configValueB = entryB->findValue(configValueA->config); - if (!configValueB) { - std::stringstream strStream; - strStream << "missing " << pkgA->name << ":" << typeA->type << "/" - << entryA->name << " config=" << configValueA->config; - emitDiffLine(apkB->getSource(), strStream.str()); + for (std::unique_ptr<ResourceConfigValue>& config_value_a : entry_a->values) { + ResourceConfigValue* config_value_b = + entry_b->FindValue(config_value_a->config); + if (!config_value_b) { + std::stringstream str_stream; + str_stream << "missing " << pkg_a->name << ":" << type_a->type << "/" + << entry_a->name << " config=" << config_value_a->config; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } else { - diff |= emitResourceConfigValueDiff(context, apkA, pkgA, typeA, entryA, - configValueA.get(), apkB, pkgB, typeB, - entryB, configValueB); + diff |= EmitResourceConfigValueDiff( + context, apk_a, pkg_a, type_a, entry_a, config_value_a.get(), apk_b, + pkg_b, type_b, entry_b, config_value_b); } } // Check for any newly added config values. - for (std::unique_ptr<ResourceConfigValue>& configValueB : entryB->values) { - ResourceConfigValue* configValueA = entryA->findValue(configValueB->config); - if (!configValueA) { - std::stringstream strStream; - strStream << "new config " << pkgB->name << ":" << typeB->type << "/" - << entryB->name << " config=" << configValueB->config; - emitDiffLine(apkB->getSource(), strStream.str()); + for (std::unique_ptr<ResourceConfigValue>& config_value_b : entry_b->values) { + ResourceConfigValue* config_value_a = + entry_a->FindValue(config_value_b->config); + if (!config_value_a) { + std::stringstream str_stream; + str_stream << "new config " << pkg_b->name << ":" << type_b->type << "/" + << entry_b->name << " config=" << config_value_b->config; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } } return false; } -static bool emitResourceTypeDiff(IAaptContext* context, LoadedApk* apkA, - ResourceTablePackage* pkgA, - ResourceTableType* typeA, LoadedApk* apkB, - ResourceTablePackage* pkgB, - ResourceTableType* typeB) { +static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a, + ResourceTablePackage* pkg_a, + ResourceTableType* type_a, LoadedApk* apk_b, + ResourceTablePackage* pkg_b, + ResourceTableType* type_b) { bool diff = false; - for (std::unique_ptr<ResourceEntry>& entryA : typeA->entries) { - ResourceEntry* entryB = typeB->findEntry(entryA->name); - if (!entryB) { - std::stringstream strStream; - strStream << "missing " << pkgA->name << ":" << typeA->type << "/" - << entryA->name; - emitDiffLine(apkB->getSource(), strStream.str()); + for (std::unique_ptr<ResourceEntry>& entry_a : type_a->entries) { + ResourceEntry* entry_b = type_b->FindEntry(entry_a->name); + if (!entry_b) { + std::stringstream str_stream; + str_stream << "missing " << pkg_a->name << ":" << type_a->type << "/" + << entry_a->name; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } else { - if (isSymbolVisibilityDifferent(entryA->symbolStatus, - entryB->symbolStatus)) { - std::stringstream strStream; - strStream << pkgA->name << ":" << typeA->type << "/" << entryA->name - << " has different visibility ("; - if (entryB->symbolStatus.state == SymbolState::kPublic) { - strStream << "PUBLIC"; + if (IsSymbolVisibilityDifferent(entry_a->symbol_status, + entry_b->symbol_status)) { + std::stringstream str_stream; + str_stream << pkg_a->name << ":" << type_a->type << "/" << entry_a->name + << " has different visibility ("; + if (entry_b->symbol_status.state == SymbolState::kPublic) { + str_stream << "PUBLIC"; } else { - strStream << "PRIVATE"; + str_stream << "PRIVATE"; } - strStream << " vs "; - if (entryA->symbolStatus.state == SymbolState::kPublic) { - strStream << "PUBLIC"; + str_stream << " vs "; + if (entry_a->symbol_status.state == SymbolState::kPublic) { + str_stream << "PUBLIC"; } else { - strStream << "PRIVATE"; + str_stream << "PRIVATE"; } - strStream << ")"; - emitDiffLine(apkB->getSource(), strStream.str()); + str_stream << ")"; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; - } else if (isIdDiff(entryA->symbolStatus, entryA->id, - entryB->symbolStatus, entryB->id)) { - std::stringstream strStream; - strStream << pkgA->name << ":" << typeA->type << "/" << entryA->name - << " has different public ID ("; - if (entryB->id) { - strStream << "0x" << std::hex << entryB->id.value(); + } else if (IsIdDiff(entry_a->symbol_status, entry_a->id, + entry_b->symbol_status, entry_b->id)) { + std::stringstream str_stream; + str_stream << pkg_a->name << ":" << type_a->type << "/" << entry_a->name + << " has different public ID ("; + if (entry_b->id) { + str_stream << "0x" << std::hex << entry_b->id.value(); } else { - strStream << "none"; + str_stream << "none"; } - strStream << " vs "; - if (entryA->id) { - strStream << "0x " << std::hex << entryA->id.value(); + str_stream << " vs "; + if (entry_a->id) { + str_stream << "0x " << std::hex << entry_a->id.value(); } else { - strStream << "none"; + str_stream << "none"; } - strStream << ")"; - emitDiffLine(apkB->getSource(), strStream.str()); + str_stream << ")"; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } - diff |= emitResourceEntryDiff(context, apkA, pkgA, typeA, entryA.get(), - apkB, pkgB, typeB, entryB); + diff |= + EmitResourceEntryDiff(context, apk_a, pkg_a, type_a, entry_a.get(), + apk_b, pkg_b, type_b, entry_b); } } // Check for any newly added entries. - for (std::unique_ptr<ResourceEntry>& entryB : typeB->entries) { - ResourceEntry* entryA = typeA->findEntry(entryB->name); - if (!entryA) { - std::stringstream strStream; - strStream << "new entry " << pkgB->name << ":" << typeB->type << "/" - << entryB->name; - emitDiffLine(apkB->getSource(), strStream.str()); + for (std::unique_ptr<ResourceEntry>& entry_b : type_b->entries) { + ResourceEntry* entry_a = type_a->FindEntry(entry_b->name); + if (!entry_a) { + std::stringstream str_stream; + str_stream << "new entry " << pkg_b->name << ":" << type_b->type << "/" + << entry_b->name; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } } return diff; } -static bool emitResourcePackageDiff(IAaptContext* context, LoadedApk* apkA, - ResourceTablePackage* pkgA, LoadedApk* apkB, - ResourceTablePackage* pkgB) { +static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a, + ResourceTablePackage* pkg_a, + LoadedApk* apk_b, + ResourceTablePackage* pkg_b) { bool diff = false; - for (std::unique_ptr<ResourceTableType>& typeA : pkgA->types) { - ResourceTableType* typeB = pkgB->findType(typeA->type); - if (!typeB) { - std::stringstream strStream; - strStream << "missing " << pkgA->name << ":" << typeA->type; - emitDiffLine(apkA->getSource(), strStream.str()); + for (std::unique_ptr<ResourceTableType>& type_a : pkg_a->types) { + ResourceTableType* type_b = pkg_b->FindType(type_a->type); + if (!type_b) { + std::stringstream str_stream; + str_stream << "missing " << pkg_a->name << ":" << type_a->type; + EmitDiffLine(apk_a->GetSource(), str_stream.str()); diff = true; } else { - if (isSymbolVisibilityDifferent(typeA->symbolStatus, - typeB->symbolStatus)) { - std::stringstream strStream; - strStream << pkgA->name << ":" << typeA->type - << " has different visibility ("; - if (typeB->symbolStatus.state == SymbolState::kPublic) { - strStream << "PUBLIC"; + if (IsSymbolVisibilityDifferent(type_a->symbol_status, + type_b->symbol_status)) { + std::stringstream str_stream; + str_stream << pkg_a->name << ":" << type_a->type + << " has different visibility ("; + if (type_b->symbol_status.state == SymbolState::kPublic) { + str_stream << "PUBLIC"; } else { - strStream << "PRIVATE"; + str_stream << "PRIVATE"; } - strStream << " vs "; - if (typeA->symbolStatus.state == SymbolState::kPublic) { - strStream << "PUBLIC"; + str_stream << " vs "; + if (type_a->symbol_status.state == SymbolState::kPublic) { + str_stream << "PUBLIC"; } else { - strStream << "PRIVATE"; + str_stream << "PRIVATE"; } - strStream << ")"; - emitDiffLine(apkB->getSource(), strStream.str()); + str_stream << ")"; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; - } else if (isIdDiff(typeA->symbolStatus, typeA->id, typeB->symbolStatus, - typeB->id)) { - std::stringstream strStream; - strStream << pkgA->name << ":" << typeA->type - << " has different public ID ("; - if (typeB->id) { - strStream << "0x" << std::hex << typeB->id.value(); + } else if (IsIdDiff(type_a->symbol_status, type_a->id, + type_b->symbol_status, type_b->id)) { + std::stringstream str_stream; + str_stream << pkg_a->name << ":" << type_a->type + << " has different public ID ("; + if (type_b->id) { + str_stream << "0x" << std::hex << type_b->id.value(); } else { - strStream << "none"; + str_stream << "none"; } - strStream << " vs "; - if (typeA->id) { - strStream << "0x " << std::hex << typeA->id.value(); + str_stream << " vs "; + if (type_a->id) { + str_stream << "0x " << std::hex << type_a->id.value(); } else { - strStream << "none"; + str_stream << "none"; } - strStream << ")"; - emitDiffLine(apkB->getSource(), strStream.str()); + str_stream << ")"; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } - diff |= emitResourceTypeDiff(context, apkA, pkgA, typeA.get(), apkB, pkgB, - typeB); + diff |= EmitResourceTypeDiff(context, apk_a, pkg_a, type_a.get(), apk_b, + pkg_b, type_b); } } // Check for any newly added types. - for (std::unique_ptr<ResourceTableType>& typeB : pkgB->types) { - ResourceTableType* typeA = pkgA->findType(typeB->type); - if (!typeA) { - std::stringstream strStream; - strStream << "new type " << pkgB->name << ":" << typeB->type; - emitDiffLine(apkB->getSource(), strStream.str()); + for (std::unique_ptr<ResourceTableType>& type_b : pkg_b->types) { + ResourceTableType* type_a = pkg_a->FindType(type_b->type); + if (!type_a) { + std::stringstream str_stream; + str_stream << "new type " << pkg_b->name << ":" << type_b->type; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } } return diff; } -static bool emitResourceTableDiff(IAaptContext* context, LoadedApk* apkA, - LoadedApk* apkB) { - ResourceTable* tableA = apkA->getResourceTable(); - ResourceTable* tableB = apkB->getResourceTable(); +static bool EmitResourceTableDiff(IAaptContext* context, LoadedApk* apk_a, + LoadedApk* apk_b) { + ResourceTable* table_a = apk_a->GetResourceTable(); + ResourceTable* table_b = apk_b->GetResourceTable(); bool diff = false; - for (std::unique_ptr<ResourceTablePackage>& pkgA : tableA->packages) { - ResourceTablePackage* pkgB = tableB->findPackage(pkgA->name); - if (!pkgB) { - std::stringstream strStream; - strStream << "missing package " << pkgA->name; - emitDiffLine(apkB->getSource(), strStream.str()); + for (std::unique_ptr<ResourceTablePackage>& pkg_a : table_a->packages) { + ResourceTablePackage* pkg_b = table_b->FindPackage(pkg_a->name); + if (!pkg_b) { + std::stringstream str_stream; + str_stream << "missing package " << pkg_a->name; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } else { - if (pkgA->id != pkgB->id) { - std::stringstream strStream; - strStream << "package '" << pkgA->name << "' has different id ("; - if (pkgB->id) { - strStream << "0x" << std::hex << pkgB->id.value(); + if (pkg_a->id != pkg_b->id) { + std::stringstream str_stream; + str_stream << "package '" << pkg_a->name << "' has different id ("; + if (pkg_b->id) { + str_stream << "0x" << std::hex << pkg_b->id.value(); } else { - strStream << "none"; + str_stream << "none"; } - strStream << " vs "; - if (pkgA->id) { - strStream << "0x" << std::hex << pkgA->id.value(); + str_stream << " vs "; + if (pkg_a->id) { + str_stream << "0x" << std::hex << pkg_a->id.value(); } else { - strStream << "none"; + str_stream << "none"; } - strStream << ")"; - emitDiffLine(apkB->getSource(), strStream.str()); + str_stream << ")"; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } - diff |= emitResourcePackageDiff(context, apkA, pkgA.get(), apkB, pkgB); + diff |= + EmitResourcePackageDiff(context, apk_a, pkg_a.get(), apk_b, pkg_b); } } // Check for any newly added packages. - for (std::unique_ptr<ResourceTablePackage>& pkgB : tableB->packages) { - ResourceTablePackage* pkgA = tableA->findPackage(pkgB->name); - if (!pkgA) { - std::stringstream strStream; - strStream << "new package " << pkgB->name; - emitDiffLine(apkB->getSource(), strStream.str()); + for (std::unique_ptr<ResourceTablePackage>& pkg_b : table_b->packages) { + ResourceTablePackage* pkg_a = table_a->FindPackage(pkg_b->name); + if (!pkg_a) { + std::stringstream str_stream; + str_stream << "new package " << pkg_b->name; + EmitDiffLine(apk_b->GetSource(), str_stream.str()); diff = true; } } @@ -375,49 +380,49 @@ static bool emitResourceTableDiff(IAaptContext* context, LoadedApk* apkA, class ZeroingReferenceVisitor : public ValueVisitor { public: - using ValueVisitor::visit; + using ValueVisitor::Visit; - void visit(Reference* ref) override { + void Visit(Reference* ref) override { if (ref->name && ref->id) { - if (ref->id.value().packageId() == 0x7f) { + if (ref->id.value().package_id() == 0x7f) { ref->id = {}; } } } }; -static void zeroOutAppReferences(ResourceTable* table) { +static void ZeroOutAppReferences(ResourceTable* table) { ZeroingReferenceVisitor visitor; - visitAllValuesInTable(table, &visitor); + VisitAllValuesInTable(table, &visitor); } -int diff(const std::vector<StringPiece>& args) { +int Diff(const std::vector<StringPiece>& args) { DiffContext context; Flags flags; - if (!flags.parse("aapt2 diff", args, &std::cerr)) { + if (!flags.Parse("aapt2 diff", args, &std::cerr)) { return 1; } - if (flags.getArgs().size() != 2u) { + if (flags.GetArgs().size() != 2u) { std::cerr << "must have two apks as arguments.\n\n"; - flags.usage("aapt2 diff", &std::cerr); + flags.Usage("aapt2 diff", &std::cerr); return 1; } - std::unique_ptr<LoadedApk> apkA = - loadApkFromPath(&context, flags.getArgs()[0]); - std::unique_ptr<LoadedApk> apkB = - loadApkFromPath(&context, flags.getArgs()[1]); - if (!apkA || !apkB) { + std::unique_ptr<LoadedApk> apk_a = + LoadApkFromPath(&context, flags.GetArgs()[0]); + std::unique_ptr<LoadedApk> apk_b = + LoadApkFromPath(&context, flags.GetArgs()[1]); + if (!apk_a || !apk_b) { return 1; } // Zero out Application IDs in references. - zeroOutAppReferences(apkA->getResourceTable()); - zeroOutAppReferences(apkB->getResourceTable()); + ZeroOutAppReferences(apk_a->GetResourceTable()); + ZeroOutAppReferences(apk_b->GetResourceTable()); - if (emitResourceTableDiff(&context, apkA.get(), apkB.get())) { + if (EmitResourceTableDiff(&context, apk_a.get(), apk_b.get())) { // We emitted a diff, so return 1 (failure). return 1; } diff --git a/tools/aapt2/dump/Dump.cpp b/tools/aapt2/dump/Dump.cpp index 3556cd882cf8..2920c2abb57a 100644 --- a/tools/aapt2/dump/Dump.cpp +++ b/tools/aapt2/dump/Dump.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include <vector> + #include "Debug.h" #include "Diagnostics.h" #include "Flags.h" @@ -24,20 +26,14 @@ #include "util/Files.h" #include "util/StringPiece.h" -#include <vector> - namespace aapt { -// struct DumpOptions { -// -//}; - -void dumpCompiledFile(const pb::CompiledFile& pbFile, const void* data, +void DumpCompiledFile(const pb::CompiledFile& pb_file, const void* data, size_t len, const Source& source, IAaptContext* context) { std::unique_ptr<ResourceFile> file = - deserializeCompiledFileFromPb(pbFile, source, context->getDiagnostics()); + DeserializeCompiledFileFromPb(pb_file, source, context->GetDiagnostics()); if (!file) { - context->getDiagnostics()->warn(DiagMessage() + context->GetDiagnostics()->Warn(DiagMessage() << "failed to read compiled file"); return; } @@ -47,50 +43,50 @@ void dumpCompiledFile(const pb::CompiledFile& pbFile, const void* data, << "Source: " << file->source << "\n"; } -void tryDumpFile(IAaptContext* context, const std::string& filePath) { +void TryDumpFile(IAaptContext* context, const std::string& file_path) { std::unique_ptr<ResourceTable> table; std::string err; std::unique_ptr<io::ZipFileCollection> zip = - io::ZipFileCollection::create(filePath, &err); + io::ZipFileCollection::Create(file_path, &err); if (zip) { - io::IFile* file = zip->findFile("resources.arsc.flat"); + io::IFile* file = zip->FindFile("resources.arsc.flat"); if (file) { - std::unique_ptr<io::IData> data = file->openAsData(); + std::unique_ptr<io::IData> data = file->OpenAsData(); if (!data) { - context->getDiagnostics()->error( - DiagMessage(filePath) << "failed to open resources.arsc.flat"); + context->GetDiagnostics()->Error( + DiagMessage(file_path) << "failed to open resources.arsc.flat"); return; } - pb::ResourceTable pbTable; - if (!pbTable.ParseFromArray(data->data(), data->size())) { - context->getDiagnostics()->error(DiagMessage(filePath) + pb::ResourceTable pb_table; + if (!pb_table.ParseFromArray(data->data(), data->size())) { + context->GetDiagnostics()->Error(DiagMessage(file_path) << "invalid resources.arsc.flat"); return; } - table = deserializeTableFromPb(pbTable, Source(filePath), - context->getDiagnostics()); + table = DeserializeTableFromPb(pb_table, Source(file_path), + context->GetDiagnostics()); if (!table) { return; } } if (!table) { - file = zip->findFile("resources.arsc"); + file = zip->FindFile("resources.arsc"); if (file) { - std::unique_ptr<io::IData> data = file->openAsData(); + std::unique_ptr<io::IData> data = file->OpenAsData(); if (!data) { - context->getDiagnostics()->error(DiagMessage(filePath) + context->GetDiagnostics()->Error(DiagMessage(file_path) << "failed to open resources.arsc"); return; } table = util::make_unique<ResourceTable>(); - BinaryResourceParser parser(context, table.get(), Source(filePath), + BinaryResourceParser parser(context, table.get(), Source(file_path), data->data(), data->size()); - if (!parser.parse()) { + if (!parser.Parse()) { return; } } @@ -98,109 +94,109 @@ void tryDumpFile(IAaptContext* context, const std::string& filePath) { } if (!table) { - Maybe<android::FileMap> file = file::mmapPath(filePath, &err); + Maybe<android::FileMap> file = file::MmapPath(file_path, &err); if (!file) { - context->getDiagnostics()->error(DiagMessage(filePath) << err); + context->GetDiagnostics()->Error(DiagMessage(file_path) << err); return; } - android::FileMap* fileMap = &file.value(); + android::FileMap* file_map = &file.value(); // Try as a compiled table. - pb::ResourceTable pbTable; - if (pbTable.ParseFromArray(fileMap->getDataPtr(), - fileMap->getDataLength())) { - table = deserializeTableFromPb(pbTable, Source(filePath), - context->getDiagnostics()); + pb::ResourceTable pb_table; + if (pb_table.ParseFromArray(file_map->getDataPtr(), + file_map->getDataLength())) { + table = DeserializeTableFromPb(pb_table, Source(file_path), + context->GetDiagnostics()); } if (!table) { // Try as a compiled file. - CompiledFileInputStream input(fileMap->getDataPtr(), - fileMap->getDataLength()); + CompiledFileInputStream input(file_map->getDataPtr(), + file_map->getDataLength()); - uint32_t numFiles = 0; - if (!input.ReadLittleEndian32(&numFiles)) { + uint32_t num_files = 0; + if (!input.ReadLittleEndian32(&num_files)) { return; } - for (uint32_t i = 0; i < numFiles; i++) { - pb::CompiledFile compiledFile; - if (!input.ReadCompiledFile(&compiledFile)) { - context->getDiagnostics()->warn(DiagMessage() + for (uint32_t i = 0; i < num_files; i++) { + pb::CompiledFile compiled_file; + if (!input.ReadCompiledFile(&compiled_file)) { + context->GetDiagnostics()->Warn(DiagMessage() << "failed to read compiled file"); return; } uint64_t offset, len; if (!input.ReadDataMetaData(&offset, &len)) { - context->getDiagnostics()->warn(DiagMessage() + context->GetDiagnostics()->Warn(DiagMessage() << "failed to read meta data"); return; } const void* data = - static_cast<const uint8_t*>(fileMap->getDataPtr()) + offset; - dumpCompiledFile(compiledFile, data, len, Source(filePath), context); + static_cast<const uint8_t*>(file_map->getDataPtr()) + offset; + DumpCompiledFile(compiled_file, data, len, Source(file_path), context); } } } if (table) { - DebugPrintTableOptions debugPrintTableOptions; - debugPrintTableOptions.showSources = true; - Debug::printTable(table.get(), debugPrintTableOptions); + DebugPrintTableOptions options; + options.show_sources = true; + Debug::PrintTable(table.get(), options); } } class DumpContext : public IAaptContext { public: - IDiagnostics* getDiagnostics() override { return &mDiagnostics; } + IDiagnostics* GetDiagnostics() override { return &diagnostics_; } - NameMangler* getNameMangler() override { + NameMangler* GetNameMangler() override { abort(); return nullptr; } - const std::string& getCompilationPackage() override { + const std::string& GetCompilationPackage() override { static std::string empty; return empty; } - uint8_t getPackageId() override { return 0; } + uint8_t GetPackageId() override { return 0; } - SymbolTable* getExternalSymbols() override { + SymbolTable* GetExternalSymbols() override { abort(); return nullptr; } - bool verbose() override { return mVerbose; } + bool IsVerbose() override { return verbose_; } - void setVerbose(bool val) { mVerbose = val; } + void SetVerbose(bool val) { verbose_ = val; } - int getMinSdkVersion() override { return 0; } + int GetMinSdkVersion() override { return 0; } private: - StdErrDiagnostics mDiagnostics; - bool mVerbose = false; + StdErrDiagnostics diagnostics_; + bool verbose_ = false; }; /** * Entry point for dump command. */ -int dump(const std::vector<StringPiece>& args) { +int Dump(const std::vector<StringPiece>& args) { bool verbose = false; Flags flags = - Flags().optionalSwitch("-v", "increase verbosity of output", &verbose); - if (!flags.parse("aapt2 dump", args, &std::cerr)) { + Flags().OptionalSwitch("-v", "increase verbosity of output", &verbose); + if (!flags.Parse("aapt2 dump", args, &std::cerr)) { return 1; } DumpContext context; - context.setVerbose(verbose); + context.SetVerbose(verbose); - for (const std::string& arg : flags.getArgs()) { - tryDumpFile(&context, arg); + for (const std::string& arg : flags.GetArgs()) { + TryDumpFile(&context, arg); } return 0; } diff --git a/tools/aapt2/filter/ConfigFilter.cpp b/tools/aapt2/filter/ConfigFilter.cpp index 5af996ca8911..66aff829d71c 100644 --- a/tools/aapt2/filter/ConfigFilter.cpp +++ b/tools/aapt2/filter/ConfigFilter.cpp @@ -15,44 +15,45 @@ */ #include "filter/ConfigFilter.h" -#include "ConfigDescription.h" -#include <androidfw/ResourceTypes.h> +#include "androidfw/ResourceTypes.h" + +#include "ConfigDescription.h" namespace aapt { -void AxisConfigFilter::addConfig(ConfigDescription config) { - uint32_t diffMask = ConfigDescription::defaultConfig().diff(config); +void AxisConfigFilter::AddConfig(ConfigDescription config) { + uint32_t diff_mask = ConfigDescription::DefaultConfig().diff(config); // Ignore the version - diffMask &= ~android::ResTable_config::CONFIG_VERSION; + diff_mask &= ~android::ResTable_config::CONFIG_VERSION; // Ignore any densities. Those are best handled in --preferred-density - if ((diffMask & android::ResTable_config::CONFIG_DENSITY) != 0) { + if ((diff_mask & android::ResTable_config::CONFIG_DENSITY) != 0) { config.density = 0; - diffMask &= ~android::ResTable_config::CONFIG_DENSITY; + diff_mask &= ~android::ResTable_config::CONFIG_DENSITY; } - mConfigs.insert(std::make_pair(config, diffMask)); - mConfigMask |= diffMask; + configs_.insert(std::make_pair(config, diff_mask)); + config_mask_ |= diff_mask; } -bool AxisConfigFilter::match(const ConfigDescription& config) const { - const uint32_t mask = ConfigDescription::defaultConfig().diff(config); - if ((mConfigMask & mask) == 0) { +bool AxisConfigFilter::Match(const ConfigDescription& config) const { + const uint32_t mask = ConfigDescription::DefaultConfig().diff(config); + if ((config_mask_ & mask) == 0) { // The two configurations don't have any common axis. return true; } - uint32_t matchedAxis = 0; - for (const auto& entry : mConfigs) { + uint32_t matched_axis = 0; + for (const auto& entry : configs_) { const ConfigDescription& target = entry.first; - const uint32_t diffMask = entry.second; + const uint32_t diff_mask = entry.second; uint32_t diff = target.diff(config); - if ((diff & diffMask) == 0) { + if ((diff & diff_mask) == 0) { // Mark the axis that was matched. - matchedAxis |= diffMask; - } else if ((diff & diffMask) == android::ResTable_config::CONFIG_LOCALE) { + matched_axis |= diff_mask; + } else if ((diff & diff_mask) == android::ResTable_config::CONFIG_LOCALE) { // If the locales differ, but the languages are the same and // the locale we are matching only has a language specified, // we match. @@ -60,10 +61,10 @@ bool AxisConfigFilter::match(const ConfigDescription& config) const { memcmp(config.language, target.language, sizeof(config.language)) == 0) { if (config.country[0] == 0) { - matchedAxis |= android::ResTable_config::CONFIG_LOCALE; + matched_axis |= android::ResTable_config::CONFIG_LOCALE; } } - } else if ((diff & diffMask) == + } else if ((diff & diff_mask) == android::ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE) { // Special case if the smallest screen width doesn't match. We check that // the @@ -71,11 +72,11 @@ bool AxisConfigFilter::match(const ConfigDescription& config) const { // specified. if (config.smallestScreenWidthDp != 0 && config.smallestScreenWidthDp < target.smallestScreenWidthDp) { - matchedAxis |= android::ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE; + matched_axis |= android::ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE; } } } - return matchedAxis == (mConfigMask & mask); + return matched_axis == (config_mask_ & mask); } } // namespace aapt diff --git a/tools/aapt2/filter/ConfigFilter.h b/tools/aapt2/filter/ConfigFilter.h index c50160baaa37..3f1341684912 100644 --- a/tools/aapt2/filter/ConfigFilter.h +++ b/tools/aapt2/filter/ConfigFilter.h @@ -17,11 +17,11 @@ #ifndef AAPT_FILTER_CONFIGFILTER_H #define AAPT_FILTER_CONFIGFILTER_H -#include "ConfigDescription.h" - #include <set> #include <utility> +#include "ConfigDescription.h" + namespace aapt { /** @@ -34,7 +34,7 @@ class IConfigFilter { /** * Returns true if the filter matches the configuration, false otherwise. */ - virtual bool match(const ConfigDescription& config) const = 0; + virtual bool Match(const ConfigDescription& config) const = 0; }; /** @@ -50,13 +50,13 @@ class IConfigFilter { */ class AxisConfigFilter : public IConfigFilter { public: - void addConfig(ConfigDescription config); + void AddConfig(ConfigDescription config); - bool match(const ConfigDescription& config) const override; + bool Match(const ConfigDescription& config) const override; private: - std::set<std::pair<ConfigDescription, uint32_t>> mConfigs; - uint32_t mConfigMask = 0; + std::set<std::pair<ConfigDescription, uint32_t>> configs_; + uint32_t config_mask_ = 0; }; } // namespace aapt diff --git a/tools/aapt2/filter/ConfigFilter_test.cpp b/tools/aapt2/filter/ConfigFilter_test.cpp index edb40a8b3324..586dd5f68f1b 100644 --- a/tools/aapt2/filter/ConfigFilter_test.cpp +++ b/tools/aapt2/filter/ConfigFilter_test.cpp @@ -15,99 +15,98 @@ */ #include "filter/ConfigFilter.h" -#include "test/Common.h" -#include <gtest/gtest.h> +#include "test/Test.h" namespace aapt { TEST(ConfigFilterTest, EmptyFilterMatchesAnything) { AxisConfigFilter filter; - EXPECT_TRUE(filter.match(test::parseConfigOrDie("320dpi"))); - EXPECT_TRUE(filter.match(test::parseConfigOrDie("fr"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("320dpi"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("fr"))); } TEST(ConfigFilterTest, MatchesConfigWithUnrelatedAxis) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("fr")); + filter.AddConfig(test::ParseConfigOrDie("fr")); - EXPECT_TRUE(filter.match(test::parseConfigOrDie("320dpi"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("320dpi"))); } TEST(ConfigFilterTest, MatchesConfigWithSameValueAxis) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("fr")); + filter.AddConfig(test::ParseConfigOrDie("fr")); - EXPECT_TRUE(filter.match(test::parseConfigOrDie("fr"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("fr"))); } TEST(ConfigFilterTest, MatchesConfigWithSameValueAxisAndOtherUnrelatedAxis) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("fr")); + filter.AddConfig(test::ParseConfigOrDie("fr")); - EXPECT_TRUE(filter.match(test::parseConfigOrDie("fr-320dpi"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("fr-320dpi"))); } TEST(ConfigFilterTest, MatchesConfigWithOneMatchingAxis) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("fr-rFR")); - filter.addConfig(test::parseConfigOrDie("sw360dp")); - filter.addConfig(test::parseConfigOrDie("normal")); - filter.addConfig(test::parseConfigOrDie("en-rUS")); + filter.AddConfig(test::ParseConfigOrDie("fr-rFR")); + filter.AddConfig(test::ParseConfigOrDie("sw360dp")); + filter.AddConfig(test::ParseConfigOrDie("normal")); + filter.AddConfig(test::ParseConfigOrDie("en-rUS")); - EXPECT_TRUE(filter.match(test::parseConfigOrDie("en"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("en"))); } TEST(ConfigFilterTest, DoesNotMatchConfigWithDifferentValueAxis) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("fr")); + filter.AddConfig(test::ParseConfigOrDie("fr")); - EXPECT_FALSE(filter.match(test::parseConfigOrDie("de"))); + EXPECT_FALSE(filter.Match(test::ParseConfigOrDie("de"))); } TEST(ConfigFilterTest, DoesNotMatchWhenOneQualifierIsExplicitlyNotMatched) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("fr-rFR")); - filter.addConfig(test::parseConfigOrDie("en-rUS")); - filter.addConfig(test::parseConfigOrDie("normal")); - filter.addConfig(test::parseConfigOrDie("large")); - filter.addConfig(test::parseConfigOrDie("xxhdpi")); - filter.addConfig(test::parseConfigOrDie("sw320dp")); - - EXPECT_FALSE(filter.match(test::parseConfigOrDie("fr-sw600dp-v13"))); + filter.AddConfig(test::ParseConfigOrDie("fr-rFR")); + filter.AddConfig(test::ParseConfigOrDie("en-rUS")); + filter.AddConfig(test::ParseConfigOrDie("normal")); + filter.AddConfig(test::ParseConfigOrDie("large")); + filter.AddConfig(test::ParseConfigOrDie("xxhdpi")); + filter.AddConfig(test::ParseConfigOrDie("sw320dp")); + + EXPECT_FALSE(filter.Match(test::ParseConfigOrDie("fr-sw600dp-v13"))); } TEST(ConfigFilterTest, MatchesSmallestWidthWhenSmaller) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("sw600dp")); + filter.AddConfig(test::ParseConfigOrDie("sw600dp")); - EXPECT_TRUE(filter.match(test::parseConfigOrDie("fr-sw320dp-v13"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("fr-sw320dp-v13"))); } TEST(ConfigFilterTest, MatchesConfigWithSameLanguageButNoRegionSpecified) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("de-rDE")); + filter.AddConfig(test::ParseConfigOrDie("de-rDE")); - EXPECT_TRUE(filter.match(test::parseConfigOrDie("de"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("de"))); } TEST(ConfigFilterTest, IgnoresVersion) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("normal-v4")); + filter.AddConfig(test::ParseConfigOrDie("normal-v4")); // The configs don't match on any axis besides version, which should be // ignored. - EXPECT_TRUE(filter.match(test::parseConfigOrDie("sw600dp-v13"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("sw600dp-v13"))); } TEST(ConfigFilterTest, MatchesConfigWithRegion) { AxisConfigFilter filter; - filter.addConfig(test::parseConfigOrDie("kok")); - filter.addConfig(test::parseConfigOrDie("kok-rIN")); - filter.addConfig(test::parseConfigOrDie("kok-v419")); + filter.AddConfig(test::ParseConfigOrDie("kok")); + filter.AddConfig(test::ParseConfigOrDie("kok-rIN")); + filter.AddConfig(test::ParseConfigOrDie("kok-v419")); - EXPECT_TRUE(filter.match(test::parseConfigOrDie("kok-rIN"))); + EXPECT_TRUE(filter.Match(test::ParseConfigOrDie("kok-rIN"))); } } // namespace aapt diff --git a/tools/aapt2/flatten/Archive.cpp b/tools/aapt2/flatten/Archive.cpp index ae08f6588217..47de0a3b8d6c 100644 --- a/tools/aapt2/flatten/Archive.cpp +++ b/tools/aapt2/flatten/Archive.cpp @@ -15,131 +15,139 @@ */ #include "flatten/Archive.h" -#include "util/Files.h" -#include "util/StringPiece.h" -#include <ziparchive/zip_writer.h> #include <cstdio> #include <memory> #include <string> #include <vector> +#include "android-base/macros.h" +#include "ziparchive/zip_writer.h" + +#include "util/Files.h" +#include "util/StringPiece.h" + namespace aapt { namespace { -struct DirectoryWriter : public IArchiveWriter { - std::string mOutDir; - std::unique_ptr<FILE, decltype(fclose)*> mFile = {nullptr, fclose}; +class DirectoryWriter : public IArchiveWriter { + public: + DirectoryWriter() = default; - bool open(IDiagnostics* diag, const StringPiece& outDir) { - mOutDir = outDir.toString(); - file::FileType type = file::getFileType(mOutDir); + bool Open(IDiagnostics* diag, const StringPiece& out_dir) { + dir_ = out_dir.ToString(); + file::FileType type = file::GetFileType(dir_); if (type == file::FileType::kNonexistant) { - diag->error(DiagMessage() << "directory " << mOutDir - << " does not exist"); + diag->Error(DiagMessage() << "directory " << dir_ << " does not exist"); return false; } else if (type != file::FileType::kDirectory) { - diag->error(DiagMessage() << mOutDir << " is not a directory"); + diag->Error(DiagMessage() << dir_ << " is not a directory"); return false; } return true; } - bool startEntry(const StringPiece& path, uint32_t flags) override { - if (mFile) { + bool StartEntry(const StringPiece& path, uint32_t flags) override { + if (file_) { return false; } - std::string fullPath = mOutDir; - file::appendPath(&fullPath, path); - file::mkdirs(file::getStem(fullPath)); + std::string full_path = dir_; + file::AppendPath(&full_path, path); + file::mkdirs(file::GetStem(full_path)); - mFile = {fopen(fullPath.data(), "wb"), fclose}; - if (!mFile) { + file_ = {fopen(full_path.data(), "wb"), fclose}; + if (!file_) { return false; } return true; } - bool writeEntry(const BigBuffer& buffer) override { - if (!mFile) { + bool WriteEntry(const BigBuffer& buffer) override { + if (!file_) { return false; } for (const BigBuffer::Block& b : buffer) { - if (fwrite(b.buffer.get(), 1, b.size, mFile.get()) != b.size) { - mFile.reset(nullptr); + if (fwrite(b.buffer.get(), 1, b.size, file_.get()) != b.size) { + file_.reset(nullptr); return false; } } return true; } - bool writeEntry(const void* data, size_t len) override { - if (fwrite(data, 1, len, mFile.get()) != len) { - mFile.reset(nullptr); + bool WriteEntry(const void* data, size_t len) override { + if (fwrite(data, 1, len, file_.get()) != len) { + file_.reset(nullptr); return false; } return true; } - bool finishEntry() override { - if (!mFile) { + bool FinishEntry() override { + if (!file_) { return false; } - mFile.reset(nullptr); + file_.reset(nullptr); return true; } + + private: + DISALLOW_COPY_AND_ASSIGN(DirectoryWriter); + + std::string dir_; + std::unique_ptr<FILE, decltype(fclose)*> file_ = {nullptr, fclose}; }; -struct ZipFileWriter : public IArchiveWriter { - std::unique_ptr<FILE, decltype(fclose)*> mFile = {nullptr, fclose}; - std::unique_ptr<ZipWriter> mWriter; +class ZipFileWriter : public IArchiveWriter { + public: + ZipFileWriter() = default; - bool open(IDiagnostics* diag, const StringPiece& path) { - mFile = {fopen(path.data(), "w+b"), fclose}; - if (!mFile) { - diag->error(DiagMessage() << "failed to open " << path << ": " + bool Open(IDiagnostics* diag, const StringPiece& path) { + file_ = {fopen(path.data(), "w+b"), fclose}; + if (!file_) { + diag->Error(DiagMessage() << "failed to Open " << path << ": " << strerror(errno)); return false; } - mWriter = util::make_unique<ZipWriter>(mFile.get()); + writer_ = util::make_unique<ZipWriter>(file_.get()); return true; } - bool startEntry(const StringPiece& path, uint32_t flags) override { - if (!mWriter) { + bool StartEntry(const StringPiece& path, uint32_t flags) override { + if (!writer_) { return false; } - size_t zipFlags = 0; + size_t zip_flags = 0; if (flags & ArchiveEntry::kCompress) { - zipFlags |= ZipWriter::kCompress; + zip_flags |= ZipWriter::kCompress; } if (flags & ArchiveEntry::kAlign) { - zipFlags |= ZipWriter::kAlign32; + zip_flags |= ZipWriter::kAlign32; } - int32_t result = mWriter->StartEntry(path.data(), zipFlags); + int32_t result = writer_->StartEntry(path.data(), zip_flags); if (result != 0) { return false; } return true; } - bool writeEntry(const void* data, size_t len) override { - int32_t result = mWriter->WriteBytes(data, len); + bool WriteEntry(const void* data, size_t len) override { + int32_t result = writer_->WriteBytes(data, len); if (result != 0) { return false; } return true; } - bool writeEntry(const BigBuffer& buffer) override { + bool WriteEntry(const BigBuffer& buffer) override { for (const BigBuffer::Block& b : buffer) { - int32_t result = mWriter->WriteBytes(b.buffer.get(), b.size); + int32_t result = writer_->WriteBytes(b.buffer.get(), b.size); if (result != 0) { return false; } @@ -147,8 +155,8 @@ struct ZipFileWriter : public IArchiveWriter { return true; } - bool finishEntry() override { - int32_t result = mWriter->FinishEntry(); + bool FinishEntry() override { + int32_t result = writer_->FinishEntry(); if (result != 0) { return false; } @@ -156,28 +164,34 @@ struct ZipFileWriter : public IArchiveWriter { } virtual ~ZipFileWriter() { - if (mWriter) { - mWriter->Finish(); + if (writer_) { + writer_->Finish(); } } + + private: + DISALLOW_COPY_AND_ASSIGN(ZipFileWriter); + + std::unique_ptr<FILE, decltype(fclose)*> file_ = {nullptr, fclose}; + std::unique_ptr<ZipWriter> writer_; }; } // namespace -std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter( +std::unique_ptr<IArchiveWriter> CreateDirectoryArchiveWriter( IDiagnostics* diag, const StringPiece& path) { std::unique_ptr<DirectoryWriter> writer = util::make_unique<DirectoryWriter>(); - if (!writer->open(diag, path)) { + if (!writer->Open(diag, path)) { return {}; } return std::move(writer); } -std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter( +std::unique_ptr<IArchiveWriter> CreateZipFileArchiveWriter( IDiagnostics* diag, const StringPiece& path) { std::unique_ptr<ZipFileWriter> writer = util::make_unique<ZipFileWriter>(); - if (!writer->open(diag, path)) { + if (!writer->Open(diag, path)) { return {}; } return std::move(writer); diff --git a/tools/aapt2/flatten/Archive.h b/tools/aapt2/flatten/Archive.h index 46cd0ac0adc2..4fcb3ffa2b78 100644 --- a/tools/aapt2/flatten/Archive.h +++ b/tools/aapt2/flatten/Archive.h @@ -17,17 +17,18 @@ #ifndef AAPT_FLATTEN_ARCHIVE_H #define AAPT_FLATTEN_ARCHIVE_H -#include "Diagnostics.h" -#include "util/BigBuffer.h" -#include "util/Files.h" -#include "util/StringPiece.h" - -#include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include <fstream> #include <memory> #include <string> #include <vector> +#include "google/protobuf/io/zero_copy_stream_impl_lite.h" + +#include "Diagnostics.h" +#include "util/BigBuffer.h" +#include "util/Files.h" +#include "util/StringPiece.h" + namespace aapt { struct ArchiveEntry { @@ -38,28 +39,28 @@ struct ArchiveEntry { std::string path; uint32_t flags; - size_t uncompressedSize; + size_t uncompressed_size; }; class IArchiveWriter : public google::protobuf::io::CopyingOutputStream { public: virtual ~IArchiveWriter() = default; - virtual bool startEntry(const StringPiece& path, uint32_t flags) = 0; - virtual bool writeEntry(const BigBuffer& buffer) = 0; - virtual bool writeEntry(const void* data, size_t len) = 0; - virtual bool finishEntry() = 0; + virtual bool StartEntry(const StringPiece& path, uint32_t flags) = 0; + virtual bool WriteEntry(const BigBuffer& buffer) = 0; + virtual bool WriteEntry(const void* data, size_t len) = 0; + virtual bool FinishEntry() = 0; // CopyingOutputStream implementations. bool Write(const void* buffer, int size) override { - return writeEntry(buffer, size); + return WriteEntry(buffer, size); } }; -std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter( +std::unique_ptr<IArchiveWriter> CreateDirectoryArchiveWriter( IDiagnostics* diag, const StringPiece& path); -std::unique_ptr<IArchiveWriter> createZipFileArchiveWriter( +std::unique_ptr<IArchiveWriter> CreateZipFileArchiveWriter( IDiagnostics* diag, const StringPiece& path); } // namespace aapt diff --git a/tools/aapt2/flatten/ChunkWriter.h b/tools/aapt2/flatten/ChunkWriter.h index 852afd4255d9..968d3eef48ec 100644 --- a/tools/aapt2/flatten/ChunkWriter.h +++ b/tools/aapt2/flatten/ChunkWriter.h @@ -17,62 +17,62 @@ #ifndef AAPT_FLATTEN_CHUNKWRITER_H #define AAPT_FLATTEN_CHUNKWRITER_H +#include "android-base/macros.h" +#include "androidfw/ResourceTypes.h" + #include "util/BigBuffer.h" #include "util/Util.h" -#include <androidfw/ResourceTypes.h> - namespace aapt { class ChunkWriter { - private: - BigBuffer* mBuffer; - size_t mStartSize = 0; - android::ResChunk_header* mHeader = nullptr; - public: - explicit inline ChunkWriter(BigBuffer* buffer) : mBuffer(buffer) {} - - ChunkWriter(const ChunkWriter&) = delete; - ChunkWriter& operator=(const ChunkWriter&) = delete; + explicit inline ChunkWriter(BigBuffer* buffer) : buffer_(buffer) {} ChunkWriter(ChunkWriter&&) = default; ChunkWriter& operator=(ChunkWriter&&) = default; template <typename T> - inline T* startChunk(uint16_t type) { - mStartSize = mBuffer->size(); - T* chunk = mBuffer->nextBlock<T>(); - mHeader = &chunk->header; - mHeader->type = util::hostToDevice16(type); - mHeader->headerSize = util::hostToDevice16(sizeof(T)); + inline T* StartChunk(uint16_t type) { + start_size_ = buffer_->size(); + T* chunk = buffer_->NextBlock<T>(); + header_ = &chunk->header; + header_->type = util::HostToDevice16(type); + header_->headerSize = util::HostToDevice16(sizeof(T)); return chunk; } template <typename T> - inline T* nextBlock(size_t count = 1) { - return mBuffer->nextBlock<T>(count); + inline T* NextBlock(size_t count = 1) { + return buffer_->NextBlock<T>(count); } - inline BigBuffer* getBuffer() { return mBuffer; } + inline BigBuffer* buffer() { return buffer_; } - inline android::ResChunk_header* getChunkHeader() { return mHeader; } + inline android::ResChunk_header* chunk_header() { return header_; } - inline size_t size() { return mBuffer->size() - mStartSize; } + inline size_t size() { return buffer_->size() - start_size_; } - inline android::ResChunk_header* finish() { - mBuffer->align4(); - mHeader->size = util::hostToDevice32(mBuffer->size() - mStartSize); - return mHeader; + inline android::ResChunk_header* Finish() { + buffer_->Align4(); + header_->size = util::HostToDevice32(buffer_->size() - start_size_); + return header_; } + + private: + DISALLOW_COPY_AND_ASSIGN(ChunkWriter); + + BigBuffer* buffer_; + size_t start_size_ = 0; + android::ResChunk_header* header_ = nullptr; }; template <> -inline android::ResChunk_header* ChunkWriter::startChunk(uint16_t type) { - mStartSize = mBuffer->size(); - mHeader = mBuffer->nextBlock<android::ResChunk_header>(); - mHeader->type = util::hostToDevice16(type); - mHeader->headerSize = util::hostToDevice16(sizeof(android::ResChunk_header)); - return mHeader; +inline android::ResChunk_header* ChunkWriter::StartChunk(uint16_t type) { + start_size_ = buffer_->size(); + header_ = buffer_->NextBlock<android::ResChunk_header>(); + header_->type = util::HostToDevice16(type); + header_->headerSize = util::HostToDevice16(sizeof(android::ResChunk_header)); + return header_; } } // namespace aapt diff --git a/tools/aapt2/flatten/ResourceTypeExtensions.h b/tools/aapt2/flatten/ResourceTypeExtensions.h index 0b192404de28..6359b4143f1e 100644 --- a/tools/aapt2/flatten/ResourceTypeExtensions.h +++ b/tools/aapt2/flatten/ResourceTypeExtensions.h @@ -17,7 +17,7 @@ #ifndef AAPT_RESOURCE_TYPE_EXTENSIONS_H #define AAPT_RESOURCE_TYPE_EXTENSIONS_H -#include <androidfw/ResourceTypes.h> +#include "androidfw/ResourceTypes.h" namespace aapt { diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp index d4ea6c05c9b0..19d030ec4a25 100644 --- a/tools/aapt2/flatten/TableFlattener.cpp +++ b/tools/aapt2/flatten/TableFlattener.cpp @@ -14,21 +14,23 @@ * limitations under the License. */ -#include "ResourceTable.h" -#include "ResourceValues.h" -#include "ValueVisitor.h" - -#include "flatten/ChunkWriter.h" -#include "flatten/ResourceTypeExtensions.h" #include "flatten/TableFlattener.h" -#include "util/BigBuffer.h" -#include <android-base/macros.h> #include <algorithm> #include <numeric> #include <sstream> #include <type_traits> +#include "android-base/logging.h" +#include "android-base/macros.h" + +#include "ResourceTable.h" +#include "ResourceValues.h" +#include "ValueVisitor.h" +#include "flatten/ChunkWriter.h" +#include "flatten/ResourceTypeExtensions.h" +#include "util/BigBuffer.h" + using namespace android; namespace aapt { @@ -36,7 +38,7 @@ namespace aapt { namespace { template <typename T> -static bool cmpIds(const T* a, const T* b) { +static bool cmp_ids(const T* a, const T* b) { return a->id.value() < b->id.value(); } @@ -46,14 +48,14 @@ static void strcpy16_htod(uint16_t* dst, size_t len, const StringPiece16& src) { } size_t i; - const char16_t* srcData = src.data(); + const char16_t* src_data = src.data(); for (i = 0; i < len - 1 && i < src.size(); i++) { - dst[i] = util::hostToDevice16((uint16_t)srcData[i]); + dst[i] = util::HostToDevice16((uint16_t)src_data[i]); } dst[i] = 0; } -static bool cmpStyleEntries(const Style::Entry& a, const Style::Entry& b) { +static bool cmp_style_entries(const Style::Entry& a, const Style::Entry& b) { if (a.key.id) { if (b.key.id) { return a.key.id.value() < b.key.id.value(); @@ -70,75 +72,75 @@ struct FlatEntry { Value* value; // The entry string pool index to the entry's name. - uint32_t entryKey; + uint32_t entry_key; }; class MapFlattenVisitor : public RawValueVisitor { public: - using RawValueVisitor::visit; + using RawValueVisitor::Visit; - MapFlattenVisitor(ResTable_entry_ext* outEntry, BigBuffer* buffer) - : mOutEntry(outEntry), mBuffer(buffer) {} + MapFlattenVisitor(ResTable_entry_ext* out_entry, BigBuffer* buffer) + : out_entry_(out_entry), buffer_(buffer) {} - void visit(Attribute* attr) override { + void Visit(Attribute* attr) override { { Reference key = Reference(ResourceId(ResTable_map::ATTR_TYPE)); - BinaryPrimitive val(Res_value::TYPE_INT_DEC, attr->typeMask); - flattenEntry(&key, &val); + BinaryPrimitive val(Res_value::TYPE_INT_DEC, attr->type_mask); + FlattenEntry(&key, &val); } - if (attr->minInt != std::numeric_limits<int32_t>::min()) { + if (attr->min_int != std::numeric_limits<int32_t>::min()) { Reference key = Reference(ResourceId(ResTable_map::ATTR_MIN)); BinaryPrimitive val(Res_value::TYPE_INT_DEC, - static_cast<uint32_t>(attr->minInt)); - flattenEntry(&key, &val); + static_cast<uint32_t>(attr->min_int)); + FlattenEntry(&key, &val); } - if (attr->maxInt != std::numeric_limits<int32_t>::max()) { + if (attr->max_int != std::numeric_limits<int32_t>::max()) { Reference key = Reference(ResourceId(ResTable_map::ATTR_MAX)); BinaryPrimitive val(Res_value::TYPE_INT_DEC, - static_cast<uint32_t>(attr->maxInt)); - flattenEntry(&key, &val); + static_cast<uint32_t>(attr->max_int)); + FlattenEntry(&key, &val); } for (Attribute::Symbol& s : attr->symbols) { BinaryPrimitive val(Res_value::TYPE_INT_DEC, s.value); - flattenEntry(&s.symbol, &val); + FlattenEntry(&s.symbol, &val); } } - void visit(Style* style) override { + void Visit(Style* style) override { if (style->parent) { - const Reference& parentRef = style->parent.value(); - assert(parentRef.id && "parent has no ID"); - mOutEntry->parent.ident = util::hostToDevice32(parentRef.id.value().id); + const Reference& parent_ref = style->parent.value(); + CHECK(bool(parent_ref.id)) << "parent has no ID"; + out_entry_->parent.ident = util::HostToDevice32(parent_ref.id.value().id); } // Sort the style. - std::sort(style->entries.begin(), style->entries.end(), cmpStyleEntries); + std::sort(style->entries.begin(), style->entries.end(), cmp_style_entries); for (Style::Entry& entry : style->entries) { - flattenEntry(&entry.key, entry.value.get()); + FlattenEntry(&entry.key, entry.value.get()); } } - void visit(Styleable* styleable) override { - for (auto& attrRef : styleable->entries) { + void Visit(Styleable* styleable) override { + for (auto& attr_ref : styleable->entries) { BinaryPrimitive val(Res_value{}); - flattenEntry(&attrRef, &val); + FlattenEntry(&attr_ref, &val); } } - void visit(Array* array) override { + void Visit(Array* array) override { for (auto& item : array->items) { - ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>(); - flattenValue(item.get(), outEntry); - outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value)); - mEntryCount++; + ResTable_map* out_entry = buffer_->NextBlock<ResTable_map>(); + FlattenValue(item.get(), out_entry); + out_entry->value.size = util::HostToDevice16(sizeof(out_entry->value)); + entry_count_++; } } - void visit(Plural* plural) override { + void Visit(Plural* plural) override { const size_t count = plural->values.size(); for (size_t i = 0; i < count; i++) { if (!plural->values[i]) { @@ -172,12 +174,12 @@ class MapFlattenVisitor : public RawValueVisitor { break; default: - assert(false); + LOG(FATAL) << "unhandled plural type"; break; } Reference key(q); - flattenEntry(&key, plural->values[i].get()); + FlattenEntry(&key, plural->values[i].get()); } } @@ -185,267 +187,264 @@ class MapFlattenVisitor : public RawValueVisitor { * Call this after visiting a Value. This will finish any work that * needs to be done to prepare the entry. */ - void finish() { mOutEntry->count = util::hostToDevice32(mEntryCount); } + void Finish() { out_entry_->count = util::HostToDevice32(entry_count_); } private: - void flattenKey(Reference* key, ResTable_map* outEntry) { - assert(key->id && "key has no ID"); - outEntry->name.ident = util::hostToDevice32(key->id.value().id); + DISALLOW_COPY_AND_ASSIGN(MapFlattenVisitor); + + void FlattenKey(Reference* key, ResTable_map* out_entry) { + CHECK(bool(key->id)) << "key has no ID"; + out_entry->name.ident = util::HostToDevice32(key->id.value().id); } - void flattenValue(Item* value, ResTable_map* outEntry) { - bool result = value->flatten(&outEntry->value); - assert(result && "flatten failed"); + void FlattenValue(Item* value, ResTable_map* out_entry) { + CHECK(value->Flatten(&out_entry->value)) << "flatten failed"; } - void flattenEntry(Reference* key, Item* value) { - ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>(); - flattenKey(key, outEntry); - flattenValue(value, outEntry); - outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value)); - mEntryCount++; + void FlattenEntry(Reference* key, Item* value) { + ResTable_map* out_entry = buffer_->NextBlock<ResTable_map>(); + FlattenKey(key, out_entry); + FlattenValue(value, out_entry); + out_entry->value.size = util::HostToDevice16(sizeof(out_entry->value)); + entry_count_++; } - ResTable_entry_ext* mOutEntry; - BigBuffer* mBuffer; - size_t mEntryCount = 0; + ResTable_entry_ext* out_entry_; + BigBuffer* buffer_; + size_t entry_count_ = 0; }; class PackageFlattener { public: PackageFlattener(IDiagnostics* diag, ResourceTablePackage* package) - : mDiag(diag), mPackage(package) {} + : diag_(diag), package_(package) {} - bool flattenPackage(BigBuffer* buffer) { - ChunkWriter pkgWriter(buffer); - ResTable_package* pkgHeader = - pkgWriter.startChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE); - pkgHeader->id = util::hostToDevice32(mPackage->id.value()); + bool FlattenPackage(BigBuffer* buffer) { + ChunkWriter pkg_writer(buffer); + ResTable_package* pkg_header = + pkg_writer.StartChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE); + pkg_header->id = util::HostToDevice32(package_->id.value()); - if (mPackage->name.size() >= arraysize(pkgHeader->name)) { - mDiag->error(DiagMessage() << "package name '" << mPackage->name + if (package_->name.size() >= arraysize(pkg_header->name)) { + diag_->Error(DiagMessage() << "package name '" << package_->name << "' is too long"); return false; } // Copy the package name in device endianness. - strcpy16_htod(pkgHeader->name, arraysize(pkgHeader->name), - util::utf8ToUtf16(mPackage->name)); + strcpy16_htod(pkg_header->name, arraysize(pkg_header->name), + util::Utf8ToUtf16(package_->name)); // Serialize the types. We do this now so that our type and key strings // are populated. We write those first. - BigBuffer typeBuffer(1024); - flattenTypes(&typeBuffer); + BigBuffer type_buffer(1024); + FlattenTypes(&type_buffer); - pkgHeader->typeStrings = util::hostToDevice32(pkgWriter.size()); - StringPool::flattenUtf16(pkgWriter.getBuffer(), mTypePool); + pkg_header->typeStrings = util::HostToDevice32(pkg_writer.size()); + StringPool::FlattenUtf16(pkg_writer.buffer(), type_pool_); - pkgHeader->keyStrings = util::hostToDevice32(pkgWriter.size()); - StringPool::flattenUtf8(pkgWriter.getBuffer(), mKeyPool); + pkg_header->keyStrings = util::HostToDevice32(pkg_writer.size()); + StringPool::FlattenUtf8(pkg_writer.buffer(), key_pool_); // Append the types. - buffer->appendBuffer(std::move(typeBuffer)); + buffer->AppendBuffer(std::move(type_buffer)); - pkgWriter.finish(); + pkg_writer.Finish(); return true; } private: - IDiagnostics* mDiag; - ResourceTablePackage* mPackage; - StringPool mTypePool; - StringPool mKeyPool; + DISALLOW_COPY_AND_ASSIGN(PackageFlattener); template <typename T, bool IsItem> - T* writeEntry(FlatEntry* entry, BigBuffer* buffer) { + T* WriteEntry(FlatEntry* entry, BigBuffer* buffer) { static_assert(std::is_same<ResTable_entry, T>::value || std::is_same<ResTable_entry_ext, T>::value, "T must be ResTable_entry or ResTable_entry_ext"); - T* result = buffer->nextBlock<T>(); - ResTable_entry* outEntry = (ResTable_entry*)(result); - if (entry->entry->symbolStatus.state == SymbolState::kPublic) { - outEntry->flags |= ResTable_entry::FLAG_PUBLIC; + T* result = buffer->NextBlock<T>(); + ResTable_entry* out_entry = (ResTable_entry*)result; + if (entry->entry->symbol_status.state == SymbolState::kPublic) { + out_entry->flags |= ResTable_entry::FLAG_PUBLIC; } - if (entry->value->isWeak()) { - outEntry->flags |= ResTable_entry::FLAG_WEAK; + if (entry->value->IsWeak()) { + out_entry->flags |= ResTable_entry::FLAG_WEAK; } if (!IsItem) { - outEntry->flags |= ResTable_entry::FLAG_COMPLEX; + out_entry->flags |= ResTable_entry::FLAG_COMPLEX; } - outEntry->flags = util::hostToDevice16(outEntry->flags); - outEntry->key.index = util::hostToDevice32(entry->entryKey); - outEntry->size = util::hostToDevice16(sizeof(T)); + out_entry->flags = util::HostToDevice16(out_entry->flags); + out_entry->key.index = util::HostToDevice32(entry->entry_key); + out_entry->size = util::HostToDevice16(sizeof(T)); return result; } - bool flattenValue(FlatEntry* entry, BigBuffer* buffer) { - if (Item* item = valueCast<Item>(entry->value)) { - writeEntry<ResTable_entry, true>(entry, buffer); - Res_value* outValue = buffer->nextBlock<Res_value>(); - bool result = item->flatten(outValue); - assert(result && "flatten failed"); - outValue->size = util::hostToDevice16(sizeof(*outValue)); + bool FlattenValue(FlatEntry* entry, BigBuffer* buffer) { + if (Item* item = ValueCast<Item>(entry->value)) { + WriteEntry<ResTable_entry, true>(entry, buffer); + Res_value* outValue = buffer->NextBlock<Res_value>(); + CHECK(item->Flatten(outValue)) << "flatten failed"; + outValue->size = util::HostToDevice16(sizeof(*outValue)); } else { - ResTable_entry_ext* outEntry = - writeEntry<ResTable_entry_ext, false>(entry, buffer); - MapFlattenVisitor visitor(outEntry, buffer); - entry->value->accept(&visitor); - visitor.finish(); + ResTable_entry_ext* out_entry = + WriteEntry<ResTable_entry_ext, false>(entry, buffer); + MapFlattenVisitor visitor(out_entry, buffer); + entry->value->Accept(&visitor); + visitor.Finish(); } return true; } - bool flattenConfig(const ResourceTableType* type, + bool FlattenConfig(const ResourceTableType* type, const ConfigDescription& config, std::vector<FlatEntry>* entries, BigBuffer* buffer) { - ChunkWriter typeWriter(buffer); - ResTable_type* typeHeader = - typeWriter.startChunk<ResTable_type>(RES_TABLE_TYPE_TYPE); - typeHeader->id = type->id.value(); - typeHeader->config = config; - typeHeader->config.swapHtoD(); - - auto maxAccum = [](uint32_t max, - const std::unique_ptr<ResourceEntry>& a) -> uint32_t { + ChunkWriter type_writer(buffer); + ResTable_type* type_header = + type_writer.StartChunk<ResTable_type>(RES_TABLE_TYPE_TYPE); + type_header->id = type->id.value(); + type_header->config = config; + type_header->config.swapHtoD(); + + auto max_accum = [](uint32_t max, + const std::unique_ptr<ResourceEntry>& a) -> uint32_t { return std::max(max, (uint32_t)a->id.value()); }; // Find the largest entry ID. That is how many entries we will have. - const uint32_t entryCount = + const uint32_t entry_count = std::accumulate(type->entries.begin(), type->entries.end(), 0, - maxAccum) + + max_accum) + 1; - typeHeader->entryCount = util::hostToDevice32(entryCount); - uint32_t* indices = typeWriter.nextBlock<uint32_t>(entryCount); + type_header->entryCount = util::HostToDevice32(entry_count); + uint32_t* indices = type_writer.NextBlock<uint32_t>(entry_count); - assert((size_t)entryCount <= std::numeric_limits<uint16_t>::max() + 1); - memset(indices, 0xff, entryCount * sizeof(uint32_t)); + CHECK((size_t)entry_count <= std::numeric_limits<uint16_t>::max()); + memset(indices, 0xff, entry_count * sizeof(uint32_t)); - typeHeader->entriesStart = util::hostToDevice32(typeWriter.size()); + type_header->entriesStart = util::HostToDevice32(type_writer.size()); - const size_t entryStart = typeWriter.getBuffer()->size(); - for (FlatEntry& flatEntry : *entries) { - assert(flatEntry.entry->id.value() < entryCount); - indices[flatEntry.entry->id.value()] = - util::hostToDevice32(typeWriter.getBuffer()->size() - entryStart); - if (!flattenValue(&flatEntry, typeWriter.getBuffer())) { - mDiag->error(DiagMessage() + const size_t entry_start = type_writer.buffer()->size(); + for (FlatEntry& flat_entry : *entries) { + CHECK(flat_entry.entry->id.value() < entry_count); + indices[flat_entry.entry->id.value()] = + util::HostToDevice32(type_writer.buffer()->size() - entry_start); + if (!FlattenValue(&flat_entry, type_writer.buffer())) { + diag_->Error(DiagMessage() << "failed to flatten resource '" - << ResourceNameRef(mPackage->name, type->type, - flatEntry.entry->name) + << ResourceNameRef(package_->name, type->type, + flat_entry.entry->name) << "' for configuration '" << config << "'"); return false; } } - typeWriter.finish(); + type_writer.Finish(); return true; } - std::vector<ResourceTableType*> collectAndSortTypes() { - std::vector<ResourceTableType*> sortedTypes; - for (auto& type : mPackage->types) { + std::vector<ResourceTableType*> CollectAndSortTypes() { + std::vector<ResourceTableType*> sorted_types; + for (auto& type : package_->types) { if (type->type == ResourceType::kStyleable) { // Styleables aren't real Resource Types, they are represented in the - // R.java - // file. + // R.java file. continue; } - assert(type->id && "type must have an ID set"); + CHECK(bool(type->id)) << "type must have an ID set"; - sortedTypes.push_back(type.get()); + sorted_types.push_back(type.get()); } - std::sort(sortedTypes.begin(), sortedTypes.end(), - cmpIds<ResourceTableType>); - return sortedTypes; + std::sort(sorted_types.begin(), sorted_types.end(), + cmp_ids<ResourceTableType>); + return sorted_types; } - std::vector<ResourceEntry*> collectAndSortEntries(ResourceTableType* type) { + std::vector<ResourceEntry*> CollectAndSortEntries(ResourceTableType* type) { // Sort the entries by entry ID. - std::vector<ResourceEntry*> sortedEntries; + std::vector<ResourceEntry*> sorted_entries; for (auto& entry : type->entries) { - assert(entry->id && "entry must have an ID set"); - sortedEntries.push_back(entry.get()); + CHECK(bool(entry->id)) << "entry must have an ID set"; + sorted_entries.push_back(entry.get()); } - std::sort(sortedEntries.begin(), sortedEntries.end(), - cmpIds<ResourceEntry>); - return sortedEntries; + std::sort(sorted_entries.begin(), sorted_entries.end(), + cmp_ids<ResourceEntry>); + return sorted_entries; } - bool flattenTypeSpec(ResourceTableType* type, - std::vector<ResourceEntry*>* sortedEntries, + bool FlattenTypeSpec(ResourceTableType* type, + std::vector<ResourceEntry*>* sorted_entries, BigBuffer* buffer) { - ChunkWriter typeSpecWriter(buffer); - ResTable_typeSpec* specHeader = - typeSpecWriter.startChunk<ResTable_typeSpec>(RES_TABLE_TYPE_SPEC_TYPE); - specHeader->id = type->id.value(); - - if (sortedEntries->empty()) { - typeSpecWriter.finish(); + ChunkWriter type_spec_writer(buffer); + ResTable_typeSpec* spec_header = + type_spec_writer.StartChunk<ResTable_typeSpec>( + RES_TABLE_TYPE_SPEC_TYPE); + spec_header->id = type->id.value(); + + if (sorted_entries->empty()) { + type_spec_writer.Finish(); return true; } // We can't just take the size of the vector. There may be holes in the // entry ID space. // Since the entries are sorted by ID, the last one will be the biggest. - const size_t numEntries = sortedEntries->back()->id.value() + 1; + const size_t num_entries = sorted_entries->back()->id.value() + 1; - specHeader->entryCount = util::hostToDevice32(numEntries); + spec_header->entryCount = util::HostToDevice32(num_entries); // Reserve space for the masks of each resource in this type. These // show for which configuration axis the resource changes. - uint32_t* configMasks = typeSpecWriter.nextBlock<uint32_t>(numEntries); + uint32_t* config_masks = type_spec_writer.NextBlock<uint32_t>(num_entries); - const size_t actualNumEntries = sortedEntries->size(); - for (size_t entryIndex = 0; entryIndex < actualNumEntries; entryIndex++) { - ResourceEntry* entry = sortedEntries->at(entryIndex); + const size_t actual_num_entries = sorted_entries->size(); + for (size_t entryIndex = 0; entryIndex < actual_num_entries; entryIndex++) { + ResourceEntry* entry = sorted_entries->at(entryIndex); // Populate the config masks for this entry. - if (entry->symbolStatus.state == SymbolState::kPublic) { - configMasks[entry->id.value()] |= - util::hostToDevice32(ResTable_typeSpec::SPEC_PUBLIC); + if (entry->symbol_status.state == SymbolState::kPublic) { + config_masks[entry->id.value()] |= + util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC); } - const size_t configCount = entry->values.size(); - for (size_t i = 0; i < configCount; i++) { + const size_t config_count = entry->values.size(); + for (size_t i = 0; i < config_count; i++) { const ConfigDescription& config = entry->values[i]->config; - for (size_t j = i + 1; j < configCount; j++) { - configMasks[entry->id.value()] |= - util::hostToDevice32(config.diff(entry->values[j]->config)); + for (size_t j = i + 1; j < config_count; j++) { + config_masks[entry->id.value()] |= + util::HostToDevice32(config.diff(entry->values[j]->config)); } } } - typeSpecWriter.finish(); + type_spec_writer.Finish(); return true; } - bool flattenTypes(BigBuffer* buffer) { + bool FlattenTypes(BigBuffer* buffer) { // Sort the types by their IDs. They will be inserted into the StringPool in // this order. - std::vector<ResourceTableType*> sortedTypes = collectAndSortTypes(); + std::vector<ResourceTableType*> sorted_types = CollectAndSortTypes(); - size_t expectedTypeId = 1; - for (ResourceTableType* type : sortedTypes) { + size_t expected_type_id = 1; + for (ResourceTableType* type : sorted_types) { // If there is a gap in the type IDs, fill in the StringPool // with empty values until we reach the ID we expect. - while (type->id.value() > expectedTypeId) { - std::stringstream typeName; - typeName << "?" << expectedTypeId; - mTypePool.makeRef(typeName.str()); - expectedTypeId++; + while (type->id.value() > expected_type_id) { + std::stringstream type_name; + type_name << "?" << expected_type_id; + type_pool_.MakeRef(type_name.str()); + expected_type_id++; } - expectedTypeId++; - mTypePool.makeRef(toString(type->type)); + expected_type_id++; + type_pool_.MakeRef(ToString(type->type)); - std::vector<ResourceEntry*> sortedEntries = collectAndSortEntries(type); + std::vector<ResourceEntry*> sorted_entries = CollectAndSortEntries(type); - if (!flattenTypeSpec(type, &sortedEntries, buffer)) { + if (!FlattenTypeSpec(type, &sorted_entries, buffer)) { return false; } @@ -455,35 +454,41 @@ class PackageFlattener { // each // configuration available. Here we reverse this to match the binary // table. - std::map<ConfigDescription, std::vector<FlatEntry>> configToEntryListMap; - for (ResourceEntry* entry : sortedEntries) { - const uint32_t keyIndex = - (uint32_t)mKeyPool.makeRef(entry->name).getIndex(); + std::map<ConfigDescription, std::vector<FlatEntry>> + config_to_entry_list_map; + for (ResourceEntry* entry : sorted_entries) { + const uint32_t key_index = + (uint32_t)key_pool_.MakeRef(entry->name).index(); // Group values by configuration. - for (auto& configValue : entry->values) { - configToEntryListMap[configValue->config].push_back( - FlatEntry{entry, configValue->value.get(), keyIndex}); + for (auto& config_value : entry->values) { + config_to_entry_list_map[config_value->config].push_back( + FlatEntry{entry, config_value->value.get(), key_index}); } } // Flatten a configuration value. - for (auto& entry : configToEntryListMap) { - if (!flattenConfig(type, entry.first, &entry.second, buffer)) { + for (auto& entry : config_to_entry_list_map) { + if (!FlattenConfig(type, entry.first, &entry.second, buffer)) { return false; } } } return true; } + + IDiagnostics* diag_; + ResourceTablePackage* package_; + StringPool type_pool_; + StringPool key_pool_; }; } // namespace -bool TableFlattener::consume(IAaptContext* context, ResourceTable* table) { +bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) { // We must do this before writing the resources, since the string pool IDs may // change. - table->stringPool.sort( + table->string_pool.Sort( [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { int diff = a.context.priority - b.context.priority; if (diff < 0) return true; @@ -493,30 +498,30 @@ bool TableFlattener::consume(IAaptContext* context, ResourceTable* table) { if (diff > 0) return false; return a.value < b.value; }); - table->stringPool.prune(); + table->string_pool.Prune(); // Write the ResTable header. - ChunkWriter tableWriter(mBuffer); - ResTable_header* tableHeader = - tableWriter.startChunk<ResTable_header>(RES_TABLE_TYPE); - tableHeader->packageCount = util::hostToDevice32(table->packages.size()); + ChunkWriter table_writer(buffer_); + ResTable_header* table_header = + table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE); + table_header->packageCount = util::HostToDevice32(table->packages.size()); // Flatten the values string pool. - StringPool::flattenUtf8(tableWriter.getBuffer(), table->stringPool); + StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool); - BigBuffer packageBuffer(1024); + BigBuffer package_buffer(1024); // Flatten each package. for (auto& package : table->packages) { - PackageFlattener flattener(context->getDiagnostics(), package.get()); - if (!flattener.flattenPackage(&packageBuffer)) { + PackageFlattener flattener(context->GetDiagnostics(), package.get()); + if (!flattener.FlattenPackage(&package_buffer)) { return false; } } // Finally merge all the packages into the main buffer. - tableWriter.getBuffer()->appendBuffer(std::move(packageBuffer)); - tableWriter.finish(); + table_writer.buffer()->AppendBuffer(std::move(package_buffer)); + table_writer.Finish(); return true; } diff --git a/tools/aapt2/flatten/TableFlattener.h b/tools/aapt2/flatten/TableFlattener.h index 91f96547fbd7..53f52c29a6a3 100644 --- a/tools/aapt2/flatten/TableFlattener.h +++ b/tools/aapt2/flatten/TableFlattener.h @@ -17,21 +17,24 @@ #ifndef AAPT_FLATTEN_TABLEFLATTENER_H #define AAPT_FLATTEN_TABLEFLATTENER_H +#include "android-base/macros.h" + +#include "ResourceTable.h" #include "process/IResourceTableConsumer.h" +#include "util/BigBuffer.h" namespace aapt { -class BigBuffer; -class ResourceTable; - class TableFlattener : public IResourceTableConsumer { public: - explicit TableFlattener(BigBuffer* buffer) : mBuffer(buffer) {} + explicit TableFlattener(BigBuffer* buffer) : buffer_(buffer) {} - bool consume(IAaptContext* context, ResourceTable* table) override; + bool Consume(IAaptContext* context, ResourceTable* table) override; private: - BigBuffer* mBuffer; + DISALLOW_COPY_AND_ASSIGN(TableFlattener); + + BigBuffer* buffer_; }; } // namespace aapt diff --git a/tools/aapt2/flatten/TableFlattener_test.cpp b/tools/aapt2/flatten/TableFlattener_test.cpp index a7706bd51e47..c72624066fb8 100644 --- a/tools/aapt2/flatten/TableFlattener_test.cpp +++ b/tools/aapt2/flatten/TableFlattener_test.cpp @@ -15,6 +15,7 @@ */ #include "flatten/TableFlattener.h" + #include "ResourceUtils.h" #include "test/Test.h" #include "unflatten/BinaryResourceParser.h" @@ -27,162 +28,165 @@ namespace aapt { class TableFlattenerTest : public ::testing::Test { public: void SetUp() override { - mContext = test::ContextBuilder() - .setCompilationPackage("com.app.test") - .setPackageId(0x7f) - .build(); + context_ = test::ContextBuilder() + .SetCompilationPackage("com.app.test") + .SetPackageId(0x7f) + .Build(); } - ::testing::AssertionResult flatten(ResourceTable* table, ResTable* outTable) { + ::testing::AssertionResult Flatten(ResourceTable* table, + ResTable* out_table) { BigBuffer buffer(1024); TableFlattener flattener(&buffer); - if (!flattener.consume(mContext.get(), table)) { + if (!flattener.Consume(context_.get(), table)) { return ::testing::AssertionFailure() << "failed to flatten ResourceTable"; } - std::unique_ptr<uint8_t[]> data = util::copy(buffer); - if (outTable->add(data.get(), buffer.size(), -1, true) != NO_ERROR) { + std::unique_ptr<uint8_t[]> data = util::Copy(buffer); + if (out_table->add(data.get(), buffer.size(), -1, true) != NO_ERROR) { return ::testing::AssertionFailure() << "flattened ResTable is corrupt"; } return ::testing::AssertionSuccess(); } - ::testing::AssertionResult flatten(ResourceTable* table, - ResourceTable* outTable) { + ::testing::AssertionResult Flatten(ResourceTable* table, + ResourceTable* out_table) { BigBuffer buffer(1024); TableFlattener flattener(&buffer); - if (!flattener.consume(mContext.get(), table)) { + if (!flattener.Consume(context_.get(), table)) { return ::testing::AssertionFailure() << "failed to flatten ResourceTable"; } - std::unique_ptr<uint8_t[]> data = util::copy(buffer); - BinaryResourceParser parser(mContext.get(), outTable, {}, data.get(), + std::unique_ptr<uint8_t[]> data = util::Copy(buffer); + BinaryResourceParser parser(context_.get(), out_table, {}, data.get(), buffer.size()); - if (!parser.parse()) { + if (!parser.Parse()) { return ::testing::AssertionFailure() << "flattened ResTable is corrupt"; } return ::testing::AssertionSuccess(); } - ::testing::AssertionResult exists(ResTable* table, - const StringPiece& expectedName, - const ResourceId& expectedId, - const ConfigDescription& expectedConfig, - const uint8_t expectedDataType, - const uint32_t expectedData, - const uint32_t expectedSpecFlags) { - const ResourceName expectedResName = test::parseNameOrDie(expectedName); + ::testing::AssertionResult Exists(ResTable* table, + const StringPiece& expected_name, + const ResourceId& expected_id, + const ConfigDescription& expected_config, + const uint8_t expected_data_type, + const uint32_t expected_data, + const uint32_t expected_spec_flags) { + const ResourceName expected_res_name = test::ParseNameOrDie(expected_name); - table->setParameters(&expectedConfig); + table->setParameters(&expected_config); ResTable_config config; Res_value val; - uint32_t specFlags; - if (table->getResource(expectedId.id, &val, false, 0, &specFlags, &config) < - 0) { + uint32_t spec_flags; + if (table->getResource(expected_id.id, &val, false, 0, &spec_flags, + &config) < 0) { return ::testing::AssertionFailure() << "could not find resource with"; } - if (expectedDataType != val.dataType) { + if (expected_data_type != val.dataType) { return ::testing::AssertionFailure() - << "expected data type " << std::hex << (int)expectedDataType + << "expected data type " << std::hex << (int)expected_data_type << " but got data type " << (int)val.dataType << std::dec << " instead"; } - if (expectedData != val.data) { + if (expected_data != val.data) { return ::testing::AssertionFailure() - << "expected data " << std::hex << expectedData << " but got data " - << val.data << std::dec << " instead"; + << "expected data " << std::hex << expected_data + << " but got data " << val.data << std::dec << " instead"; } - if (expectedSpecFlags != specFlags) { + if (expected_spec_flags != spec_flags) { return ::testing::AssertionFailure() - << "expected specFlags " << std::hex << expectedSpecFlags - << " but got specFlags " << specFlags << std::dec << " instead"; + << "expected specFlags " << std::hex << expected_spec_flags + << " but got specFlags " << spec_flags << std::dec << " instead"; } - ResTable::resource_name actualName; - if (!table->getResourceName(expectedId.id, false, &actualName)) { + ResTable::resource_name actual_name; + if (!table->getResourceName(expected_id.id, false, &actual_name)) { return ::testing::AssertionFailure() << "failed to find resource name"; } - Maybe<ResourceName> resName = ResourceUtils::toResourceName(actualName); + Maybe<ResourceName> resName = ResourceUtils::ToResourceName(actual_name); if (!resName) { return ::testing::AssertionFailure() - << "expected name '" << expectedResName << "' but got '" - << StringPiece16(actualName.package, actualName.packageLen) << ":" - << StringPiece16(actualName.type, actualName.typeLen) << "/" - << StringPiece16(actualName.name, actualName.nameLen) << "'"; + << "expected name '" << expected_res_name << "' but got '" + << StringPiece16(actual_name.package, actual_name.packageLen) + << ":" << StringPiece16(actual_name.type, actual_name.typeLen) + << "/" << StringPiece16(actual_name.name, actual_name.nameLen) + << "'"; } - if (expectedConfig != config) { + if (expected_config != config) { return ::testing::AssertionFailure() << "expected config '" - << expectedConfig << "' but got '" + << expected_config << "' but got '" << ConfigDescription(config) << "'"; } return ::testing::AssertionSuccess(); } private: - std::unique_ptr<IAaptContext> mContext; + std::unique_ptr<IAaptContext> context_; }; TEST_F(TableFlattenerTest, FlattenFullyLinkedTable) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("com.app.test", 0x7f) - .addSimple("com.app.test:id/one", ResourceId(0x7f020000)) - .addSimple("com.app.test:id/two", ResourceId(0x7f020001)) - .addValue("com.app.test:id/three", ResourceId(0x7f020002), - test::buildReference("com.app.test:id/one", + .SetPackageId("com.app.test", 0x7f) + .AddSimple("com.app.test:id/one", ResourceId(0x7f020000)) + .AddSimple("com.app.test:id/two", ResourceId(0x7f020001)) + .AddValue("com.app.test:id/three", ResourceId(0x7f020002), + test::BuildReference("com.app.test:id/one", ResourceId(0x7f020000))) - .addValue("com.app.test:integer/one", ResourceId(0x7f030000), + .AddValue("com.app.test:integer/one", ResourceId(0x7f030000), util::make_unique<BinaryPrimitive>( uint8_t(Res_value::TYPE_INT_DEC), 1u)) - .addValue("com.app.test:integer/one", test::parseConfigOrDie("v1"), + .AddValue("com.app.test:integer/one", test::ParseConfigOrDie("v1"), ResourceId(0x7f030000), util::make_unique<BinaryPrimitive>( uint8_t(Res_value::TYPE_INT_DEC), 2u)) - .addString("com.app.test:string/test", ResourceId(0x7f040000), "foo") - .addString("com.app.test:layout/bar", ResourceId(0x7f050000), + .AddString("com.app.test:string/test", ResourceId(0x7f040000), "foo") + .AddString("com.app.test:layout/bar", ResourceId(0x7f050000), "res/layout/bar.xml") - .build(); + .Build(); - ResTable resTable; - ASSERT_TRUE(flatten(table.get(), &resTable)); + ResTable res_table; + ASSERT_TRUE(Flatten(table.get(), &res_table)); - EXPECT_TRUE(exists(&resTable, "com.app.test:id/one", ResourceId(0x7f020000), + EXPECT_TRUE(Exists(&res_table, "com.app.test:id/one", ResourceId(0x7f020000), {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u)); - EXPECT_TRUE(exists(&resTable, "com.app.test:id/two", ResourceId(0x7f020001), + EXPECT_TRUE(Exists(&res_table, "com.app.test:id/two", ResourceId(0x7f020001), {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u)); - EXPECT_TRUE(exists(&resTable, "com.app.test:id/three", ResourceId(0x7f020002), - {}, Res_value::TYPE_REFERENCE, 0x7f020000u, 0u)); + EXPECT_TRUE(Exists(&res_table, "com.app.test:id/three", + ResourceId(0x7f020002), {}, Res_value::TYPE_REFERENCE, + 0x7f020000u, 0u)); - EXPECT_TRUE(exists(&resTable, "com.app.test:integer/one", + EXPECT_TRUE(Exists(&res_table, "com.app.test:integer/one", ResourceId(0x7f030000), {}, Res_value::TYPE_INT_DEC, 1u, ResTable_config::CONFIG_VERSION)); - EXPECT_TRUE(exists(&resTable, "com.app.test:integer/one", - ResourceId(0x7f030000), test::parseConfigOrDie("v1"), + EXPECT_TRUE(Exists(&res_table, "com.app.test:integer/one", + ResourceId(0x7f030000), test::ParseConfigOrDie("v1"), Res_value::TYPE_INT_DEC, 2u, ResTable_config::CONFIG_VERSION)); - std::u16string fooStr = u"foo"; - ssize_t idx = resTable.getTableStringBlock(0)->indexOfString(fooStr.data(), - fooStr.size()); + std::u16string foo_str = u"foo"; + ssize_t idx = res_table.getTableStringBlock(0)->indexOfString(foo_str.data(), + foo_str.size()); ASSERT_GE(idx, 0); - EXPECT_TRUE(exists(&resTable, "com.app.test:string/test", + EXPECT_TRUE(Exists(&res_table, "com.app.test:string/test", ResourceId(0x7f040000), {}, Res_value::TYPE_STRING, (uint32_t)idx, 0u)); - std::u16string barPath = u"res/layout/bar.xml"; - idx = resTable.getTableStringBlock(0)->indexOfString(barPath.data(), - barPath.size()); + std::u16string bar_path = u"res/layout/bar.xml"; + idx = res_table.getTableStringBlock(0)->indexOfString(bar_path.data(), + bar_path.size()); ASSERT_GE(idx, 0); - EXPECT_TRUE(exists(&resTable, "com.app.test:layout/bar", + EXPECT_TRUE(Exists(&res_table, "com.app.test:layout/bar", ResourceId(0x7f050000), {}, Res_value::TYPE_STRING, (uint32_t)idx, 0u)); } @@ -190,42 +194,43 @@ TEST_F(TableFlattenerTest, FlattenFullyLinkedTable) { TEST_F(TableFlattenerTest, FlattenEntriesWithGapsInIds) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("com.app.test", 0x7f) - .addSimple("com.app.test:id/one", ResourceId(0x7f020001)) - .addSimple("com.app.test:id/three", ResourceId(0x7f020003)) - .build(); + .SetPackageId("com.app.test", 0x7f) + .AddSimple("com.app.test:id/one", ResourceId(0x7f020001)) + .AddSimple("com.app.test:id/three", ResourceId(0x7f020003)) + .Build(); - ResTable resTable; - ASSERT_TRUE(flatten(table.get(), &resTable)); + ResTable res_table; + ASSERT_TRUE(Flatten(table.get(), &res_table)); - EXPECT_TRUE(exists(&resTable, "com.app.test:id/one", ResourceId(0x7f020001), - {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u)); - EXPECT_TRUE(exists(&resTable, "com.app.test:id/three", ResourceId(0x7f020003), + EXPECT_TRUE(Exists(&res_table, "com.app.test:id/one", ResourceId(0x7f020001), {}, Res_value::TYPE_INT_BOOLEAN, 0u, 0u)); + EXPECT_TRUE(Exists(&res_table, "com.app.test:id/three", + ResourceId(0x7f020003), {}, Res_value::TYPE_INT_BOOLEAN, + 0u, 0u)); } TEST_F(TableFlattenerTest, FlattenMinMaxAttributes) { Attribute attr(false); - attr.typeMask = android::ResTable_map::TYPE_INTEGER; - attr.minInt = 10; - attr.maxInt = 23; + attr.type_mask = android::ResTable_map::TYPE_INTEGER; + attr.min_int = 10; + attr.max_int = 23; std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .addValue("android:attr/foo", ResourceId(0x01010000), + .SetPackageId("android", 0x01) + .AddValue("android:attr/foo", ResourceId(0x01010000), util::make_unique<Attribute>(attr)) - .build(); + .Build(); ResourceTable result; - ASSERT_TRUE(flatten(table.get(), &result)); + ASSERT_TRUE(Flatten(table.get(), &result)); Attribute* actualAttr = - test::getValue<Attribute>(&result, "android:attr/foo"); + test::GetValue<Attribute>(&result, "android:attr/foo"); ASSERT_NE(nullptr, actualAttr); - EXPECT_EQ(attr.isWeak(), actualAttr->isWeak()); - EXPECT_EQ(attr.typeMask, actualAttr->typeMask); - EXPECT_EQ(attr.minInt, actualAttr->minInt); - EXPECT_EQ(attr.maxInt, actualAttr->maxInt); + EXPECT_EQ(attr.IsWeak(), actualAttr->IsWeak()); + EXPECT_EQ(attr.type_mask, actualAttr->type_mask); + EXPECT_EQ(attr.min_int, actualAttr->min_int); + EXPECT_EQ(attr.max_int, actualAttr->max_int); } } // namespace aapt diff --git a/tools/aapt2/flatten/XmlFlattener.cpp b/tools/aapt2/flatten/XmlFlattener.cpp index b1536d5f21d2..366c373223dc 100644 --- a/tools/aapt2/flatten/XmlFlattener.cpp +++ b/tools/aapt2/flatten/XmlFlattener.cpp @@ -15,17 +15,21 @@ */ #include "flatten/XmlFlattener.h" -#include "SdkConstants.h" -#include "flatten/ChunkWriter.h" -#include "flatten/ResourceTypeExtensions.h" -#include "xml/XmlDom.h" -#include <androidfw/ResourceTypes.h> -#include <utils/misc.h> #include <algorithm> #include <map> #include <vector> +#include "android-base/logging.h" +#include "android-base/macros.h" +#include "androidfw/ResourceTypes.h" +#include "utils/misc.h" + +#include "SdkConstants.h" +#include "flatten/ChunkWriter.h" +#include "flatten/ResourceTypeExtensions.h" +#include "xml/XmlDom.h" + using namespace android; namespace aapt { @@ -34,216 +38,215 @@ namespace { constexpr uint32_t kLowPriority = 0xffffffffu; -struct XmlFlattenerVisitor : public xml::Visitor { - using xml::Visitor::visit; +static bool cmp_xml_attribute_by_id(const xml::Attribute* a, + const xml::Attribute* b) { + if (a->compiled_attribute && a->compiled_attribute.value().id) { + if (b->compiled_attribute && b->compiled_attribute.value().id) { + return a->compiled_attribute.value().id.value() < + b->compiled_attribute.value().id.value(); + } + return true; + } else if (!b->compiled_attribute) { + int diff = a->namespace_uri.compare(b->namespace_uri); + if (diff < 0) { + return true; + } else if (diff > 0) { + return false; + } + return a->name < b->name; + } + return false; +} + +class XmlFlattenerVisitor : public xml::Visitor { + public: + using xml::Visitor::Visit; - BigBuffer* mBuffer; - XmlFlattenerOptions mOptions; - StringPool mPool; - std::map<uint8_t, StringPool> mPackagePools; + StringPool pool; + std::map<uint8_t, StringPool> package_pools; struct StringFlattenDest { StringPool::Ref ref; ResStringPool_ref* dest; }; - std::vector<StringFlattenDest> mStringRefs; - // Scratch vector to filter attributes. We avoid allocations - // making this a member. - std::vector<xml::Attribute*> mFilteredAttrs; + std::vector<StringFlattenDest> string_refs; XmlFlattenerVisitor(BigBuffer* buffer, XmlFlattenerOptions options) - : mBuffer(buffer), mOptions(options) {} - - void addString(const StringPiece& str, uint32_t priority, - android::ResStringPool_ref* dest, - bool treatEmptyStringAsNull = false) { - if (str.empty() && treatEmptyStringAsNull) { - // Some parts of the runtime treat null differently than empty string. - dest->index = util::deviceToHost32(-1); - } else { - mStringRefs.push_back(StringFlattenDest{ - mPool.makeRef(str, StringPool::Context(priority)), dest}); - } - } - - void addString(const StringPool::Ref& ref, android::ResStringPool_ref* dest) { - mStringRefs.push_back(StringFlattenDest{ref, dest}); - } - - void writeNamespace(xml::Namespace* node, uint16_t type) { - ChunkWriter writer(mBuffer); - - ResXMLTree_node* flatNode = writer.startChunk<ResXMLTree_node>(type); - flatNode->lineNumber = util::hostToDevice32(node->lineNumber); - flatNode->comment.index = util::hostToDevice32(-1); - - ResXMLTree_namespaceExt* flatNs = - writer.nextBlock<ResXMLTree_namespaceExt>(); - addString(node->namespacePrefix, kLowPriority, &flatNs->prefix); - addString(node->namespaceUri, kLowPriority, &flatNs->uri); + : buffer_(buffer), options_(options) {} - writer.finish(); - } - - void visit(xml::Namespace* node) override { - if (node->namespaceUri == xml::kSchemaTools) { + void Visit(xml::Namespace* node) override { + if (node->namespace_uri == xml::kSchemaTools) { // Skip dedicated tools namespace. - xml::Visitor::visit(node); + xml::Visitor::Visit(node); } else { - writeNamespace(node, android::RES_XML_START_NAMESPACE_TYPE); - xml::Visitor::visit(node); - writeNamespace(node, android::RES_XML_END_NAMESPACE_TYPE); + WriteNamespace(node, android::RES_XML_START_NAMESPACE_TYPE); + xml::Visitor::Visit(node); + WriteNamespace(node, android::RES_XML_END_NAMESPACE_TYPE); } } - void visit(xml::Text* node) override { - if (util::trimWhitespace(node->text).empty()) { + void Visit(xml::Text* node) override { + if (util::TrimWhitespace(node->text).empty()) { // Skip whitespace only text nodes. return; } - ChunkWriter writer(mBuffer); - ResXMLTree_node* flatNode = - writer.startChunk<ResXMLTree_node>(RES_XML_CDATA_TYPE); - flatNode->lineNumber = util::hostToDevice32(node->lineNumber); - flatNode->comment.index = util::hostToDevice32(-1); + ChunkWriter writer(buffer_); + ResXMLTree_node* flat_node = + writer.StartChunk<ResXMLTree_node>(RES_XML_CDATA_TYPE); + flat_node->lineNumber = util::HostToDevice32(node->line_number); + flat_node->comment.index = util::HostToDevice32(-1); - ResXMLTree_cdataExt* flatText = writer.nextBlock<ResXMLTree_cdataExt>(); - addString(node->text, kLowPriority, &flatText->data); + ResXMLTree_cdataExt* flat_text = writer.NextBlock<ResXMLTree_cdataExt>(); + AddString(node->text, kLowPriority, &flat_text->data); - writer.finish(); + writer.Finish(); } - void visit(xml::Element* node) override { + void Visit(xml::Element* node) override { { - ChunkWriter startWriter(mBuffer); - ResXMLTree_node* flatNode = - startWriter.startChunk<ResXMLTree_node>(RES_XML_START_ELEMENT_TYPE); - flatNode->lineNumber = util::hostToDevice32(node->lineNumber); - flatNode->comment.index = util::hostToDevice32(-1); + ChunkWriter start_writer(buffer_); + ResXMLTree_node* flat_node = + start_writer.StartChunk<ResXMLTree_node>(RES_XML_START_ELEMENT_TYPE); + flat_node->lineNumber = util::HostToDevice32(node->line_number); + flat_node->comment.index = util::HostToDevice32(-1); - ResXMLTree_attrExt* flatElem = - startWriter.nextBlock<ResXMLTree_attrExt>(); + ResXMLTree_attrExt* flat_elem = + start_writer.NextBlock<ResXMLTree_attrExt>(); // A missing namespace must be null, not an empty string. Otherwise the - // runtime - // complains. - addString(node->namespaceUri, kLowPriority, &flatElem->ns, - true /* treatEmptyStringAsNull */); - addString(node->name, kLowPriority, &flatElem->name, - true /* treatEmptyStringAsNull */); + // runtime complains. + AddString(node->namespace_uri, kLowPriority, &flat_elem->ns, + true /* treat_empty_string_as_null */); + AddString(node->name, kLowPriority, &flat_elem->name, + true /* treat_empty_string_as_null */); - flatElem->attributeStart = util::hostToDevice16(sizeof(*flatElem)); - flatElem->attributeSize = - util::hostToDevice16(sizeof(ResXMLTree_attribute)); + flat_elem->attributeStart = util::HostToDevice16(sizeof(*flat_elem)); + flat_elem->attributeSize = + util::HostToDevice16(sizeof(ResXMLTree_attribute)); - writeAttributes(node, flatElem, &startWriter); + WriteAttributes(node, flat_elem, &start_writer); - startWriter.finish(); + start_writer.Finish(); } - xml::Visitor::visit(node); + xml::Visitor::Visit(node); { - ChunkWriter endWriter(mBuffer); - ResXMLTree_node* flatEndNode = - endWriter.startChunk<ResXMLTree_node>(RES_XML_END_ELEMENT_TYPE); - flatEndNode->lineNumber = util::hostToDevice32(node->lineNumber); - flatEndNode->comment.index = util::hostToDevice32(-1); - - ResXMLTree_endElementExt* flatEndElem = - endWriter.nextBlock<ResXMLTree_endElementExt>(); - addString(node->namespaceUri, kLowPriority, &flatEndElem->ns, - true /* treatEmptyStringAsNull */); - addString(node->name, kLowPriority, &flatEndElem->name); - - endWriter.finish(); + ChunkWriter end_writer(buffer_); + ResXMLTree_node* flat_end_node = + end_writer.StartChunk<ResXMLTree_node>(RES_XML_END_ELEMENT_TYPE); + flat_end_node->lineNumber = util::HostToDevice32(node->line_number); + flat_end_node->comment.index = util::HostToDevice32(-1); + + ResXMLTree_endElementExt* flat_end_elem = + end_writer.NextBlock<ResXMLTree_endElementExt>(); + AddString(node->namespace_uri, kLowPriority, &flat_end_elem->ns, + true /* treat_empty_string_as_null */); + AddString(node->name, kLowPriority, &flat_end_elem->name); + + end_writer.Finish(); } } - static bool cmpXmlAttributeById(const xml::Attribute* a, - const xml::Attribute* b) { - if (a->compiledAttribute && a->compiledAttribute.value().id) { - if (b->compiledAttribute && b->compiledAttribute.value().id) { - return a->compiledAttribute.value().id.value() < - b->compiledAttribute.value().id.value(); - } - return true; - } else if (!b->compiledAttribute) { - int diff = a->namespaceUri.compare(b->namespaceUri); - if (diff < 0) { - return true; - } else if (diff > 0) { - return false; - } - return a->name < b->name; + private: + DISALLOW_COPY_AND_ASSIGN(XmlFlattenerVisitor); + + void AddString(const StringPiece& str, uint32_t priority, + android::ResStringPool_ref* dest, + bool treat_empty_string_as_null = false) { + if (str.empty() && treat_empty_string_as_null) { + // Some parts of the runtime treat null differently than empty string. + dest->index = util::DeviceToHost32(-1); + } else { + string_refs.push_back(StringFlattenDest{ + pool.MakeRef(str, StringPool::Context(priority)), dest}); } - return false; } - void writeAttributes(xml::Element* node, ResXMLTree_attrExt* flatElem, + void AddString(const StringPool::Ref& ref, android::ResStringPool_ref* dest) { + string_refs.push_back(StringFlattenDest{ref, dest}); + } + + void WriteNamespace(xml::Namespace* node, uint16_t type) { + ChunkWriter writer(buffer_); + + ResXMLTree_node* flatNode = writer.StartChunk<ResXMLTree_node>(type); + flatNode->lineNumber = util::HostToDevice32(node->line_number); + flatNode->comment.index = util::HostToDevice32(-1); + + ResXMLTree_namespaceExt* flat_ns = + writer.NextBlock<ResXMLTree_namespaceExt>(); + AddString(node->namespace_prefix, kLowPriority, &flat_ns->prefix); + AddString(node->namespace_uri, kLowPriority, &flat_ns->uri); + + writer.Finish(); + } + + void WriteAttributes(xml::Element* node, ResXMLTree_attrExt* flat_elem, ChunkWriter* writer) { - mFilteredAttrs.clear(); - mFilteredAttrs.reserve(node->attributes.size()); + filtered_attrs_.clear(); + filtered_attrs_.reserve(node->attributes.size()); // Filter the attributes. for (xml::Attribute& attr : node->attributes) { - if (mOptions.maxSdkLevel && attr.compiledAttribute && - attr.compiledAttribute.value().id) { - size_t sdkLevel = - findAttributeSdkLevel(attr.compiledAttribute.value().id.value()); - if (sdkLevel > mOptions.maxSdkLevel.value()) { + if (options_.max_sdk_level && attr.compiled_attribute && + attr.compiled_attribute.value().id) { + size_t sdk_level = + FindAttributeSdkLevel(attr.compiled_attribute.value().id.value()); + if (sdk_level > options_.max_sdk_level.value()) { continue; } } - if (attr.namespaceUri == xml::kSchemaTools) { + if (attr.namespace_uri == xml::kSchemaTools) { continue; } - mFilteredAttrs.push_back(&attr); + filtered_attrs_.push_back(&attr); } - if (mFilteredAttrs.empty()) { + if (filtered_attrs_.empty()) { return; } const ResourceId kIdAttr(0x010100d0); - std::sort(mFilteredAttrs.begin(), mFilteredAttrs.end(), - cmpXmlAttributeById); + std::sort(filtered_attrs_.begin(), filtered_attrs_.end(), + cmp_xml_attribute_by_id); - flatElem->attributeCount = util::hostToDevice16(mFilteredAttrs.size()); + flat_elem->attributeCount = util::HostToDevice16(filtered_attrs_.size()); - ResXMLTree_attribute* flatAttr = - writer->nextBlock<ResXMLTree_attribute>(mFilteredAttrs.size()); - uint16_t attributeIndex = 1; - for (const xml::Attribute* xmlAttr : mFilteredAttrs) { + ResXMLTree_attribute* flat_attr = + writer->NextBlock<ResXMLTree_attribute>(filtered_attrs_.size()); + uint16_t attribute_index = 1; + for (const xml::Attribute* xml_attr : filtered_attrs_) { // Assign the indices for specific attributes. - if (xmlAttr->compiledAttribute && xmlAttr->compiledAttribute.value().id && - xmlAttr->compiledAttribute.value().id.value() == kIdAttr) { - flatElem->idIndex = util::hostToDevice16(attributeIndex); - } else if (xmlAttr->namespaceUri.empty()) { - if (xmlAttr->name == "class") { - flatElem->classIndex = util::hostToDevice16(attributeIndex); - } else if (xmlAttr->name == "style") { - flatElem->styleIndex = util::hostToDevice16(attributeIndex); + if (xml_attr->compiled_attribute && + xml_attr->compiled_attribute.value().id && + xml_attr->compiled_attribute.value().id.value() == kIdAttr) { + flat_elem->idIndex = util::HostToDevice16(attribute_index); + } else if (xml_attr->namespace_uri.empty()) { + if (xml_attr->name == "class") { + flat_elem->classIndex = util::HostToDevice16(attribute_index); + } else if (xml_attr->name == "style") { + flat_elem->styleIndex = util::HostToDevice16(attribute_index); } } - attributeIndex++; + attribute_index++; // Add the namespaceUri to the list of StringRefs to encode. Use null if // the namespace // is empty (doesn't exist). - addString(xmlAttr->namespaceUri, kLowPriority, &flatAttr->ns, - true /* treatEmptyStringAsNull */); + AddString(xml_attr->namespace_uri, kLowPriority, &flat_attr->ns, + true /* treat_empty_string_as_null */); - flatAttr->rawValue.index = util::hostToDevice32(-1); + flat_attr->rawValue.index = util::HostToDevice32(-1); - if (!xmlAttr->compiledAttribute || - !xmlAttr->compiledAttribute.value().id) { + if (!xml_attr->compiled_attribute || + !xml_attr->compiled_attribute.value().id) { // The attribute has no associated ResourceID, so the string order // doesn't matter. - addString(xmlAttr->name, kLowPriority, &flatAttr->name); + AddString(xml_attr->name, kLowPriority, &flat_attr->name); } else { // Attribute names are stored without packages, but we use // their StringPool index to lookup their resource IDs. @@ -252,99 +255,106 @@ struct XmlFlattenerVisitor : public xml::Visitor { // pools that we later combine. // // Lookup the StringPool for this package and make the reference there. - const xml::AaptAttribute& aaptAttr = xmlAttr->compiledAttribute.value(); + const xml::AaptAttribute& aapt_attr = + xml_attr->compiled_attribute.value(); - StringPool::Ref nameRef = - mPackagePools[aaptAttr.id.value().packageId()].makeRef( - xmlAttr->name, StringPool::Context(aaptAttr.id.value().id)); + StringPool::Ref name_ref = + package_pools[aapt_attr.id.value().package_id()].MakeRef( + xml_attr->name, StringPool::Context(aapt_attr.id.value().id)); // Add it to the list of strings to flatten. - addString(nameRef, &flatAttr->name); + AddString(name_ref, &flat_attr->name); } - if (mOptions.keepRawValues || !xmlAttr->compiledValue) { + if (options_.keep_raw_values || !xml_attr->compiled_value) { // Keep raw values if the value is not compiled or // if we're building a static library (need symbols). - addString(xmlAttr->value, kLowPriority, &flatAttr->rawValue); + AddString(xml_attr->value, kLowPriority, &flat_attr->rawValue); } - if (xmlAttr->compiledValue) { - bool result = xmlAttr->compiledValue->flatten(&flatAttr->typedValue); - assert(result); + if (xml_attr->compiled_value) { + CHECK(xml_attr->compiled_value->Flatten(&flat_attr->typedValue)); } else { // Flatten as a regular string type. - flatAttr->typedValue.dataType = android::Res_value::TYPE_STRING; - addString(xmlAttr->value, kLowPriority, - (ResStringPool_ref*)&flatAttr->typedValue.data); + flat_attr->typedValue.dataType = android::Res_value::TYPE_STRING; + AddString(xml_attr->value, kLowPriority, + (ResStringPool_ref*)&flat_attr->typedValue.data); } - flatAttr->typedValue.size = - util::hostToDevice16(sizeof(flatAttr->typedValue)); - flatAttr++; + flat_attr->typedValue.size = + util::HostToDevice16(sizeof(flat_attr->typedValue)); + flat_attr++; } } + + BigBuffer* buffer_; + XmlFlattenerOptions options_; + + // Scratch vector to filter attributes. We avoid allocations + // making this a member. + std::vector<xml::Attribute*> filtered_attrs_; }; } // namespace -bool XmlFlattener::flatten(IAaptContext* context, xml::Node* node) { - BigBuffer nodeBuffer(1024); - XmlFlattenerVisitor visitor(&nodeBuffer, mOptions); - node->accept(&visitor); +bool XmlFlattener::Flatten(IAaptContext* context, xml::Node* node) { + BigBuffer node_buffer(1024); + XmlFlattenerVisitor visitor(&node_buffer, options_); + node->Accept(&visitor); // Merge the package pools into the main pool. - for (auto& packagePoolEntry : visitor.mPackagePools) { - visitor.mPool.merge(std::move(packagePoolEntry.second)); + for (auto& package_pool_entry : visitor.package_pools) { + visitor.pool.Merge(std::move(package_pool_entry.second)); } // Sort the string pool so that attribute resource IDs show up first. - visitor.mPool.sort( + visitor.pool.Sort( [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { return a.context.priority < b.context.priority; }); // Now we flatten the string pool references into the correct places. - for (const auto& refEntry : visitor.mStringRefs) { - refEntry.dest->index = util::hostToDevice32(refEntry.ref.getIndex()); + for (const auto& ref_entry : visitor.string_refs) { + ref_entry.dest->index = util::HostToDevice32(ref_entry.ref.index()); } // Write the XML header. - ChunkWriter xmlHeaderWriter(mBuffer); - xmlHeaderWriter.startChunk<ResXMLTree_header>(RES_XML_TYPE); + ChunkWriter xml_header_writer(buffer_); + xml_header_writer.StartChunk<ResXMLTree_header>(RES_XML_TYPE); // Flatten the StringPool. - StringPool::flattenUtf8(mBuffer, visitor.mPool); + StringPool::FlattenUtf8(buffer_, visitor.pool); { // Write the array of resource IDs, indexed by StringPool order. - ChunkWriter resIdMapWriter(mBuffer); - resIdMapWriter.startChunk<ResChunk_header>(RES_XML_RESOURCE_MAP_TYPE); - for (const auto& str : visitor.mPool) { + ChunkWriter res_id_map_writer(buffer_); + res_id_map_writer.StartChunk<ResChunk_header>(RES_XML_RESOURCE_MAP_TYPE); + for (const auto& str : visitor.pool) { ResourceId id = {str->context.priority}; - if (id.id == kLowPriority || !id.isValid()) { + if (id.id == kLowPriority || !id.is_valid()) { // When we see the first non-resource ID, // we're done. break; } - *resIdMapWriter.nextBlock<uint32_t>() = id.id; + *res_id_map_writer.NextBlock<uint32_t>() = id.id; } - resIdMapWriter.finish(); + res_id_map_writer.Finish(); } // Move the nodeBuffer and append it to the out buffer. - mBuffer->appendBuffer(std::move(nodeBuffer)); + buffer_->AppendBuffer(std::move(node_buffer)); // Finish the xml header. - xmlHeaderWriter.finish(); + xml_header_writer.Finish(); return true; } -bool XmlFlattener::consume(IAaptContext* context, xml::XmlResource* resource) { +bool XmlFlattener::Consume(IAaptContext* context, xml::XmlResource* resource) { if (!resource->root) { return false; } - return flatten(context, resource->root.get()); + return Flatten(context, resource->root.get()); } } // namespace aapt diff --git a/tools/aapt2/flatten/XmlFlattener.h b/tools/aapt2/flatten/XmlFlattener.h index d8d592b41c2c..f5129fd40e99 100644 --- a/tools/aapt2/flatten/XmlFlattener.h +++ b/tools/aapt2/flatten/XmlFlattener.h @@ -17,6 +17,8 @@ #ifndef AAPT_FLATTEN_XMLFLATTENER_H #define AAPT_FLATTEN_XMLFLATTENER_H +#include "android-base/macros.h" + #include "process/IResourceTableConsumer.h" #include "util/BigBuffer.h" #include "xml/XmlDom.h" @@ -27,26 +29,28 @@ struct XmlFlattenerOptions { /** * Keep attribute raw string values along with typed values. */ - bool keepRawValues = false; + bool keep_raw_values = false; /** * If set, the max SDK level of attribute to flatten. All others are ignored. */ - Maybe<size_t> maxSdkLevel; + Maybe<size_t> max_sdk_level; }; class XmlFlattener : public IXmlResourceConsumer { public: XmlFlattener(BigBuffer* buffer, XmlFlattenerOptions options) - : mBuffer(buffer), mOptions(options) {} + : buffer_(buffer), options_(options) {} - bool consume(IAaptContext* context, xml::XmlResource* resource) override; + bool Consume(IAaptContext* context, xml::XmlResource* resource) override; private: - BigBuffer* mBuffer; - XmlFlattenerOptions mOptions; + DISALLOW_COPY_AND_ASSIGN(XmlFlattener); + + bool Flatten(IAaptContext* context, xml::Node* node); - bool flatten(IAaptContext* context, xml::Node* node); + BigBuffer* buffer_; + XmlFlattenerOptions options_; }; } // namespace aapt diff --git a/tools/aapt2/flatten/XmlFlattener_test.cpp b/tools/aapt2/flatten/XmlFlattener_test.cpp index e0159cb5dc49..2c83bb384cc5 100644 --- a/tools/aapt2/flatten/XmlFlattener_test.cpp +++ b/tools/aapt2/flatten/XmlFlattener_test.cpp @@ -15,61 +15,62 @@ */ #include "flatten/XmlFlattener.h" + +#include "androidfw/ResourceTypes.h" + #include "link/Linkers.h" #include "test/Test.h" #include "util/BigBuffer.h" #include "util/Util.h" -#include <androidfw/ResourceTypes.h> - namespace aapt { class XmlFlattenerTest : public ::testing::Test { public: void SetUp() override { - mContext = + context_ = test::ContextBuilder() - .setCompilationPackage("com.app.test") - .setNameManglerPolicy(NameManglerPolicy{"com.app.test"}) - .addSymbolSource( + .SetCompilationPackage("com.app.test") + .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"}) + .AddSymbolSource( test::StaticSymbolSourceBuilder() - .addSymbol("android:attr/id", ResourceId(0x010100d0), - test::AttributeBuilder().build()) - .addSymbol("com.app.test:id/id", ResourceId(0x7f020000)) - .addSymbol("android:attr/paddingStart", + .AddSymbol("android:attr/id", ResourceId(0x010100d0), + test::AttributeBuilder().Build()) + .AddSymbol("com.app.test:id/id", ResourceId(0x7f020000)) + .AddSymbol("android:attr/paddingStart", ResourceId(0x010103b3), - test::AttributeBuilder().build()) - .addSymbol("android:attr/colorAccent", + test::AttributeBuilder().Build()) + .AddSymbol("android:attr/colorAccent", ResourceId(0x01010435), - test::AttributeBuilder().build()) - .build()) - .build(); + test::AttributeBuilder().Build()) + .Build()) + .Build(); } - ::testing::AssertionResult flatten(xml::XmlResource* doc, - android::ResXMLTree* outTree, + ::testing::AssertionResult Flatten(xml::XmlResource* doc, + android::ResXMLTree* out_tree, const XmlFlattenerOptions& options = {}) { using namespace android; // For NO_ERROR on windows because it is a macro. BigBuffer buffer(1024); XmlFlattener flattener(&buffer, options); - if (!flattener.consume(mContext.get(), doc)) { + if (!flattener.Consume(context_.get(), doc)) { return ::testing::AssertionFailure() << "failed to flatten XML Tree"; } - std::unique_ptr<uint8_t[]> data = util::copy(buffer); - if (outTree->setTo(data.get(), buffer.size(), true) != NO_ERROR) { + std::unique_ptr<uint8_t[]> data = util::Copy(buffer); + if (out_tree->setTo(data.get(), buffer.size(), true) != NO_ERROR) { return ::testing::AssertionFailure() << "flattened XML is corrupt"; } return ::testing::AssertionSuccess(); } protected: - std::unique_ptr<IAaptContext> mContext; + std::unique_ptr<IAaptContext> context_; }; TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) { - std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF( + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( <View xmlns:test="http://com.test" attr="hey"> <Layout test:hello="hi" /> @@ -77,27 +78,27 @@ TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) { </View>)EOF"); android::ResXMLTree tree; - ASSERT_TRUE(flatten(doc.get(), &tree)); + ASSERT_TRUE(Flatten(doc.get(), &tree)); ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE); size_t len; - const char16_t* namespacePrefix = tree.getNamespacePrefix(&len); - EXPECT_EQ(StringPiece16(namespacePrefix, len), u"test"); + const char16_t* namespace_prefix = tree.getNamespacePrefix(&len); + EXPECT_EQ(StringPiece16(namespace_prefix, len), u"test"); - const char16_t* namespaceUri = tree.getNamespaceUri(&len); - ASSERT_EQ(StringPiece16(namespaceUri, len), u"http://com.test"); + const char16_t* namespace_uri = tree.getNamespaceUri(&len); + ASSERT_EQ(StringPiece16(namespace_uri, len), u"http://com.test"); ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG); ASSERT_EQ(tree.getElementNamespace(&len), nullptr); - const char16_t* tagName = tree.getElementName(&len); - EXPECT_EQ(StringPiece16(tagName, len), u"View"); + const char16_t* tag_name = tree.getElementName(&len); + EXPECT_EQ(StringPiece16(tag_name, len), u"View"); ASSERT_EQ(1u, tree.getAttributeCount()); ASSERT_EQ(tree.getAttributeNamespace(0, &len), nullptr); - const char16_t* attrName = tree.getAttributeName(0, &len); - EXPECT_EQ(StringPiece16(attrName, len), u"attr"); + const char16_t* attr_name = tree.getAttributeName(0, &len); + EXPECT_EQ(StringPiece16(attr_name, len), u"attr"); EXPECT_EQ(0, tree.indexOfAttribute(nullptr, 0, u"attr", StringPiece16(u"attr").size())); @@ -105,22 +106,22 @@ TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) { ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG); ASSERT_EQ(tree.getElementNamespace(&len), nullptr); - tagName = tree.getElementName(&len); - EXPECT_EQ(StringPiece16(tagName, len), u"Layout"); + tag_name = tree.getElementName(&len); + EXPECT_EQ(StringPiece16(tag_name, len), u"Layout"); ASSERT_EQ(1u, tree.getAttributeCount()); - const char16_t* attrNamespace = tree.getAttributeNamespace(0, &len); - EXPECT_EQ(StringPiece16(attrNamespace, len), u"http://com.test"); + const char16_t* attr_namespace = tree.getAttributeNamespace(0, &len); + EXPECT_EQ(StringPiece16(attr_namespace, len), u"http://com.test"); - attrName = tree.getAttributeName(0, &len); - EXPECT_EQ(StringPiece16(attrName, len), u"hello"); + attr_name = tree.getAttributeName(0, &len); + EXPECT_EQ(StringPiece16(attr_name, len), u"hello"); ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG); ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG); ASSERT_EQ(tree.getElementNamespace(&len), nullptr); - tagName = tree.getElementName(&len); - EXPECT_EQ(StringPiece16(tagName, len), u"Layout"); + tag_name = tree.getElementName(&len); + EXPECT_EQ(StringPiece16(tag_name, len), u"Layout"); ASSERT_EQ(0u, tree.getAttributeCount()); ASSERT_EQ(tree.next(), android::ResXMLTree::TEXT); @@ -129,39 +130,39 @@ TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) { ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG); ASSERT_EQ(tree.getElementNamespace(&len), nullptr); - tagName = tree.getElementName(&len); - EXPECT_EQ(StringPiece16(tagName, len), u"Layout"); + tag_name = tree.getElementName(&len); + EXPECT_EQ(StringPiece16(tag_name, len), u"Layout"); ASSERT_EQ(tree.next(), android::ResXMLTree::END_TAG); ASSERT_EQ(tree.getElementNamespace(&len), nullptr); - tagName = tree.getElementName(&len); - EXPECT_EQ(StringPiece16(tagName, len), u"View"); + tag_name = tree.getElementName(&len); + EXPECT_EQ(StringPiece16(tag_name, len), u"View"); ASSERT_EQ(tree.next(), android::ResXMLTree::END_NAMESPACE); - namespacePrefix = tree.getNamespacePrefix(&len); - EXPECT_EQ(StringPiece16(namespacePrefix, len), u"test"); + namespace_prefix = tree.getNamespacePrefix(&len); + EXPECT_EQ(StringPiece16(namespace_prefix, len), u"test"); - namespaceUri = tree.getNamespaceUri(&len); - ASSERT_EQ(StringPiece16(namespaceUri, len), u"http://com.test"); + namespace_uri = tree.getNamespaceUri(&len); + ASSERT_EQ(StringPiece16(namespace_uri, len), u"http://com.test"); ASSERT_EQ(tree.next(), android::ResXMLTree::END_DOCUMENT); } TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripSdk21) { - std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF( + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" android:paddingStart="1dp" android:colorAccent="#ffffff"/>)EOF"); XmlReferenceLinker linker; - ASSERT_TRUE(linker.consume(mContext.get(), doc.get())); - ASSERT_TRUE(linker.getSdkLevels().count(17) == 1); - ASSERT_TRUE(linker.getSdkLevels().count(21) == 1); + ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); + ASSERT_TRUE(linker.sdk_levels().count(17) == 1); + ASSERT_TRUE(linker.sdk_levels().count(21) == 1); android::ResXMLTree tree; XmlFlattenerOptions options; - options.maxSdkLevel = 17; - ASSERT_TRUE(flatten(doc.get(), &tree, options)); + options.max_sdk_level = 17; + ASSERT_TRUE(Flatten(doc.get(), &tree, options)); while (tree.next() != android::ResXMLTree::START_TAG) { ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT); @@ -173,23 +174,23 @@ TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripSdk21) { } TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripOnlyTools) { - std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF( + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( <View xmlns:tools="http://schemas.android.com/tools" xmlns:foo="http://schemas.android.com/foo" foo:bar="Foo" tools:ignore="MissingTranslation"/>)EOF"); android::ResXMLTree tree; - ASSERT_TRUE(flatten(doc.get(), &tree)); + ASSERT_TRUE(Flatten(doc.get(), &tree)); ASSERT_EQ(tree.next(), android::ResXMLTree::START_NAMESPACE); size_t len; - const char16_t* namespacePrefix = tree.getNamespacePrefix(&len); - EXPECT_EQ(StringPiece16(namespacePrefix, len), u"foo"); + const char16_t* namespace_prefix = tree.getNamespacePrefix(&len); + EXPECT_EQ(StringPiece16(namespace_prefix, len), u"foo"); - const char16_t* namespaceUri = tree.getNamespaceUri(&len); - ASSERT_EQ(StringPiece16(namespaceUri, len), + const char16_t* namespace_uri = tree.getNamespaceUri(&len); + ASSERT_EQ(StringPiece16(namespace_uri, len), u"http://schemas.android.com/foo"); ASSERT_EQ(tree.next(), android::ResXMLTree::START_TAG); @@ -200,14 +201,14 @@ TEST_F(XmlFlattenerTest, FlattenCompiledXmlAndStripOnlyTools) { } TEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) { - std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(R"EOF( + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" android:id="@id/id" class="str" style="@id/id"/>)EOF"); android::ResXMLTree tree; - ASSERT_TRUE(flatten(doc.get(), &tree)); + ASSERT_TRUE(Flatten(doc.get(), &tree)); while (tree.next() != android::ResXMLTree::START_TAG) { ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT); @@ -225,10 +226,10 @@ TEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) { */ TEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDom("<View package=\"android\"/>"); + test::BuildXmlDom("<View package=\"android\"/>"); android::ResXMLTree tree; - ASSERT_TRUE(flatten(doc.get(), &tree)); + ASSERT_TRUE(Flatten(doc.get(), &tree)); while (tree.next() != android::ResXMLTree::START_TAG) { ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT); @@ -242,10 +243,10 @@ TEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) { TEST_F(XmlFlattenerTest, EmptyStringValueInAttributeIsNotNull) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDom("<View package=\"\"/>"); + test::BuildXmlDom("<View package=\"\"/>"); android::ResXMLTree tree; - ASSERT_TRUE(flatten(doc.get(), &tree)); + ASSERT_TRUE(Flatten(doc.get(), &tree)); while (tree.next() != android::ResXMLTree::START_TAG) { ASSERT_NE(tree.getEventType(), android::ResXMLTree::BAD_DOCUMENT); diff --git a/tools/aapt2/io/Data.h b/tools/aapt2/io/Data.h index 0479228b44e7..fdc044d86e5a 100644 --- a/tools/aapt2/io/Data.h +++ b/tools/aapt2/io/Data.h @@ -17,10 +17,11 @@ #ifndef AAPT_IO_DATA_H #define AAPT_IO_DATA_H -#include <android-base/macros.h> -#include <utils/FileMap.h> #include <memory> +#include "android-base/macros.h" +#include "utils/FileMap.h" + namespace aapt { namespace io { @@ -39,20 +40,20 @@ class IData { class DataSegment : public IData { public: explicit DataSegment(std::unique_ptr<IData> data, size_t offset, size_t len) - : mData(std::move(data)), mOffset(offset), mLen(len) {} + : data_(std::move(data)), offset_(offset), len_(len) {} const void* data() const override { - return static_cast<const uint8_t*>(mData->data()) + mOffset; + return static_cast<const uint8_t*>(data_->data()) + offset_; } - size_t size() const override { return mLen; } + size_t size() const override { return len_; } private: DISALLOW_COPY_AND_ASSIGN(DataSegment); - std::unique_ptr<IData> mData; - size_t mOffset; - size_t mLen; + std::unique_ptr<IData> data_; + size_t offset_; + size_t len_; }; /** @@ -63,14 +64,14 @@ class DataSegment : public IData { class MmappedData : public IData { public: explicit MmappedData(android::FileMap&& map) - : mMap(std::forward<android::FileMap>(map)) {} + : map_(std::forward<android::FileMap>(map)) {} - const void* data() const override { return mMap.getDataPtr(); } + const void* data() const override { return map_.getDataPtr(); } - size_t size() const override { return mMap.getDataLength(); } + size_t size() const override { return map_.getDataLength(); } private: - android::FileMap mMap; + android::FileMap map_; }; /** @@ -81,15 +82,15 @@ class MmappedData : public IData { class MallocData : public IData { public: MallocData(std::unique_ptr<const uint8_t[]> data, size_t size) - : mData(std::move(data)), mSize(size) {} + : data_(std::move(data)), size_(size) {} - const void* data() const override { return mData.get(); } + const void* data() const override { return data_.get(); } - size_t size() const override { return mSize; } + size_t size() const override { return size_; } private: - std::unique_ptr<const uint8_t[]> mData; - size_t mSize; + std::unique_ptr<const uint8_t[]> data_; + size_t size_; }; /** diff --git a/tools/aapt2/io/File.cpp b/tools/aapt2/io/File.cpp index 739c0d21e06e..ee737280ec81 100644 --- a/tools/aapt2/io/File.cpp +++ b/tools/aapt2/io/File.cpp @@ -21,23 +21,23 @@ namespace aapt { namespace io { -IFile* IFile::createFileSegment(size_t offset, size_t len) { - FileSegment* fileSegment = new FileSegment(this, offset, len); - mSegments.push_back(std::unique_ptr<IFile>(fileSegment)); - return fileSegment; +IFile* IFile::CreateFileSegment(size_t offset, size_t len) { + FileSegment* file_segment = new FileSegment(this, offset, len); + segments_.push_back(std::unique_ptr<IFile>(file_segment)); + return file_segment; } -std::unique_ptr<IData> FileSegment::openAsData() { - std::unique_ptr<IData> data = mFile->openAsData(); - if (!data) { - return {}; - } - - if (mOffset <= data->size() - mLen) { - return util::make_unique<DataSegment>(std::move(data), mOffset, mLen); - } +std::unique_ptr<IData> FileSegment::OpenAsData() { + std::unique_ptr<IData> data = file_->OpenAsData(); + if (!data) { return {}; + } + + if (offset_ <= data->size() - len_) { + return util::make_unique<DataSegment>(std::move(data), offset_, len_); + } + return {}; } -} // namespace io -} // namespace aapt +} // namespace io +} // namespace aapt diff --git a/tools/aapt2/io/File.h b/tools/aapt2/io/File.h index 012f44631a9f..644f59f8f3ba 100644 --- a/tools/aapt2/io/File.h +++ b/tools/aapt2/io/File.h @@ -17,15 +17,16 @@ #ifndef AAPT_IO_FILE_H #define AAPT_IO_FILE_H -#include "Source.h" -#include "io/Data.h" -#include "util/Util.h" - -#include <android-base/macros.h> #include <list> #include <memory> #include <vector> +#include "android-base/macros.h" + +#include "Source.h" +#include "io/Data.h" +#include "util/Util.h" + namespace aapt { namespace io { @@ -49,7 +50,7 @@ class IFile { * * Returns nullptr on failure. */ - virtual std::unique_ptr<IData> openAsData() = 0; + virtual std::unique_ptr<IData> OpenAsData() = 0; /** * Returns the source of this file. This is for presentation to the user and @@ -58,9 +59,9 @@ class IFile { * the files within * a ZIP archive from the path to the containing ZIP archive. */ - virtual const Source& getSource() const = 0; + virtual const Source& GetSource() const = 0; - IFile* createFileSegment(size_t offset, size_t len); + IFile* CreateFileSegment(size_t offset, size_t len); private: // Any segments created from this IFile need to be owned by this IFile, so @@ -68,7 +69,7 @@ class IFile { // in a list. This will never be read, so we prefer better insertion // performance // than cache locality, hence the list. - std::list<std::unique_ptr<IFile>> mSegments; + std::list<std::unique_ptr<IFile>> segments_; }; /** @@ -78,26 +79,26 @@ class IFile { class FileSegment : public IFile { public: explicit FileSegment(IFile* file, size_t offset, size_t len) - : mFile(file), mOffset(offset), mLen(len) {} + : file_(file), offset_(offset), len_(len) {} - std::unique_ptr<IData> openAsData() override; + std::unique_ptr<IData> OpenAsData() override; - const Source& getSource() const override { return mFile->getSource(); } + const Source& GetSource() const override { return file_->GetSource(); } private: DISALLOW_COPY_AND_ASSIGN(FileSegment); - IFile* mFile; - size_t mOffset; - size_t mLen; + IFile* file_; + size_t offset_; + size_t len_; }; class IFileCollectionIterator { public: virtual ~IFileCollectionIterator() = default; - virtual bool hasNext() = 0; - virtual IFile* next() = 0; + virtual bool HasNext() = 0; + virtual IFile* Next() = 0; }; /** @@ -109,8 +110,8 @@ class IFileCollection { public: virtual ~IFileCollection() = default; - virtual IFile* findFile(const StringPiece& path) = 0; - virtual std::unique_ptr<IFileCollectionIterator> iterator() = 0; + virtual IFile* FindFile(const StringPiece& path) = 0; + virtual std::unique_ptr<IFileCollectionIterator> Iterator() = 0; }; } // namespace io diff --git a/tools/aapt2/io/FileSystem.cpp b/tools/aapt2/io/FileSystem.cpp index e758d8a421e1..828f34e9c883 100644 --- a/tools/aapt2/io/FileSystem.cpp +++ b/tools/aapt2/io/FileSystem.cpp @@ -14,65 +14,62 @@ * limitations under the License. */ -#include "Source.h" #include "io/FileSystem.h" + +#include "utils/FileMap.h" + +#include "Source.h" #include "util/Files.h" #include "util/Maybe.h" #include "util/StringPiece.h" #include "util/Util.h" -#include <utils/FileMap.h> - namespace aapt { namespace io { -RegularFile::RegularFile(const Source& source) : mSource(source) { -} +RegularFile::RegularFile(const Source& source) : source_(source) {} -std::unique_ptr<IData> RegularFile::openAsData() { - android::FileMap map; - if (Maybe<android::FileMap> map = file::mmapPath(mSource.path, nullptr)) { - if (map.value().getDataPtr() && map.value().getDataLength() > 0) { - return util::make_unique<MmappedData>(std::move(map.value())); - } - return util::make_unique<EmptyData>(); +std::unique_ptr<IData> RegularFile::OpenAsData() { + android::FileMap map; + if (Maybe<android::FileMap> map = file::MmapPath(source_.path, nullptr)) { + if (map.value().getDataPtr() && map.value().getDataLength() > 0) { + return util::make_unique<MmappedData>(std::move(map.value())); } - return {}; + return util::make_unique<EmptyData>(); + } + return {}; } -const Source& RegularFile::getSource() const { - return mSource; -} +const Source& RegularFile::GetSource() const { return source_; } -FileCollectionIterator::FileCollectionIterator(FileCollection* collection) : - mCurrent(collection->mFiles.begin()), mEnd(collection->mFiles.end()) { -} +FileCollectionIterator::FileCollectionIterator(FileCollection* collection) + : current_(collection->files_.begin()), end_(collection->files_.end()) {} -bool FileCollectionIterator::hasNext() { - return mCurrent != mEnd; -} +bool FileCollectionIterator::HasNext() { return current_ != end_; } -IFile* FileCollectionIterator::next() { - IFile* result = mCurrent->second.get(); - ++mCurrent; - return result; +IFile* FileCollectionIterator::Next() { + IFile* result = current_->second.get(); + ++current_; + return result; } -IFile* FileCollection::insertFile(const StringPiece& path) { - return (mFiles[path.toString()] = util::make_unique<RegularFile>(Source(path))).get(); +IFile* FileCollection::InsertFile(const StringPiece& path) { + return (files_[path.ToString()] = + util::make_unique<RegularFile>(Source(path))) + .get(); } -IFile* FileCollection::findFile(const StringPiece& path) { - auto iter = mFiles.find(path.toString()); - if (iter != mFiles.end()) { - return iter->second.get(); - } - return nullptr; +IFile* FileCollection::FindFile(const StringPiece& path) { + auto iter = files_.find(path.ToString()); + if (iter != files_.end()) { + return iter->second.get(); + } + return nullptr; } -std::unique_ptr<IFileCollectionIterator> FileCollection::iterator() { - return util::make_unique<FileCollectionIterator>(this); +std::unique_ptr<IFileCollectionIterator> FileCollection::Iterator() { + return util::make_unique<FileCollectionIterator>(this); } -} // namespace io -} // namespace aapt +} // namespace io +} // namespace aapt diff --git a/tools/aapt2/io/FileSystem.h b/tools/aapt2/io/FileSystem.h index 8584d486685c..84f851ff694b 100644 --- a/tools/aapt2/io/FileSystem.h +++ b/tools/aapt2/io/FileSystem.h @@ -17,10 +17,10 @@ #ifndef AAPT_IO_FILESYSTEM_H #define AAPT_IO_FILESYSTEM_H -#include "io/File.h" - #include <map> +#include "io/File.h" + namespace aapt { namespace io { @@ -31,11 +31,11 @@ class RegularFile : public IFile { public: explicit RegularFile(const Source& source); - std::unique_ptr<IData> openAsData() override; - const Source& getSource() const override; + std::unique_ptr<IData> OpenAsData() override; + const Source& GetSource() const override; private: - Source mSource; + Source source_; }; class FileCollection; @@ -44,11 +44,11 @@ class FileCollectionIterator : public IFileCollectionIterator { public: explicit FileCollectionIterator(FileCollection* collection); - bool hasNext() override; - io::IFile* next() override; + bool HasNext() override; + io::IFile* Next() override; private: - std::map<std::string, std::unique_ptr<IFile>>::const_iterator mCurrent, mEnd; + std::map<std::string, std::unique_ptr<IFile>>::const_iterator current_, end_; }; /** @@ -59,13 +59,13 @@ class FileCollection : public IFileCollection { /** * Adds a file located at path. Returns the IFile representation of that file. */ - IFile* insertFile(const StringPiece& path); - IFile* findFile(const StringPiece& path) override; - std::unique_ptr<IFileCollectionIterator> iterator() override; + IFile* InsertFile(const StringPiece& path); + IFile* FindFile(const StringPiece& path) override; + std::unique_ptr<IFileCollectionIterator> Iterator() override; private: friend class FileCollectionIterator; - std::map<std::string, std::unique_ptr<IFile>> mFiles; + std::map<std::string, std::unique_ptr<IFile>> files_; }; } // namespace io diff --git a/tools/aapt2/io/Io.cpp b/tools/aapt2/io/Io.cpp index 963c21c31806..cab4b65f2f5a 100644 --- a/tools/aapt2/io/Io.cpp +++ b/tools/aapt2/io/Io.cpp @@ -22,23 +22,23 @@ namespace aapt { namespace io { -bool copy(OutputStream* out, InputStream* in) { - const void* inBuffer; - int inLen; - while (in->Next(&inBuffer, &inLen)) { - void* outBuffer; - int outLen; - if (!out->Next(&outBuffer, &outLen)) { - return !out->HadError(); - } - - const int bytesToCopy = std::min(inLen, outLen); - memcpy(outBuffer, inBuffer, bytesToCopy); - out->BackUp(outLen - bytesToCopy); - in->BackUp(inLen - bytesToCopy); +bool Copy(OutputStream* out, InputStream* in) { + const void* in_buffer; + int in_len; + while (in->Next(&in_buffer, &in_len)) { + void* out_buffer; + int out_len; + if (!out->Next(&out_buffer, &out_len)) { + return !out->HadError(); } - return !in->HadError(); + + const int bytes_to_copy = std::min(in_len, out_len); + memcpy(out_buffer, in_buffer, bytes_to_copy); + out->BackUp(out_len - bytes_to_copy); + in->BackUp(in_len - bytes_to_copy); + } + return !in->HadError(); } -} // namespace io -} // namespace aapt +} // namespace io +} // namespace aapt diff --git a/tools/aapt2/io/Io.h b/tools/aapt2/io/Io.h index 49b9fc36e293..33cdc7bbe498 100644 --- a/tools/aapt2/io/Io.h +++ b/tools/aapt2/io/Io.h @@ -17,9 +17,10 @@ #ifndef AAPT_IO_IO_H #define AAPT_IO_IO_H -#include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include <string> +#include "google/protobuf/io/zero_copy_stream_impl_lite.h" + namespace aapt { namespace io { @@ -29,7 +30,7 @@ namespace io { * * The code style here matches the protobuf style. */ -class InputStream : public google::protobuf::io::ZeroCopyInputStream { +class InputStream : public ::google::protobuf::io::ZeroCopyInputStream { public: virtual std::string GetError() const { return {}; } @@ -42,7 +43,7 @@ class InputStream : public google::protobuf::io::ZeroCopyInputStream { * * The code style here matches the protobuf style. */ -class OutputStream : public google::protobuf::io::ZeroCopyOutputStream { +class OutputStream : public ::google::protobuf::io::ZeroCopyOutputStream { public: virtual std::string GetError() const { return {}; } @@ -54,7 +55,7 @@ class OutputStream : public google::protobuf::io::ZeroCopyOutputStream { * If there was an error, check the individual streams' HadError/GetError * methods. */ -bool copy(OutputStream* out, InputStream* in); +bool Copy(OutputStream* out, InputStream* in); } // namespace io } // namespace aapt diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp index b3e7a02102e4..f4a128eca9d1 100644 --- a/tools/aapt2/io/ZipArchive.cpp +++ b/tools/aapt2/io/ZipArchive.cpp @@ -14,129 +14,128 @@ * limitations under the License. */ -#include "Source.h" #include "io/ZipArchive.h" -#include "util/Util.h" -#include <utils/FileMap.h> -#include <ziparchive/zip_archive.h> +#include "utils/FileMap.h" +#include "ziparchive/zip_archive.h" + +#include "Source.h" +#include "util/Util.h" namespace aapt { namespace io { -ZipFile::ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source) : - mZipHandle(handle), mZipEntry(entry), mSource(source) { -} +ZipFile::ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, + const Source& source) + : zip_handle_(handle), zip_entry_(entry), source_(source) {} -std::unique_ptr<IData> ZipFile::openAsData() { - if (mZipEntry.method == kCompressStored) { - int fd = GetFileDescriptor(mZipHandle); - - android::FileMap fileMap; - bool result = fileMap.create(nullptr, fd, mZipEntry.offset, - mZipEntry.uncompressed_length, true); - if (!result) { - return {}; - } - return util::make_unique<MmappedData>(std::move(fileMap)); - - } else { - std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>( - new uint8_t[mZipEntry.uncompressed_length]); - int32_t result = ExtractToMemory(mZipHandle, &mZipEntry, data.get(), - static_cast<uint32_t>(mZipEntry.uncompressed_length)); - if (result != 0) { - return {}; - } - return util::make_unique<MallocData>(std::move(data), mZipEntry.uncompressed_length); - } -} +std::unique_ptr<IData> ZipFile::OpenAsData() { + if (zip_entry_.method == kCompressStored) { + int fd = GetFileDescriptor(zip_handle_); -const Source& ZipFile::getSource() const { - return mSource; + android::FileMap file_map; + bool result = file_map.create(nullptr, fd, zip_entry_.offset, + zip_entry_.uncompressed_length, true); + if (!result) { + return {}; + } + return util::make_unique<MmappedData>(std::move(file_map)); + + } else { + std::unique_ptr<uint8_t[]> data = + std::unique_ptr<uint8_t[]>(new uint8_t[zip_entry_.uncompressed_length]); + int32_t result = + ExtractToMemory(zip_handle_, &zip_entry_, data.get(), + static_cast<uint32_t>(zip_entry_.uncompressed_length)); + if (result != 0) { + return {}; + } + return util::make_unique<MallocData>(std::move(data), + zip_entry_.uncompressed_length); + } } -ZipFileCollectionIterator::ZipFileCollectionIterator(ZipFileCollection* collection) : - mCurrent(collection->mFiles.begin()), mEnd(collection->mFiles.end()) { -} +const Source& ZipFile::GetSource() const { return source_; } -bool ZipFileCollectionIterator::hasNext() { - return mCurrent != mEnd; -} +ZipFileCollectionIterator::ZipFileCollectionIterator( + ZipFileCollection* collection) + : current_(collection->files_.begin()), end_(collection->files_.end()) {} -IFile* ZipFileCollectionIterator::next() { - IFile* result = mCurrent->second.get(); - ++mCurrent; - return result; -} +bool ZipFileCollectionIterator::HasNext() { return current_ != end_; } -ZipFileCollection::ZipFileCollection() : mHandle(nullptr) { +IFile* ZipFileCollectionIterator::Next() { + IFile* result = current_->second.get(); + ++current_; + return result; } -std::unique_ptr<ZipFileCollection> ZipFileCollection::create(const StringPiece& path, - std::string* outError) { - constexpr static const int32_t kEmptyArchive = -6; +ZipFileCollection::ZipFileCollection() : handle_(nullptr) {} - std::unique_ptr<ZipFileCollection> collection = std::unique_ptr<ZipFileCollection>( - new ZipFileCollection()); +std::unique_ptr<ZipFileCollection> ZipFileCollection::Create( + const StringPiece& path, std::string* out_error) { + constexpr static const int32_t kEmptyArchive = -6; - int32_t result = OpenArchive(path.data(), &collection->mHandle); - if (result != 0) { - // If a zip is empty, result will be an error code. This is fine and we should - // return an empty ZipFileCollection. - if (result == kEmptyArchive) { - return collection; - } - - if (outError) *outError = ErrorCodeString(result); - return {}; - } + std::unique_ptr<ZipFileCollection> collection = + std::unique_ptr<ZipFileCollection>(new ZipFileCollection()); - void* cookie = nullptr; - result = StartIteration(collection->mHandle, &cookie, nullptr, nullptr); - if (result != 0) { - if (outError) *outError = ErrorCodeString(result); - return {}; + int32_t result = OpenArchive(path.data(), &collection->handle_); + if (result != 0) { + // If a zip is empty, result will be an error code. This is fine and we + // should + // return an empty ZipFileCollection. + if (result == kEmptyArchive) { + return collection; } - using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>; - IterationEnder iterationEnder(cookie, EndIteration); - - ZipString zipEntryName; - ZipEntry zipData; - while ((result = Next(cookie, &zipData, &zipEntryName)) == 0) { - std::string zipEntryPath = std::string(reinterpret_cast<const char*>(zipEntryName.name), - zipEntryName.name_length); - std::string nestedPath = path.toString() + "@" + zipEntryPath; - collection->mFiles[zipEntryPath] = util::make_unique<ZipFile>(collection->mHandle, - zipData, - Source(nestedPath)); - } - - if (result != -1) { - if (outError) *outError = ErrorCodeString(result); - return {}; - } - return collection; + if (out_error) *out_error = ErrorCodeString(result); + return {}; + } + + void* cookie = nullptr; + result = StartIteration(collection->handle_, &cookie, nullptr, nullptr); + if (result != 0) { + if (out_error) *out_error = ErrorCodeString(result); + return {}; + } + + using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>; + IterationEnder iteration_ender(cookie, EndIteration); + + ZipString zip_entry_name; + ZipEntry zip_data; + while ((result = Next(cookie, &zip_data, &zip_entry_name)) == 0) { + std::string zip_entry_path = + std::string(reinterpret_cast<const char*>(zip_entry_name.name), + zip_entry_name.name_length); + std::string nested_path = path.ToString() + "@" + zip_entry_path; + collection->files_[zip_entry_path] = util::make_unique<ZipFile>( + collection->handle_, zip_data, Source(nested_path)); + } + + if (result != -1) { + if (out_error) *out_error = ErrorCodeString(result); + return {}; + } + return collection; } -IFile* ZipFileCollection::findFile(const StringPiece& path) { - auto iter = mFiles.find(path.toString()); - if (iter != mFiles.end()) { - return iter->second.get(); - } - return nullptr; +IFile* ZipFileCollection::FindFile(const StringPiece& path) { + auto iter = files_.find(path.ToString()); + if (iter != files_.end()) { + return iter->second.get(); + } + return nullptr; } -std::unique_ptr<IFileCollectionIterator> ZipFileCollection::iterator() { - return util::make_unique<ZipFileCollectionIterator>(this); +std::unique_ptr<IFileCollectionIterator> ZipFileCollection::Iterator() { + return util::make_unique<ZipFileCollectionIterator>(this); } ZipFileCollection::~ZipFileCollection() { - if (mHandle) { - CloseArchive(mHandle); - } + if (handle_) { + CloseArchive(handle_); + } } -} // namespace io -} // namespace aapt +} // namespace io +} // namespace aapt diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h index e04525f51f4b..85ca1aed4edc 100644 --- a/tools/aapt2/io/ZipArchive.h +++ b/tools/aapt2/io/ZipArchive.h @@ -17,12 +17,13 @@ #ifndef AAPT_IO_ZIPARCHIVE_H #define AAPT_IO_ZIPARCHIVE_H -#include "io/File.h" -#include "util/StringPiece.h" +#include "ziparchive/zip_archive.h" -#include <ziparchive/zip_archive.h> #include <map> +#include "io/File.h" +#include "util/StringPiece.h" + namespace aapt { namespace io { @@ -36,13 +37,13 @@ class ZipFile : public IFile { public: ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source); - std::unique_ptr<IData> openAsData() override; - const Source& getSource() const override; + std::unique_ptr<IData> OpenAsData() override; + const Source& GetSource() const override; private: - ZipArchiveHandle mZipHandle; - ZipEntry mZipEntry; - Source mSource; + ZipArchiveHandle zip_handle_; + ZipEntry zip_entry_; + Source source_; }; class ZipFileCollection; @@ -51,11 +52,11 @@ class ZipFileCollectionIterator : public IFileCollectionIterator { public: explicit ZipFileCollectionIterator(ZipFileCollection* collection); - bool hasNext() override; - io::IFile* next() override; + bool HasNext() override; + io::IFile* Next() override; private: - std::map<std::string, std::unique_ptr<IFile>>::const_iterator mCurrent, mEnd; + std::map<std::string, std::unique_ptr<IFile>>::const_iterator current_, end_; }; /** @@ -63,11 +64,11 @@ class ZipFileCollectionIterator : public IFileCollectionIterator { */ class ZipFileCollection : public IFileCollection { public: - static std::unique_ptr<ZipFileCollection> create(const StringPiece& path, + static std::unique_ptr<ZipFileCollection> Create(const StringPiece& path, std::string* outError); - io::IFile* findFile(const StringPiece& path) override; - std::unique_ptr<IFileCollectionIterator> iterator() override; + io::IFile* FindFile(const StringPiece& path) override; + std::unique_ptr<IFileCollectionIterator> Iterator() override; ~ZipFileCollection() override; @@ -75,8 +76,8 @@ class ZipFileCollection : public IFileCollection { friend class ZipFileCollectionIterator; ZipFileCollection(); - ZipArchiveHandle mHandle; - std::map<std::string, std::unique_ptr<IFile>> mFiles; + ZipArchiveHandle handle_; + std::map<std::string, std::unique_ptr<IFile>> files_; }; } // namespace io diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp index 23ff8abf8950..2951e5cff6d7 100644 --- a/tools/aapt2/java/AnnotationProcessor.cpp +++ b/tools/aapt2/java/AnnotationProcessor.cpp @@ -15,69 +15,71 @@ */ #include "java/AnnotationProcessor.h" -#include "util/Util.h" #include <algorithm> +#include "util/Util.h" + namespace aapt { -void AnnotationProcessor::appendCommentLine(std::string& comment) { - static const std::string sDeprecated = "@deprecated"; - static const std::string sSystemApi = "@SystemApi"; +void AnnotationProcessor::AppendCommentLine(std::string& comment) { + static const std::string sDeprecated = "@deprecated"; + static const std::string sSystemApi = "@SystemApi"; - if (comment.find(sDeprecated) != std::string::npos) { - mAnnotationBitMask |= kDeprecated; - } + if (comment.find(sDeprecated) != std::string::npos) { + annotation_bit_mask_ |= kDeprecated; + } - std::string::size_type idx = comment.find(sSystemApi); - if (idx != std::string::npos) { - mAnnotationBitMask |= kSystemApi; - comment.erase(comment.begin() + idx, comment.begin() + idx + sSystemApi.size()); - } + std::string::size_type idx = comment.find(sSystemApi); + if (idx != std::string::npos) { + annotation_bit_mask_ |= kSystemApi; + comment.erase(comment.begin() + idx, + comment.begin() + idx + sSystemApi.size()); + } - if (util::trimWhitespace(comment).empty()) { - return; - } + if (util::TrimWhitespace(comment).empty()) { + return; + } - if (!mHasComments) { - mHasComments = true; - mComment << "/**"; - } + if (!has_comments_) { + has_comments_ = true; + comment_ << "/**"; + } - mComment << "\n * " << std::move(comment); + comment_ << "\n * " << std::move(comment); } -void AnnotationProcessor::appendComment(const StringPiece& comment) { - // We need to process line by line to clean-up whitespace and append prefixes. - for (StringPiece line : util::tokenize(comment, '\n')) { - line = util::trimWhitespace(line); - if (!line.empty()) { - std::string lineCopy = line.toString(); - appendCommentLine(lineCopy); - } +void AnnotationProcessor::AppendComment(const StringPiece& comment) { + // We need to process line by line to clean-up whitespace and append prefixes. + for (StringPiece line : util::Tokenize(comment, '\n')) { + line = util::TrimWhitespace(line); + if (!line.empty()) { + std::string lineCopy = line.ToString(); + AppendCommentLine(lineCopy); } + } } -void AnnotationProcessor::appendNewLine() { - mComment << "\n *"; -} +void AnnotationProcessor::AppendNewLine() { comment_ << "\n *"; } -void AnnotationProcessor::writeToStream(std::ostream* out, const StringPiece& prefix) const { - if (mHasComments) { - std::string result = mComment.str(); - for (StringPiece line : util::tokenize(result, '\n')) { - *out << prefix << line << "\n"; - } - *out << prefix << " */" << "\n"; +void AnnotationProcessor::WriteToStream(std::ostream* out, + const StringPiece& prefix) const { + if (has_comments_) { + std::string result = comment_.str(); + for (StringPiece line : util::Tokenize(result, '\n')) { + *out << prefix << line << "\n"; } + *out << prefix << " */" + << "\n"; + } - if (mAnnotationBitMask & kDeprecated) { - *out << prefix << "@Deprecated\n"; - } + if (annotation_bit_mask_ & kDeprecated) { + *out << prefix << "@Deprecated\n"; + } - if (mAnnotationBitMask & kSystemApi) { - *out << prefix << "@android.annotation.SystemApi\n"; - } + if (annotation_bit_mask_ & kSystemApi) { + *out << prefix << "@android.annotation.SystemApi\n"; + } } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/java/AnnotationProcessor.h b/tools/aapt2/java/AnnotationProcessor.h index 54196085db17..666a7f356768 100644 --- a/tools/aapt2/java/AnnotationProcessor.h +++ b/tools/aapt2/java/AnnotationProcessor.h @@ -17,11 +17,11 @@ #ifndef AAPT_JAVA_ANNOTATIONPROCESSOR_H #define AAPT_JAVA_ANNOTATIONPROCESSOR_H -#include "util/StringPiece.h" - #include <sstream> #include <string> +#include "util/StringPiece.h" + namespace aapt { /** @@ -58,15 +58,15 @@ class AnnotationProcessor { * configurations, * we need to collect all the comments. */ - void appendComment(const StringPiece& comment); + void AppendComment(const StringPiece& comment); - void appendNewLine(); + void AppendNewLine(); /** * Writes the comments and annotations to the stream, with the given prefix * before each line. */ - void writeToStream(std::ostream* out, const StringPiece& prefix) const; + void WriteToStream(std::ostream* out, const StringPiece& prefix) const; private: enum : uint32_t { @@ -74,12 +74,12 @@ class AnnotationProcessor { kSystemApi = 0x02, }; - std::stringstream mComment; + std::stringstream comment_; std::stringstream mAnnotations; - bool mHasComments = false; - uint32_t mAnnotationBitMask = 0; + bool has_comments_ = false; + uint32_t annotation_bit_mask_ = 0; - void appendCommentLine(std::string& line); + void AppendCommentLine(std::string& line); }; } // namespace aapt diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp index 5a39add48fbd..3e43c4295c07 100644 --- a/tools/aapt2/java/AnnotationProcessor_test.cpp +++ b/tools/aapt2/java/AnnotationProcessor_test.cpp @@ -15,38 +15,39 @@ */ #include "java/AnnotationProcessor.h" + #include "test/Test.h" namespace aapt { TEST(AnnotationProcessorTest, EmitsDeprecated) { - const char* comment = "Some comment, and it should contain a marker word, " - "something that marks this resource as nor needed. " - "{@deprecated That's the marker! }"; + const char* comment = + "Some comment, and it should contain a marker word, " + "something that marks this resource as nor needed. " + "{@deprecated That's the marker! }"; - AnnotationProcessor processor; - processor.appendComment(comment); + AnnotationProcessor processor; + processor.AppendComment(comment); - std::stringstream result; - processor.writeToStream(&result, ""); - std::string annotations = result.str(); + std::stringstream result; + processor.WriteToStream(&result, ""); + std::string annotations = result.str(); - EXPECT_NE(std::string::npos, annotations.find("@Deprecated")); + EXPECT_NE(std::string::npos, annotations.find("@Deprecated")); } TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationAndRemovesFromComment) { - AnnotationProcessor processor; - processor.appendComment("@SystemApi This is a system API"); + AnnotationProcessor processor; + processor.AppendComment("@SystemApi This is a system API"); - std::stringstream result; - processor.writeToStream(&result, ""); - std::string annotations = result.str(); + std::stringstream result; + processor.WriteToStream(&result, ""); + std::string annotations = result.str(); - EXPECT_NE(std::string::npos, annotations.find("@android.annotation.SystemApi")); - EXPECT_EQ(std::string::npos, annotations.find("@SystemApi")); - EXPECT_NE(std::string::npos, annotations.find("This is a system API")); + EXPECT_NE(std::string::npos, + annotations.find("@android.annotation.SystemApi")); + EXPECT_EQ(std::string::npos, annotations.find("@SystemApi")); + EXPECT_NE(std::string::npos, annotations.find("This is a system API")); } -} // namespace aapt - - +} // namespace aapt diff --git a/tools/aapt2/java/ClassDefinition.cpp b/tools/aapt2/java/ClassDefinition.cpp index 08f2c8b9805c..f1f1f925480c 100644 --- a/tools/aapt2/java/ClassDefinition.cpp +++ b/tools/aapt2/java/ClassDefinition.cpp @@ -15,61 +15,59 @@ */ #include "java/ClassDefinition.h" -#include "util/StringPiece.h" -#include <ostream> +#include "util/StringPiece.h" namespace aapt { bool ClassDefinition::empty() const { - for (const std::unique_ptr<ClassMember>& member : mMembers) { - if (!member->empty()) { - return false; - } + for (const std::unique_ptr<ClassMember>& member : members_) { + if (!member->empty()) { + return false; } - return true; + } + return true; } -void ClassDefinition::writeToStream(const StringPiece& prefix, bool final, +void ClassDefinition::WriteToStream(const StringPiece& prefix, bool final, std::ostream* out) const { - if (mMembers.empty() && !mCreateIfEmpty) { - return; - } + if (members_.empty() && !create_if_empty_) { + return; + } - ClassMember::writeToStream(prefix, final, out); + ClassMember::WriteToStream(prefix, final, out); - *out << prefix << "public "; - if (mQualifier == ClassQualifier::Static) { - *out << "static "; - } - *out << "final class " << mName << " {\n"; + *out << prefix << "public "; + if (qualifier_ == ClassQualifier::Static) { + *out << "static "; + } + *out << "final class " << name_ << " {\n"; - std::string newPrefix = prefix.toString(); - newPrefix.append(kIndent); + std::string new_prefix = prefix.ToString(); + new_prefix.append(kIndent); - for (const std::unique_ptr<ClassMember>& member : mMembers) { - member->writeToStream(newPrefix, final, out); - *out << "\n"; - } + for (const std::unique_ptr<ClassMember>& member : members_) { + member->WriteToStream(new_prefix, final, out); + *out << "\n"; + } - *out << prefix << "}"; + *out << prefix << "}"; } constexpr static const char* sWarningHeader = - "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n" - " *\n" - " * This class was automatically generated by the\n" - " * aapt tool from the resource data it found. It\n" - " * should not be modified by hand.\n" - " */\n\n"; + "/* AUTO-GENERATED FILE. DO NOT MODIFY.\n" + " *\n" + " * This class was automatically generated by the\n" + " * aapt tool from the resource data it found. It\n" + " * should not be modified by hand.\n" + " */\n\n"; -bool ClassDefinition::writeJavaFile(const ClassDefinition* def, - const StringPiece& package, - bool final, +bool ClassDefinition::WriteJavaFile(const ClassDefinition* def, + const StringPiece& package, bool final, std::ostream* out) { - *out << sWarningHeader << "package " << package << ";\n\n"; - def->writeToStream("", final, out); - return bool(*out); + *out << sWarningHeader << "package " << package << ";\n\n"; + def->WriteToStream("", final, out); + return bool(*out); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h index bd7e7b277fe5..d8b61d919fd8 100644 --- a/tools/aapt2/java/ClassDefinition.h +++ b/tools/aapt2/java/ClassDefinition.h @@ -17,15 +17,16 @@ #ifndef AAPT_JAVA_CLASSDEFINITION_H #define AAPT_JAVA_CLASSDEFINITION_H +#include <ostream> +#include <string> + +#include "android-base/macros.h" + #include "Resource.h" #include "java/AnnotationProcessor.h" #include "util/StringPiece.h" #include "util/Util.h" -#include <android-base/macros.h> -#include <sstream> -#include <string> - namespace aapt { // The number of attributes to emit per line in a Styleable array. @@ -36,38 +37,38 @@ class ClassMember { public: virtual ~ClassMember() = default; - AnnotationProcessor* getCommentBuilder() { return &mProcessor; } + AnnotationProcessor* GetCommentBuilder() { return &processor_; } virtual bool empty() const = 0; - virtual void writeToStream(const StringPiece& prefix, bool final, + virtual void WriteToStream(const StringPiece& prefix, bool final, std::ostream* out) const { - mProcessor.writeToStream(out, prefix); + processor_.WriteToStream(out, prefix); } private: - AnnotationProcessor mProcessor; + AnnotationProcessor processor_; }; template <typename T> class PrimitiveMember : public ClassMember { public: PrimitiveMember(const StringPiece& name, const T& val) - : mName(name.toString()), mVal(val) {} + : name_(name.ToString()), val_(val) {} bool empty() const override { return false; } - void writeToStream(const StringPiece& prefix, bool final, + void WriteToStream(const StringPiece& prefix, bool final, std::ostream* out) const override { - ClassMember::writeToStream(prefix, final, out); + ClassMember::WriteToStream(prefix, final, out); *out << prefix << "public static " << (final ? "final " : "") << "int " - << mName << "=" << mVal << ";"; + << name_ << "=" << val_ << ";"; } private: - std::string mName; - T mVal; + std::string name_; + T val_; DISALLOW_COPY_AND_ASSIGN(PrimitiveMember); }; @@ -79,21 +80,21 @@ template <> class PrimitiveMember<std::string> : public ClassMember { public: PrimitiveMember(const StringPiece& name, const std::string& val) - : mName(name.toString()), mVal(val) {} + : name_(name.ToString()), val_(val) {} bool empty() const override { return false; } - void writeToStream(const StringPiece& prefix, bool final, + void WriteToStream(const StringPiece& prefix, bool final, std::ostream* out) const override { - ClassMember::writeToStream(prefix, final, out); + ClassMember::WriteToStream(prefix, final, out); *out << prefix << "public static " << (final ? "final " : "") << "String " - << mName << "=\"" << mVal << "\";"; + << name_ << "=\"" << val_ << "\";"; } private: - std::string mName; - std::string mVal; + std::string name_; + std::string val_; DISALLOW_COPY_AND_ASSIGN(PrimitiveMember); }; @@ -106,20 +107,20 @@ template <typename T> class PrimitiveArrayMember : public ClassMember { public: explicit PrimitiveArrayMember(const StringPiece& name) - : mName(name.toString()) {} + : name_(name.ToString()) {} - void addElement(const T& val) { mElements.push_back(val); } + void AddElement(const T& val) { elements_.push_back(val); } bool empty() const override { return false; } - void writeToStream(const StringPiece& prefix, bool final, + void WriteToStream(const StringPiece& prefix, bool final, std::ostream* out) const override { - ClassMember::writeToStream(prefix, final, out); + ClassMember::WriteToStream(prefix, final, out); - *out << prefix << "public static final int[] " << mName << "={"; + *out << prefix << "public static final int[] " << name_ << "={"; - const auto begin = mElements.begin(); - const auto end = mElements.end(); + const auto begin = elements_.begin(); + const auto end = elements_.end(); for (auto current = begin; current != end; ++current) { if (std::distance(begin, current) % kAttribsPerLine == 0) { *out << "\n" << prefix << kIndent << kIndent; @@ -134,8 +135,8 @@ class PrimitiveArrayMember : public ClassMember { } private: - std::string mName; - std::vector<T> mElements; + std::string name_; + std::vector<T> elements_; DISALLOW_COPY_AND_ASSIGN(PrimitiveArrayMember); }; @@ -146,29 +147,29 @@ enum class ClassQualifier { None, Static }; class ClassDefinition : public ClassMember { public: - static bool writeJavaFile(const ClassDefinition* def, + static bool WriteJavaFile(const ClassDefinition* def, const StringPiece& package, bool final, std::ostream* out); ClassDefinition(const StringPiece& name, ClassQualifier qualifier, bool createIfEmpty) - : mName(name.toString()), - mQualifier(qualifier), - mCreateIfEmpty(createIfEmpty) {} + : name_(name.ToString()), + qualifier_(qualifier), + create_if_empty_(createIfEmpty) {} - void addMember(std::unique_ptr<ClassMember> member) { - mMembers.push_back(std::move(member)); + void AddMember(std::unique_ptr<ClassMember> member) { + members_.push_back(std::move(member)); } bool empty() const override; - void writeToStream(const StringPiece& prefix, bool final, + void WriteToStream(const StringPiece& prefix, bool final, std::ostream* out) const override; private: - std::string mName; - ClassQualifier mQualifier; - bool mCreateIfEmpty; - std::vector<std::unique_ptr<ClassMember>> mMembers; + std::string name_; + ClassQualifier qualifier_; + bool create_if_empty_; + std::vector<std::unique_ptr<ClassMember>> members_; DISALLOW_COPY_AND_ASSIGN(ClassDefinition); }; diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp index fbaefb1f0c80..6e7c707847b9 100644 --- a/tools/aapt2/java/JavaClassGenerator.cpp +++ b/tools/aapt2/java/JavaClassGenerator.cpp @@ -14,6 +14,16 @@ * limitations under the License. */ +#include "java/JavaClassGenerator.h" + +#include <algorithm> +#include <ostream> +#include <set> +#include <sstream> +#include <tuple> + +#include "android-base/logging.h" + #include "NameMangler.h" #include "Resource.h" #include "ResourceTable.h" @@ -21,52 +31,40 @@ #include "ValueVisitor.h" #include "java/AnnotationProcessor.h" #include "java/ClassDefinition.h" -#include "java/JavaClassGenerator.h" #include "process/SymbolTable.h" #include "util/StringPiece.h" -#include <algorithm> -#include <ostream> -#include <set> -#include <sstream> -#include <tuple> - namespace aapt { -JavaClassGenerator::JavaClassGenerator(IAaptContext* context, ResourceTable* table, - const JavaClassGeneratorOptions& options) : - mContext(context), mTable(table), mOptions(options) { -} - static const std::set<StringPiece> sJavaIdentifiers = { - "abstract", "assert", "boolean", "break", "byte", - "case", "catch", "char", "class", "const", "continue", - "default", "do", "double", "else", "enum", "extends", - "final", "finally", "float", "for", "goto", "if", - "implements", "import", "instanceof", "int", "interface", - "long", "native", "new", "package", "private", "protected", - "public", "return", "short", "static", "strictfp", "super", - "switch", "synchronized", "this", "throw", "throws", - "transient", "try", "void", "volatile", "while", "true", - "false", "null" -}; - -static bool isValidSymbol(const StringPiece& symbol) { - return sJavaIdentifiers.find(symbol) == sJavaIdentifiers.end(); + "abstract", "assert", "boolean", "break", "byte", + "case", "catch", "char", "class", "const", + "continue", "default", "do", "double", "else", + "enum", "extends", "final", "finally", "float", + "for", "goto", "if", "implements", "import", + "instanceof", "int", "interface", "long", "native", + "new", "package", "private", "protected", "public", + "return", "short", "static", "strictfp", "super", + "switch", "synchronized", "this", "throw", "throws", + "transient", "try", "void", "volatile", "while", + "true", "false", "null"}; + +static bool IsValidSymbol(const StringPiece& symbol) { + return sJavaIdentifiers.find(symbol) == sJavaIdentifiers.end(); } /* * Java symbols can not contain . or -, but those are valid in a resource name. * Replace those with '_'. */ -static std::string transform(const StringPiece& symbol) { - std::string output = symbol.toString(); - for (char& c : output) { - if (c == '.' || c == '-') { - c = '_'; - } +static std::string Transform(const StringPiece& symbol) { + std::string output = symbol.ToString(); + for (char& c : output) { + if (c == '.' || c == '-') { + c = '_'; } - return output; + } + return output; } /** @@ -80,475 +78,519 @@ static std::string transform(const StringPiece& symbol) { * Foo_android_bar * Foo_bar */ -static std::string transformNestedAttr(const ResourceNameRef& attrName, - const std::string& styleableClassName, - const StringPiece& packageNameToGenerate) { - std::string output = styleableClassName; - - // We may reference IDs from other packages, so prefix the entry name with - // the package. - if (!attrName.package.empty() && packageNameToGenerate != attrName.package) { - output += "_" + transform(attrName.package); - } - output += "_" + transform(attrName.entry); - return output; +static std::string TransformNestedAttr( + const ResourceNameRef& attr_name, const std::string& styleable_class_name, + const StringPiece& package_name_to_generate) { + std::string output = styleable_class_name; + + // We may reference IDs from other packages, so prefix the entry name with + // the package. + if (!attr_name.package.empty() && + package_name_to_generate != attr_name.package) { + output += "_" + Transform(attr_name.package); + } + output += "_" + Transform(attr_name.entry); + return output; } -static void addAttributeFormatDoc(AnnotationProcessor* processor, Attribute* attr) { - const uint32_t typeMask = attr->typeMask; - if (typeMask & android::ResTable_map::TYPE_REFERENCE) { - processor->appendComment( - "<p>May be a reference to another resource, in the form\n" - "\"<code>@[+][<i>package</i>:]<i>type</i>/<i>name</i></code>\" or a theme\n" - "attribute in the form\n" - "\"<code>?[<i>package</i>:]<i>type</i>/<i>name</i></code>\"."); +static void AddAttributeFormatDoc(AnnotationProcessor* processor, + Attribute* attr) { + const uint32_t type_mask = attr->type_mask; + if (type_mask & android::ResTable_map::TYPE_REFERENCE) { + processor->AppendComment( + "<p>May be a reference to another resource, in the form\n" + "\"<code>@[+][<i>package</i>:]<i>type</i>/<i>name</i></code>\" or a " + "theme\n" + "attribute in the form\n" + "\"<code>?[<i>package</i>:]<i>type</i>/<i>name</i></code>\"."); + } + + if (type_mask & android::ResTable_map::TYPE_STRING) { + processor->AppendComment( + "<p>May be a string value, using '\\\\;' to escape characters such as\n" + "'\\\\n' or '\\\\uxxxx' for a unicode character;"); + } + + if (type_mask & android::ResTable_map::TYPE_INTEGER) { + processor->AppendComment( + "<p>May be an integer value, such as \"<code>100</code>\"."); + } + + if (type_mask & android::ResTable_map::TYPE_BOOLEAN) { + processor->AppendComment( + "<p>May be a boolean value, such as \"<code>true</code>\" or\n" + "\"<code>false</code>\"."); + } + + if (type_mask & android::ResTable_map::TYPE_COLOR) { + processor->AppendComment( + "<p>May be a color value, in the form of " + "\"<code>#<i>rgb</i></code>\",\n" + "\"<code>#<i>argb</i></code>\", \"<code>#<i>rrggbb</i></code\", or \n" + "\"<code>#<i>aarrggbb</i></code>\"."); + } + + if (type_mask & android::ResTable_map::TYPE_FLOAT) { + processor->AppendComment( + "<p>May be a floating point value, such as \"<code>1.2</code>\"."); + } + + if (type_mask & android::ResTable_map::TYPE_DIMENSION) { + processor->AppendComment( + "<p>May be a dimension value, which is a floating point number " + "appended with a\n" + "unit such as \"<code>14.5sp</code>\".\n" + "Available units are: px (pixels), dp (density-independent pixels),\n" + "sp (scaled pixels based on preferred font size), in (inches), and\n" + "mm (millimeters)."); + } + + if (type_mask & android::ResTable_map::TYPE_FRACTION) { + processor->AppendComment( + "<p>May be a fractional value, which is a floating point number " + "appended with\n" + "either % or %p, such as \"<code>14.5%</code>\".\n" + "The % suffix always means a percentage of the base size;\n" + "the optional %p suffix provides a size relative to some parent " + "container."); + } + + if (type_mask & + (android::ResTable_map::TYPE_FLAGS | android::ResTable_map::TYPE_ENUM)) { + if (type_mask & android::ResTable_map::TYPE_FLAGS) { + processor->AppendComment( + "<p>Must be one or more (separated by '|') of the following " + "constant values.</p>"); + } else { + processor->AppendComment( + "<p>Must be one of the following constant values.</p>"); } - if (typeMask & android::ResTable_map::TYPE_STRING) { - processor->appendComment( - "<p>May be a string value, using '\\\\;' to escape characters such as\n" - "'\\\\n' or '\\\\uxxxx' for a unicode character;"); + processor->AppendComment( + "<table>\n<colgroup align=\"left\" />\n" + "<colgroup align=\"left\" />\n" + "<colgroup align=\"left\" />\n" + "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\n"); + for (const Attribute::Symbol& symbol : attr->symbols) { + std::stringstream line; + line << "<tr><td>" << symbol.symbol.name.value().entry << "</td>" + << "<td>" << std::hex << symbol.value << std::dec << "</td>" + << "<td>" << util::TrimWhitespace(symbol.symbol.GetComment()) + << "</td></tr>"; + processor->AppendComment(line.str()); } + processor->AppendComment("</table>"); + } +} - if (typeMask & android::ResTable_map::TYPE_INTEGER) { - processor->appendComment("<p>May be an integer value, such as \"<code>100</code>\"."); - } +JavaClassGenerator::JavaClassGenerator(IAaptContext* context, + ResourceTable* table, + const JavaClassGeneratorOptions& options) + : context_(context), table_(table), options_(options) {} - if (typeMask & android::ResTable_map::TYPE_BOOLEAN) { - processor->appendComment( - "<p>May be a boolean value, such as \"<code>true</code>\" or\n" - "\"<code>false</code>\"."); - } +bool JavaClassGenerator::SkipSymbol(SymbolState state) { + switch (options_.types) { + case JavaClassGeneratorOptions::SymbolTypes::kAll: + return false; + case JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate: + return state == SymbolState::kUndefined; + case JavaClassGeneratorOptions::SymbolTypes::kPublic: + return state != SymbolState::kPublic; + } + return true; +} - if (typeMask & android::ResTable_map::TYPE_COLOR) { - processor->appendComment( - "<p>May be a color value, in the form of \"<code>#<i>rgb</i></code>\",\n" - "\"<code>#<i>argb</i></code>\", \"<code>#<i>rrggbb</i></code\", or \n" - "\"<code>#<i>aarrggbb</i></code>\"."); - } +struct StyleableAttr { + const Reference* attr_ref; + std::string field_name; + std::unique_ptr<SymbolTable::Symbol> symbol; +}; - if (typeMask & android::ResTable_map::TYPE_FLOAT) { - processor->appendComment( - "<p>May be a floating point value, such as \"<code>1.2</code>\"."); - } +static bool less_styleable_attr(const StyleableAttr& lhs, + const StyleableAttr& rhs) { + const ResourceId lhs_id = + lhs.attr_ref->id ? lhs.attr_ref->id.value() : ResourceId(0); + const ResourceId rhs_id = + rhs.attr_ref->id ? rhs.attr_ref->id.value() : ResourceId(0); + if (lhs_id < rhs_id) { + return true; + } else if (lhs_id > rhs_id) { + return false; + } else { + return lhs.attr_ref->name.value() < rhs.attr_ref->name.value(); + } +} - if (typeMask & android::ResTable_map::TYPE_DIMENSION) { - processor->appendComment( - "<p>May be a dimension value, which is a floating point number appended with a\n" - "unit such as \"<code>14.5sp</code>\".\n" - "Available units are: px (pixels), dp (density-independent pixels),\n" - "sp (scaled pixels based on preferred font size), in (inches), and\n" - "mm (millimeters)."); +void JavaClassGenerator::AddMembersToStyleableClass( + const StringPiece& package_name_to_generate, const std::string& entry_name, + const Styleable* styleable, ClassDefinition* out_styleable_class_def) { + const std::string class_name = Transform(entry_name); + + std::unique_ptr<ResourceArrayMember> styleable_array_def = + util::make_unique<ResourceArrayMember>(class_name); + + // This must be sorted by resource ID. + std::vector<StyleableAttr> sorted_attributes; + sorted_attributes.reserve(styleable->entries.size()); + for (const auto& attr : styleable->entries) { + // If we are not encoding final attributes, the styleable entry may have no + // ID if we are building a static library. + CHECK(!options_.use_final || attr.id) << "no ID set for Styleable entry"; + CHECK(bool(attr.name)) << "no name set for Styleable entry"; + + // We will need the unmangled, transformed name in the comments and the + // field, + // so create it once and cache it in this StyleableAttr data structure. + StyleableAttr styleable_attr = {}; + styleable_attr.attr_ref = &attr; + styleable_attr.field_name = TransformNestedAttr( + attr.name.value(), class_name, package_name_to_generate); + + Reference mangled_reference; + mangled_reference.id = attr.id; + mangled_reference.name = attr.name; + if (mangled_reference.name.value().package.empty()) { + mangled_reference.name.value().package = + context_->GetCompilationPackage(); } - if (typeMask & android::ResTable_map::TYPE_FRACTION) { - processor->appendComment( - "<p>May be a fractional value, which is a floating point number appended with\n" - "either % or %p, such as \"<code>14.5%</code>\".\n" - "The % suffix always means a percentage of the base size;\n" - "the optional %p suffix provides a size relative to some parent container."); + if (Maybe<ResourceName> mangled_name = + context_->GetNameMangler()->MangleName( + mangled_reference.name.value())) { + mangled_reference.name = mangled_name; } - if (typeMask & (android::ResTable_map::TYPE_FLAGS | android::ResTable_map::TYPE_ENUM)) { - if (typeMask & android::ResTable_map::TYPE_FLAGS) { - processor->appendComment( - "<p>Must be one or more (separated by '|') of the following " - "constant values.</p>"); - } else { - processor->appendComment("<p>Must be one of the following constant values.</p>"); - } - - processor->appendComment("<table>\n<colgroup align=\"left\" />\n" - "<colgroup align=\"left\" />\n" - "<colgroup align=\"left\" />\n" - "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\n"); - for (const Attribute::Symbol& symbol : attr->symbols) { - std::stringstream line; - line << "<tr><td>" << symbol.symbol.name.value().entry << "</td>" - << "<td>" << std::hex << symbol.value << std::dec << "</td>" - << "<td>" << util::trimWhitespace(symbol.symbol.getComment()) << "</td></tr>"; - processor->appendComment(line.str()); - } - processor->appendComment("</table>"); + // Look up the symbol so that we can write out in the comments what are + // possible + // legal values for this attribute. + const SymbolTable::Symbol* symbol = + context_->GetExternalSymbols()->FindByReference(mangled_reference); + if (symbol && symbol->attribute) { + // Copy the symbol data structure because the returned instance can be + // destroyed. + styleable_attr.symbol = util::make_unique<SymbolTable::Symbol>(*symbol); } -} - -bool JavaClassGenerator::skipSymbol(SymbolState state) { - switch (mOptions.types) { - case JavaClassGeneratorOptions::SymbolTypes::kAll: - return false; - case JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate: - return state == SymbolState::kUndefined; - case JavaClassGeneratorOptions::SymbolTypes::kPublic: - return state != SymbolState::kPublic; + sorted_attributes.push_back(std::move(styleable_attr)); + } + + // Sort the attributes by ID. + std::sort(sorted_attributes.begin(), sorted_attributes.end(), + less_styleable_attr); + + const size_t attr_count = sorted_attributes.size(); + if (attr_count > 0) { + // Build the comment string for the Styleable. It includes details about the + // child attributes. + std::stringstream styleable_comment; + if (!styleable->GetComment().empty()) { + styleable_comment << styleable->GetComment() << "\n"; + } else { + styleable_comment << "Attributes that can be used with a " << class_name + << ".\n"; } - return true; -} - -struct StyleableAttr { - const Reference* attrRef; - std::string fieldName; - std::unique_ptr<SymbolTable::Symbol> symbol; -}; -static bool lessStyleableAttr(const StyleableAttr& lhs, const StyleableAttr& rhs) { - const ResourceId lhsId = lhs.attrRef->id ? lhs.attrRef->id.value() : ResourceId(0); - const ResourceId rhsId = rhs.attrRef->id ? rhs.attrRef->id.value() : ResourceId(0); - if (lhsId < rhsId) { - return true; - } else if (lhsId > rhsId) { - return false; - } else { - return lhs.attrRef->name.value() < rhs.attrRef->name.value(); + styleable_comment << "<p>Includes the following attributes:</p>\n" + "<table>\n" + "<colgroup align=\"left\" />\n" + "<colgroup align=\"left\" />\n" + "<tr><th>Attribute</th><th>Description</th></tr>\n"; + + for (const StyleableAttr& entry : sorted_attributes) { + if (!entry.symbol) { + continue; + } + + if (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && + !entry.symbol->is_public) { + // Don't write entries for non-public attributes. + continue; + } + + StringPiece attr_comment_line = entry.symbol->attribute->GetComment(); + if (attr_comment_line.contains("@removed")) { + // Removed attributes are public but hidden from the documentation, so + // don't emit + // them as part of the class documentation. + continue; + } + + const ResourceName& attr_name = entry.attr_ref->name.value(); + styleable_comment << "<tr><td>"; + styleable_comment << "<code>{@link #" << entry.field_name << " " + << (!attr_name.package.empty() + ? attr_name.package + : context_->GetCompilationPackage()) + << ":" << attr_name.entry << "}</code>"; + styleable_comment << "</td>"; + + styleable_comment << "<td>"; + + // Only use the comment up until the first '.'. This is to stay compatible + // with + // the way old AAPT did it (presumably to keep it short and to avoid + // including + // annotations like @hide which would affect this Styleable). + auto iter = + std::find(attr_comment_line.begin(), attr_comment_line.end(), u'.'); + if (iter != attr_comment_line.end()) { + attr_comment_line = + attr_comment_line.substr(0, (iter - attr_comment_line.begin()) + 1); + } + styleable_comment << attr_comment_line << "</td></tr>\n"; + } + styleable_comment << "</table>\n"; + + for (const StyleableAttr& entry : sorted_attributes) { + if (!entry.symbol) { + continue; + } + + if (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && + !entry.symbol->is_public) { + // Don't write entries for non-public attributes. + continue; + } + styleable_comment << "@see #" << entry.field_name << "\n"; } -} -void JavaClassGenerator::addMembersToStyleableClass(const StringPiece& packageNameToGenerate, - const std::string& entryName, - const Styleable* styleable, - ClassDefinition* outStyleableClassDef) { - const std::string className = transform(entryName); - - std::unique_ptr<ResourceArrayMember> styleableArrayDef = - util::make_unique<ResourceArrayMember>(className); - - // This must be sorted by resource ID. - std::vector<StyleableAttr> sortedAttributes; - sortedAttributes.reserve(styleable->entries.size()); - for (const auto& attr : styleable->entries) { - // If we are not encoding final attributes, the styleable entry may have no ID - // if we are building a static library. - assert((!mOptions.useFinal || attr.id) && "no ID set for Styleable entry"); - assert(attr.name && "no name set for Styleable entry"); - - // We will need the unmangled, transformed name in the comments and the field, - // so create it once and cache it in this StyleableAttr data structure. - StyleableAttr styleableAttr = {}; - styleableAttr.attrRef = &attr; - styleableAttr.fieldName = transformNestedAttr(attr.name.value(), className, - packageNameToGenerate); - - Reference mangledReference; - mangledReference.id = attr.id; - mangledReference.name = attr.name; - if (mangledReference.name.value().package.empty()) { - mangledReference.name.value().package = mContext->getCompilationPackage(); - } + styleable_array_def->GetCommentBuilder()->AppendComment( + styleable_comment.str()); + } - if (Maybe<ResourceName> mangledName = - mContext->getNameMangler()->mangleName(mangledReference.name.value())) { - mangledReference.name = mangledName; - } + // Add the ResourceIds to the array member. + for (const StyleableAttr& styleable_attr : sorted_attributes) { + styleable_array_def->AddElement(styleable_attr.attr_ref->id + ? styleable_attr.attr_ref->id.value() + : ResourceId(0)); + } - // Look up the symbol so that we can write out in the comments what are possible - // legal values for this attribute. - const SymbolTable::Symbol* symbol = mContext->getExternalSymbols()->findByReference( - mangledReference); - if (symbol && symbol->attribute) { - // Copy the symbol data structure because the returned instance can be destroyed. - styleableAttr.symbol = util::make_unique<SymbolTable::Symbol>(*symbol); - } - sortedAttributes.push_back(std::move(styleableAttr)); - } + // Add the Styleable array to the Styleable class. + out_styleable_class_def->AddMember(std::move(styleable_array_def)); - // Sort the attributes by ID. - std::sort(sortedAttributes.begin(), sortedAttributes.end(), lessStyleableAttr); - - const size_t attrCount = sortedAttributes.size(); - if (attrCount > 0) { - // Build the comment string for the Styleable. It includes details about the - // child attributes. - std::stringstream styleableComment; - if (!styleable->getComment().empty()) { - styleableComment << styleable->getComment() << "\n"; - } else { - styleableComment << "Attributes that can be used with a " << className << ".\n"; - } + // Now we emit the indices into the array. + for (size_t i = 0; i < attr_count; i++) { + const StyleableAttr& styleable_attr = sorted_attributes[i]; - styleableComment << - "<p>Includes the following attributes:</p>\n" - "<table>\n" - "<colgroup align=\"left\" />\n" - "<colgroup align=\"left\" />\n" - "<tr><th>Attribute</th><th>Description</th></tr>\n"; - - for (const StyleableAttr& entry : sortedAttributes) { - if (!entry.symbol) { - continue; - } - - if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && - !entry.symbol->isPublic) { - // Don't write entries for non-public attributes. - continue; - } - - StringPiece attrCommentLine = entry.symbol->attribute->getComment(); - if (attrCommentLine.contains("@removed")) { - // Removed attributes are public but hidden from the documentation, so don't emit - // them as part of the class documentation. - continue; - } - - const ResourceName& attrName = entry.attrRef->name.value(); - styleableComment << "<tr><td>"; - styleableComment << "<code>{@link #" - << entry.fieldName << " " - << (!attrName.package.empty() - ? attrName.package : mContext->getCompilationPackage()) - << ":" << attrName.entry - << "}</code>"; - styleableComment << "</td>"; - - styleableComment << "<td>"; - - // Only use the comment up until the first '.'. This is to stay compatible with - // the way old AAPT did it (presumably to keep it short and to avoid including - // annotations like @hide which would affect this Styleable). - auto iter = std::find(attrCommentLine.begin(), attrCommentLine.end(), u'.'); - if (iter != attrCommentLine.end()) { - attrCommentLine = attrCommentLine.substr( - 0, (iter - attrCommentLine.begin()) + 1); - } - styleableComment << attrCommentLine << "</td></tr>\n"; - } - styleableComment << "</table>\n"; - - for (const StyleableAttr& entry : sortedAttributes) { - if (!entry.symbol) { - continue; - } - - if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && - !entry.symbol->isPublic) { - // Don't write entries for non-public attributes. - continue; - } - styleableComment << "@see #" << entry.fieldName << "\n"; - } + if (!styleable_attr.symbol) { + continue; + } - styleableArrayDef->getCommentBuilder()->appendComment(styleableComment.str()); + if (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && + !styleable_attr.symbol->is_public) { + // Don't write entries for non-public attributes. + continue; } - // Add the ResourceIds to the array member. - for (const StyleableAttr& styleableAttr : sortedAttributes) { - styleableArrayDef->addElement( - styleableAttr.attrRef->id ? styleableAttr.attrRef->id.value() : ResourceId(0)); + StringPiece comment = styleable_attr.attr_ref->GetComment(); + if (styleable_attr.symbol->attribute && comment.empty()) { + comment = styleable_attr.symbol->attribute->GetComment(); } - // Add the Styleable array to the Styleable class. - outStyleableClassDef->addMember(std::move(styleableArrayDef)); + if (comment.contains("@removed")) { + // Removed attributes are public but hidden from the documentation, so + // don't emit them + // as part of the class documentation. + continue; + } - // Now we emit the indices into the array. - for (size_t i = 0; i < attrCount; i++) { - const StyleableAttr& styleableAttr = sortedAttributes[i]; + const ResourceName& attr_name = styleable_attr.attr_ref->name.value(); - if (!styleableAttr.symbol) { - continue; - } + StringPiece package_name = attr_name.package; + if (package_name.empty()) { + package_name = context_->GetCompilationPackage(); + } - if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && - !styleableAttr.symbol->isPublic) { - // Don't write entries for non-public attributes. - continue; - } + std::unique_ptr<IntMember> index_member = util::make_unique<IntMember>( + sorted_attributes[i].field_name, static_cast<uint32_t>(i)); - StringPiece comment = styleableAttr.attrRef->getComment(); - if (styleableAttr.symbol->attribute && comment.empty()) { - comment = styleableAttr.symbol->attribute->getComment(); - } + AnnotationProcessor* attr_processor = index_member->GetCommentBuilder(); - if (comment.contains("@removed")) { - // Removed attributes are public but hidden from the documentation, so don't emit them - // as part of the class documentation. - continue; - } + if (!comment.empty()) { + attr_processor->AppendComment("<p>\n@attr description"); + attr_processor->AppendComment(comment); + } else { + std::stringstream default_comment; + default_comment << "<p>This symbol is the offset where the " + << "{@link " << package_name << ".R.attr#" + << Transform(attr_name.entry) << "}\n" + << "attribute's value can be found in the " + << "{@link #" << class_name << "} array."; + attr_processor->AppendComment(default_comment.str()); + } - const ResourceName& attrName = styleableAttr.attrRef->name.value(); + attr_processor->AppendNewLine(); - StringPiece packageName = attrName.package; - if (packageName.empty()) { - packageName = mContext->getCompilationPackage(); - } + AddAttributeFormatDoc(attr_processor, + styleable_attr.symbol->attribute.get()); + attr_processor->AppendNewLine(); - std::unique_ptr<IntMember> indexMember = util::make_unique<IntMember>( - sortedAttributes[i].fieldName, static_cast<uint32_t>(i)); - - AnnotationProcessor* attrProcessor = indexMember->getCommentBuilder(); - - if (!comment.empty()) { - attrProcessor->appendComment("<p>\n@attr description"); - attrProcessor->appendComment(comment); - } else { - std::stringstream defaultComment; - defaultComment - << "<p>This symbol is the offset where the " - << "{@link " << packageName << ".R.attr#" << transform(attrName.entry) << "}\n" - << "attribute's value can be found in the " - << "{@link #" << className << "} array."; - attrProcessor->appendComment(defaultComment.str()); - } + std::stringstream doclava_name; + doclava_name << "@attr name " << package_name << ":" << attr_name.entry; - attrProcessor->appendNewLine(); + attr_processor->AppendComment(doclava_name.str()); - addAttributeFormatDoc(attrProcessor, styleableAttr.symbol->attribute.get()); - attrProcessor->appendNewLine(); + out_styleable_class_def->AddMember(std::move(index_member)); + } +} - std::stringstream doclavaName; - doclavaName << "@attr name " << packageName << ":" << attrName.entry;; - attrProcessor->appendComment(doclavaName.str()); +bool JavaClassGenerator::AddMembersToTypeClass( + const StringPiece& package_name_to_generate, + const ResourceTablePackage* package, const ResourceTableType* type, + ClassDefinition* out_type_class_def) { + for (const auto& entry : type->entries) { + if (SkipSymbol(entry->symbol_status.state)) { + continue; + } - outStyleableClassDef->addMember(std::move(indexMember)); + ResourceId id; + if (package->id && type->id && entry->id) { + id = ResourceId(package->id.value(), type->id.value(), entry->id.value()); } -} -bool JavaClassGenerator::addMembersToTypeClass(const StringPiece& packageNameToGenerate, - const ResourceTablePackage* package, - const ResourceTableType* type, - ClassDefinition* outTypeClassDef) { + std::string unmangled_package; + std::string unmangled_name = entry->name; + if (NameMangler::Unmangle(&unmangled_name, &unmangled_package)) { + // The entry name was mangled, and we successfully unmangled it. + // Check that we want to emit this symbol. + if (package->name != unmangled_package) { + // Skip the entry if it doesn't belong to the package we're writing. + continue; + } + } else if (package_name_to_generate != package->name) { + // We are processing a mangled package name, + // but this is a non-mangled resource. + continue; + } - for (const auto& entry : type->entries) { - if (skipSymbol(entry->symbolStatus.state)) { - continue; - } + if (!IsValidSymbol(unmangled_name)) { + ResourceNameRef resource_name(package_name_to_generate, type->type, + unmangled_name); + std::stringstream err; + err << "invalid symbol name '" << resource_name << "'"; + error_ = err.str(); + return false; + } - ResourceId id; - if (package->id && type->id && entry->id) { - id = ResourceId(package->id.value(), type->id.value(), entry->id.value()); - } + if (type->type == ResourceType::kStyleable) { + CHECK(!entry->values.empty()); - std::string unmangledPackage; - std::string unmangledName = entry->name; - if (NameMangler::unmangle(&unmangledName, &unmangledPackage)) { - // The entry name was mangled, and we successfully unmangled it. - // Check that we want to emit this symbol. - if (package->name != unmangledPackage) { - // Skip the entry if it doesn't belong to the package we're writing. - continue; - } - } else if (packageNameToGenerate != package->name) { - // We are processing a mangled package name, - // but this is a non-mangled resource. - continue; - } + const Styleable* styleable = + static_cast<const Styleable*>(entry->values.front()->value.get()); - if (!isValidSymbol(unmangledName)) { - ResourceNameRef resourceName(packageNameToGenerate, type->type, unmangledName); - std::stringstream err; - err << "invalid symbol name '" << resourceName << "'"; - mError = err.str(); - return false; + // Comments are handled within this method. + AddMembersToStyleableClass(package_name_to_generate, unmangled_name, + styleable, out_type_class_def); + } else { + std::unique_ptr<ResourceMember> resource_member = + util::make_unique<ResourceMember>(Transform(unmangled_name), id); + + // Build the comments and annotations for this entry. + AnnotationProcessor* processor = resource_member->GetCommentBuilder(); + + // Add the comments from any <public> tags. + if (entry->symbol_status.state != SymbolState::kUndefined) { + processor->AppendComment(entry->symbol_status.comment); + } + + // Add the comments from all configurations of this entry. + for (const auto& config_value : entry->values) { + processor->AppendComment(config_value->value->GetComment()); + } + + // If this is an Attribute, append the format Javadoc. + if (!entry->values.empty()) { + if (Attribute* attr = + ValueCast<Attribute>(entry->values.front()->value.get())) { + // We list out the available values for the given attribute. + AddAttributeFormatDoc(processor, attr); } + } - if (type->type == ResourceType::kStyleable) { - assert(!entry->values.empty()); - - const Styleable* styleable = static_cast<const Styleable*>( - entry->values.front()->value.get()); - - // Comments are handled within this method. - addMembersToStyleableClass(packageNameToGenerate, unmangledName, styleable, - outTypeClassDef); - } else { - std::unique_ptr<ResourceMember> resourceMember = - util::make_unique<ResourceMember>(transform(unmangledName), id); - - // Build the comments and annotations for this entry. - AnnotationProcessor* processor = resourceMember->getCommentBuilder(); - - // Add the comments from any <public> tags. - if (entry->symbolStatus.state != SymbolState::kUndefined) { - processor->appendComment(entry->symbolStatus.comment); - } - - // Add the comments from all configurations of this entry. - for (const auto& configValue : entry->values) { - processor->appendComment(configValue->value->getComment()); - } - - // If this is an Attribute, append the format Javadoc. - if (!entry->values.empty()) { - if (Attribute* attr = valueCast<Attribute>(entry->values.front()->value.get())) { - // We list out the available values for the given attribute. - addAttributeFormatDoc(processor, attr); - } - } - - outTypeClassDef->addMember(std::move(resourceMember)); - } + out_type_class_def->AddMember(std::move(resource_member)); } - return true; + } + return true; } -bool JavaClassGenerator::generate(const StringPiece& packageNameToGenerate, std::ostream* out) { - return generate(packageNameToGenerate, packageNameToGenerate, out); +bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, + std::ostream* out) { + return Generate(package_name_to_generate, package_name_to_generate, out); } -static void appendJavaDocAnnotations(const std::vector<std::string>& annotations, - AnnotationProcessor* processor) { - for (const std::string& annotation : annotations) { - std::string properAnnotation = "@"; - properAnnotation += annotation; - processor->appendComment(properAnnotation); - } +static void AppendJavaDocAnnotations( + const std::vector<std::string>& annotations, + AnnotationProcessor* processor) { + for (const std::string& annotation : annotations) { + std::string proper_annotation = "@"; + proper_annotation += annotation; + processor->AppendComment(proper_annotation); + } } -bool JavaClassGenerator::generate(const StringPiece& packageNameToGenerate, - const StringPiece& outPackageName, std::ostream* out) { - - ClassDefinition rClass("R", ClassQualifier::None, true); - - for (const auto& package : mTable->packages) { - for (const auto& type : package->types) { - if (type->type == ResourceType::kAttrPrivate) { - continue; - } - - const bool forceCreationIfEmpty = - (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic); - - std::unique_ptr<ClassDefinition> classDef = util::make_unique<ClassDefinition>( - toString(type->type), ClassQualifier::Static, forceCreationIfEmpty); - - bool result = addMembersToTypeClass(packageNameToGenerate, package.get(), type.get(), - classDef.get()); - if (!result) { - return false; - } - - if (type->type == ResourceType::kAttr) { - // Also include private attributes in this same class. - ResourceTableType* privType = package->findType(ResourceType::kAttrPrivate); - if (privType) { - result = addMembersToTypeClass(packageNameToGenerate, package.get(), privType, - classDef.get()); - if (!result) { - return false; - } - } - } - - if (type->type == ResourceType::kStyleable && - mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic) { - // When generating a public R class, we don't want Styleable to be part of the API. - // It is only emitted for documentation purposes. - classDef->getCommentBuilder()->appendComment("@doconly"); - } - - appendJavaDocAnnotations(mOptions.javadocAnnotations, classDef->getCommentBuilder()); - - rClass.addMember(std::move(classDef)); - } - } +bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, + const StringPiece& out_package_name, + std::ostream* out) { + ClassDefinition r_class("R", ClassQualifier::None, true); + + for (const auto& package : table_->packages) { + for (const auto& type : package->types) { + if (type->type == ResourceType::kAttrPrivate) { + continue; + } - appendJavaDocAnnotations(mOptions.javadocAnnotations, rClass.getCommentBuilder()); + const bool force_creation_if_empty = + (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic); - if (!ClassDefinition::writeJavaFile(&rClass, outPackageName, mOptions.useFinal, out)) { + std::unique_ptr<ClassDefinition> class_def = + util::make_unique<ClassDefinition>(ToString(type->type), + ClassQualifier::Static, + force_creation_if_empty); + + bool result = AddMembersToTypeClass( + package_name_to_generate, package.get(), type.get(), class_def.get()); + if (!result) { return false; + } + + if (type->type == ResourceType::kAttr) { + // Also include private attributes in this same class. + ResourceTableType* priv_type = + package->FindType(ResourceType::kAttrPrivate); + if (priv_type) { + result = + AddMembersToTypeClass(package_name_to_generate, package.get(), + priv_type, class_def.get()); + if (!result) { + return false; + } + } + } + + if (type->type == ResourceType::kStyleable && + options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic) { + // When generating a public R class, we don't want Styleable to be part + // of the API. + // It is only emitted for documentation purposes. + class_def->GetCommentBuilder()->AppendComment("@doconly"); + } + + AppendJavaDocAnnotations(options_.javadoc_annotations, + class_def->GetCommentBuilder()); + + r_class.AddMember(std::move(class_def)); } + } - out->flush(); - return true; + AppendJavaDocAnnotations(options_.javadoc_annotations, + r_class.GetCommentBuilder()); + + if (!ClassDefinition::WriteJavaFile(&r_class, out_package_name, + options_.use_final, out)) { + return false; + } + + out->flush(); + return true; } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h index 2fdf2682a162..190e73b66b9e 100644 --- a/tools/aapt2/java/JavaClassGenerator.h +++ b/tools/aapt2/java/JavaClassGenerator.h @@ -17,14 +17,14 @@ #ifndef AAPT_JAVA_CLASS_GENERATOR_H #define AAPT_JAVA_CLASS_GENERATOR_H +#include <ostream> +#include <string> + #include "ResourceTable.h" #include "ResourceValues.h" #include "process/IResourceTableConsumer.h" #include "util/StringPiece.h" -#include <ostream> -#include <string> - namespace aapt { class AnnotationProcessor; @@ -35,7 +35,7 @@ struct JavaClassGeneratorOptions { * Specifies whether to use the 'final' modifier * on resource entries. Default is true. */ - bool useFinal = true; + bool use_final = true; enum class SymbolTypes { kAll, @@ -49,7 +49,7 @@ struct JavaClassGeneratorOptions { * A list of JavaDoc annotations to add to the comments of all generated * classes. */ - std::vector<std::string> javadocAnnotations; + std::vector<std::string> javadoc_annotations; }; /* @@ -69,34 +69,34 @@ class JavaClassGenerator { * We need to generate these symbols in a separate file. * Returns true on success. */ - bool generate(const StringPiece& packageNameToGenerate, std::ostream* out); + bool Generate(const StringPiece& packageNameToGenerate, std::ostream* out); - bool generate(const StringPiece& packageNameToGenerate, + bool Generate(const StringPiece& packageNameToGenerate, const StringPiece& outputPackageName, std::ostream* out); const std::string& getError() const; private: - bool addMembersToTypeClass(const StringPiece& packageNameToGenerate, + bool AddMembersToTypeClass(const StringPiece& packageNameToGenerate, const ResourceTablePackage* package, const ResourceTableType* type, ClassDefinition* outTypeClassDef); - void addMembersToStyleableClass(const StringPiece& packageNameToGenerate, + void AddMembersToStyleableClass(const StringPiece& packageNameToGenerate, const std::string& entryName, const Styleable* styleable, ClassDefinition* outStyleableClassDef); - bool skipSymbol(SymbolState state); + bool SkipSymbol(SymbolState state); - IAaptContext* mContext; - ResourceTable* mTable; - JavaClassGeneratorOptions mOptions; - std::string mError; + IAaptContext* context_; + ResourceTable* table_; + JavaClassGeneratorOptions options_; + std::string error_; }; inline const std::string& JavaClassGenerator::getError() const { - return mError; + return error_; } } // namespace aapt diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp index ed7c6bd238b0..3d3d24e6aab5 100644 --- a/tools/aapt2/java/JavaClassGenerator_test.cpp +++ b/tools/aapt2/java/JavaClassGenerator_test.cpp @@ -15,154 +15,181 @@ */ #include "java/JavaClassGenerator.h" -#include "test/Test.h" -#include "util/Util.h" #include <sstream> #include <string> +#include "test/Test.h" +#include "util/Util.h" + namespace aapt { TEST(JavaClassGeneratorTest, FailWhenEntryIsJavaKeyword) { - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .addSimple("android:id/class", ResourceId(0x01020000)) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) - .setNameManglerPolicy(NameManglerPolicy{ "android" }) - .build(); - JavaClassGenerator generator(context.get(), table.get(), {}); - - std::stringstream out; - EXPECT_FALSE(generator.generate("android", &out)); + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("android", 0x01) + .AddSimple("android:id/class", ResourceId(0x01020000)) + .Build(); + + std::unique_ptr<IAaptContext> context = + test::ContextBuilder() + .AddSymbolSource( + util::make_unique<ResourceTableSymbolSource>(table.get())) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .Build(); + JavaClassGenerator generator(context.get(), table.get(), {}); + + std::stringstream out; + EXPECT_FALSE(generator.Generate("android", &out)); } TEST(JavaClassGeneratorTest, TransformInvalidJavaIdentifierCharacter) { - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .addSimple("android:id/hey-man", ResourceId(0x01020000)) - .addValue("android:attr/cool.attr", ResourceId(0x01010000), - test::AttributeBuilder(false).build()) - .addValue("android:styleable/hey.dude", ResourceId(0x01030000), - test::StyleableBuilder() - .addItem("android:attr/cool.attr", ResourceId(0x01010000)) - .build()) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) - .setNameManglerPolicy(NameManglerPolicy{ "android" }) - .build(); - JavaClassGenerator generator(context.get(), table.get(), {}); - - std::stringstream out; - EXPECT_TRUE(generator.generate("android", &out)); - - std::string output = out.str(); - - EXPECT_NE(std::string::npos, - output.find("public static final int hey_man=0x01020000;")); + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("android", 0x01) + .AddSimple("android:id/hey-man", ResourceId(0x01020000)) + .AddValue("android:attr/cool.attr", ResourceId(0x01010000), + test::AttributeBuilder(false).Build()) + .AddValue( + "android:styleable/hey.dude", ResourceId(0x01030000), + test::StyleableBuilder() + .AddItem("android:attr/cool.attr", ResourceId(0x01010000)) + .Build()) + .Build(); + + std::unique_ptr<IAaptContext> context = + test::ContextBuilder() + .AddSymbolSource( + util::make_unique<ResourceTableSymbolSource>(table.get())) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .Build(); + JavaClassGenerator generator(context.get(), table.get(), {}); + + std::stringstream out; + EXPECT_TRUE(generator.Generate("android", &out)); + + std::string output = out.str(); + + EXPECT_NE(std::string::npos, + output.find("public static final int hey_man=0x01020000;")); + + EXPECT_NE(std::string::npos, + output.find("public static final int[] hey_dude={")); + + EXPECT_NE(std::string::npos, + output.find("public static final int hey_dude_cool_attr=0;")); +} - EXPECT_NE(std::string::npos, - output.find("public static final int[] hey_dude={")); +TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) { + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("android", 0x01) + .AddSimple("android:id/one", ResourceId(0x01020000)) + .AddSimple("android:id/com.foo$two", ResourceId(0x01020001)) + .Build(); + + std::unique_ptr<IAaptContext> context = + test::ContextBuilder() + .AddSymbolSource( + util::make_unique<ResourceTableSymbolSource>(table.get())) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .Build(); + JavaClassGenerator generator(context.get(), table.get(), {}); + std::stringstream out; + ASSERT_TRUE(generator.Generate("android", "com.android.internal", &out)); + + std::string output = out.str(); + EXPECT_NE(std::string::npos, output.find("package com.android.internal;")); + EXPECT_NE(std::string::npos, + output.find("public static final int one=0x01020000;")); + EXPECT_EQ(std::string::npos, output.find("two")); + EXPECT_EQ(std::string::npos, output.find("com_foo$two")); +} - EXPECT_NE(std::string::npos, - output.find("public static final int hey_dude_cool_attr=0;")); +TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) { + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("android", 0x01) + .AddSimple("android:attr/two", ResourceId(0x01010001)) + .AddSimple("android:^attr-private/one", ResourceId(0x01010000)) + .Build(); + + std::unique_ptr<IAaptContext> context = + test::ContextBuilder() + .AddSymbolSource( + util::make_unique<ResourceTableSymbolSource>(table.get())) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .Build(); + JavaClassGenerator generator(context.get(), table.get(), {}); + std::stringstream out; + ASSERT_TRUE(generator.Generate("android", &out)); + + std::string output = out.str(); + EXPECT_NE(std::string::npos, output.find("public static final class attr")); + EXPECT_EQ(std::string::npos, + output.find("public static final class ^attr-private")); } -TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) { - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .addSimple("android:id/one", ResourceId(0x01020000)) - .addSimple("android:id/com.foo$two", ResourceId(0x01020001)) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) - .setNameManglerPolicy(NameManglerPolicy{ "android" }) - .build(); - JavaClassGenerator generator(context.get(), table.get(), {}); +TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { + StdErrDiagnostics diag; + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("android", 0x01) + .AddSimple("android:id/one", ResourceId(0x01020000)) + .AddSimple("android:id/two", ResourceId(0x01020001)) + .AddSimple("android:id/three", ResourceId(0x01020002)) + .SetSymbolState("android:id/one", ResourceId(0x01020000), + SymbolState::kPublic) + .SetSymbolState("android:id/two", ResourceId(0x01020001), + SymbolState::kPrivate) + .Build(); + + std::unique_ptr<IAaptContext> context = + test::ContextBuilder() + .AddSymbolSource( + util::make_unique<ResourceTableSymbolSource>(table.get())) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .Build(); + + JavaClassGeneratorOptions options; + options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic; + { + JavaClassGenerator generator(context.get(), table.get(), options); std::stringstream out; - ASSERT_TRUE(generator.generate("android", "com.android.internal", &out)); - + ASSERT_TRUE(generator.Generate("android", &out)); std::string output = out.str(); - EXPECT_NE(std::string::npos, output.find("package com.android.internal;")); - EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;")); + EXPECT_NE(std::string::npos, + output.find("public static final int one=0x01020000;")); EXPECT_EQ(std::string::npos, output.find("two")); - EXPECT_EQ(std::string::npos, output.find("com_foo$two")); -} + EXPECT_EQ(std::string::npos, output.find("three")); + } -TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) { - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .addSimple("android:attr/two", ResourceId(0x01010001)) - .addSimple("android:^attr-private/one", ResourceId(0x01010000)) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) - .setNameManglerPolicy(NameManglerPolicy{ "android" }) - .build(); - JavaClassGenerator generator(context.get(), table.get(), {}); + options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate; + { + JavaClassGenerator generator(context.get(), table.get(), options); std::stringstream out; - ASSERT_TRUE(generator.generate("android", &out)); - + ASSERT_TRUE(generator.Generate("android", &out)); std::string output = out.str(); - EXPECT_NE(std::string::npos, output.find("public static final class attr")); - EXPECT_EQ(std::string::npos, output.find("public static final class ^attr-private")); -} + EXPECT_NE(std::string::npos, + output.find("public static final int one=0x01020000;")); + EXPECT_NE(std::string::npos, + output.find("public static final int two=0x01020001;")); + EXPECT_EQ(std::string::npos, output.find("three")); + } -TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { - StdErrDiagnostics diag; - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .addSimple("android:id/one", ResourceId(0x01020000)) - .addSimple("android:id/two", ResourceId(0x01020001)) - .addSimple("android:id/three", ResourceId(0x01020002)) - .setSymbolState("android:id/one", ResourceId(0x01020000), SymbolState::kPublic) - .setSymbolState("android:id/two", ResourceId(0x01020001), SymbolState::kPrivate) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) - .setNameManglerPolicy(NameManglerPolicy{ "android" }) - .build(); - - JavaClassGeneratorOptions options; - options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic; - { - JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; - ASSERT_TRUE(generator.generate("android", &out)); - std::string output = out.str(); - EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;")); - EXPECT_EQ(std::string::npos, output.find("two")); - EXPECT_EQ(std::string::npos, output.find("three")); - } - - options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate; - { - JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; - ASSERT_TRUE(generator.generate("android", &out)); - std::string output = out.str(); - EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;")); - EXPECT_NE(std::string::npos, output.find("public static final int two=0x01020001;")); - EXPECT_EQ(std::string::npos, output.find("three")); - } - - options.types = JavaClassGeneratorOptions::SymbolTypes::kAll; - { - JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; - ASSERT_TRUE(generator.generate("android", &out)); - std::string output = out.str(); - EXPECT_NE(std::string::npos, output.find("public static final int one=0x01020000;")); - EXPECT_NE(std::string::npos, output.find("public static final int two=0x01020001;")); - EXPECT_NE(std::string::npos, output.find("public static final int three=0x01020002;")); - } + options.types = JavaClassGeneratorOptions::SymbolTypes::kAll; + { + JavaClassGenerator generator(context.get(), table.get(), options); + std::stringstream out; + ASSERT_TRUE(generator.Generate("android", &out)); + std::string output = out.str(); + EXPECT_NE(std::string::npos, + output.find("public static final int one=0x01020000;")); + EXPECT_NE(std::string::npos, + output.find("public static final int two=0x01020001;")); + EXPECT_NE(std::string::npos, + output.find("public static final int three=0x01020002;")); + } } /* @@ -172,12 +199,15 @@ TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { ResourceId{ 0x01, 0x02, 0x0000 })); ResourceTable table; table.setPackage(u"com.lib"); - ASSERT_TRUE(table.addResource(ResourceName{ {}, ResourceType::kId, u"test" }, {}, - Source{ "lib.xml", 33 }, util::make_unique<Id>())); + ASSERT_TRUE(table.addResource(ResourceName{ {}, ResourceType::kId, u"test" +}, {}, + Source{ "lib.xml", 33 }, +util::make_unique<Id>())); ASSERT_TRUE(mTable->merge(std::move(table))); Linker linker(mTable, - std::make_shared<MockResolver>(mTable, std::map<ResourceName, ResourceId>()), + std::make_shared<MockResolver>(mTable, std::map<ResourceName, +ResourceId>()), {}); ASSERT_TRUE(linker.linkAndValidate()); @@ -197,126 +227,139 @@ TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { }*/ TEST(JavaClassGeneratorTest, EmitOtherPackagesAttributesInStyleable) { - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .setPackageId("com.lib", 0x02) - .addValue("android:attr/bar", ResourceId(0x01010000), - test::AttributeBuilder(false).build()) - .addValue("com.lib:attr/bar", ResourceId(0x02010000), - test::AttributeBuilder(false).build()) - .addValue("android:styleable/foo", ResourceId(0x01030000), - test::StyleableBuilder() - .addItem("android:attr/bar", ResourceId(0x01010000)) - .addItem("com.lib:attr/bar", ResourceId(0x02010000)) - .build()) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) - .setNameManglerPolicy(NameManglerPolicy{ "android" }) - .build(); - JavaClassGenerator generator(context.get(), table.get(), {}); - - std::stringstream out; - EXPECT_TRUE(generator.generate("android", &out)); - - std::string output = out.str(); - EXPECT_NE(std::string::npos, output.find("int foo_bar=")); - EXPECT_NE(std::string::npos, output.find("int foo_com_lib_bar=")); + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("android", 0x01) + .SetPackageId("com.lib", 0x02) + .AddValue("android:attr/bar", ResourceId(0x01010000), + test::AttributeBuilder(false).Build()) + .AddValue("com.lib:attr/bar", ResourceId(0x02010000), + test::AttributeBuilder(false).Build()) + .AddValue("android:styleable/foo", ResourceId(0x01030000), + test::StyleableBuilder() + .AddItem("android:attr/bar", ResourceId(0x01010000)) + .AddItem("com.lib:attr/bar", ResourceId(0x02010000)) + .Build()) + .Build(); + + std::unique_ptr<IAaptContext> context = + test::ContextBuilder() + .AddSymbolSource( + util::make_unique<ResourceTableSymbolSource>(table.get())) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .Build(); + JavaClassGenerator generator(context.get(), table.get(), {}); + + std::stringstream out; + EXPECT_TRUE(generator.Generate("android", &out)); + + std::string output = out.str(); + EXPECT_NE(std::string::npos, output.find("int foo_bar=")); + EXPECT_NE(std::string::npos, output.find("int foo_com_lib_bar=")); } TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) { - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .addSimple("android:id/foo", ResourceId(0x01010000)) - .build(); - test::getValue<Id>(table.get(), "android:id/foo") - ->setComment(std::string("This is a comment\n@deprecated")); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) - .setNameManglerPolicy(NameManglerPolicy{ "android" }) - .build(); - JavaClassGenerator generator(context.get(), table.get(), {}); - std::stringstream out; - ASSERT_TRUE(generator.generate("android", &out)); - std::string actual = out.str(); - - const char* expectedText = -R"EOF(/** + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("android", 0x01) + .AddSimple("android:id/foo", ResourceId(0x01010000)) + .Build(); + test::GetValue<Id>(table.get(), "android:id/foo") + ->SetComment(std::string("This is a comment\n@deprecated")); + + std::unique_ptr<IAaptContext> context = + test::ContextBuilder() + .AddSymbolSource( + util::make_unique<ResourceTableSymbolSource>(table.get())) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .Build(); + JavaClassGenerator generator(context.get(), table.get(), {}); + std::stringstream out; + ASSERT_TRUE(generator.Generate("android", &out)); + std::string actual = out.str(); + + const char* expectedText = + R"EOF(/** * This is a comment * @deprecated */ @Deprecated public static final int foo=0x01010000;)EOF"; - EXPECT_NE(std::string::npos, actual.find(expectedText)); + EXPECT_NE(std::string::npos, actual.find(expectedText)); } -TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) { - -} - -TEST(JavaClassGeneratorTest, CommentsForStyleablesAndNestedAttributesArePresent) { - Attribute attr(false); - attr.setComment(StringPiece("This is an attribute")); - - Styleable styleable; - styleable.entries.push_back(Reference(test::parseNameOrDie("android:attr/one"))); - styleable.setComment(StringPiece("This is a styleable")); - - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .addValue("android:attr/one", util::make_unique<Attribute>(attr)) - .addValue("android:styleable/Container", - std::unique_ptr<Styleable>(styleable.clone(nullptr))) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) - .setNameManglerPolicy(NameManglerPolicy{ "android" }) - .build(); - JavaClassGeneratorOptions options; - options.useFinal = false; - JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; - ASSERT_TRUE(generator.generate("android", &out)); - std::string actual = out.str(); - - EXPECT_NE(std::string::npos, actual.find("attr name android:one")); - EXPECT_NE(std::string::npos, actual.find("attr description")); - EXPECT_NE(std::string::npos, actual.find(attr.getComment().data())); - EXPECT_NE(std::string::npos, actual.find(styleable.getComment().data())); +TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {} + +TEST(JavaClassGeneratorTest, + CommentsForStyleablesAndNestedAttributesArePresent) { + Attribute attr(false); + attr.SetComment(StringPiece("This is an attribute")); + + Styleable styleable; + styleable.entries.push_back( + Reference(test::ParseNameOrDie("android:attr/one"))); + styleable.SetComment(StringPiece("This is a styleable")); + + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("android", 0x01) + .AddValue("android:attr/one", util::make_unique<Attribute>(attr)) + .AddValue("android:styleable/Container", + std::unique_ptr<Styleable>(styleable.Clone(nullptr))) + .Build(); + + std::unique_ptr<IAaptContext> context = + test::ContextBuilder() + .AddSymbolSource( + util::make_unique<ResourceTableSymbolSource>(table.get())) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .Build(); + JavaClassGeneratorOptions options; + options.use_final = false; + JavaClassGenerator generator(context.get(), table.get(), options); + std::stringstream out; + ASSERT_TRUE(generator.Generate("android", &out)); + std::string actual = out.str(); + + EXPECT_NE(std::string::npos, actual.find("attr name android:one")); + EXPECT_NE(std::string::npos, actual.find("attr description")); + EXPECT_NE(std::string::npos, actual.find(attr.GetComment().data())); + EXPECT_NE(std::string::npos, actual.find(styleable.GetComment().data())); } TEST(JavaClassGeneratorTest, CommentsForRemovedAttributesAreNotPresentInClass) { - Attribute attr(false); - attr.setComment(StringPiece("removed")); - - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("android", 0x01) - .addValue("android:attr/one", util::make_unique<Attribute>(attr)) - .build(); - - std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) - .setNameManglerPolicy(NameManglerPolicy{ "android" }) - .build(); - JavaClassGeneratorOptions options; - options.useFinal = false; - JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; - ASSERT_TRUE(generator.generate("android", &out)); - std::string actual = out.str(); - - EXPECT_EQ(std::string::npos, actual.find("@attr name android:one")); - EXPECT_EQ(std::string::npos, actual.find("@attr description")); - - // We should find @removed only in the attribute javadoc and not anywhere else (i.e. the class - // javadoc). - const size_t pos = actual.find("removed"); - EXPECT_NE(std::string::npos, pos); - EXPECT_EQ(std::string::npos, actual.find("removed", pos + 1)); + Attribute attr(false); + attr.SetComment(StringPiece("removed")); + + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("android", 0x01) + .AddValue("android:attr/one", util::make_unique<Attribute>(attr)) + .Build(); + + std::unique_ptr<IAaptContext> context = + test::ContextBuilder() + .AddSymbolSource( + util::make_unique<ResourceTableSymbolSource>(table.get())) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .Build(); + JavaClassGeneratorOptions options; + options.use_final = false; + JavaClassGenerator generator(context.get(), table.get(), options); + std::stringstream out; + ASSERT_TRUE(generator.Generate("android", &out)); + std::string actual = out.str(); + + EXPECT_EQ(std::string::npos, actual.find("@attr name android:one")); + EXPECT_EQ(std::string::npos, actual.find("@attr description")); + + // We should find @removed only in the attribute javadoc and not anywhere else + // (i.e. the class + // javadoc). + const size_t pos = actual.find("removed"); + EXPECT_NE(std::string::npos, pos); + EXPECT_EQ(std::string::npos, actual.find("removed", pos + 1)); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/java/ManifestClassGenerator.cpp b/tools/aapt2/java/ManifestClassGenerator.cpp index 5ff11b1303d3..db84f295db2a 100644 --- a/tools/aapt2/java/ManifestClassGenerator.cpp +++ b/tools/aapt2/java/ManifestClassGenerator.cpp @@ -14,111 +14,120 @@ * limitations under the License. */ +#include "java/ManifestClassGenerator.h" + +#include <algorithm> + #include "Source.h" #include "java/AnnotationProcessor.h" #include "java/ClassDefinition.h" -#include "java/ManifestClassGenerator.h" #include "util/Maybe.h" #include "xml/XmlDom.h" -#include <algorithm> - namespace aapt { -static Maybe<StringPiece> extractJavaIdentifier(IDiagnostics* diag, const Source& source, +static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag, + const Source& source, const StringPiece& value) { - const StringPiece sep = "."; - auto iter = std::find_end(value.begin(), value.end(), sep.begin(), sep.end()); - - StringPiece result; - if (iter != value.end()) { - result.assign(iter + sep.size(), value.end() - (iter + sep.size())); - } else { - result = value; - } - - if (result.empty()) { - diag->error(DiagMessage(source) << "empty symbol"); - return {}; - } - - iter = util::findNonAlphaNumericAndNotInSet(result, "_"); - if (iter != result.end()) { - diag->error(DiagMessage(source) - << "invalid character '" << StringPiece(iter, 1) - << "' in '" << result << "'"); - return {}; - } - - if (*result.begin() >= '0' && *result.begin() <= '9') { - diag->error(DiagMessage(source) << "symbol can not start with a digit"); - return {}; - } - - return result; + const StringPiece sep = "."; + auto iter = std::find_end(value.begin(), value.end(), sep.begin(), sep.end()); + + StringPiece result; + if (iter != value.end()) { + result.assign(iter + sep.size(), value.end() - (iter + sep.size())); + } else { + result = value; + } + + if (result.empty()) { + diag->Error(DiagMessage(source) << "empty symbol"); + return {}; + } + + iter = util::FindNonAlphaNumericAndNotInSet(result, "_"); + if (iter != result.end()) { + diag->Error(DiagMessage(source) << "invalid character '" + << StringPiece(iter, 1) << "' in '" + << result << "'"); + return {}; + } + + if (*result.begin() >= '0' && *result.begin() <= '9') { + diag->Error(DiagMessage(source) << "symbol can not start with a digit"); + return {}; + } + + return result; } -static bool writeSymbol(const Source& source, IDiagnostics* diag, xml::Element* el, - ClassDefinition* classDef) { - xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, "name"); - if (!attr) { - diag->error(DiagMessage(source) << "<" << el->name << "> must define 'android:name'"); - return false; - } - - Maybe<StringPiece> result = extractJavaIdentifier(diag, source.withLine(el->lineNumber), - attr->value); - if (!result) { - return false; - } - - std::unique_ptr<StringMember> stringMember = util::make_unique<StringMember>( - result.value(), attr->value); - stringMember->getCommentBuilder()->appendComment(el->comment); - - classDef->addMember(std::move(stringMember)); - return true; +static bool WriteSymbol(const Source& source, IDiagnostics* diag, + xml::Element* el, ClassDefinition* class_def) { + xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name"); + if (!attr) { + diag->Error(DiagMessage(source) << "<" << el->name + << "> must define 'android:name'"); + return false; + } + + Maybe<StringPiece> result = ExtractJavaIdentifier( + diag, source.WithLine(el->line_number), attr->value); + if (!result) { + return false; + } + + std::unique_ptr<StringMember> string_member = + util::make_unique<StringMember>(result.value(), attr->value); + string_member->GetCommentBuilder()->AppendComment(el->comment); + + class_def->AddMember(std::move(string_member)); + return true; } -std::unique_ptr<ClassDefinition> generateManifestClass(IDiagnostics* diag, xml::XmlResource* res) { - xml::Element* el = xml::findRootElement(res->root.get()); - if (!el) { - diag->error(DiagMessage(res->file.source) << "no root tag defined"); - return {}; +std::unique_ptr<ClassDefinition> GenerateManifestClass(IDiagnostics* diag, + xml::XmlResource* res) { + xml::Element* el = xml::FindRootElement(res->root.get()); + if (!el) { + diag->Error(DiagMessage(res->file.source) << "no root tag defined"); + return {}; + } + + if (el->name != "manifest" && !el->namespace_uri.empty()) { + diag->Error(DiagMessage(res->file.source) + << "no <manifest> root tag defined"); + return {}; + } + + std::unique_ptr<ClassDefinition> permission_class = + util::make_unique<ClassDefinition>("permission", ClassQualifier::Static, + false); + std::unique_ptr<ClassDefinition> permission_group_class = + util::make_unique<ClassDefinition>("permission_group", + ClassQualifier::Static, false); + + bool error = false; + std::vector<xml::Element*> children = el->GetChildElements(); + for (xml::Element* child_el : children) { + if (child_el->namespace_uri.empty()) { + if (child_el->name == "permission") { + error |= !WriteSymbol(res->file.source, diag, child_el, + permission_class.get()); + } else if (child_el->name == "permission-group") { + error |= !WriteSymbol(res->file.source, diag, child_el, + permission_group_class.get()); + } } - - if (el->name != "manifest" && !el->namespaceUri.empty()) { - diag->error(DiagMessage(res->file.source) << "no <manifest> root tag defined"); - return {}; - } - - std::unique_ptr<ClassDefinition> permissionClass = - util::make_unique<ClassDefinition>("permission", ClassQualifier::Static, false); - std::unique_ptr<ClassDefinition> permissionGroupClass = - util::make_unique<ClassDefinition>("permission_group", ClassQualifier::Static, false); - - bool error = false; - - std::vector<xml::Element*> children = el->getChildElements(); - for (xml::Element* childEl : children) { - if (childEl->namespaceUri.empty()) { - if (childEl->name == "permission") { - error |= !writeSymbol(res->file.source, diag, childEl, permissionClass.get()); - } else if (childEl->name == "permission-group") { - error |= !writeSymbol(res->file.source, diag, childEl, permissionGroupClass.get()); - } - } - } - - if (error) { - return {}; - } - - std::unique_ptr<ClassDefinition> manifestClass = - util::make_unique<ClassDefinition>("Manifest", ClassQualifier::None, false); - manifestClass->addMember(std::move(permissionClass)); - manifestClass->addMember(std::move(permissionGroupClass)); - return manifestClass; + } + + if (error) { + return {}; + } + + std::unique_ptr<ClassDefinition> manifest_class = + util::make_unique<ClassDefinition>("Manifest", ClassQualifier::None, + false); + manifest_class->AddMember(std::move(permission_class)); + manifest_class->AddMember(std::move(permission_group_class)); + return manifest_class; } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/java/ManifestClassGenerator.h b/tools/aapt2/java/ManifestClassGenerator.h index 18176483fa01..b12202a8d137 100644 --- a/tools/aapt2/java/ManifestClassGenerator.h +++ b/tools/aapt2/java/ManifestClassGenerator.h @@ -19,14 +19,11 @@ #include "Diagnostics.h" #include "java/ClassDefinition.h" -#include "util/StringPiece.h" #include "xml/XmlDom.h" -#include <iostream> - namespace aapt { -std::unique_ptr<ClassDefinition> generateManifestClass(IDiagnostics* diag, +std::unique_ptr<ClassDefinition> GenerateManifestClass(IDiagnostics* diag, xml::XmlResource* res); } // namespace aapt diff --git a/tools/aapt2/java/ManifestClassGenerator_test.cpp b/tools/aapt2/java/ManifestClassGenerator_test.cpp index eecb54464d40..5ebf508807e8 100644 --- a/tools/aapt2/java/ManifestClassGenerator_test.cpp +++ b/tools/aapt2/java/ManifestClassGenerator_test.cpp @@ -15,30 +15,33 @@ */ #include "java/ManifestClassGenerator.h" + #include "test/Test.h" namespace aapt { -static ::testing::AssertionResult getManifestClassText(IAaptContext* context, xml::XmlResource* res, - std::string* outStr) { - std::unique_ptr<ClassDefinition> manifestClass = generateManifestClass( - context->getDiagnostics(), res); - if (!manifestClass) { - return ::testing::AssertionFailure() << "manifestClass == nullptr"; - } - - std::stringstream out; - if (!manifestClass->writeJavaFile(manifestClass.get(), "android", true, &out)) { - return ::testing::AssertionFailure() << "failed to write java file"; - } - - *outStr = out.str(); - return ::testing::AssertionSuccess(); +static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, + xml::XmlResource* res, + std::string* out_str) { + std::unique_ptr<ClassDefinition> manifest_class = + GenerateManifestClass(context->GetDiagnostics(), res); + if (!manifest_class) { + return ::testing::AssertionFailure() << "manifest_class == nullptr"; + } + + std::stringstream out; + if (!manifest_class->WriteJavaFile(manifest_class.get(), "android", true, + &out)) { + return ::testing::AssertionFailure() << "failed to write java file"; + } + + *out_str = out.str(); + return ::testing::AssertionSuccess(); } TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); - std::unique_ptr<xml::XmlResource> manifest = test::buildXmlDom(R"EOF( + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <permission android:name="android.permission.ACCESS_INTERNET" /> <permission android:name="android.DO_DANGEROUS_THINGS" /> @@ -46,46 +49,51 @@ TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) { <permission-group android:name="foo.bar.PERMISSION" /> </manifest>)EOF"); - std::string actual; - ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual)); - - const size_t permissionClassPos = actual.find("public static final class permission {"); - const size_t permissionGroupClassPos = - actual.find("public static final class permission_group {"); - ASSERT_NE(std::string::npos, permissionClassPos); - ASSERT_NE(std::string::npos, permissionGroupClassPos); - - // - // Make sure these permissions are in the permission class. - // - - size_t pos = actual.find("public static final String ACCESS_INTERNET=" - "\"android.permission.ACCESS_INTERNET\";"); - EXPECT_GT(pos, permissionClassPos); - EXPECT_LT(pos, permissionGroupClassPos); - - pos = actual.find("public static final String DO_DANGEROUS_THINGS=" - "\"android.DO_DANGEROUS_THINGS\";"); - EXPECT_GT(pos, permissionClassPos); - EXPECT_LT(pos, permissionGroupClassPos); - - pos = actual.find("public static final String HUH=\"com.test.sample.permission.HUH\";"); - EXPECT_GT(pos, permissionClassPos); - EXPECT_LT(pos, permissionGroupClassPos); - - // - // Make sure these permissions are in the permission_group class - // - - pos = actual.find("public static final String PERMISSION=" - "\"foo.bar.PERMISSION\";"); - EXPECT_GT(pos, permissionGroupClassPos); - EXPECT_LT(pos, std::string::npos); + std::string actual; + ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual)); + + const size_t permission_class_pos = + actual.find("public static final class permission {"); + const size_t permission_croup_class_pos = + actual.find("public static final class permission_group {"); + ASSERT_NE(std::string::npos, permission_class_pos); + ASSERT_NE(std::string::npos, permission_croup_class_pos); + + // + // Make sure these permissions are in the permission class. + // + + size_t pos = actual.find( + "public static final String ACCESS_INTERNET=" + "\"android.permission.ACCESS_INTERNET\";"); + EXPECT_GT(pos, permission_class_pos); + EXPECT_LT(pos, permission_croup_class_pos); + + pos = actual.find( + "public static final String DO_DANGEROUS_THINGS=" + "\"android.DO_DANGEROUS_THINGS\";"); + EXPECT_GT(pos, permission_class_pos); + EXPECT_LT(pos, permission_croup_class_pos); + + pos = actual.find( + "public static final String HUH=\"com.test.sample.permission.HUH\";"); + EXPECT_GT(pos, permission_class_pos); + EXPECT_LT(pos, permission_croup_class_pos); + + // + // Make sure these permissions are in the permission_group class + // + + pos = actual.find( + "public static final String PERMISSION=" + "\"foo.bar.PERMISSION\";"); + EXPECT_GT(pos, permission_croup_class_pos); + EXPECT_LT(pos, std::string::npos); } TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); - std::unique_ptr<xml::XmlResource> manifest = test::buildXmlDom(R"EOF( + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Required to access the internet. Added in API 1. --> @@ -98,36 +106,36 @@ TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) { <permission android:name="android.permission.SECRET" /> </manifest>)EOF"); - std::string actual; - ASSERT_TRUE(getManifestClassText(context.get(), manifest.get(), &actual)); + std::string actual; + ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual)); - const char* expectedAccessInternet = -R"EOF( /** + const char* expected_access_internet = + R"EOF( /** * Required to access the internet. * Added in API 1. */ public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)EOF"; - EXPECT_NE(std::string::npos, actual.find(expectedAccessInternet)); + EXPECT_NE(std::string::npos, actual.find(expected_access_internet)); - const char* expectedPlayOutside = -R"EOF( /** + const char* expected_play_outside = + R"EOF( /** * @deprecated This permission is for playing outside. */ @Deprecated public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)EOF"; - EXPECT_NE(std::string::npos, actual.find(expectedPlayOutside)); + EXPECT_NE(std::string::npos, actual.find(expected_play_outside)); - const char* expectedSecret = -R"EOF( /** + const char* expected_secret = + R"EOF( /** * This is a private permission for system only! * @hide */ @android.annotation.SystemApi public static final String SECRET="android.permission.SECRET";)EOF"; - EXPECT_NE(std::string::npos, actual.find(expectedSecret)); + EXPECT_NE(std::string::npos, actual.find(expected_secret)); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp index 902ec4cf3a0d..624a559c4dae 100644 --- a/tools/aapt2/java/ProguardRules.cpp +++ b/tools/aapt2/java/ProguardRules.cpp @@ -15,254 +15,281 @@ */ #include "java/ProguardRules.h" -#include "util/Util.h" -#include "xml/XmlDom.h" #include <memory> #include <string> +#include "android-base/macros.h" + +#include "util/Util.h" +#include "xml/XmlDom.h" + namespace aapt { namespace proguard { class BaseVisitor : public xml::Visitor { -public: - BaseVisitor(const Source& source, KeepSet* keepSet) : mSource(source), mKeepSet(keepSet) { - } + public: + BaseVisitor(const Source& source, KeepSet* keep_set) + : source_(source), keep_set_(keep_set) {} - virtual void visit(xml::Text*) override {}; + virtual void Visit(xml::Text*) override{}; - virtual void visit(xml::Namespace* node) override { - for (const auto& child : node->children) { - child->accept(this); - } + virtual void Visit(xml::Namespace* node) override { + for (const auto& child : node->children) { + child->Accept(this); } - - virtual void visit(xml::Element* node) override { - if (!node->namespaceUri.empty()) { - Maybe<xml::ExtractedPackage> maybePackage = xml::extractPackageFromNamespace( - node->namespaceUri); - if (maybePackage) { - // This is a custom view, let's figure out the class name from this. - std::string package = maybePackage.value().package + "." + node->name; - if (util::isJavaClassName(package)) { - addClass(node->lineNumber, package); - } - } - } else if (util::isJavaClassName(node->name)) { - addClass(node->lineNumber, node->name); - } - - for (const auto& child: node->children) { - child->accept(this); + } + + virtual void Visit(xml::Element* node) override { + if (!node->namespace_uri.empty()) { + Maybe<xml::ExtractedPackage> maybe_package = + xml::ExtractPackageFromNamespace(node->namespace_uri); + if (maybe_package) { + // This is a custom view, let's figure out the class name from this. + std::string package = maybe_package.value().package + "." + node->name; + if (util::IsJavaClassName(package)) { + AddClass(node->line_number, package); } + } + } else if (util::IsJavaClassName(node->name)) { + AddClass(node->line_number, node->name); } -protected: - void addClass(size_t lineNumber, const std::string& className) { - mKeepSet->addClass(Source(mSource.path, lineNumber), className); + for (const auto& child : node->children) { + child->Accept(this); } + } - void addMethod(size_t lineNumber, const std::string& methodName) { - mKeepSet->addMethod(Source(mSource.path, lineNumber), methodName); - } + protected: + void AddClass(size_t line_number, const std::string& class_name) { + keep_set_->AddClass(Source(source_.path, line_number), class_name); + } -private: - Source mSource; - KeepSet* mKeepSet; + void AddMethod(size_t line_number, const std::string& method_name) { + keep_set_->AddMethod(Source(source_.path, line_number), method_name); + } + + private: + DISALLOW_COPY_AND_ASSIGN(BaseVisitor); + + Source source_; + KeepSet* keep_set_; }; -struct LayoutVisitor : public BaseVisitor { - LayoutVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) { +class LayoutVisitor : public BaseVisitor { + public: + LayoutVisitor(const Source& source, KeepSet* keep_set) + : BaseVisitor(source, keep_set) {} + + virtual void Visit(xml::Element* node) override { + bool check_class = false; + bool check_name = false; + if (node->namespace_uri.empty()) { + check_class = node->name == "view" || node->name == "fragment"; + } else if (node->namespace_uri == xml::kSchemaAndroid) { + check_name = node->name == "fragment"; } - virtual void visit(xml::Element* node) override { - bool checkClass = false; - bool checkName = false; - if (node->namespaceUri.empty()) { - checkClass = node->name == "view" || node->name == "fragment"; - } else if (node->namespaceUri == xml::kSchemaAndroid) { - checkName = node->name == "fragment"; - } + for (const auto& attr : node->attributes) { + if (check_class && attr.namespace_uri.empty() && attr.name == "class" && + util::IsJavaClassName(attr.value)) { + AddClass(node->line_number, attr.value); + } else if (check_name && attr.namespace_uri == xml::kSchemaAndroid && + attr.name == "name" && util::IsJavaClassName(attr.value)) { + AddClass(node->line_number, attr.value); + } else if (attr.namespace_uri == xml::kSchemaAndroid && + attr.name == "onClick") { + AddMethod(node->line_number, attr.value); + } + } - for (const auto& attr : node->attributes) { - if (checkClass && attr.namespaceUri.empty() && attr.name == "class" && - util::isJavaClassName(attr.value)) { - addClass(node->lineNumber, attr.value); - } else if (checkName && attr.namespaceUri == xml::kSchemaAndroid && - attr.name == "name" && util::isJavaClassName(attr.value)) { - addClass(node->lineNumber, attr.value); - } else if (attr.namespaceUri == xml::kSchemaAndroid && attr.name == "onClick") { - addMethod(node->lineNumber, attr.value); - } - } + BaseVisitor::Visit(node); + } - BaseVisitor::visit(node); - } + private: + DISALLOW_COPY_AND_ASSIGN(LayoutVisitor); }; -struct XmlResourceVisitor : public BaseVisitor { - XmlResourceVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) { +class XmlResourceVisitor : public BaseVisitor { + public: + XmlResourceVisitor(const Source& source, KeepSet* keep_set) + : BaseVisitor(source, keep_set) {} + + virtual void Visit(xml::Element* node) override { + bool check_fragment = false; + if (node->namespace_uri.empty()) { + check_fragment = + node->name == "PreferenceScreen" || node->name == "header"; } - virtual void visit(xml::Element* node) override { - bool checkFragment = false; - if (node->namespaceUri.empty()) { - checkFragment = node->name == "PreferenceScreen" || node->name == "header"; - } + if (check_fragment) { + xml::Attribute* attr = + node->FindAttribute(xml::kSchemaAndroid, "fragment"); + if (attr && util::IsJavaClassName(attr->value)) { + AddClass(node->line_number, attr->value); + } + } - if (checkFragment) { - xml::Attribute* attr = node->findAttribute(xml::kSchemaAndroid, "fragment"); - if (attr && util::isJavaClassName(attr->value)) { - addClass(node->lineNumber, attr->value); - } - } + BaseVisitor::Visit(node); + } - BaseVisitor::visit(node); - } + private: + DISALLOW_COPY_AND_ASSIGN(XmlResourceVisitor); }; -struct TransitionVisitor : public BaseVisitor { - TransitionVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) { +class TransitionVisitor : public BaseVisitor { + public: + TransitionVisitor(const Source& source, KeepSet* keep_set) + : BaseVisitor(source, keep_set) {} + + virtual void Visit(xml::Element* node) override { + bool check_class = + node->namespace_uri.empty() && + (node->name == "transition" || node->name == "pathMotion"); + if (check_class) { + xml::Attribute* attr = node->FindAttribute({}, "class"); + if (attr && util::IsJavaClassName(attr->value)) { + AddClass(node->line_number, attr->value); + } } - virtual void visit(xml::Element* node) override { - bool checkClass = node->namespaceUri.empty() && - (node->name == "transition" || node->name == "pathMotion"); - if (checkClass) { - xml::Attribute* attr = node->findAttribute({}, "class"); - if (attr && util::isJavaClassName(attr->value)) { - addClass(node->lineNumber, attr->value); - } - } + BaseVisitor::Visit(node); + } - BaseVisitor::visit(node); - } + private: + DISALLOW_COPY_AND_ASSIGN(TransitionVisitor); }; -struct ManifestVisitor : public BaseVisitor { - ManifestVisitor(const Source& source, KeepSet* keepSet, bool mainDexOnly) - : BaseVisitor(source, keepSet), mMainDexOnly(mainDexOnly) { - } +class ManifestVisitor : public BaseVisitor { + public: + ManifestVisitor(const Source& source, KeepSet* keep_set, bool main_dex_only) + : BaseVisitor(source, keep_set), main_dex_only_(main_dex_only) {} + + virtual void Visit(xml::Element* node) override { + if (node->namespace_uri.empty()) { + bool get_name = false; + if (node->name == "manifest") { + xml::Attribute* attr = node->FindAttribute({}, "package"); + if (attr) { + package_ = attr->value; + } + } else if (node->name == "application") { + get_name = true; + xml::Attribute* attr = + node->FindAttribute(xml::kSchemaAndroid, "backupAgent"); + if (attr) { + Maybe<std::string> result = + util::GetFullyQualifiedClassName(package_, attr->value); + if (result) { + AddClass(node->line_number, result.value()); + } + } + if (main_dex_only_) { + xml::Attribute* default_process = + node->FindAttribute(xml::kSchemaAndroid, "process"); + if (default_process) { + default_process_ = default_process->value; + } + } + } else if (node->name == "activity" || node->name == "service" || + node->name == "receiver" || node->name == "provider") { + get_name = true; + + if (main_dex_only_) { + xml::Attribute* component_process = + node->FindAttribute(xml::kSchemaAndroid, "process"); - virtual void visit(xml::Element* node) override { - if (node->namespaceUri.empty()) { - bool getName = false; - if (node->name == "manifest") { - xml::Attribute* attr = node->findAttribute({}, "package"); - if (attr) { - mPackage = attr->value; - } - } else if (node->name == "application") { - getName = true; - xml::Attribute* attr = node->findAttribute(xml::kSchemaAndroid, "backupAgent"); - if (attr) { - Maybe<std::string> result = util::getFullyQualifiedClassName(mPackage, - attr->value); - if (result) { - addClass(node->lineNumber, result.value()); - } - } - if (mMainDexOnly) { - xml::Attribute* defaultProcess = node->findAttribute(xml::kSchemaAndroid, - "process"); - if (defaultProcess) { - mDefaultProcess = defaultProcess->value; - } - } - } else if (node->name == "activity" || node->name == "service" || - node->name == "receiver" || node->name == "provider") { - getName = true; - - if (mMainDexOnly) { - xml::Attribute* componentProcess = node->findAttribute(xml::kSchemaAndroid, - "process"); - - const std::string& process = componentProcess ? componentProcess->value - : mDefaultProcess; - getName = !process.empty() && process[0] != ':'; - } - } else if (node-> name == "instrumentation") { - getName = true; - } - - if (getName) { - xml::Attribute* attr = node->findAttribute(xml::kSchemaAndroid, "name"); - getName = attr != nullptr; - - if (getName) { - Maybe<std::string> result = util::getFullyQualifiedClassName(mPackage, - attr->value); - if (result) { - addClass(node->lineNumber, result.value()); - } - } - } + const std::string& process = + component_process ? component_process->value : default_process_; + get_name = !process.empty() && process[0] != ':'; } - BaseVisitor::visit(node); + } else if (node->name == "instrumentation") { + get_name = true; + } + + if (get_name) { + xml::Attribute* attr = node->FindAttribute(xml::kSchemaAndroid, "name"); + get_name = attr != nullptr; + + if (get_name) { + Maybe<std::string> result = + util::GetFullyQualifiedClassName(package_, attr->value); + if (result) { + AddClass(node->line_number, result.value()); + } + } + } } + BaseVisitor::Visit(node); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ManifestVisitor); -private: - std::string mPackage; - const bool mMainDexOnly; - std::string mDefaultProcess; + std::string package_; + const bool main_dex_only_; + std::string default_process_; }; -bool collectProguardRulesForManifest(const Source& source, xml::XmlResource* res, - KeepSet* keepSet, bool mainDexOnly) { - ManifestVisitor visitor(source, keepSet, mainDexOnly); - if (res->root) { - res->root->accept(&visitor); - return true; - } - return false; +bool CollectProguardRulesForManifest(const Source& source, + xml::XmlResource* res, KeepSet* keep_set, + bool main_dex_only) { + ManifestVisitor visitor(source, keep_set, main_dex_only); + if (res->root) { + res->root->Accept(&visitor); + return true; + } + return false; } -bool collectProguardRules(const Source& source, xml::XmlResource* res, KeepSet* keepSet) { - if (!res->root) { - return false; - } - - switch (res->file.name.type) { - case ResourceType::kLayout: { - LayoutVisitor visitor(source, keepSet); - res->root->accept(&visitor); - break; - } +bool CollectProguardRules(const Source& source, xml::XmlResource* res, + KeepSet* keep_set) { + if (!res->root) { + return false; + } - case ResourceType::kXml: { - XmlResourceVisitor visitor(source, keepSet); - res->root->accept(&visitor); - break; - } + switch (res->file.name.type) { + case ResourceType::kLayout: { + LayoutVisitor visitor(source, keep_set); + res->root->Accept(&visitor); + break; + } - case ResourceType::kTransition: { - TransitionVisitor visitor(source, keepSet); - res->root->accept(&visitor); - break; - } + case ResourceType::kXml: { + XmlResourceVisitor visitor(source, keep_set); + res->root->Accept(&visitor); + break; + } - default: - break; + case ResourceType::kTransition: { + TransitionVisitor visitor(source, keep_set); + res->root->Accept(&visitor); + break; } - return true; + + default: + break; + } + return true; } -bool writeKeepSet(std::ostream* out, const KeepSet& keepSet) { - for (const auto& entry : keepSet.mKeepSet) { - for (const Source& source : entry.second) { - *out << "# Referenced at " << source << "\n"; - } - *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl; +bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set) { + for (const auto& entry : keep_set.keep_set_) { + for (const Source& source : entry.second) { + *out << "# Referenced at " << source << "\n"; } + *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl; + } - for (const auto& entry : keepSet.mKeepMethodSet) { - for (const Source& source : entry.second) { - *out << "# Referenced at " << source << "\n"; - } - *out << "-keepclassmembers class * { *** " << entry.first << "(...); }\n" << std::endl; + for (const auto& entry : keep_set.keep_method_set_) { + for (const Source& source : entry.second) { + *out << "# Referenced at " << source << "\n"; } - return true; + *out << "-keepclassmembers class * { *** " << entry.first << "(...); }\n" + << std::endl; + } + return true; } -} // namespace proguard -} // namespace aapt +} // namespace proguard +} // namespace aapt diff --git a/tools/aapt2/java/ProguardRules.h b/tools/aapt2/java/ProguardRules.h index 7578ec2abf58..3c349bab1217 100644 --- a/tools/aapt2/java/ProguardRules.h +++ b/tools/aapt2/java/ProguardRules.h @@ -17,42 +17,42 @@ #ifndef AAPT_PROGUARD_RULES_H #define AAPT_PROGUARD_RULES_H -#include "Resource.h" -#include "Source.h" -#include "xml/XmlDom.h" - #include <map> #include <ostream> #include <set> #include <string> +#include "Resource.h" +#include "Source.h" +#include "xml/XmlDom.h" + namespace aapt { namespace proguard { class KeepSet { public: - inline void addClass(const Source& source, const std::string& className) { - mKeepSet[className].insert(source); + inline void AddClass(const Source& source, const std::string& class_name) { + keep_set_[class_name].insert(source); } - inline void addMethod(const Source& source, const std::string& methodName) { - mKeepMethodSet[methodName].insert(source); + inline void AddMethod(const Source& source, const std::string& method_name) { + keep_method_set_[method_name].insert(source); } private: - friend bool writeKeepSet(std::ostream* out, const KeepSet& keepSet); + friend bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set); - std::map<std::string, std::set<Source>> mKeepSet; - std::map<std::string, std::set<Source>> mKeepMethodSet; + std::map<std::string, std::set<Source>> keep_set_; + std::map<std::string, std::set<Source>> keep_method_set_; }; -bool collectProguardRulesForManifest(const Source& source, - xml::XmlResource* res, KeepSet* keepSet, - bool mainDexOnly = false); -bool collectProguardRules(const Source& source, xml::XmlResource* res, - KeepSet* keepSet); +bool CollectProguardRulesForManifest(const Source& source, + xml::XmlResource* res, KeepSet* keep_set, + bool main_dex_only = false); +bool CollectProguardRules(const Source& source, xml::XmlResource* res, + KeepSet* keep_set); -bool writeKeepSet(std::ostream* out, const KeepSet& keepSet); +bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set); } // namespace proguard } // namespace aapt diff --git a/tools/aapt2/jni/aapt2_jni.cpp b/tools/aapt2/jni/aapt2_jni.cpp index dff77b972b08..211ada8db078 100644 --- a/tools/aapt2/jni/aapt2_jni.cpp +++ b/tools/aapt2/jni/aapt2_jni.cpp @@ -14,84 +14,81 @@ * limitations under the License. */ +#include "com_android_tools_aapt2_Aapt2.h" + #include <algorithm> -#include <cassert> #include <memory> #include <utility> #include <vector> -#include <ScopedUtfChars.h> +#include "android-base/logging.h" +#include "nativehelper/ScopedUtfChars.h" #include "util/Util.h" -#include "com_android_tools_aapt2_Aapt2.h" - namespace aapt { - extern int compile(const std::vector<StringPiece>& args); - extern int link(const std::vector<StringPiece>& args); +extern int Compile(const std::vector<StringPiece> &args); +extern int Link(const std::vector<StringPiece> &args); } /* * Converts a java List<String> into C++ vector<ScopedUtfChars>. */ static std::vector<ScopedUtfChars> list_to_utfchars(JNIEnv *env, jobject obj) { - std::vector<ScopedUtfChars> converted; + std::vector<ScopedUtfChars> converted; - // Call size() method on the list to know how many elements there are. - jclass list_cls = env->GetObjectClass(obj); - jmethodID size_method_id = env->GetMethodID(list_cls, "size", "()I"); - assert(size_method_id != 0); - jint size = env->CallIntMethod(obj, size_method_id); - assert(size >= 0); + // Call size() method on the list to know how many elements there are. + jclass list_cls = env->GetObjectClass(obj); + jmethodID size_method_id = env->GetMethodID(list_cls, "size", "()I"); + CHECK(size_method_id != 0); + jint size = env->CallIntMethod(obj, size_method_id); + CHECK(size >= 0); - // Now, iterate all strings in the list - // (note: generic erasure means get() return an Object) - jmethodID get_method_id = env->GetMethodID(list_cls, "get", "()Ljava/lang/Object;"); - for (jint i = 0; i < size; i++) { - // Call get(i) to get the string in the ith position. - jobject string_obj_uncast = env->CallObjectMethod(obj, get_method_id, i); - assert(string_obj_uncast != nullptr); - jstring string_obj = static_cast<jstring>(string_obj_uncast); - converted.push_back(ScopedUtfChars(env, string_obj)); - } + // Now, iterate all strings in the list + // (note: generic erasure means get() return an Object) + jmethodID get_method_id = + env->GetMethodID(list_cls, "get", "()Ljava/lang/Object;"); + for (jint i = 0; i < size; i++) { + // Call get(i) to get the string in the ith position. + jobject string_obj_uncast = env->CallObjectMethod(obj, get_method_id, i); + CHECK(string_obj_uncast != nullptr); + jstring string_obj = static_cast<jstring>(string_obj_uncast); + converted.push_back(ScopedUtfChars(env, string_obj)); + } - return converted; + return converted; } /* * Extracts all StringPiece from the ScopedUtfChars instances. - * + * * The returned pieces can only be used while the original ones have not been * destroyed. */ static std::vector<aapt::StringPiece> extract_pieces( - const std::vector<ScopedUtfChars> &strings) { - std::vector<aapt::StringPiece> pieces; - - std::for_each( - strings.begin(), - strings.end(), - [&pieces](const ScopedUtfChars &p) { - pieces.push_back(p.c_str()); - }); - - return pieces; + const std::vector<ScopedUtfChars> &strings) { + std::vector<aapt::StringPiece> pieces; + + std::for_each( + strings.begin(), strings.end(), + [&pieces](const ScopedUtfChars &p) { pieces.push_back(p.c_str()); }); + + return pieces; } JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2_nativeCompile( - JNIEnv *env, - jclass aapt_obj, - jobject arguments_obj) { - std::vector<ScopedUtfChars> compile_args_jni = list_to_utfchars(env, arguments_obj); - std::vector<aapt::StringPiece> compile_args = extract_pieces(compile_args_jni); - aapt::compile(compile_args); + JNIEnv *env, jclass aapt_obj, jobject arguments_obj) { + std::vector<ScopedUtfChars> compile_args_jni = + list_to_utfchars(env, arguments_obj); + std::vector<aapt::StringPiece> compile_args = + extract_pieces(compile_args_jni); + aapt::Compile(compile_args); } JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2_nativeLink( - JNIEnv *env, - jclass aapt_obj, - jobject arguments_obj) { - std::vector<ScopedUtfChars> link_args_jni = list_to_utfchars(env, arguments_obj); - std::vector<aapt::StringPiece> link_args = extract_pieces(link_args_jni); - aapt::link(link_args); + JNIEnv *env, jclass aapt_obj, jobject arguments_obj) { + std::vector<ScopedUtfChars> link_args_jni = + list_to_utfchars(env, arguments_obj); + std::vector<aapt::StringPiece> link_args = extract_pieces(link_args_jni); + aapt::Link(link_args); } diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp index 5ba981931f3b..77471ea5d0da 100644 --- a/tools/aapt2/link/AutoVersioner.cpp +++ b/tools/aapt2/link/AutoVersioner.cpp @@ -14,34 +14,36 @@ * limitations under the License. */ +#include "link/Linkers.h" + +#include <algorithm> + +#include "android-base/logging.h" + #include "ConfigDescription.h" #include "ResourceTable.h" #include "SdkConstants.h" #include "ValueVisitor.h" -#include "link/Linkers.h" - -#include <algorithm> -#include <cassert> namespace aapt { -bool shouldGenerateVersionedResource(const ResourceEntry* entry, +bool ShouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config, - const int sdkVersionToGenerate) { + const int sdk_version_to_generate) { // We assume the caller is trying to generate a version greater than the // current configuration. - assert(sdkVersionToGenerate > config.sdkVersion); + CHECK(sdk_version_to_generate > config.sdkVersion); - const auto endIter = entry->values.end(); + const auto end_iter = entry->values.end(); auto iter = entry->values.begin(); - for (; iter != endIter; ++iter) { + for (; iter != end_iter; ++iter) { if ((*iter)->config == config) { break; } } // The source config came from this list, so it should be here. - assert(iter != entry->values.end()); + CHECK(iter != entry->values.end()); ++iter; // The next configuration either only varies in sdkVersion, or it is @@ -53,12 +55,12 @@ bool shouldGenerateVersionedResource(const ResourceEntry* entry, // than other // qualifiers, so we need to iterate through the entire list to be sure there // are no higher sdk level versions of this resource. - ConfigDescription tempConfig(config); - for (; iter != endIter; ++iter) { - tempConfig.sdkVersion = (*iter)->config.sdkVersion; - if (tempConfig == (*iter)->config) { + ConfigDescription temp_config(config); + for (; iter != end_iter; ++iter) { + temp_config.sdkVersion = (*iter)->config.sdkVersion; + if (temp_config == (*iter)->config) { // The two configs are the same, check the sdk version. - return sdkVersionToGenerate < (*iter)->config.sdkVersion; + return sdk_version_to_generate < (*iter)->config.sdkVersion; } } @@ -66,7 +68,7 @@ bool shouldGenerateVersionedResource(const ResourceEntry* entry, return true; } -bool AutoVersioner::consume(IAaptContext* context, ResourceTable* table) { +bool AutoVersioner::Consume(IAaptContext* context, ResourceTable* table) { for (auto& package : table->packages) { for (auto& type : package->types) { if (type->type != ResourceType::kStyle) { @@ -75,36 +77,37 @@ bool AutoVersioner::consume(IAaptContext* context, ResourceTable* table) { for (auto& entry : type->entries) { for (size_t i = 0; i < entry->values.size(); i++) { - ResourceConfigValue* configValue = entry->values[i].get(); - if (configValue->config.sdkVersion >= SDK_LOLLIPOP_MR1) { + ResourceConfigValue* config_value = entry->values[i].get(); + if (config_value->config.sdkVersion >= SDK_LOLLIPOP_MR1) { // If this configuration is only used on L-MR1 then we don't need // to do anything since we use private attributes since that // version. continue; } - if (Style* style = valueCast<Style>(configValue->value.get())) { - Maybe<size_t> minSdkStripped; + if (Style* style = ValueCast<Style>(config_value->value.get())) { + Maybe<size_t> min_sdk_stripped; std::vector<Style::Entry> stripped; auto iter = style->entries.begin(); while (iter != style->entries.end()) { - assert(iter->key.id && "IDs must be assigned and linked"); + CHECK(bool(iter->key.id)) << "IDs must be assigned and linked"; // Find the SDK level that is higher than the configuration // allows. - const size_t sdkLevel = - findAttributeSdkLevel(iter->key.id.value()); - if (sdkLevel > - std::max<size_t>(configValue->config.sdkVersion, 1)) { + const size_t sdk_level = + FindAttributeSdkLevel(iter->key.id.value()); + if (sdk_level > + std::max<size_t>(config_value->config.sdkVersion, 1)) { // Record that we are about to strip this. stripped.emplace_back(std::move(*iter)); // We use the smallest SDK level to generate the new style. - if (minSdkStripped) { - minSdkStripped = std::min(minSdkStripped.value(), sdkLevel); + if (min_sdk_stripped) { + min_sdk_stripped = + std::min(min_sdk_stripped.value(), sdk_level); } else { - minSdkStripped = sdkLevel; + min_sdk_stripped = sdk_level; } // Erase this from this style. @@ -114,31 +117,31 @@ bool AutoVersioner::consume(IAaptContext* context, ResourceTable* table) { ++iter; } - if (minSdkStripped && !stripped.empty()) { + if (min_sdk_stripped && !stripped.empty()) { // We found attributes from a higher SDK level. Check that // there is no other defined resource for the version we want to // generate. - if (shouldGenerateVersionedResource(entry.get(), - configValue->config, - minSdkStripped.value())) { + if (ShouldGenerateVersionedResource(entry.get(), + config_value->config, + min_sdk_stripped.value())) { // Let's create a new Style for this versioned resource. - ConfigDescription newConfig(configValue->config); - newConfig.sdkVersion = minSdkStripped.value(); + ConfigDescription new_config(config_value->config); + new_config.sdkVersion = min_sdk_stripped.value(); - std::unique_ptr<Style> newStyle( - style->clone(&table->stringPool)); - newStyle->setComment(style->getComment()); - newStyle->setSource(style->getSource()); + std::unique_ptr<Style> new_style( + style->Clone(&table->string_pool)); + new_style->SetComment(style->GetComment()); + new_style->SetSource(style->GetSource()); // Move the previously stripped attributes into this style. - newStyle->entries.insert( - newStyle->entries.end(), + new_style->entries.insert( + new_style->entries.end(), std::make_move_iterator(stripped.begin()), std::make_move_iterator(stripped.end())); // Insert the new Resource into the correct place. - entry->findOrCreateValue(newConfig, {})->value = - std::move(newStyle); + entry->FindOrCreateValue(new_config, {})->value = + std::move(new_style); } } } diff --git a/tools/aapt2/link/AutoVersioner_test.cpp b/tools/aapt2/link/AutoVersioner_test.cpp index 04bf9cd7fc0b..755af0a1c6cc 100644 --- a/tools/aapt2/link/AutoVersioner_test.cpp +++ b/tools/aapt2/link/AutoVersioner_test.cpp @@ -14,121 +14,124 @@ * limitations under the License. */ -#include "ConfigDescription.h" #include "link/Linkers.h" + +#include "ConfigDescription.h" #include "test/Test.h" namespace aapt { TEST(AutoVersionerTest, GenerateVersionedResources) { - const ConfigDescription defaultConfig = {}; - const ConfigDescription landConfig = test::parseConfigOrDie("land"); - const ConfigDescription sw600dpLandConfig = - test::parseConfigOrDie("sw600dp-land"); + const ConfigDescription land_config = test::ParseConfigOrDie("land"); + const ConfigDescription sw600dp_land_config = + test::ParseConfigOrDie("sw600dp-land"); ResourceEntry entry("foo"); + entry.values.push_back(util::make_unique<ResourceConfigValue>( + ConfigDescription::DefaultConfig(), "")); entry.values.push_back( - util::make_unique<ResourceConfigValue>(defaultConfig, "")); - entry.values.push_back( - util::make_unique<ResourceConfigValue>(landConfig, "")); + util::make_unique<ResourceConfigValue>(land_config, "")); entry.values.push_back( - util::make_unique<ResourceConfigValue>(sw600dpLandConfig, "")); + util::make_unique<ResourceConfigValue>(sw600dp_land_config, "")); - EXPECT_TRUE(shouldGenerateVersionedResource(&entry, defaultConfig, 17)); - EXPECT_TRUE(shouldGenerateVersionedResource(&entry, landConfig, 17)); + EXPECT_TRUE(ShouldGenerateVersionedResource( + &entry, ConfigDescription::DefaultConfig(), 17)); + EXPECT_TRUE(ShouldGenerateVersionedResource(&entry, land_config, 17)); } TEST(AutoVersionerTest, GenerateVersionedResourceWhenHigherVersionExists) { - const ConfigDescription defaultConfig = {}; - const ConfigDescription sw600dpV13Config = - test::parseConfigOrDie("sw600dp-v13"); - const ConfigDescription v21Config = test::parseConfigOrDie("v21"); + const ConfigDescription sw600dp_v13_config = + test::ParseConfigOrDie("sw600dp-v13"); + const ConfigDescription v21_config = test::ParseConfigOrDie("v21"); ResourceEntry entry("foo"); + entry.values.push_back(util::make_unique<ResourceConfigValue>( + ConfigDescription::DefaultConfig(), "")); entry.values.push_back( - util::make_unique<ResourceConfigValue>(defaultConfig, "")); + util::make_unique<ResourceConfigValue>(sw600dp_v13_config, "")); entry.values.push_back( - util::make_unique<ResourceConfigValue>(sw600dpV13Config, "")); - entry.values.push_back(util::make_unique<ResourceConfigValue>(v21Config, "")); + util::make_unique<ResourceConfigValue>(v21_config, "")); - EXPECT_TRUE(shouldGenerateVersionedResource(&entry, defaultConfig, 17)); - EXPECT_FALSE(shouldGenerateVersionedResource(&entry, defaultConfig, 22)); + EXPECT_TRUE(ShouldGenerateVersionedResource( + &entry, ConfigDescription::DefaultConfig(), 17)); + EXPECT_FALSE(ShouldGenerateVersionedResource( + &entry, ConfigDescription::DefaultConfig(), 22)); } TEST(AutoVersionerTest, VersionStylesForTable) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("app", 0x7f) - .addValue( - "app:style/Foo", test::parseConfigOrDie("v4"), + .SetPackageId("app", 0x7f) + .AddValue( + "app:style/Foo", test::ParseConfigOrDie("v4"), ResourceId(0x7f020000), test::StyleBuilder() - .addItem("android:attr/onClick", ResourceId(0x0101026f), + .AddItem("android:attr/onClick", ResourceId(0x0101026f), util::make_unique<Id>()) - .addItem("android:attr/paddingStart", ResourceId(0x010103b3), + .AddItem("android:attr/paddingStart", ResourceId(0x010103b3), util::make_unique<Id>()) - .addItem("android:attr/requiresSmallestWidthDp", + .AddItem("android:attr/requiresSmallestWidthDp", ResourceId(0x01010364), util::make_unique<Id>()) - .addItem("android:attr/colorAccent", ResourceId(0x01010435), + .AddItem("android:attr/colorAccent", ResourceId(0x01010435), util::make_unique<Id>()) - .build()) - .addValue( - "app:style/Foo", test::parseConfigOrDie("v21"), + .Build()) + .AddValue( + "app:style/Foo", test::ParseConfigOrDie("v21"), ResourceId(0x7f020000), test::StyleBuilder() - .addItem("android:attr/paddingEnd", ResourceId(0x010103b4), + .AddItem("android:attr/paddingEnd", ResourceId(0x010103b4), util::make_unique<Id>()) - .build()) - .build(); + .Build()) + .Build(); std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .setCompilationPackage("app") - .setPackageId(0x7f) - .build(); + .SetCompilationPackage("app") + .SetPackageId(0x7f) + .Build(); AutoVersioner versioner; - ASSERT_TRUE(versioner.consume(context.get(), table.get())); + ASSERT_TRUE(versioner.Consume(context.get(), table.get())); - Style* style = test::getValueForConfig<Style>(table.get(), "app:style/Foo", - test::parseConfigOrDie("v4")); + Style* style = test::GetValueForConfig<Style>(table.get(), "app:style/Foo", + test::ParseConfigOrDie("v4")); ASSERT_NE(style, nullptr); ASSERT_EQ(style->entries.size(), 1u); AAPT_ASSERT_TRUE(style->entries.front().key.name); EXPECT_EQ(style->entries.front().key.name.value(), - test::parseNameOrDie("android:attr/onClick")); + test::ParseNameOrDie("android:attr/onClick")); - style = test::getValueForConfig<Style>(table.get(), "app:style/Foo", - test::parseConfigOrDie("v13")); + style = test::GetValueForConfig<Style>(table.get(), "app:style/Foo", + test::ParseConfigOrDie("v13")); ASSERT_NE(style, nullptr); ASSERT_EQ(style->entries.size(), 2u); AAPT_ASSERT_TRUE(style->entries[0].key.name); EXPECT_EQ(style->entries[0].key.name.value(), - test::parseNameOrDie("android:attr/onClick")); + test::ParseNameOrDie("android:attr/onClick")); AAPT_ASSERT_TRUE(style->entries[1].key.name); EXPECT_EQ(style->entries[1].key.name.value(), - test::parseNameOrDie("android:attr/requiresSmallestWidthDp")); + test::ParseNameOrDie("android:attr/requiresSmallestWidthDp")); - style = test::getValueForConfig<Style>(table.get(), "app:style/Foo", - test::parseConfigOrDie("v17")); + style = test::GetValueForConfig<Style>(table.get(), "app:style/Foo", + test::ParseConfigOrDie("v17")); ASSERT_NE(style, nullptr); ASSERT_EQ(style->entries.size(), 3u); AAPT_ASSERT_TRUE(style->entries[0].key.name); EXPECT_EQ(style->entries[0].key.name.value(), - test::parseNameOrDie("android:attr/onClick")); + test::ParseNameOrDie("android:attr/onClick")); AAPT_ASSERT_TRUE(style->entries[1].key.name); EXPECT_EQ(style->entries[1].key.name.value(), - test::parseNameOrDie("android:attr/requiresSmallestWidthDp")); + test::ParseNameOrDie("android:attr/requiresSmallestWidthDp")); AAPT_ASSERT_TRUE(style->entries[2].key.name); EXPECT_EQ(style->entries[2].key.name.value(), - test::parseNameOrDie("android:attr/paddingStart")); + test::ParseNameOrDie("android:attr/paddingStart")); - style = test::getValueForConfig<Style>(table.get(), "app:style/Foo", - test::parseConfigOrDie("v21")); + style = test::GetValueForConfig<Style>(table.get(), "app:style/Foo", + test::ParseConfigOrDie("v21")); ASSERT_NE(style, nullptr); ASSERT_EQ(style->entries.size(), 1u); AAPT_ASSERT_TRUE(style->entries.front().key.name); EXPECT_EQ(style->entries.front().key.name.value(), - test::parseNameOrDie("android:attr/paddingEnd")); + test::ParseNameOrDie("android:attr/paddingEnd")); } } // namespace aapt diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp index 6dd34e3e5f11..717978eaa226 100644 --- a/tools/aapt2/link/Link.cpp +++ b/tools/aapt2/link/Link.cpp @@ -14,6 +14,17 @@ * limitations under the License. */ +#include <sys/stat.h> + +#include <fstream> +#include <queue> +#include <unordered_map> +#include <vector> + +#include "android-base/errors.h" +#include "android-base/file.h" +#include "google/protobuf/io/coded_stream.h" + #include "AppInfo.h" #include "Debug.h" #include "Flags.h" @@ -32,7 +43,6 @@ #include "java/ProguardRules.h" #include "link/Linkers.h" #include "link/ManifestFixer.h" -#include "link/ProductFilter.h" #include "link/ReferenceLinker.h" #include "link/TableMerger.h" #include "process/IResourceTableConsumer.h" @@ -44,179 +54,179 @@ #include "util/StringPiece.h" #include "xml/XmlDom.h" -#include <android-base/file.h> -#include <google/protobuf/io/coded_stream.h> - -#include <sys/stat.h> -#include <fstream> -#include <queue> -#include <unordered_map> -#include <vector> - -using google::protobuf::io::CopyingOutputStreamAdaptor; +using ::google::protobuf::io::CopyingOutputStreamAdaptor; namespace aapt { struct LinkOptions { - std::string outputPath; - std::string manifestPath; - std::vector<std::string> includePaths; - std::vector<std::string> overlayFiles; + std::string output_path; + std::string manifest_path; + std::vector<std::string> include_paths; + std::vector<std::string> overlay_files; + bool output_to_directory = false; + bool auto_add_overlay = false; // Java/Proguard options. - Maybe<std::string> generateJavaClassPath; - Maybe<std::string> customJavaPackage; - std::set<std::string> extraJavaPackages; - Maybe<std::string> generateProguardRulesPath; - Maybe<std::string> generateMainDexProguardRulesPath; - - bool noAutoVersion = false; - bool noVersionVectors = false; - bool noResourceDeduping = false; - bool staticLib = false; - bool noStaticLibPackages = false; - bool generateNonFinalIds = false; - std::vector<std::string> javadocAnnotations; - bool outputToDirectory = false; - bool noXmlNamespaces = false; - bool autoAddOverlay = false; - bool doNotCompressAnything = false; - std::unordered_set<std::string> extensionsToNotCompress; - Maybe<std::string> privateSymbols; - ManifestFixerOptions manifestFixerOptions; + Maybe<std::string> generate_java_class_path; + Maybe<std::string> custom_java_package; + std::set<std::string> extra_java_packages; + Maybe<std::string> generate_proguard_rules_path; + Maybe<std::string> generate_main_dex_proguard_rules_path; + bool generate_non_final_ids = false; + std::vector<std::string> javadoc_annotations; + Maybe<std::string> private_symbols; + + // Optimizations/features. + bool no_auto_version = false; + bool no_version_vectors = false; + bool no_resource_deduping = false; + bool no_xml_namespaces = false; + bool do_not_compress_anything = false; + std::unordered_set<std::string> extensions_to_not_compress; + + // Static lib options. + bool static_lib = false; + bool no_static_lib_packages = false; + + // AndroidManifest.xml massaging options. + ManifestFixerOptions manifest_fixer_options; + + // Products to use/filter on. std::unordered_set<std::string> products; // Split APK options. - TableSplitterOptions tableSplitterOptions; - std::vector<SplitConstraints> splitConstraints; - std::vector<std::string> splitPaths; + TableSplitterOptions table_splitter_options; + std::vector<SplitConstraints> split_constraints; + std::vector<std::string> split_paths; // Stable ID options. - std::unordered_map<ResourceName, ResourceId> stableIdMap; - Maybe<std::string> resourceIdMapPath; + std::unordered_map<ResourceName, ResourceId> stable_id_map; + Maybe<std::string> resource_id_map_path; }; class LinkContext : public IAaptContext { public: - LinkContext() : mNameMangler({}) {} + LinkContext() : name_mangler_({}) {} - IDiagnostics* getDiagnostics() override { return &mDiagnostics; } + IDiagnostics* GetDiagnostics() override { return &diagnostics_; } - NameMangler* getNameMangler() override { return &mNameMangler; } + NameMangler* GetNameMangler() override { return &name_mangler_; } - void setNameManglerPolicy(const NameManglerPolicy& policy) { - mNameMangler = NameMangler(policy); + void SetNameManglerPolicy(const NameManglerPolicy& policy) { + name_mangler_ = NameMangler(policy); } - const std::string& getCompilationPackage() override { - return mCompilationPackage; + const std::string& GetCompilationPackage() override { + return compilation_package_; } - void setCompilationPackage(const StringPiece& packageName) { - mCompilationPackage = packageName.toString(); + void SetCompilationPackage(const StringPiece& package_name) { + compilation_package_ = package_name.ToString(); } - uint8_t getPackageId() override { return mPackageId; } + uint8_t GetPackageId() override { return package_id_; } - void setPackageId(uint8_t id) { mPackageId = id; } + void SetPackageId(uint8_t id) { package_id_ = id; } - SymbolTable* getExternalSymbols() override { return &mSymbols; } + SymbolTable* GetExternalSymbols() override { return &symbols_; } - bool verbose() override { return mVerbose; } + bool IsVerbose() override { return verbose_; } - void setVerbose(bool val) { mVerbose = val; } + void SetVerbose(bool val) { verbose_ = val; } - int getMinSdkVersion() override { return mMinSdkVersion; } + int GetMinSdkVersion() override { return min_sdk_version_; } - void setMinSdkVersion(int minSdk) { mMinSdkVersion = minSdk; } + void SetMinSdkVersion(int minSdk) { min_sdk_version_ = minSdk; } private: - StdErrDiagnostics mDiagnostics; - NameMangler mNameMangler; - std::string mCompilationPackage; - uint8_t mPackageId = 0x0; - SymbolTable mSymbols; - bool mVerbose = false; - int mMinSdkVersion = 0; + DISALLOW_COPY_AND_ASSIGN(LinkContext); + + StdErrDiagnostics diagnostics_; + NameMangler name_mangler_; + std::string compilation_package_; + uint8_t package_id_ = 0x0; + SymbolTable symbols_; + bool verbose_ = false; + int min_sdk_version_ = 0; }; -static bool copyFileToArchive(io::IFile* file, const std::string& outPath, - uint32_t compressionFlags, IArchiveWriter* writer, - IAaptContext* context) { - std::unique_ptr<io::IData> data = file->openAsData(); +static bool CopyFileToArchive(io::IFile* file, const std::string& out_path, + uint32_t compression_flags, + IArchiveWriter* writer, IAaptContext* context) { + std::unique_ptr<io::IData> data = file->OpenAsData(); if (!data) { - context->getDiagnostics()->error(DiagMessage(file->getSource()) + context->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << "failed to open file"); return false; } const uint8_t* buffer = reinterpret_cast<const uint8_t*>(data->data()); - const size_t bufferSize = data->size(); + const size_t buffer_size = data->size(); - if (context->verbose()) { - context->getDiagnostics()->note(DiagMessage() << "writing " << outPath + if (context->IsVerbose()) { + context->GetDiagnostics()->Note(DiagMessage() << "writing " << out_path << " to archive"); } - if (writer->startEntry(outPath, compressionFlags)) { - if (writer->writeEntry(buffer, bufferSize)) { - if (writer->finishEntry()) { + if (writer->StartEntry(out_path, compression_flags)) { + if (writer->WriteEntry(buffer, buffer_size)) { + if (writer->FinishEntry()) { return true; } } } - context->getDiagnostics()->error(DiagMessage() << "failed to write file " - << outPath); + context->GetDiagnostics()->Error(DiagMessage() << "failed to write file " + << out_path); return false; } -static bool flattenXml(xml::XmlResource* xmlRes, const StringPiece& path, - Maybe<size_t> maxSdkLevel, bool keepRawValues, +static bool FlattenXml(xml::XmlResource* xml_res, const StringPiece& path, + Maybe<size_t> max_sdk_level, bool keep_raw_values, IArchiveWriter* writer, IAaptContext* context) { BigBuffer buffer(1024); XmlFlattenerOptions options = {}; - options.keepRawValues = keepRawValues; - options.maxSdkLevel = maxSdkLevel; + options.keep_raw_values = keep_raw_values; + options.max_sdk_level = max_sdk_level; XmlFlattener flattener(&buffer, options); - if (!flattener.consume(context, xmlRes)) { + if (!flattener.Consume(context, xml_res)) { return false; } - if (context->verbose()) { + if (context->IsVerbose()) { DiagMessage msg; msg << "writing " << path << " to archive"; - if (maxSdkLevel) { - msg << " maxSdkLevel=" << maxSdkLevel.value() - << " keepRawValues=" << keepRawValues; + if (max_sdk_level) { + msg << " maxSdkLevel=" << max_sdk_level.value() + << " keepRawValues=" << keep_raw_values; } - context->getDiagnostics()->note(msg); + context->GetDiagnostics()->Note(msg); } - if (writer->startEntry(path, ArchiveEntry::kCompress)) { - if (writer->writeEntry(buffer)) { - if (writer->finishEntry()) { + if (writer->StartEntry(path, ArchiveEntry::kCompress)) { + if (writer->WriteEntry(buffer)) { + if (writer->FinishEntry()) { return true; } } } - context->getDiagnostics()->error(DiagMessage() << "failed to write " << path + context->GetDiagnostics()->Error(DiagMessage() << "failed to write " << path << " to archive"); return false; } -static std::unique_ptr<ResourceTable> loadTableFromPb(const Source& source, +static std::unique_ptr<ResourceTable> LoadTableFromPb(const Source& source, const void* data, size_t len, IDiagnostics* diag) { - pb::ResourceTable pbTable; - if (!pbTable.ParseFromArray(data, len)) { - diag->error(DiagMessage(source) << "invalid compiled table"); + pb::ResourceTable pb_table; + if (!pb_table.ParseFromArray(data, len)) { + diag->Error(DiagMessage(source) << "invalid compiled table"); return {}; } std::unique_ptr<ResourceTable> table = - deserializeTableFromPb(pbTable, source, diag); + DeserializeTableFromPb(pb_table, source, diag); if (!table) { return {}; } @@ -226,33 +236,33 @@ static std::unique_ptr<ResourceTable> loadTableFromPb(const Source& source, /** * Inflates an XML file from the source path. */ -static std::unique_ptr<xml::XmlResource> loadXml(const std::string& path, +static std::unique_ptr<xml::XmlResource> LoadXml(const std::string& path, IDiagnostics* diag) { std::ifstream fin(path, std::ifstream::binary); if (!fin) { - diag->error(DiagMessage(path) << strerror(errno)); + diag->Error(DiagMessage(path) << strerror(errno)); return {}; } - return xml::inflate(&fin, diag, Source(path)); + return xml::Inflate(&fin, diag, Source(path)); } struct ResourceFileFlattenerOptions { - bool noAutoVersion = false; - bool noVersionVectors = false; - bool noXmlNamespaces = false; - bool keepRawValues = false; - bool doNotCompressAnything = false; - bool updateProguardSpec = false; - std::unordered_set<std::string> extensionsToNotCompress; + bool no_auto_version = false; + bool no_version_vectors = false; + bool no_xml_namespaces = false; + bool keep_raw_values = false; + bool do_not_compress_anything = false; + bool update_proguard_spec = false; + std::unordered_set<std::string> extensions_to_not_compress; }; class ResourceFileFlattener { public: ResourceFileFlattener(const ResourceFileFlattenerOptions& options, - IAaptContext* context, proguard::KeepSet* keepSet) - : mOptions(options), mContext(context), mKeepSet(keepSet) {} + IAaptContext* context, proguard::KeepSet* keep_set) + : options_(options), context_(context), keep_set_(keep_set) {} - bool flatten(ResourceTable* table, IArchiveWriter* archiveWriter); + bool Flatten(ResourceTable* table, IArchiveWriter* archive_writer); private: struct FileOperation { @@ -262,118 +272,119 @@ class ResourceFileFlattener { const ResourceEntry* entry; // The file to copy as-is. - io::IFile* fileToCopy; + io::IFile* file_to_copy; // The XML to process and flatten. - std::unique_ptr<xml::XmlResource> xmlToFlatten; + std::unique_ptr<xml::XmlResource> xml_to_flatten; // The destination to write this file to. - std::string dstPath; - bool skipVersion = false; + std::string dst_path; + bool skip_version = false; }; - uint32_t getCompressionFlags(const StringPiece& str); + uint32_t GetCompressionFlags(const StringPiece& str); - bool linkAndVersionXmlFile(ResourceTable* table, FileOperation* fileOp, - std::queue<FileOperation>* outFileOpQueue); + bool LinkAndVersionXmlFile(ResourceTable* table, FileOperation* file_op, + std::queue<FileOperation>* out_file_op_queue); - ResourceFileFlattenerOptions mOptions; - IAaptContext* mContext; - proguard::KeepSet* mKeepSet; + ResourceFileFlattenerOptions options_; + IAaptContext* context_; + proguard::KeepSet* keep_set_; }; -uint32_t ResourceFileFlattener::getCompressionFlags(const StringPiece& str) { - if (mOptions.doNotCompressAnything) { +uint32_t ResourceFileFlattener::GetCompressionFlags(const StringPiece& str) { + if (options_.do_not_compress_anything) { return 0; } - for (const std::string& extension : mOptions.extensionsToNotCompress) { - if (util::stringEndsWith(str, extension)) { + for (const std::string& extension : options_.extensions_to_not_compress) { + if (util::EndsWith(str, extension)) { return 0; } } return ArchiveEntry::kCompress; } -bool ResourceFileFlattener::linkAndVersionXmlFile( - ResourceTable* table, FileOperation* fileOp, - std::queue<FileOperation>* outFileOpQueue) { - xml::XmlResource* doc = fileOp->xmlToFlatten.get(); +bool ResourceFileFlattener::LinkAndVersionXmlFile( + ResourceTable* table, FileOperation* file_op, + std::queue<FileOperation>* out_file_op_queue) { + xml::XmlResource* doc = file_op->xml_to_flatten.get(); const Source& src = doc->file.source; - if (mContext->verbose()) { - mContext->getDiagnostics()->note(DiagMessage() << "linking " << src.path); + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note(DiagMessage() << "linking " << src.path); } - XmlReferenceLinker xmlLinker; - if (!xmlLinker.consume(mContext, doc)) { + XmlReferenceLinker xml_linker; + if (!xml_linker.Consume(context_, doc)) { return false; } - if (mOptions.updateProguardSpec && - !proguard::collectProguardRules(src, doc, mKeepSet)) { + if (options_.update_proguard_spec && + !proguard::CollectProguardRules(src, doc, keep_set_)) { return false; } - if (mOptions.noXmlNamespaces) { - XmlNamespaceRemover namespaceRemover; - if (!namespaceRemover.consume(mContext, doc)) { + if (options_.no_xml_namespaces) { + XmlNamespaceRemover namespace_remover; + if (!namespace_remover.Consume(context_, doc)) { return false; } } - if (!mOptions.noAutoVersion) { - if (mOptions.noVersionVectors) { + if (!options_.no_auto_version) { + if (options_.no_version_vectors) { // Skip this if it is a vector or animated-vector. - xml::Element* el = xml::findRootElement(doc); - if (el && el->namespaceUri.empty()) { + xml::Element* el = xml::FindRootElement(doc); + if (el && el->namespace_uri.empty()) { if (el->name == "vector" || el->name == "animated-vector") { // We are NOT going to version this file. - fileOp->skipVersion = true; + file_op->skip_version = true; return true; } } } - const ConfigDescription& config = fileOp->config; + const ConfigDescription& config = file_op->config; // Find the first SDK level used that is higher than this defined config and // not superseded by a lower or equal SDK level resource. - const int minSdkVersion = mContext->getMinSdkVersion(); - for (int sdkLevel : xmlLinker.getSdkLevels()) { - if (sdkLevel > minSdkVersion && sdkLevel > config.sdkVersion) { - if (!shouldGenerateVersionedResource(fileOp->entry, config, sdkLevel)) { + const int min_sdk_version = context_->GetMinSdkVersion(); + for (int sdk_level : xml_linker.sdk_levels()) { + if (sdk_level > min_sdk_version && sdk_level > config.sdkVersion) { + if (!ShouldGenerateVersionedResource(file_op->entry, config, + sdk_level)) { // If we shouldn't generate a versioned resource, stop checking. break; } - ResourceFile versionedFileDesc = doc->file; - versionedFileDesc.config.sdkVersion = (uint16_t)sdkLevel; + ResourceFile versioned_file_desc = doc->file; + versioned_file_desc.config.sdkVersion = (uint16_t)sdk_level; - FileOperation newFileOp; - newFileOp.xmlToFlatten = util::make_unique<xml::XmlResource>( - versionedFileDesc, doc->root->clone()); - newFileOp.config = versionedFileDesc.config; - newFileOp.entry = fileOp->entry; - newFileOp.dstPath = ResourceUtils::buildResourceFileName( - versionedFileDesc, mContext->getNameMangler()); + FileOperation new_file_op; + new_file_op.xml_to_flatten = util::make_unique<xml::XmlResource>( + versioned_file_desc, doc->root->Clone()); + new_file_op.config = versioned_file_desc.config; + new_file_op.entry = file_op->entry; + new_file_op.dst_path = ResourceUtils::BuildResourceFileName( + versioned_file_desc, context_->GetNameMangler()); - if (mContext->verbose()) { - mContext->getDiagnostics()->note( - DiagMessage(versionedFileDesc.source) + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note( + DiagMessage(versioned_file_desc.source) << "auto-versioning resource from config '" << config << "' -> '" - << versionedFileDesc.config << "'"); + << versioned_file_desc.config << "'"); } - bool added = table->addFileReferenceAllowMangled( - versionedFileDesc.name, versionedFileDesc.config, - versionedFileDesc.source, newFileOp.dstPath, nullptr, - mContext->getDiagnostics()); + bool added = table->AddFileReferenceAllowMangled( + versioned_file_desc.name, versioned_file_desc.config, + versioned_file_desc.source, new_file_op.dst_path, nullptr, + context_->GetDiagnostics()); if (!added) { return false; } - outFileOpQueue->push(std::move(newFileOp)); + out_file_op_queue->push(std::move(new_file_op)); break; } } @@ -386,100 +397,96 @@ bool ResourceFileFlattener::linkAndVersionXmlFile( * will * corrupt the iteration order. */ -bool ResourceFileFlattener::flatten(ResourceTable* table, - IArchiveWriter* archiveWriter) { +bool ResourceFileFlattener::Flatten(ResourceTable* table, + IArchiveWriter* archive_writer) { bool error = false; std::map<std::pair<ConfigDescription, StringPiece>, FileOperation> - configSortedFiles; + config_sorted_files; for (auto& pkg : table->packages) { for (auto& type : pkg->types) { // Sort by config and name, so that we get better locality in the zip // file. - configSortedFiles.clear(); - std::queue<FileOperation> fileOperations; + config_sorted_files.clear(); + std::queue<FileOperation> file_operations; // Populate the queue with all files in the ResourceTable. for (auto& entry : type->entries) { - for (auto& configValue : entry->values) { - FileReference* fileRef = - valueCast<FileReference>(configValue->value.get()); - if (!fileRef) { + for (auto& config_value : entry->values) { + FileReference* file_ref = + ValueCast<FileReference>(config_value->value.get()); + if (!file_ref) { continue; } - io::IFile* file = fileRef->file; + io::IFile* file = file_ref->file; if (!file) { - mContext->getDiagnostics()->error(DiagMessage(fileRef->getSource()) + context_->GetDiagnostics()->Error(DiagMessage(file_ref->GetSource()) << "file not found"); return false; } - FileOperation fileOp; - fileOp.entry = entry.get(); - fileOp.dstPath = *fileRef->path; - fileOp.config = configValue->config; + FileOperation file_op; + file_op.entry = entry.get(); + file_op.dst_path = *file_ref->path; + file_op.config = config_value->config; - const StringPiece srcPath = file->getSource().path; + const StringPiece src_path = file->GetSource().path; if (type->type != ResourceType::kRaw && - (util::stringEndsWith(srcPath, ".xml.flat") || - util::stringEndsWith(srcPath, ".xml"))) { - std::unique_ptr<io::IData> data = file->openAsData(); + (util::EndsWith(src_path, ".xml.flat") || + util::EndsWith(src_path, ".xml"))) { + std::unique_ptr<io::IData> data = file->OpenAsData(); if (!data) { - mContext->getDiagnostics()->error(DiagMessage(file->getSource()) + context_->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << "failed to open file"); return false; } - fileOp.xmlToFlatten = - xml::inflate(data->data(), data->size(), - mContext->getDiagnostics(), file->getSource()); + file_op.xml_to_flatten = + xml::Inflate(data->data(), data->size(), + context_->GetDiagnostics(), file->GetSource()); - if (!fileOp.xmlToFlatten) { + if (!file_op.xml_to_flatten) { return false; } - fileOp.xmlToFlatten->file.config = configValue->config; - fileOp.xmlToFlatten->file.source = fileRef->getSource(); - fileOp.xmlToFlatten->file.name = + file_op.xml_to_flatten->file.config = config_value->config; + file_op.xml_to_flatten->file.source = file_ref->GetSource(); + file_op.xml_to_flatten->file.name = ResourceName(pkg->name, type->type, entry->name); // Enqueue the XML files to be processed. - fileOperations.push(std::move(fileOp)); + file_operations.push(std::move(file_op)); } else { - fileOp.fileToCopy = file; + file_op.file_to_copy = file; // NOTE(adamlesinski): Explicitly construct a StringPiece here, or - // else - // we end up copying the string in the std::make_pair() method, then - // creating a StringPiece from the copy, which would cause us to end - // up - // referencing garbage in the map. - const StringPiece entryName(entry->name); - configSortedFiles[std::make_pair(configValue->config, entryName)] = - std::move(fileOp); + // else we end up copying the string in the std::make_pair() method, + // then creating a StringPiece from the copy, which would cause us + // to end up referencing garbage in the map. + const StringPiece entry_name(entry->name); + config_sorted_files[std::make_pair( + config_value->config, entry_name)] = std::move(file_op); } } } // Now process the XML queue - for (; !fileOperations.empty(); fileOperations.pop()) { - FileOperation& fileOp = fileOperations.front(); + for (; !file_operations.empty(); file_operations.pop()) { + FileOperation& file_op = file_operations.front(); - if (!linkAndVersionXmlFile(table, &fileOp, &fileOperations)) { + if (!LinkAndVersionXmlFile(table, &file_op, &file_operations)) { error = true; continue; } // NOTE(adamlesinski): Explicitly construct a StringPiece here, or else // we end up copying the string in the std::make_pair() method, then - // creating - // a StringPiece from the copy, which would cause us to end up - // referencing - // garbage in the map. - const StringPiece entryName(fileOp.entry->name); - configSortedFiles[std::make_pair(fileOp.config, entryName)] = - std::move(fileOp); + // creating a StringPiece from the copy, which would cause us to end up + // referencing garbage in the map. + const StringPiece entry_name(file_op.entry->name); + config_sorted_files[std::make_pair(file_op.config, entry_name)] = + std::move(file_op); } if (error) { @@ -487,28 +494,28 @@ bool ResourceFileFlattener::flatten(ResourceTable* table, } // Now flatten the sorted values. - for (auto& mapEntry : configSortedFiles) { - const ConfigDescription& config = mapEntry.first.first; - const FileOperation& fileOp = mapEntry.second; - - if (fileOp.xmlToFlatten) { - Maybe<size_t> maxSdkLevel; - if (!mOptions.noAutoVersion && !fileOp.skipVersion) { - maxSdkLevel = + for (auto& map_entry : config_sorted_files) { + const ConfigDescription& config = map_entry.first.first; + const FileOperation& file_op = map_entry.second; + + if (file_op.xml_to_flatten) { + Maybe<size_t> max_sdk_level; + if (!options_.no_auto_version && !file_op.skip_version) { + max_sdk_level = std::max<size_t>(std::max<size_t>(config.sdkVersion, 1u), - mContext->getMinSdkVersion()); + context_->GetMinSdkVersion()); } - bool result = - flattenXml(fileOp.xmlToFlatten.get(), fileOp.dstPath, maxSdkLevel, - mOptions.keepRawValues, archiveWriter, mContext); + bool result = FlattenXml( + file_op.xml_to_flatten.get(), file_op.dst_path, max_sdk_level, + options_.keep_raw_values, archive_writer, context_); if (!result) { error = true; } } else { - bool result = copyFileToArchive(fileOp.fileToCopy, fileOp.dstPath, - getCompressionFlags(fileOp.dstPath), - archiveWriter, mContext); + bool result = CopyFileToArchive( + file_op.file_to_copy, file_op.dst_path, + GetCompressionFlags(file_op.dst_path), archive_writer, context_); if (!result) { error = true; } @@ -519,136 +526,136 @@ bool ResourceFileFlattener::flatten(ResourceTable* table, return !error; } -static bool writeStableIdMapToPath( +static bool WriteStableIdMapToPath( IDiagnostics* diag, - const std::unordered_map<ResourceName, ResourceId>& idMap, - const std::string& idMapPath) { - std::ofstream fout(idMapPath, std::ofstream::binary); + const std::unordered_map<ResourceName, ResourceId>& id_map, + const std::string& id_map_path) { + std::ofstream fout(id_map_path, std::ofstream::binary); if (!fout) { - diag->error(DiagMessage(idMapPath) << strerror(errno)); + diag->Error(DiagMessage(id_map_path) << strerror(errno)); return false; } - for (const auto& entry : idMap) { + for (const auto& entry : id_map) { const ResourceName& name = entry.first; const ResourceId& id = entry.second; fout << name << " = " << id << "\n"; } if (!fout) { - diag->error(DiagMessage(idMapPath) << "failed writing to file: " - << strerror(errno)); + diag->Error(DiagMessage(id_map_path) + << "failed writing to file: " + << android::base::SystemErrorCodeToString(errno)); return false; } return true; } -static bool loadStableIdMap( +static bool LoadStableIdMap( IDiagnostics* diag, const std::string& path, - std::unordered_map<ResourceName, ResourceId>* outIdMap) { + std::unordered_map<ResourceName, ResourceId>* out_id_map) { std::string content; if (!android::base::ReadFileToString(path, &content)) { - diag->error(DiagMessage(path) << "failed reading stable ID file"); + diag->Error(DiagMessage(path) << "failed reading stable ID file"); return false; } - outIdMap->clear(); - size_t lineNo = 0; - for (StringPiece line : util::tokenize(content, '\n')) { - lineNo++; - line = util::trimWhitespace(line); + out_id_map->clear(); + size_t line_no = 0; + for (StringPiece line : util::Tokenize(content, '\n')) { + line_no++; + line = util::TrimWhitespace(line); if (line.empty()) { continue; } auto iter = std::find(line.begin(), line.end(), '='); if (iter == line.end()) { - diag->error(DiagMessage(Source(path, lineNo)) << "missing '='"); + diag->Error(DiagMessage(Source(path, line_no)) << "missing '='"); return false; } ResourceNameRef name; - StringPiece resNameStr = - util::trimWhitespace(line.substr(0, std::distance(line.begin(), iter))); - if (!ResourceUtils::parseResourceName(resNameStr, &name)) { - diag->error(DiagMessage(Source(path, lineNo)) << "invalid resource name '" - << resNameStr << "'"); + StringPiece res_name_str = + util::TrimWhitespace(line.substr(0, std::distance(line.begin(), iter))); + if (!ResourceUtils::ParseResourceName(res_name_str, &name)) { + diag->Error(DiagMessage(Source(path, line_no)) + << "invalid resource name '" << res_name_str << "'"); return false; } - const size_t resIdStartIdx = std::distance(line.begin(), iter) + 1; - const size_t resIdStrLen = line.size() - resIdStartIdx; - StringPiece resIdStr = - util::trimWhitespace(line.substr(resIdStartIdx, resIdStrLen)); + const size_t res_id_start_idx = std::distance(line.begin(), iter) + 1; + const size_t res_id_str_len = line.size() - res_id_start_idx; + StringPiece res_id_str = + util::TrimWhitespace(line.substr(res_id_start_idx, res_id_str_len)); - Maybe<ResourceId> maybeId = ResourceUtils::parseResourceId(resIdStr); - if (!maybeId) { - diag->error(DiagMessage(Source(path, lineNo)) << "invalid resource ID '" - << resIdStr << "'"); + Maybe<ResourceId> maybe_id = ResourceUtils::ParseResourceId(res_id_str); + if (!maybe_id) { + diag->Error(DiagMessage(Source(path, line_no)) << "invalid resource ID '" + << res_id_str << "'"); return false; } - (*outIdMap)[name.toResourceName()] = maybeId.value(); + (*out_id_map)[name.ToResourceName()] = maybe_id.value(); } return true; } -static bool parseSplitParameter(const StringPiece& arg, IDiagnostics* diag, - std::string* outPath, - SplitConstraints* outSplit) { - std::vector<std::string> parts = util::split(arg, ':'); +static bool ParseSplitParameter(const StringPiece& arg, IDiagnostics* diag, + std::string* out_path, + SplitConstraints* out_split) { + std::vector<std::string> parts = util::Split(arg, ':'); if (parts.size() != 2) { - diag->error(DiagMessage() << "invalid split parameter '" << arg << "'"); - diag->note( + diag->Error(DiagMessage() << "invalid split parameter '" << arg << "'"); + diag->Note( DiagMessage() << "should be --split path/to/output.apk:<config>[,<config>...]"); return false; } - *outPath = parts[0]; + *out_path = parts[0]; std::vector<ConfigDescription> configs; - for (const StringPiece& configStr : util::tokenize(parts[1], ',')) { + for (const StringPiece& config_str : util::Tokenize(parts[1], ',')) { configs.push_back({}); - if (!ConfigDescription::parse(configStr, &configs.back())) { - diag->error(DiagMessage() << "invalid config '" << configStr + if (!ConfigDescription::Parse(config_str, &configs.back())) { + diag->Error(DiagMessage() << "invalid config '" << config_str << "' in split parameter '" << arg << "'"); return false; } } - outSplit->configs.insert(configs.begin(), configs.end()); + out_split->configs.insert(configs.begin(), configs.end()); return true; } class LinkCommand { public: LinkCommand(LinkContext* context, const LinkOptions& options) - : mOptions(options), - mContext(context), - mFinalTable(), - mFileCollection(util::make_unique<io::FileCollection>()) {} + : options_(options), + context_(context), + final_table_(), + file_collection_(util::make_unique<io::FileCollection>()) {} /** * Creates a SymbolTable that loads symbols from the various APKs and caches - * the - * results for faster lookup. + * the results for faster lookup. */ - bool loadSymbolsFromIncludePaths() { - std::unique_ptr<AssetManagerSymbolSource> assetSource = + bool LoadSymbolsFromIncludePaths() { + std::unique_ptr<AssetManagerSymbolSource> asset_source = util::make_unique<AssetManagerSymbolSource>(); - for (const std::string& path : mOptions.includePaths) { - if (mContext->verbose()) { - mContext->getDiagnostics()->note(DiagMessage(path) + for (const std::string& path : options_.include_paths) { + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note(DiagMessage(path) << "loading include path"); } // First try to load the file as a static lib. - std::string errorStr; - std::unique_ptr<ResourceTable> staticInclude = - loadStaticLibrary(path, &errorStr); - if (staticInclude) { - if (!mOptions.staticLib) { + std::string error_str; + std::unique_ptr<ResourceTable> static_include = + LoadStaticLibrary(path, &error_str); + if (static_include) { + if (!options_.static_lib) { // Can't include static libraries when not building a static library. - mContext->getDiagnostics()->error( + context_->GetDiagnostics()->Error( DiagMessage(path) << "can't include static library when building app"); return false; @@ -657,92 +664,92 @@ class LinkCommand { // If we are using --no-static-lib-packages, we need to rename the // package of this // table to our compilation package. - if (mOptions.noStaticLibPackages) { + if (options_.no_static_lib_packages) { if (ResourceTablePackage* pkg = - staticInclude->findPackageById(0x7f)) { - pkg->name = mContext->getCompilationPackage(); + static_include->FindPackageById(0x7f)) { + pkg->name = context_->GetCompilationPackage(); } } - mContext->getExternalSymbols()->appendSource( - util::make_unique<ResourceTableSymbolSource>(staticInclude.get())); + context_->GetExternalSymbols()->AppendSource( + util::make_unique<ResourceTableSymbolSource>(static_include.get())); - mStaticTableIncludes.push_back(std::move(staticInclude)); + static_table_includes_.push_back(std::move(static_include)); - } else if (!errorStr.empty()) { + } else if (!error_str.empty()) { // We had an error with reading, so fail. - mContext->getDiagnostics()->error(DiagMessage(path) << errorStr); + context_->GetDiagnostics()->Error(DiagMessage(path) << error_str); return false; } - if (!assetSource->addAssetPath(path)) { - mContext->getDiagnostics()->error(DiagMessage(path) + if (!asset_source->AddAssetPath(path)) { + context_->GetDiagnostics()->Error(DiagMessage(path) << "failed to load include path"); return false; } } - mContext->getExternalSymbols()->appendSource(std::move(assetSource)); + context_->GetExternalSymbols()->AppendSource(std::move(asset_source)); return true; } - Maybe<AppInfo> extractAppInfoFromManifest(xml::XmlResource* xmlRes, + Maybe<AppInfo> ExtractAppInfoFromManifest(xml::XmlResource* xml_res, IDiagnostics* diag) { // Make sure the first element is <manifest> with package attribute. - if (xml::Element* manifestEl = xml::findRootElement(xmlRes->root.get())) { - AppInfo appInfo; + if (xml::Element* manifest_el = xml::FindRootElement(xml_res->root.get())) { + AppInfo app_info; - if (!manifestEl->namespaceUri.empty() || manifestEl->name != "manifest") { - diag->error(DiagMessage(xmlRes->file.source) + if (!manifest_el->namespace_uri.empty() || + manifest_el->name != "manifest") { + diag->Error(DiagMessage(xml_res->file.source) << "root tag must be <manifest>"); return {}; } - xml::Attribute* packageAttr = manifestEl->findAttribute({}, "package"); - if (!packageAttr) { - diag->error(DiagMessage(xmlRes->file.source) + xml::Attribute* package_attr = manifest_el->FindAttribute({}, "package"); + if (!package_attr) { + diag->Error(DiagMessage(xml_res->file.source) << "<manifest> must have a 'package' attribute"); return {}; } - appInfo.package = packageAttr->value; - - if (xml::Attribute* versionCodeAttr = - manifestEl->findAttribute(xml::kSchemaAndroid, "versionCode")) { - Maybe<uint32_t> maybeCode = - ResourceUtils::parseInt(versionCodeAttr->value); - if (!maybeCode) { - diag->error( - DiagMessage(xmlRes->file.source.withLine(manifestEl->lineNumber)) - << "invalid android:versionCode '" << versionCodeAttr->value - << "'"); + app_info.package = package_attr->value; + + if (xml::Attribute* version_code_attr = + manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode")) { + Maybe<uint32_t> maybe_code = + ResourceUtils::ParseInt(version_code_attr->value); + if (!maybe_code) { + diag->Error(DiagMessage(xml_res->file.source.WithLine( + manifest_el->line_number)) + << "invalid android:versionCode '" + << version_code_attr->value << "'"); return {}; } - appInfo.versionCode = maybeCode.value(); + app_info.version_code = maybe_code.value(); } - if (xml::Attribute* revisionCodeAttr = - manifestEl->findAttribute(xml::kSchemaAndroid, "revisionCode")) { - Maybe<uint32_t> maybeCode = - ResourceUtils::parseInt(revisionCodeAttr->value); - if (!maybeCode) { - diag->error( - DiagMessage(xmlRes->file.source.withLine(manifestEl->lineNumber)) - << "invalid android:revisionCode '" << revisionCodeAttr->value - << "'"); + if (xml::Attribute* revision_code_attr = + manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode")) { + Maybe<uint32_t> maybe_code = + ResourceUtils::ParseInt(revision_code_attr->value); + if (!maybe_code) { + diag->Error(DiagMessage(xml_res->file.source.WithLine( + manifest_el->line_number)) + << "invalid android:revisionCode '" + << revision_code_attr->value << "'"); return {}; } - appInfo.revisionCode = maybeCode.value(); + app_info.revision_code = maybe_code.value(); } - if (xml::Element* usesSdkEl = manifestEl->findChild({}, "uses-sdk")) { - if (xml::Attribute* minSdk = usesSdkEl->findAttribute( + if (xml::Element* uses_sdk_el = manifest_el->FindChild({}, "uses-sdk")) { + if (xml::Attribute* min_sdk = uses_sdk_el->FindAttribute( xml::kSchemaAndroid, "minSdkVersion")) { - appInfo.minSdkVersion = minSdk->value; + app_info.min_sdk_version = min_sdk->value; } } - - return appInfo; + return app_info; } return {}; } @@ -751,38 +758,36 @@ class LinkCommand { * Precondition: ResourceTable doesn't have any IDs assigned yet, nor is it * linked. * Postcondition: ResourceTable has only one package left. All others are - * stripped, or there - * is an error and false is returned. + * stripped, or there is an error and false is returned. */ - bool verifyNoExternalPackages() { - auto isExtPackageFunc = + bool VerifyNoExternalPackages() { + auto is_ext_package_func = [&](const std::unique_ptr<ResourceTablePackage>& pkg) -> bool { - return mContext->getCompilationPackage() != pkg->name || !pkg->id || - pkg->id.value() != mContext->getPackageId(); + return context_->GetCompilationPackage() != pkg->name || !pkg->id || + pkg->id.value() != context_->GetPackageId(); }; bool error = false; - for (const auto& package : mFinalTable.packages) { - if (isExtPackageFunc(package)) { + for (const auto& package : final_table_.packages) { + if (is_ext_package_func(package)) { // We have a package that is not related to the one we're building! for (const auto& type : package->types) { for (const auto& entry : type->entries) { - ResourceNameRef resName(package->name, type->type, entry->name); + ResourceNameRef res_name(package->name, type->type, entry->name); - for (const auto& configValue : entry->values) { + for (const auto& config_value : entry->values) { // Special case the occurrence of an ID that is being generated - // for the - // 'android' package. This is due to legacy reasons. - if (valueCast<Id>(configValue->value.get()) && + // for the 'android' package. This is due to legacy reasons. + if (ValueCast<Id>(config_value->value.get()) && package->name == "android") { - mContext->getDiagnostics()->warn( - DiagMessage(configValue->value->getSource()) - << "generated id '" << resName << "' for external package '" - << package->name << "'"); + context_->GetDiagnostics()->Warn( + DiagMessage(config_value->value->GetSource()) + << "generated id '" << res_name + << "' for external package '" << package->name << "'"); } else { - mContext->getDiagnostics()->error( - DiagMessage(configValue->value->getSource()) - << "defined resource '" << resName + context_->GetDiagnostics()->Error( + DiagMessage(config_value->value->GetSource()) + << "defined resource '" << res_name << "' for external package '" << package->name << "'"); error = true; } @@ -792,21 +797,21 @@ class LinkCommand { } } - auto newEndIter = - std::remove_if(mFinalTable.packages.begin(), mFinalTable.packages.end(), - isExtPackageFunc); - mFinalTable.packages.erase(newEndIter, mFinalTable.packages.end()); + auto new_end_iter = + std::remove_if(final_table_.packages.begin(), + final_table_.packages.end(), is_ext_package_func); + final_table_.packages.erase(new_end_iter, final_table_.packages.end()); return !error; } /** * Returns true if no IDs have been set, false otherwise. */ - bool verifyNoIdsSet() { - for (const auto& package : mFinalTable.packages) { + bool VerifyNoIdsSet() { + for (const auto& package : final_table_.packages) { for (const auto& type : package->types) { if (type->id) { - mContext->getDiagnostics()->error( + context_->GetDiagnostics()->Error( DiagMessage() << "type " << type->type << " has ID " << std::hex << (int)type->id.value() << std::dec << " assigned"); @@ -815,9 +820,9 @@ class LinkCommand { for (const auto& entry : type->entries) { if (entry->id) { - ResourceNameRef resName(package->name, type->type, entry->name); - mContext->getDiagnostics()->error( - DiagMessage() << "entry " << resName << " has ID " << std::hex + ResourceNameRef res_name(package->name, type->type, entry->name); + context_->GetDiagnostics()->Error( + DiagMessage() << "entry " << res_name << " has ID " << std::hex << (int)entry->id.value() << std::dec << " assigned"); return false; @@ -828,265 +833,261 @@ class LinkCommand { return true; } - std::unique_ptr<IArchiveWriter> makeArchiveWriter(const StringPiece& out) { - if (mOptions.outputToDirectory) { - return createDirectoryArchiveWriter(mContext->getDiagnostics(), out); + std::unique_ptr<IArchiveWriter> MakeArchiveWriter(const StringPiece& out) { + if (options_.output_to_directory) { + return CreateDirectoryArchiveWriter(context_->GetDiagnostics(), out); } else { - return createZipFileArchiveWriter(mContext->getDiagnostics(), out); + return CreateZipFileArchiveWriter(context_->GetDiagnostics(), out); } } - bool flattenTable(ResourceTable* table, IArchiveWriter* writer) { + bool FlattenTable(ResourceTable* table, IArchiveWriter* writer) { BigBuffer buffer(1024); TableFlattener flattener(&buffer); - if (!flattener.consume(mContext, table)) { + if (!flattener.Consume(context_, table)) { return false; } - if (writer->startEntry("resources.arsc", ArchiveEntry::kAlign)) { - if (writer->writeEntry(buffer)) { - if (writer->finishEntry()) { + if (writer->StartEntry("resources.arsc", ArchiveEntry::kAlign)) { + if (writer->WriteEntry(buffer)) { + if (writer->FinishEntry()) { return true; } } } - mContext->getDiagnostics()->error( + context_->GetDiagnostics()->Error( DiagMessage() << "failed to write resources.arsc to archive"); return false; } - bool flattenTableToPb(ResourceTable* table, IArchiveWriter* writer) { + bool FlattenTableToPb(ResourceTable* table, IArchiveWriter* writer) { // Create the file/zip entry. - if (!writer->startEntry("resources.arsc.flat", 0)) { - mContext->getDiagnostics()->error(DiagMessage() << "failed to open"); + if (!writer->StartEntry("resources.arsc.flat", 0)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed to open"); return false; } // Make sure CopyingOutputStreamAdaptor is deleted before we call - // writer->finishEntry(). + // writer->FinishEntry(). { // Wrap our IArchiveWriter with an adaptor that implements the - // ZeroCopyOutputStream - // interface. + // ZeroCopyOutputStream interface. CopyingOutputStreamAdaptor adaptor(writer); - std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(table); - if (!pbTable->SerializeToZeroCopyStream(&adaptor)) { - mContext->getDiagnostics()->error(DiagMessage() << "failed to write"); + std::unique_ptr<pb::ResourceTable> pb_table = SerializeTableToPb(table); + if (!pb_table->SerializeToZeroCopyStream(&adaptor)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed to write"); return false; } } - if (!writer->finishEntry()) { - mContext->getDiagnostics()->error(DiagMessage() + if (!writer->FinishEntry()) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed to finish entry"); return false; } return true; } - bool writeJavaFile(ResourceTable* table, - const StringPiece& packageNameToGenerate, - const StringPiece& outPackage, - const JavaClassGeneratorOptions& javaOptions) { - if (!mOptions.generateJavaClassPath) { + bool WriteJavaFile(ResourceTable* table, + const StringPiece& package_name_to_generate, + const StringPiece& out_package, + const JavaClassGeneratorOptions& java_options) { + if (!options_.generate_java_class_path) { return true; } - std::string outPath = mOptions.generateJavaClassPath.value(); - file::appendPath(&outPath, file::packageToPath(outPackage)); - if (!file::mkdirs(outPath)) { - mContext->getDiagnostics()->error( - DiagMessage() << "failed to create directory '" << outPath << "'"); + std::string out_path = options_.generate_java_class_path.value(); + file::AppendPath(&out_path, file::PackageToPath(out_package)); + if (!file::mkdirs(out_path)) { + context_->GetDiagnostics()->Error( + DiagMessage() << "failed to create directory '" << out_path << "'"); return false; } - file::appendPath(&outPath, "R.java"); + file::AppendPath(&out_path, "R.java"); - std::ofstream fout(outPath, std::ofstream::binary); + std::ofstream fout(out_path, std::ofstream::binary); if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() - << "failed writing to '" << outPath - << "': " << strerror(errno)); + context_->GetDiagnostics()->Error( + DiagMessage() << "failed writing to '" << out_path << "': " + << android::base::SystemErrorCodeToString(errno)); return false; } - JavaClassGenerator generator(mContext, table, javaOptions); - if (!generator.generate(packageNameToGenerate, outPackage, &fout)) { - mContext->getDiagnostics()->error(DiagMessage(outPath) + JavaClassGenerator generator(context_, table, java_options); + if (!generator.Generate(package_name_to_generate, out_package, &fout)) { + context_->GetDiagnostics()->Error(DiagMessage(out_path) << generator.getError()); return false; } if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() - << "failed writing to '" << outPath - << "': " << strerror(errno)); + context_->GetDiagnostics()->Error( + DiagMessage() << "failed writing to '" << out_path << "': " + << android::base::SystemErrorCodeToString(errno)); } return true; } - bool writeManifestJavaFile(xml::XmlResource* manifestXml) { - if (!mOptions.generateJavaClassPath) { + bool WriteManifestJavaFile(xml::XmlResource* manifest_xml) { + if (!options_.generate_java_class_path) { return true; } - std::unique_ptr<ClassDefinition> manifestClass = - generateManifestClass(mContext->getDiagnostics(), manifestXml); + std::unique_ptr<ClassDefinition> manifest_class = + GenerateManifestClass(context_->GetDiagnostics(), manifest_xml); - if (!manifestClass) { + if (!manifest_class) { // Something bad happened, but we already logged it, so exit. return false; } - if (manifestClass->empty()) { + if (manifest_class->empty()) { // Empty Manifest class, no need to generate it. return true; } // Add any JavaDoc annotations to the generated class. - for (const std::string& annotation : mOptions.javadocAnnotations) { - std::string properAnnotation = "@"; - properAnnotation += annotation; - manifestClass->getCommentBuilder()->appendComment(properAnnotation); + for (const std::string& annotation : options_.javadoc_annotations) { + std::string proper_annotation = "@"; + proper_annotation += annotation; + manifest_class->GetCommentBuilder()->AppendComment(proper_annotation); } - const std::string& packageUtf8 = mContext->getCompilationPackage(); + const std::string& package_utf8 = context_->GetCompilationPackage(); - std::string outPath = mOptions.generateJavaClassPath.value(); - file::appendPath(&outPath, file::packageToPath(packageUtf8)); + std::string out_path = options_.generate_java_class_path.value(); + file::AppendPath(&out_path, file::PackageToPath(package_utf8)); - if (!file::mkdirs(outPath)) { - mContext->getDiagnostics()->error( - DiagMessage() << "failed to create directory '" << outPath << "'"); + if (!file::mkdirs(out_path)) { + context_->GetDiagnostics()->Error( + DiagMessage() << "failed to create directory '" << out_path << "'"); return false; } - file::appendPath(&outPath, "Manifest.java"); + file::AppendPath(&out_path, "Manifest.java"); - std::ofstream fout(outPath, std::ofstream::binary); + std::ofstream fout(out_path, std::ofstream::binary); if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() - << "failed writing to '" << outPath - << "': " << strerror(errno)); + context_->GetDiagnostics()->Error( + DiagMessage() << "failed writing to '" << out_path << "': " + << android::base::SystemErrorCodeToString(errno)); return false; } - if (!ClassDefinition::writeJavaFile(manifestClass.get(), packageUtf8, true, - &fout)) { - mContext->getDiagnostics()->error(DiagMessage() - << "failed writing to '" << outPath - << "': " << strerror(errno)); + if (!ClassDefinition::WriteJavaFile(manifest_class.get(), package_utf8, + true, &fout)) { + context_->GetDiagnostics()->Error( + DiagMessage() << "failed writing to '" << out_path << "': " + << android::base::SystemErrorCodeToString(errno)); return false; } return true; } - bool writeProguardFile(const Maybe<std::string>& out, - const proguard::KeepSet& keepSet) { + bool WriteProguardFile(const Maybe<std::string>& out, + const proguard::KeepSet& keep_set) { if (!out) { return true; } - const std::string& outPath = out.value(); - std::ofstream fout(outPath, std::ofstream::binary); + const std::string& out_path = out.value(); + std::ofstream fout(out_path, std::ofstream::binary); if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() - << "failed to open '" << outPath - << "': " << strerror(errno)); + context_->GetDiagnostics()->Error( + DiagMessage() << "failed to open '" << out_path << "': " + << android::base::SystemErrorCodeToString(errno)); return false; } - proguard::writeKeepSet(&fout, keepSet); + proguard::WriteKeepSet(&fout, keep_set); if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() - << "failed writing to '" << outPath - << "': " << strerror(errno)); + context_->GetDiagnostics()->Error( + DiagMessage() << "failed writing to '" << out_path << "': " + << android::base::SystemErrorCodeToString(errno)); return false; } return true; } - std::unique_ptr<ResourceTable> loadStaticLibrary(const std::string& input, - std::string* outError) { + std::unique_ptr<ResourceTable> LoadStaticLibrary(const std::string& input, + std::string* out_error) { std::unique_ptr<io::ZipFileCollection> collection = - io::ZipFileCollection::create(input, outError); + io::ZipFileCollection::Create(input, out_error); if (!collection) { return {}; } - return loadTablePbFromCollection(collection.get()); + return LoadTablePbFromCollection(collection.get()); } - std::unique_ptr<ResourceTable> loadTablePbFromCollection( + std::unique_ptr<ResourceTable> LoadTablePbFromCollection( io::IFileCollection* collection) { - io::IFile* file = collection->findFile("resources.arsc.flat"); + io::IFile* file = collection->FindFile("resources.arsc.flat"); if (!file) { return {}; } - std::unique_ptr<io::IData> data = file->openAsData(); - return loadTableFromPb(file->getSource(), data->data(), data->size(), - mContext->getDiagnostics()); + std::unique_ptr<io::IData> data = file->OpenAsData(); + return LoadTableFromPb(file->GetSource(), data->data(), data->size(), + context_->GetDiagnostics()); } - bool mergeStaticLibrary(const std::string& input, bool override) { - if (mContext->verbose()) { - mContext->getDiagnostics()->note(DiagMessage() + bool MergeStaticLibrary(const std::string& input, bool override) { + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note(DiagMessage() << "merging static library " << input); } - std::string errorStr; + std::string error_str; std::unique_ptr<io::ZipFileCollection> collection = - io::ZipFileCollection::create(input, &errorStr); + io::ZipFileCollection::Create(input, &error_str); if (!collection) { - mContext->getDiagnostics()->error(DiagMessage(input) << errorStr); + context_->GetDiagnostics()->Error(DiagMessage(input) << error_str); return false; } std::unique_ptr<ResourceTable> table = - loadTablePbFromCollection(collection.get()); + LoadTablePbFromCollection(collection.get()); if (!table) { - mContext->getDiagnostics()->error(DiagMessage(input) + context_->GetDiagnostics()->Error(DiagMessage(input) << "invalid static library"); return false; } - ResourceTablePackage* pkg = table->findPackageById(0x7f); + ResourceTablePackage* pkg = table->FindPackageById(0x7f); if (!pkg) { - mContext->getDiagnostics()->error(DiagMessage(input) + context_->GetDiagnostics()->Error(DiagMessage(input) << "static library has no package"); return false; } bool result; - if (mOptions.noStaticLibPackages) { + if (options_.no_static_lib_packages) { // Merge all resources as if they were in the compilation package. This is - // the old - // behaviour of aapt. + // the old behavior of aapt. // Add the package to the set of --extra-packages so we emit an R.java for - // each - // library package. + // each library package. if (!pkg->name.empty()) { - mOptions.extraJavaPackages.insert(pkg->name); + options_.extra_java_packages.insert(pkg->name); } pkg->name = ""; if (override) { - result = mTableMerger->mergeOverlay(Source(input), table.get(), - collection.get()); + result = table_merger_->MergeOverlay(Source(input), table.get(), + collection.get()); } else { result = - mTableMerger->merge(Source(input), table.get(), collection.get()); + table_merger_->Merge(Source(input), table.get(), collection.get()); } } else { // This is the proper way to merge libraries, where the package name is - // preserved - // and resource names are mangled. - result = mTableMerger->mergeAndMangle(Source(input), pkg->name, - table.get(), collection.get()); + // preserved and resource names are mangled. + result = table_merger_->MergeAndMangle(Source(input), pkg->name, + table.get(), collection.get()); } if (!result) { @@ -1094,52 +1095,52 @@ class LinkCommand { } // Make sure to move the collection into the set of IFileCollections. - mCollections.push_back(std::move(collection)); + collections_.push_back(std::move(collection)); return true; } - bool mergeResourceTable(io::IFile* file, bool override) { - if (mContext->verbose()) { - mContext->getDiagnostics()->note( - DiagMessage() << "merging resource table " << file->getSource()); + bool MergeResourceTable(io::IFile* file, bool override) { + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note( + DiagMessage() << "merging resource table " << file->GetSource()); } - std::unique_ptr<io::IData> data = file->openAsData(); + std::unique_ptr<io::IData> data = file->OpenAsData(); if (!data) { - mContext->getDiagnostics()->error(DiagMessage(file->getSource()) + context_->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << "failed to open file"); return false; } std::unique_ptr<ResourceTable> table = - loadTableFromPb(file->getSource(), data->data(), data->size(), - mContext->getDiagnostics()); + LoadTableFromPb(file->GetSource(), data->data(), data->size(), + context_->GetDiagnostics()); if (!table) { return false; } bool result = false; if (override) { - result = mTableMerger->mergeOverlay(file->getSource(), table.get()); + result = table_merger_->MergeOverlay(file->GetSource(), table.get()); } else { - result = mTableMerger->merge(file->getSource(), table.get()); + result = table_merger_->Merge(file->GetSource(), table.get()); } return result; } - bool mergeCompiledFile(io::IFile* file, ResourceFile* fileDesc, + bool MergeCompiledFile(io::IFile* file, ResourceFile* file_desc, bool override) { - if (mContext->verbose()) { - mContext->getDiagnostics()->note( - DiagMessage() << "merging '" << fileDesc->name - << "' from compiled file " << file->getSource()); + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note( + DiagMessage() << "merging '" << file_desc->name + << "' from compiled file " << file->GetSource()); } bool result = false; if (override) { - result = mTableMerger->mergeFileOverlay(*fileDesc, file); + result = table_merger_->MergeFileOverlay(*file_desc, file); } else { - result = mTableMerger->mergeFile(*fileDesc, file); + result = table_merger_->MergeFile(*file_desc, file); } if (!result) { @@ -1147,24 +1148,24 @@ class LinkCommand { } // Add the exports of this file to the table. - for (SourcedResourceName& exportedSymbol : fileDesc->exportedSymbols) { - if (exportedSymbol.name.package.empty()) { - exportedSymbol.name.package = mContext->getCompilationPackage(); + for (SourcedResourceName& exported_symbol : file_desc->exported_symbols) { + if (exported_symbol.name.package.empty()) { + exported_symbol.name.package = context_->GetCompilationPackage(); } - ResourceNameRef resName = exportedSymbol.name; + ResourceNameRef res_name = exported_symbol.name; - Maybe<ResourceName> mangledName = - mContext->getNameMangler()->mangleName(exportedSymbol.name); - if (mangledName) { - resName = mangledName.value(); + Maybe<ResourceName> mangled_name = + context_->GetNameMangler()->MangleName(exported_symbol.name); + if (mangled_name) { + res_name = mangled_name.value(); } std::unique_ptr<Id> id = util::make_unique<Id>(); - id->setSource(fileDesc->source.withLine(exportedSymbol.line)); - bool result = mFinalTable.addResourceAllowMangled( - resName, ConfigDescription::defaultConfig(), std::string(), - std::move(id), mContext->getDiagnostics()); + id->SetSource(file_desc->source.WithLine(exported_symbol.line)); + bool result = final_table_.AddResourceAllowMangled( + res_name, ConfigDescription::DefaultConfig(), std::string(), + std::move(id), context_->GetDiagnostics()); if (!result) { return false; } @@ -1176,35 +1177,34 @@ class LinkCommand { * Takes a path to load as a ZIP file and merges the files within into the * master ResourceTable. * If override is true, conflicting resources are allowed to override each - * other, in order of - * last seen. + * other, in order of last seen. * * An io::IFileCollection is created from the ZIP file and added to the set of * io::IFileCollections that are open. */ - bool mergeArchive(const std::string& input, bool override) { - if (mContext->verbose()) { - mContext->getDiagnostics()->note(DiagMessage() << "merging archive " + bool MergeArchive(const std::string& input, bool override) { + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note(DiagMessage() << "merging archive " << input); } - std::string errorStr; + std::string error_str; std::unique_ptr<io::ZipFileCollection> collection = - io::ZipFileCollection::create(input, &errorStr); + io::ZipFileCollection::Create(input, &error_str); if (!collection) { - mContext->getDiagnostics()->error(DiagMessage(input) << errorStr); + context_->GetDiagnostics()->Error(DiagMessage(input) << error_str); return false; } bool error = false; - for (auto iter = collection->iterator(); iter->hasNext();) { - if (!mergeFile(iter->next(), override)) { + for (auto iter = collection->Iterator(); iter->HasNext();) { + if (!MergeFile(iter->Next(), override)) { error = true; } } // Make sure to move the collection into the set of IFileCollections. - mCollections.push_back(std::move(collection)); + collections_.push_back(std::move(collection)); return !error; } @@ -1220,18 +1220,16 @@ class LinkCommand { * * Otherwise the files is processed on its own. */ - bool mergePath(const std::string& path, bool override) { - if (util::stringEndsWith(path, ".flata") || - util::stringEndsWith(path, ".jar") || - util::stringEndsWith(path, ".jack") || - util::stringEndsWith(path, ".zip")) { - return mergeArchive(path, override); - } else if (util::stringEndsWith(path, ".apk")) { - return mergeStaticLibrary(path, override); - } - - io::IFile* file = mFileCollection->insertFile(path); - return mergeFile(file, override); + bool MergePath(const std::string& path, bool override) { + if (util::EndsWith(path, ".flata") || util::EndsWith(path, ".jar") || + util::EndsWith(path, ".jack") || util::EndsWith(path, ".zip")) { + return MergeArchive(path, override); + } else if (util::EndsWith(path, ".apk")) { + return MergeStaticLibrary(path, override); + } + + io::IFile* file = file_collection_->InsertFile(path); + return MergeFile(file, override); } /** @@ -1250,63 +1248,63 @@ class LinkCommand { * coming from a zip, * where we could have other files like classes.dex. */ - bool mergeFile(io::IFile* file, bool override) { - const Source& src = file->getSource(); - if (util::stringEndsWith(src.path, ".arsc.flat")) { - return mergeResourceTable(file, override); + bool MergeFile(io::IFile* file, bool override) { + const Source& src = file->GetSource(); + if (util::EndsWith(src.path, ".arsc.flat")) { + return MergeResourceTable(file, override); - } else if (util::stringEndsWith(src.path, ".flat")) { + } else if (util::EndsWith(src.path, ".flat")) { // Try opening the file and looking for an Export header. - std::unique_ptr<io::IData> data = file->openAsData(); + std::unique_ptr<io::IData> data = file->OpenAsData(); if (!data) { - mContext->getDiagnostics()->error(DiagMessage(src) << "failed to open"); + context_->GetDiagnostics()->Error(DiagMessage(src) << "failed to open"); return false; } - CompiledFileInputStream inputStream(data->data(), data->size()); - uint32_t numFiles = 0; - if (!inputStream.ReadLittleEndian32(&numFiles)) { - mContext->getDiagnostics()->error(DiagMessage(src) + CompiledFileInputStream input_stream(data->data(), data->size()); + uint32_t num_files = 0; + if (!input_stream.ReadLittleEndian32(&num_files)) { + context_->GetDiagnostics()->Error(DiagMessage(src) << "failed read num files"); return false; } - for (uint32_t i = 0; i < numFiles; i++) { - pb::CompiledFile compiledFile; - if (!inputStream.ReadCompiledFile(&compiledFile)) { - mContext->getDiagnostics()->error( + for (uint32_t i = 0; i < num_files; i++) { + pb::CompiledFile compiled_file; + if (!input_stream.ReadCompiledFile(&compiled_file)) { + context_->GetDiagnostics()->Error( DiagMessage(src) << "failed to read compiled file header"); return false; } uint64_t offset, len; - if (!inputStream.ReadDataMetaData(&offset, &len)) { - mContext->getDiagnostics()->error(DiagMessage(src) + if (!input_stream.ReadDataMetaData(&offset, &len)) { + context_->GetDiagnostics()->Error(DiagMessage(src) << "failed to read data meta data"); return false; } - std::unique_ptr<ResourceFile> resourceFile = - deserializeCompiledFileFromPb(compiledFile, file->getSource(), - mContext->getDiagnostics()); - if (!resourceFile) { + std::unique_ptr<ResourceFile> resource_file = + DeserializeCompiledFileFromPb(compiled_file, file->GetSource(), + context_->GetDiagnostics()); + if (!resource_file) { return false; } - if (!mergeCompiledFile(file->createFileSegment(offset, len), - resourceFile.get(), override)) { + if (!MergeCompiledFile(file->CreateFileSegment(offset, len), + resource_file.get(), override)) { return false; } } return true; - } else if (util::stringEndsWith(src.path, ".xml") || - util::stringEndsWith(src.path, ".png")) { + } else if (util::EndsWith(src.path, ".xml") || + util::EndsWith(src.path, ".png")) { // Since AAPT compiles these file types and appends .flat to them, seeing // their raw extensions is a sign that they weren't compiled. - const StringPiece fileType = - util::stringEndsWith(src.path, ".xml") ? "XML" : "PNG"; - mContext->getDiagnostics()->error(DiagMessage(src) - << "uncompiled " << fileType + const StringPiece file_type = + util::EndsWith(src.path, ".xml") ? "XML" : "PNG"; + context_->GetDiagnostics()->Error(DiagMessage(src) + << "uncompiled " << file_type << " file passed as argument. Must be " "compiled first into .flat file."); return false; @@ -1318,95 +1316,95 @@ class LinkCommand { return true; } - std::unique_ptr<xml::XmlResource> generateSplitManifest( - const AppInfo& appInfo, const SplitConstraints& constraints) { + std::unique_ptr<xml::XmlResource> GenerateSplitManifest( + const AppInfo& app_info, const SplitConstraints& constraints) { std::unique_ptr<xml::XmlResource> doc = util::make_unique<xml::XmlResource>(); - std::unique_ptr<xml::Namespace> namespaceAndroid = + std::unique_ptr<xml::Namespace> namespace_android = util::make_unique<xml::Namespace>(); - namespaceAndroid->namespaceUri = xml::kSchemaAndroid; - namespaceAndroid->namespacePrefix = "android"; + namespace_android->namespace_uri = xml::kSchemaAndroid; + namespace_android->namespace_prefix = "android"; - std::unique_ptr<xml::Element> manifestEl = + std::unique_ptr<xml::Element> manifest_el = util::make_unique<xml::Element>(); - manifestEl->name = "manifest"; - manifestEl->attributes.push_back( - xml::Attribute{"", "package", appInfo.package}); + manifest_el->name = "manifest"; + manifest_el->attributes.push_back( + xml::Attribute{"", "package", app_info.package}); - if (appInfo.versionCode) { - manifestEl->attributes.push_back( + if (app_info.version_code) { + manifest_el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "versionCode", - std::to_string(appInfo.versionCode.value())}); + std::to_string(app_info.version_code.value())}); } - if (appInfo.revisionCode) { - manifestEl->attributes.push_back( + if (app_info.revision_code) { + manifest_el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "revisionCode", - std::to_string(appInfo.revisionCode.value())}); + std::to_string(app_info.revision_code.value())}); } - std::stringstream splitName; - splitName << "config." << util::joiner(constraints.configs, "_"); + std::stringstream split_name; + split_name << "config." << util::Joiner(constraints.configs, "_"); - manifestEl->attributes.push_back( - xml::Attribute{"", "split", splitName.str()}); + manifest_el->attributes.push_back( + xml::Attribute{"", "split", split_name.str()}); - std::unique_ptr<xml::Element> applicationEl = + std::unique_ptr<xml::Element> application_el = util::make_unique<xml::Element>(); - applicationEl->name = "application"; - applicationEl->attributes.push_back( + application_el->name = "application"; + application_el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "hasCode", "false"}); - manifestEl->addChild(std::move(applicationEl)); - namespaceAndroid->addChild(std::move(manifestEl)); - doc->root = std::move(namespaceAndroid); + manifest_el->AddChild(std::move(application_el)); + namespace_android->AddChild(std::move(manifest_el)); + doc->root = std::move(namespace_android); return doc; } /** * Writes the AndroidManifest, ResourceTable, and all XML files referenced by - * the ResourceTable - * to the IArchiveWriter. + * the ResourceTable to the IArchiveWriter. */ - bool writeApk(IArchiveWriter* writer, proguard::KeepSet* keepSet, + bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest, ResourceTable* table) { - const bool keepRawValues = mOptions.staticLib; - bool result = flattenXml(manifest, "AndroidManifest.xml", {}, keepRawValues, - writer, mContext); + const bool keep_raw_values = options_.static_lib; + bool result = FlattenXml(manifest, "AndroidManifest.xml", {}, + keep_raw_values, writer, context_); if (!result) { return false; } - ResourceFileFlattenerOptions fileFlattenerOptions; - fileFlattenerOptions.keepRawValues = keepRawValues; - fileFlattenerOptions.doNotCompressAnything = mOptions.doNotCompressAnything; - fileFlattenerOptions.extensionsToNotCompress = - mOptions.extensionsToNotCompress; - fileFlattenerOptions.noAutoVersion = mOptions.noAutoVersion; - fileFlattenerOptions.noVersionVectors = mOptions.noVersionVectors; - fileFlattenerOptions.noXmlNamespaces = mOptions.noXmlNamespaces; - fileFlattenerOptions.updateProguardSpec = - static_cast<bool>(mOptions.generateProguardRulesPath); + ResourceFileFlattenerOptions file_flattener_options; + file_flattener_options.keep_raw_values = keep_raw_values; + file_flattener_options.do_not_compress_anything = + options_.do_not_compress_anything; + file_flattener_options.extensions_to_not_compress = + options_.extensions_to_not_compress; + file_flattener_options.no_auto_version = options_.no_auto_version; + file_flattener_options.no_version_vectors = options_.no_version_vectors; + file_flattener_options.no_xml_namespaces = options_.no_xml_namespaces; + file_flattener_options.update_proguard_spec = + static_cast<bool>(options_.generate_proguard_rules_path); - ResourceFileFlattener fileFlattener(fileFlattenerOptions, mContext, - keepSet); + ResourceFileFlattener file_flattener(file_flattener_options, context_, + keep_set); - if (!fileFlattener.flatten(table, writer)) { - mContext->getDiagnostics()->error(DiagMessage() + if (!file_flattener.Flatten(table, writer)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed linking file resources"); return false; } - if (mOptions.staticLib) { - if (!flattenTableToPb(table, writer)) { - mContext->getDiagnostics()->error( + if (options_.static_lib) { + if (!FlattenTableToPb(table, writer)) { + context_->GetDiagnostics()->Error( DiagMessage() << "failed to write resources.arsc.flat"); return false; } } else { - if (!flattenTable(table, writer)) { - mContext->getDiagnostics()->error(DiagMessage() + if (!FlattenTable(table, writer)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed to write resources.arsc"); return false; } @@ -1414,118 +1412,118 @@ class LinkCommand { return true; } - int run(const std::vector<std::string>& inputFiles) { + int Run(const std::vector<std::string>& input_files) { // Load the AndroidManifest.xml - std::unique_ptr<xml::XmlResource> manifestXml = - loadXml(mOptions.manifestPath, mContext->getDiagnostics()); - if (!manifestXml) { + std::unique_ptr<xml::XmlResource> manifest_xml = + LoadXml(options_.manifest_path, context_->GetDiagnostics()); + if (!manifest_xml) { return 1; } // First extract the Package name without modifying it (via // --rename-manifest-package). - if (Maybe<AppInfo> maybeAppInfo = extractAppInfoFromManifest( - manifestXml.get(), mContext->getDiagnostics())) { - const AppInfo& appInfo = maybeAppInfo.value(); - mContext->setCompilationPackage(appInfo.package); + if (Maybe<AppInfo> maybe_app_info = ExtractAppInfoFromManifest( + manifest_xml.get(), context_->GetDiagnostics())) { + const AppInfo& app_info = maybe_app_info.value(); + context_->SetCompilationPackage(app_info.package); } - ManifestFixer manifestFixer(mOptions.manifestFixerOptions); - if (!manifestFixer.consume(mContext, manifestXml.get())) { + ManifestFixer manifest_fixer(options_.manifest_fixer_options); + if (!manifest_fixer.Consume(context_, manifest_xml.get())) { return 1; } - Maybe<AppInfo> maybeAppInfo = extractAppInfoFromManifest( - manifestXml.get(), mContext->getDiagnostics()); - if (!maybeAppInfo) { + Maybe<AppInfo> maybe_app_info = ExtractAppInfoFromManifest( + manifest_xml.get(), context_->GetDiagnostics()); + if (!maybe_app_info) { return 1; } - const AppInfo& appInfo = maybeAppInfo.value(); - if (appInfo.minSdkVersion) { - if (Maybe<int> maybeMinSdkVersion = - ResourceUtils::parseSdkVersion(appInfo.minSdkVersion.value())) { - mContext->setMinSdkVersion(maybeMinSdkVersion.value()); + const AppInfo& app_info = maybe_app_info.value(); + if (app_info.min_sdk_version) { + if (Maybe<int> maybe_min_sdk_version = ResourceUtils::ParseSdkVersion( + app_info.min_sdk_version.value())) { + context_->SetMinSdkVersion(maybe_min_sdk_version.value()); } } - mContext->setNameManglerPolicy( - NameManglerPolicy{mContext->getCompilationPackage()}); - if (mContext->getCompilationPackage() == "android") { - mContext->setPackageId(0x01); + context_->SetNameManglerPolicy( + NameManglerPolicy{context_->GetCompilationPackage()}); + if (context_->GetCompilationPackage() == "android") { + context_->SetPackageId(0x01); } else { - mContext->setPackageId(0x7f); + context_->SetPackageId(0x7f); } - if (!loadSymbolsFromIncludePaths()) { + if (!LoadSymbolsFromIncludePaths()) { return 1; } - TableMergerOptions tableMergerOptions; - tableMergerOptions.autoAddOverlay = mOptions.autoAddOverlay; - mTableMerger = util::make_unique<TableMerger>(mContext, &mFinalTable, - tableMergerOptions); + TableMergerOptions table_merger_options; + table_merger_options.auto_add_overlay = options_.auto_add_overlay; + table_merger_ = util::make_unique<TableMerger>(context_, &final_table_, + table_merger_options); - if (mContext->verbose()) { - mContext->getDiagnostics()->note(DiagMessage() + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note(DiagMessage() << "linking package '" - << mContext->getCompilationPackage() + << context_->GetCompilationPackage() << "' with package ID " << std::hex - << (int)mContext->getPackageId()); + << (int)context_->GetPackageId()); } - for (const std::string& input : inputFiles) { - if (!mergePath(input, false)) { - mContext->getDiagnostics()->error(DiagMessage() + for (const std::string& input : input_files) { + if (!MergePath(input, false)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed parsing input"); return 1; } } - for (const std::string& input : mOptions.overlayFiles) { - if (!mergePath(input, true)) { - mContext->getDiagnostics()->error(DiagMessage() + for (const std::string& input : options_.overlay_files) { + if (!MergePath(input, true)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed parsing overlays"); return 1; } } - if (!verifyNoExternalPackages()) { + if (!VerifyNoExternalPackages()) { return 1; } - if (!mOptions.staticLib) { + if (!options_.static_lib) { PrivateAttributeMover mover; - if (!mover.consume(mContext, &mFinalTable)) { - mContext->getDiagnostics()->error( + if (!mover.Consume(context_, &final_table_)) { + context_->GetDiagnostics()->Error( DiagMessage() << "failed moving private attributes"); return 1; } // Assign IDs if we are building a regular app. - IdAssigner idAssigner(&mOptions.stableIdMap); - if (!idAssigner.consume(mContext, &mFinalTable)) { - mContext->getDiagnostics()->error(DiagMessage() + IdAssigner id_assigner(&options_.stable_id_map); + if (!id_assigner.Consume(context_, &final_table_)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed assigning IDs"); return 1; } // Now grab each ID and emit it as a file. - if (mOptions.resourceIdMapPath) { - for (auto& package : mFinalTable.packages) { + if (options_.resource_id_map_path) { + for (auto& package : final_table_.packages) { for (auto& type : package->types) { for (auto& entry : type->entries) { ResourceName name(package->name, type->type, entry->name); // The IDs are guaranteed to exist. - mOptions.stableIdMap[std::move(name)] = ResourceId( + options_.stable_id_map[std::move(name)] = ResourceId( package->id.value(), type->id.value(), entry->id.value()); } } } - if (!writeStableIdMapToPath(mContext->getDiagnostics(), - mOptions.stableIdMap, - mOptions.resourceIdMapPath.value())) { + if (!WriteStableIdMapToPath(context_->GetDiagnostics(), + options_.stable_id_map, + options_.resource_id_map_path.value())) { return 1; } } @@ -1533,80 +1531,80 @@ class LinkCommand { // Static libs are merged with other apps, and ID collisions are bad, so // verify that // no IDs have been set. - if (!verifyNoIdsSet()) { + if (!VerifyNoIdsSet()) { return 1; } } // Add the names to mangle based on our source merge earlier. - mContext->setNameManglerPolicy(NameManglerPolicy{ - mContext->getCompilationPackage(), mTableMerger->getMergedPackages()}); + context_->SetNameManglerPolicy(NameManglerPolicy{ + context_->GetCompilationPackage(), table_merger_->merged_packages()}); // Add our table to the symbol table. - mContext->getExternalSymbols()->prependSource( - util::make_unique<ResourceTableSymbolSource>(&mFinalTable)); + context_->GetExternalSymbols()->PrependSource( + util::make_unique<ResourceTableSymbolSource>(&final_table_)); ReferenceLinker linker; - if (!linker.consume(mContext, &mFinalTable)) { - mContext->getDiagnostics()->error(DiagMessage() + if (!linker.Consume(context_, &final_table_)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed linking references"); return 1; } - if (mOptions.staticLib) { - if (!mOptions.products.empty()) { - mContext->getDiagnostics() - ->warn(DiagMessage() + if (options_.static_lib) { + if (!options_.products.empty()) { + context_->GetDiagnostics() + ->Warn(DiagMessage() << "can't select products when building static library"); } } else { - ProductFilter productFilter(mOptions.products); - if (!productFilter.consume(mContext, &mFinalTable)) { - mContext->getDiagnostics()->error(DiagMessage() + ProductFilter product_filter(options_.products); + if (!product_filter.Consume(context_, &final_table_)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed stripping products"); return 1; } } - if (!mOptions.noAutoVersion) { + if (!options_.no_auto_version) { AutoVersioner versioner; - if (!versioner.consume(mContext, &mFinalTable)) { - mContext->getDiagnostics()->error(DiagMessage() + if (!versioner.Consume(context_, &final_table_)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed versioning styles"); return 1; } } - if (!mOptions.staticLib && mContext->getMinSdkVersion() > 0) { - if (mContext->verbose()) { - mContext->getDiagnostics()->note( + if (!options_.static_lib && context_->GetMinSdkVersion() > 0) { + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note( DiagMessage() << "collapsing resource versions for minimum SDK " - << mContext->getMinSdkVersion()); + << context_->GetMinSdkVersion()); } VersionCollapser collapser; - if (!collapser.consume(mContext, &mFinalTable)) { + if (!collapser.Consume(context_, &final_table_)) { return 1; } } - if (!mOptions.noResourceDeduping) { + if (!options_.no_resource_deduping) { ResourceDeduper deduper; - if (!deduper.consume(mContext, &mFinalTable)) { - mContext->getDiagnostics()->error(DiagMessage() + if (!deduper.Consume(context_, &final_table_)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed deduping resources"); return 1; } } - proguard::KeepSet proguardKeepSet; - proguard::KeepSet proguardMainDexKeepSet; + proguard::KeepSet proguard_keep_set; + proguard::KeepSet proguard_main_dex_keep_set; - if (mOptions.staticLib) { - if (mOptions.tableSplitterOptions.configFilter != nullptr || - mOptions.tableSplitterOptions.preferredDensity) { - mContext->getDiagnostics() - ->warn(DiagMessage() + if (options_.static_lib) { + if (options_.table_splitter_options.config_filter != nullptr || + options_.table_splitter_options.preferred_density) { + context_->GetDiagnostics() + ->Warn(DiagMessage() << "can't strip resources when building static library"); } } else { @@ -1615,73 +1613,73 @@ class LinkCommand { // than or equal to the minSdk. Otherwise the resources that have had // their SDK version // stripped due to minSdk won't ever match. - std::vector<SplitConstraints> adjustedConstraintsList; - adjustedConstraintsList.reserve(mOptions.splitConstraints.size()); - for (const SplitConstraints& constraints : mOptions.splitConstraints) { - SplitConstraints adjustedConstraints; + std::vector<SplitConstraints> adjusted_constraints_list; + adjusted_constraints_list.reserve(options_.split_constraints.size()); + for (const SplitConstraints& constraints : options_.split_constraints) { + SplitConstraints adjusted_constraints; for (const ConfigDescription& config : constraints.configs) { - if (config.sdkVersion <= mContext->getMinSdkVersion()) { - adjustedConstraints.configs.insert(config.copyWithoutSdkVersion()); + if (config.sdkVersion <= context_->GetMinSdkVersion()) { + adjusted_constraints.configs.insert(config.CopyWithoutSdkVersion()); } else { - adjustedConstraints.configs.insert(config); + adjusted_constraints.configs.insert(config); } } - adjustedConstraintsList.push_back(std::move(adjustedConstraints)); + adjusted_constraints_list.push_back(std::move(adjusted_constraints)); } - TableSplitter tableSplitter(adjustedConstraintsList, - mOptions.tableSplitterOptions); - if (!tableSplitter.verifySplitConstraints(mContext)) { + TableSplitter table_splitter(adjusted_constraints_list, + options_.table_splitter_options); + if (!table_splitter.VerifySplitConstraints(context_)) { return 1; } - tableSplitter.splitTable(&mFinalTable); + table_splitter.SplitTable(&final_table_); // Now we need to write out the Split APKs. - auto pathIter = mOptions.splitPaths.begin(); - auto splitConstraintsIter = adjustedConstraintsList.begin(); - for (std::unique_ptr<ResourceTable>& splitTable : - tableSplitter.getSplits()) { - if (mContext->verbose()) { - mContext->getDiagnostics()->note( - DiagMessage(*pathIter) + auto path_iter = options_.split_paths.begin(); + auto split_constraints_iter = adjusted_constraints_list.begin(); + for (std::unique_ptr<ResourceTable>& split_table : + table_splitter.splits()) { + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note( + DiagMessage(*path_iter) << "generating split with configurations '" - << util::joiner(splitConstraintsIter->configs, ", ") << "'"); + << util::Joiner(split_constraints_iter->configs, ", ") << "'"); } - std::unique_ptr<IArchiveWriter> archiveWriter = - makeArchiveWriter(*pathIter); - if (!archiveWriter) { - mContext->getDiagnostics()->error(DiagMessage() + std::unique_ptr<IArchiveWriter> archive_writer = + MakeArchiveWriter(*path_iter); + if (!archive_writer) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed to create archive"); return 1; } // Generate an AndroidManifest.xml for each split. - std::unique_ptr<xml::XmlResource> splitManifest = - generateSplitManifest(appInfo, *splitConstraintsIter); + std::unique_ptr<xml::XmlResource> split_manifest = + GenerateSplitManifest(app_info, *split_constraints_iter); XmlReferenceLinker linker; - if (!linker.consume(mContext, splitManifest.get())) { - mContext->getDiagnostics()->error( + if (!linker.Consume(context_, split_manifest.get())) { + context_->GetDiagnostics()->Error( DiagMessage() << "failed to create Split AndroidManifest.xml"); return 1; } - if (!writeApk(archiveWriter.get(), &proguardKeepSet, - splitManifest.get(), splitTable.get())) { + if (!WriteApk(archive_writer.get(), &proguard_keep_set, + split_manifest.get(), split_table.get())) { return 1; } - ++pathIter; - ++splitConstraintsIter; + ++path_iter; + ++split_constraints_iter; } } // Start writing the base APK. - std::unique_ptr<IArchiveWriter> archiveWriter = - makeArchiveWriter(mOptions.outputPath); - if (!archiveWriter) { - mContext->getDiagnostics()->error(DiagMessage() + std::unique_ptr<IArchiveWriter> archive_writer = + MakeArchiveWriter(options_.output_path); + if (!archive_writer) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed to create archive"); return 1; } @@ -1692,35 +1690,35 @@ class LinkCommand { // from the name // (aka, which package the AndroidManifest.xml is coming from). // So we give it a package name so it can see local resources. - manifestXml->file.name.package = mContext->getCompilationPackage(); - - XmlReferenceLinker manifestLinker; - if (manifestLinker.consume(mContext, manifestXml.get())) { - if (mOptions.generateProguardRulesPath && - !proguard::collectProguardRulesForManifest( - Source(mOptions.manifestPath), manifestXml.get(), - &proguardKeepSet)) { + manifest_xml->file.name.package = context_->GetCompilationPackage(); + + XmlReferenceLinker manifest_linker; + if (manifest_linker.Consume(context_, manifest_xml.get())) { + if (options_.generate_proguard_rules_path && + !proguard::CollectProguardRulesForManifest( + Source(options_.manifest_path), manifest_xml.get(), + &proguard_keep_set)) { error = true; } - if (mOptions.generateMainDexProguardRulesPath && - !proguard::collectProguardRulesForManifest( - Source(mOptions.manifestPath), manifestXml.get(), - &proguardMainDexKeepSet, true)) { + if (options_.generate_main_dex_proguard_rules_path && + !proguard::CollectProguardRulesForManifest( + Source(options_.manifest_path), manifest_xml.get(), + &proguard_main_dex_keep_set, true)) { error = true; } - if (mOptions.generateJavaClassPath) { - if (!writeManifestJavaFile(manifestXml.get())) { + if (options_.generate_java_class_path) { + if (!WriteManifestJavaFile(manifest_xml.get())) { error = true; } } - if (mOptions.noXmlNamespaces) { + if (options_.no_xml_namespaces) { // PackageParser will fail if URIs are removed from // AndroidManifest.xml. - XmlNamespaceRemover namespaceRemover(true /* keepUris */); - if (!namespaceRemover.consume(mContext, manifestXml.get())) { + XmlNamespaceRemover namespace_remover(true /* keepUris */); + if (!namespace_remover.Consume(context_, manifest_xml.get())) { error = true; } } @@ -1730,382 +1728,385 @@ class LinkCommand { } if (error) { - mContext->getDiagnostics()->error(DiagMessage() + context_->GetDiagnostics()->Error(DiagMessage() << "failed processing manifest"); return 1; } - if (!writeApk(archiveWriter.get(), &proguardKeepSet, manifestXml.get(), - &mFinalTable)) { + if (!WriteApk(archive_writer.get(), &proguard_keep_set, manifest_xml.get(), + &final_table_)) { return 1; } - if (mOptions.generateJavaClassPath) { + if (options_.generate_java_class_path) { JavaClassGeneratorOptions options; options.types = JavaClassGeneratorOptions::SymbolTypes::kAll; - options.javadocAnnotations = mOptions.javadocAnnotations; + options.javadoc_annotations = options_.javadoc_annotations; - if (mOptions.staticLib || mOptions.generateNonFinalIds) { - options.useFinal = false; + if (options_.static_lib || options_.generate_non_final_ids) { + options.use_final = false; } - const StringPiece actualPackage = mContext->getCompilationPackage(); - StringPiece outputPackage = mContext->getCompilationPackage(); - if (mOptions.customJavaPackage) { + const StringPiece actual_package = context_->GetCompilationPackage(); + StringPiece output_package = context_->GetCompilationPackage(); + if (options_.custom_java_package) { // Override the output java package to the custom one. - outputPackage = mOptions.customJavaPackage.value(); + output_package = options_.custom_java_package.value(); } - if (mOptions.privateSymbols) { + if (options_.private_symbols) { // If we defined a private symbols package, we only emit Public symbols // to the original package, and private and public symbols to the // private package. options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic; - if (!writeJavaFile(&mFinalTable, mContext->getCompilationPackage(), - outputPackage, options)) { + if (!WriteJavaFile(&final_table_, context_->GetCompilationPackage(), + output_package, options)) { return 1; } options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate; - outputPackage = mOptions.privateSymbols.value(); + output_package = options_.private_symbols.value(); } - if (!writeJavaFile(&mFinalTable, actualPackage, outputPackage, options)) { + if (!WriteJavaFile(&final_table_, actual_package, output_package, + options)) { return 1; } - for (const std::string& extraPackage : mOptions.extraJavaPackages) { - if (!writeJavaFile(&mFinalTable, actualPackage, extraPackage, + for (const std::string& extra_package : options_.extra_java_packages) { + if (!WriteJavaFile(&final_table_, actual_package, extra_package, options)) { return 1; } } } - if (!writeProguardFile(mOptions.generateProguardRulesPath, - proguardKeepSet)) { + if (!WriteProguardFile(options_.generate_proguard_rules_path, + proguard_keep_set)) { return 1; } - if (!writeProguardFile(mOptions.generateMainDexProguardRulesPath, - proguardMainDexKeepSet)) { + if (!WriteProguardFile(options_.generate_main_dex_proguard_rules_path, + proguard_main_dex_keep_set)) { return 1; } - if (mContext->verbose()) { - DebugPrintTableOptions debugPrintTableOptions; - debugPrintTableOptions.showSources = true; - Debug::printTable(&mFinalTable, debugPrintTableOptions); + if (context_->IsVerbose()) { + DebugPrintTableOptions debug_print_table_options; + debug_print_table_options.show_sources = true; + Debug::PrintTable(&final_table_, debug_print_table_options); } return 0; } private: - LinkOptions mOptions; - LinkContext* mContext; - ResourceTable mFinalTable; + LinkOptions options_; + LinkContext* context_; + ResourceTable final_table_; - std::unique_ptr<TableMerger> mTableMerger; + std::unique_ptr<TableMerger> table_merger_; // A pointer to the FileCollection representing the filesystem (not archives). - std::unique_ptr<io::FileCollection> mFileCollection; + std::unique_ptr<io::FileCollection> file_collection_; // A vector of IFileCollections. This is mainly here to keep ownership of the // collections. - std::vector<std::unique_ptr<io::IFileCollection>> mCollections; + std::vector<std::unique_ptr<io::IFileCollection>> collections_; // A vector of ResourceTables. This is here to retain ownership, so that the // SymbolTable // can use these. - std::vector<std::unique_ptr<ResourceTable>> mStaticTableIncludes; + std::vector<std::unique_ptr<ResourceTable>> static_table_includes_; }; -int link(const std::vector<StringPiece>& args) { +int Link(const std::vector<StringPiece>& args) { LinkContext context; LinkOptions options; - std::vector<std::string> overlayArgList; - std::vector<std::string> extraJavaPackages; + std::vector<std::string> overlay_arg_list; + std::vector<std::string> extra_java_packages; Maybe<std::string> configs; - Maybe<std::string> preferredDensity; - Maybe<std::string> productList; - bool legacyXFlag = false; - bool requireLocalization = false; + Maybe<std::string> preferred_density; + Maybe<std::string> product_list; + bool legacy_x_flag = false; + bool require_localization = false; bool verbose = false; - Maybe<std::string> stableIdFilePath; - std::vector<std::string> splitArgs; + Maybe<std::string> stable_id_file_path; + std::vector<std::string> split_args; Flags flags = Flags() - .requiredFlag("-o", "Output path", &options.outputPath) - .requiredFlag("--manifest", "Path to the Android manifest to build", - &options.manifestPath) - .optionalFlagList("-I", "Adds an Android APK to link against", - &options.includePaths) - .optionalFlagList( + .RequiredFlag("-o", "Output path", &options.output_path) + .RequiredFlag("--manifest", "Path to the Android manifest to build", + &options.manifest_path) + .OptionalFlagList("-I", "Adds an Android APK to link against", + &options.include_paths) + .OptionalFlagList( "-R", "Compilation unit to link, using `overlay` semantics.\n" "The last conflicting resource given takes precedence.", - &overlayArgList) - .optionalFlag("--java", "Directory in which to generate R.java", - &options.generateJavaClassPath) - .optionalFlag("--proguard", + &overlay_arg_list) + .OptionalFlag("--java", "Directory in which to generate R.java", + &options.generate_java_class_path) + .OptionalFlag("--proguard", "Output file for generated Proguard rules", - &options.generateProguardRulesPath) - .optionalFlag( + &options.generate_proguard_rules_path) + .OptionalFlag( "--proguard-main-dex", "Output file for generated Proguard rules for the main dex", - &options.generateMainDexProguardRulesPath) - .optionalSwitch("--no-auto-version", + &options.generate_main_dex_proguard_rules_path) + .OptionalSwitch("--no-auto-version", "Disables automatic style and layout SDK versioning", - &options.noAutoVersion) - .optionalSwitch("--no-version-vectors", + &options.no_auto_version) + .OptionalSwitch("--no-version-vectors", "Disables automatic versioning of vector drawables. " "Use this only\n" "when building with vector drawable support library", - &options.noVersionVectors) - .optionalSwitch("--no-resource-deduping", + &options.no_version_vectors) + .OptionalSwitch("--no-resource-deduping", "Disables automatic deduping of resources with\n" "identical values across compatible configurations.", - &options.noResourceDeduping) - .optionalSwitch( + &options.no_resource_deduping) + .OptionalSwitch( "-x", "Legacy flag that specifies to use the package identifier 0x01", - &legacyXFlag) - .optionalSwitch("-z", + &legacy_x_flag) + .OptionalSwitch("-z", "Require localization of strings marked 'suggested'", - &requireLocalization) - .optionalFlag( + &require_localization) + .OptionalFlag( "-c", "Comma separated list of configurations to include. The default\n" "is all configurations", &configs) - .optionalFlag( + .OptionalFlag( "--preferred-density", "Selects the closest matching density and strips out all others.", - &preferredDensity) - .optionalFlag("--product", + &preferred_density) + .OptionalFlag("--product", "Comma separated list of product names to keep", - &productList) - .optionalSwitch("--output-to-dir", + &product_list) + .OptionalSwitch("--output-to-dir", "Outputs the APK contents to a directory specified " "by -o", - &options.outputToDirectory) - .optionalSwitch("--no-xml-namespaces", + &options.output_to_directory) + .OptionalSwitch("--no-xml-namespaces", "Removes XML namespace prefix and URI " "information from AndroidManifest.xml\nand XML " "binaries in res/*.", - &options.noXmlNamespaces) - .optionalFlag("--min-sdk-version", + &options.no_xml_namespaces) + .OptionalFlag("--min-sdk-version", "Default minimum SDK version to use for " "AndroidManifest.xml", - &options.manifestFixerOptions.minSdkVersionDefault) - .optionalFlag("--target-sdk-version", - "Default target SDK version to use for " - "AndroidManifest.xml", - &options.manifestFixerOptions.targetSdkVersionDefault) - .optionalFlag("--version-code", + &options.manifest_fixer_options.min_sdk_version_default) + .OptionalFlag( + "--target-sdk-version", + "Default target SDK version to use for " + "AndroidManifest.xml", + &options.manifest_fixer_options.target_sdk_version_default) + .OptionalFlag("--version-code", "Version code (integer) to inject into the " "AndroidManifest.xml if none is present", - &options.manifestFixerOptions.versionCodeDefault) - .optionalFlag("--version-name", + &options.manifest_fixer_options.version_code_default) + .OptionalFlag("--version-name", "Version name to inject into the AndroidManifest.xml " "if none is present", - &options.manifestFixerOptions.versionNameDefault) - .optionalSwitch("--static-lib", "Generate a static Android library", - &options.staticLib) - .optionalSwitch("--no-static-lib-packages", + &options.manifest_fixer_options.version_name_default) + .OptionalSwitch("--static-lib", "Generate a static Android library", + &options.static_lib) + .OptionalSwitch("--no-static-lib-packages", "Merge all library resources under the app's package", - &options.noStaticLibPackages) - .optionalSwitch("--non-final-ids", + &options.no_static_lib_packages) + .OptionalSwitch("--non-final-ids", "Generates R.java without the final modifier.\n" "This is implied when --static-lib is specified.", - &options.generateNonFinalIds) - .optionalFlag("--stable-ids", + &options.generate_non_final_ids) + .OptionalFlag("--stable-ids", "File containing a list of name to ID mapping.", - &stableIdFilePath) - .optionalFlag( + &stable_id_file_path) + .OptionalFlag( "--emit-ids", "Emit a file at the given path with a list of name to ID\n" "mappings, suitable for use with --stable-ids.", - &options.resourceIdMapPath) - .optionalFlag("--private-symbols", + &options.resource_id_map_path) + .OptionalFlag("--private-symbols", "Package name to use when generating R.java for " "private symbols.\n" "If not specified, public and private symbols will use " "the application's " "package name", - &options.privateSymbols) - .optionalFlag("--custom-package", + &options.private_symbols) + .OptionalFlag("--custom-package", "Custom Java package under which to generate R.java", - &options.customJavaPackage) - .optionalFlagList("--extra-packages", + &options.custom_java_package) + .OptionalFlagList("--extra-packages", "Generate the same R.java but with different " "package names", - &extraJavaPackages) - .optionalFlagList("--add-javadoc-annotation", + &extra_java_packages) + .OptionalFlagList("--add-javadoc-annotation", "Adds a JavaDoc annotation to all " "generated Java classes", - &options.javadocAnnotations) - .optionalSwitch("--auto-add-overlay", + &options.javadoc_annotations) + .OptionalSwitch("--auto-add-overlay", "Allows the addition of new resources in " "overlays without <add-resource> tags", - &options.autoAddOverlay) - .optionalFlag("--rename-manifest-package", + &options.auto_add_overlay) + .OptionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml", - &options.manifestFixerOptions.renameManifestPackage) - .optionalFlag( + &options.manifest_fixer_options.rename_manifest_package) + .OptionalFlag( "--rename-instrumentation-target-package", "Changes the name of the target package for instrumentation. " "Most useful " "when used\nin conjunction with --rename-manifest-package", - &options.manifestFixerOptions.renameInstrumentationTargetPackage) - .optionalFlagList("-0", "File extensions not to compress", - &options.extensionsToNotCompress) - .optionalFlagList( + &options.manifest_fixer_options + .rename_instrumentation_target_package) + .OptionalFlagList("-0", "File extensions not to compress", + &options.extensions_to_not_compress) + .OptionalFlagList( "--split", "Split resources matching a set of configs out to a " "Split APK.\nSyntax: path/to/output.apk:<config>[,<config>[...]]", - &splitArgs) - .optionalSwitch("-v", "Enables verbose logging", &verbose); + &split_args) + .OptionalSwitch("-v", "Enables verbose logging", &verbose); - if (!flags.parse("aapt2 link", args, &std::cerr)) { + if (!flags.Parse("aapt2 link", args, &std::cerr)) { return 1; } // Expand all argument-files passed into the command line. These start with // '@'. - std::vector<std::string> argList; - for (const std::string& arg : flags.getArgs()) { - if (util::stringStartsWith(arg, "@")) { + std::vector<std::string> arg_list; + for (const std::string& arg : flags.GetArgs()) { + if (util::StartsWith(arg, "@")) { const std::string path = arg.substr(1, arg.size() - 1); std::string error; - if (!file::appendArgsFromFile(path, &argList, &error)) { - context.getDiagnostics()->error(DiagMessage(path) << error); + if (!file::AppendArgsFromFile(path, &arg_list, &error)) { + context.GetDiagnostics()->Error(DiagMessage(path) << error); return 1; } } else { - argList.push_back(arg); + arg_list.push_back(arg); } } // Expand all argument-files passed to -R. - for (const std::string& arg : overlayArgList) { - if (util::stringStartsWith(arg, "@")) { + for (const std::string& arg : overlay_arg_list) { + if (util::StartsWith(arg, "@")) { const std::string path = arg.substr(1, arg.size() - 1); std::string error; - if (!file::appendArgsFromFile(path, &options.overlayFiles, &error)) { - context.getDiagnostics()->error(DiagMessage(path) << error); + if (!file::AppendArgsFromFile(path, &options.overlay_files, &error)) { + context.GetDiagnostics()->Error(DiagMessage(path) << error); return 1; } } else { - options.overlayFiles.push_back(arg); + options.overlay_files.push_back(arg); } } if (verbose) { - context.setVerbose(verbose); + context.SetVerbose(verbose); } // Populate the set of extra packages for which to generate R.java. - for (std::string& extraPackage : extraJavaPackages) { + for (std::string& extra_package : extra_java_packages) { // A given package can actually be a colon separated list of packages. - for (StringPiece package : util::split(extraPackage, ':')) { - options.extraJavaPackages.insert(package.toString()); + for (StringPiece package : util::Split(extra_package, ':')) { + options.extra_java_packages.insert(package.ToString()); } } - if (productList) { - for (StringPiece product : util::tokenize(productList.value(), ',')) { + if (product_list) { + for (StringPiece product : util::Tokenize(product_list.value(), ',')) { if (product != "" && product != "default") { - options.products.insert(product.toString()); + options.products.insert(product.ToString()); } } } AxisConfigFilter filter; if (configs) { - for (const StringPiece& configStr : util::tokenize(configs.value(), ',')) { + for (const StringPiece& config_str : util::Tokenize(configs.value(), ',')) { ConfigDescription config; LocaleValue lv; - if (lv.initFromFilterString(configStr)) { - lv.writeTo(&config); - } else if (!ConfigDescription::parse(configStr, &config)) { - context.getDiagnostics()->error(DiagMessage() << "invalid config '" - << configStr + if (lv.InitFromFilterString(config_str)) { + lv.WriteTo(&config); + } else if (!ConfigDescription::Parse(config_str, &config)) { + context.GetDiagnostics()->Error(DiagMessage() << "invalid config '" + << config_str << "' for -c option"); return 1; } if (config.density != 0) { - context.getDiagnostics()->warn(DiagMessage() << "ignoring density '" + context.GetDiagnostics()->Warn(DiagMessage() << "ignoring density '" << config << "' for -c option"); } else { - filter.addConfig(config); + filter.AddConfig(config); } } - options.tableSplitterOptions.configFilter = &filter; + options.table_splitter_options.config_filter = &filter; } - if (preferredDensity) { - ConfigDescription preferredDensityConfig; - if (!ConfigDescription::parse(preferredDensity.value(), - &preferredDensityConfig)) { - context.getDiagnostics()->error( - DiagMessage() << "invalid density '" << preferredDensity.value() + if (preferred_density) { + ConfigDescription preferred_density_config; + if (!ConfigDescription::Parse(preferred_density.value(), + &preferred_density_config)) { + context.GetDiagnostics()->Error( + DiagMessage() << "invalid density '" << preferred_density.value() << "' for --preferred-density option"); return 1; } // Clear the version that can be automatically added. - preferredDensityConfig.sdkVersion = 0; + preferred_density_config.sdkVersion = 0; - if (preferredDensityConfig.diff(ConfigDescription::defaultConfig()) != + if (preferred_density_config.diff(ConfigDescription::DefaultConfig()) != ConfigDescription::CONFIG_DENSITY) { - context.getDiagnostics()->error( + context.GetDiagnostics()->Error( DiagMessage() << "invalid preferred density '" - << preferredDensity.value() << "'. " + << preferred_density.value() << "'. " << "Preferred density must only be a density value"); return 1; } - options.tableSplitterOptions.preferredDensity = - preferredDensityConfig.density; + options.table_splitter_options.preferred_density = + preferred_density_config.density; } - if (!options.staticLib && stableIdFilePath) { - if (!loadStableIdMap(context.getDiagnostics(), stableIdFilePath.value(), - &options.stableIdMap)) { + if (!options.static_lib && stable_id_file_path) { + if (!LoadStableIdMap(context.GetDiagnostics(), stable_id_file_path.value(), + &options.stable_id_map)) { return 1; } } // Populate some default no-compress extensions that are already compressed. - options.extensionsToNotCompress.insert( + options.extensions_to_not_compress.insert( {".jpg", ".jpeg", ".png", ".gif", ".wav", ".mp2", ".mp3", ".ogg", ".aac", ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet", ".rtttl", ".imy", ".xmf", ".mp4", ".m4a", ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2", ".amr", ".awb", ".wma", ".wmv", ".webm", ".mkv"}); // Parse the split parameters. - for (const std::string& splitArg : splitArgs) { - options.splitPaths.push_back({}); - options.splitConstraints.push_back({}); - if (!parseSplitParameter(splitArg, context.getDiagnostics(), - &options.splitPaths.back(), - &options.splitConstraints.back())) { + for (const std::string& split_arg : split_args) { + options.split_paths.push_back({}); + options.split_constraints.push_back({}); + if (!ParseSplitParameter(split_arg, context.GetDiagnostics(), + &options.split_paths.back(), + &options.split_constraints.back())) { return 1; } } // Turn off auto versioning for static-libs. - if (options.staticLib) { - options.noAutoVersion = true; - options.noVersionVectors = true; + if (options.static_lib) { + options.no_auto_version = true; + options.no_version_vectors = true; } LinkCommand cmd(&context, options); - return cmd.run(argList); + return cmd.Run(arg_list); } } // namespace aapt diff --git a/tools/aapt2/link/Linkers.h b/tools/aapt2/link/Linkers.h index f40c0e863d72..4687d2c01d68 100644 --- a/tools/aapt2/link/Linkers.h +++ b/tools/aapt2/link/Linkers.h @@ -17,12 +17,15 @@ #ifndef AAPT_LINKER_LINKERS_H #define AAPT_LINKER_LINKERS_H +#include <set> +#include <unordered_set> + +#include "android-base/macros.h" + #include "Resource.h" #include "process/IResourceTableConsumer.h" #include "xml/XmlDom.h" -#include <set> - namespace aapt { class ResourceTable; @@ -31,8 +34,7 @@ struct ConfigDescription; /** * Defines the location in which a value exists. This determines visibility of - * other - * package's private symbols. + * other package's private symbols. */ struct CallSite { ResourceNameRef resource; @@ -40,26 +42,30 @@ struct CallSite { /** * Determines whether a versioned resource should be created. If a versioned - * resource already - * exists, it takes precedence. + * resource already exists, it takes precedence. */ -bool shouldGenerateVersionedResource(const ResourceEntry* entry, +bool ShouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config, - const int sdkVersionToGenerate); + const int sdk_version_to_generate); class AutoVersioner : public IResourceTableConsumer { public: - bool consume(IAaptContext* context, ResourceTable* table) override; -}; + AutoVersioner() = default; -class XmlAutoVersioner : public IXmlResourceConsumer { - public: - bool consume(IAaptContext* context, xml::XmlResource* resource) override; + bool Consume(IAaptContext* context, ResourceTable* table) override; + + private: + DISALLOW_COPY_AND_ASSIGN(AutoVersioner); }; class VersionCollapser : public IResourceTableConsumer { public: - bool consume(IAaptContext* context, ResourceTable* table) override; + VersionCollapser() = default; + + bool Consume(IAaptContext* context, ResourceTable* table) override; + + private: + DISALLOW_COPY_AND_ASSIGN(VersionCollapser); }; /** @@ -67,7 +73,12 @@ class VersionCollapser : public IResourceTableConsumer { */ class ResourceDeduper : public IResourceTableConsumer { public: - bool consume(IAaptContext* context, ResourceTable* table) override; + ResourceDeduper() = default; + + bool Consume(IAaptContext* context, ResourceTable* table) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ResourceDeduper); }; /** @@ -103,8 +114,46 @@ class ResourceDeduper : public IResourceTableConsumer { * conflict will never * occur. */ -struct PrivateAttributeMover : public IResourceTableConsumer { - bool consume(IAaptContext* context, ResourceTable* table) override; +class PrivateAttributeMover : public IResourceTableConsumer { + public: + PrivateAttributeMover() = default; + + bool Consume(IAaptContext* context, ResourceTable* table) override; + + private: + DISALLOW_COPY_AND_ASSIGN(PrivateAttributeMover); +}; + +class ResourceConfigValue; + +class ProductFilter : public IResourceTableConsumer { + public: + using ResourceConfigValueIter = + std::vector<std::unique_ptr<ResourceConfigValue>>::iterator; + + explicit ProductFilter(std::unordered_set<std::string> products) + : products_(products) {} + + ResourceConfigValueIter SelectProductToKeep( + const ResourceNameRef& name, const ResourceConfigValueIter begin, + const ResourceConfigValueIter end, IDiagnostics* diag); + + bool Consume(IAaptContext* context, ResourceTable* table) override; + + private: + std::unordered_set<std::string> products_; + + DISALLOW_COPY_AND_ASSIGN(ProductFilter); +}; + +class XmlAutoVersioner : public IXmlResourceConsumer { + public: + XmlAutoVersioner() = default; + + bool Consume(IAaptContext* context, xml::XmlResource* resource) override; + + private: + DISALLOW_COPY_AND_ASSIGN(XmlAutoVersioner); }; /** @@ -116,13 +165,16 @@ struct PrivateAttributeMover : public IResourceTableConsumer { * XmlReferenceLinker. */ class XmlNamespaceRemover : public IXmlResourceConsumer { - private: - bool mKeepUris; - public: - XmlNamespaceRemover(bool keepUris = false) : mKeepUris(keepUris){}; + explicit XmlNamespaceRemover(bool keep_uris = false) + : keep_uris_(keep_uris){}; + + bool Consume(IAaptContext* context, xml::XmlResource* resource) override; + + private: + DISALLOW_COPY_AND_ASSIGN(XmlNamespaceRemover); - bool consume(IAaptContext* context, xml::XmlResource* resource) override; + bool keep_uris_; }; /** @@ -131,18 +183,22 @@ class XmlNamespaceRemover : public IXmlResourceConsumer { * Once an XmlResource is processed by this linker, it is ready to be flattened. */ class XmlReferenceLinker : public IXmlResourceConsumer { - private: - std::set<int> mSdkLevelsFound; - public: - bool consume(IAaptContext* context, xml::XmlResource* resource) override; + XmlReferenceLinker() = default; + + bool Consume(IAaptContext* context, xml::XmlResource* resource) override; /** * Once the XmlResource has been consumed, this returns the various SDK levels * in which * framework attributes used within the XML document were defined. */ - inline const std::set<int>& getSdkLevels() const { return mSdkLevelsFound; } + inline const std::set<int>& sdk_levels() const { return sdk_levels_found_; } + + private: + DISALLOW_COPY_AND_ASSIGN(XmlReferenceLinker); + + std::set<int> sdk_levels_found_; }; } // namespace aapt diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index 3c9298bb6301..a418fc815d49 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -15,32 +15,36 @@ */ #include "link/ManifestFixer.h" + +#include <unordered_set> + +#include "android-base/logging.h" + #include "ResourceUtils.h" #include "util/Util.h" #include "xml/XmlActionExecutor.h" #include "xml/XmlDom.h" -#include <unordered_set> - namespace aapt { /** * This is how PackageManager builds class names from AndroidManifest.xml * entries. */ -static bool nameIsJavaClassName(xml::Element* el, xml::Attribute* attr, +static bool NameIsJavaClassName(xml::Element* el, xml::Attribute* attr, SourcePathDiagnostics* diag) { // We allow unqualified class names (ie: .HelloActivity) // Since we don't know the package name, we can just make a fake one here and // the test will be identical as long as the real package name is valid too. - Maybe<std::string> fullyQualifiedClassName = - util::getFullyQualifiedClassName("a", attr->value); + Maybe<std::string> fully_qualified_class_name = + util::GetFullyQualifiedClassName("a", attr->value); - StringPiece qualifiedClassName = - fullyQualifiedClassName ? fullyQualifiedClassName.value() : attr->value; + StringPiece qualified_class_name = fully_qualified_class_name + ? fully_qualified_class_name.value() + : attr->value; - if (!util::isJavaClassName(qualifiedClassName)) { - diag->error(DiagMessage(el->lineNumber) + if (!util::IsJavaClassName(qualified_class_name)) { + diag->Error(DiagMessage(el->line_number) << "attribute 'android:name' in <" << el->name << "> tag must be a valid Java class name"); return false; @@ -48,37 +52,37 @@ static bool nameIsJavaClassName(xml::Element* el, xml::Attribute* attr, return true; } -static bool optionalNameIsJavaClassName(xml::Element* el, +static bool OptionalNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) { - if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, "name")) { - return nameIsJavaClassName(el, attr, diag); + if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) { + return NameIsJavaClassName(el, attr, diag); } return true; } -static bool requiredNameIsJavaClassName(xml::Element* el, +static bool RequiredNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) { - if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, "name")) { - return nameIsJavaClassName(el, attr, diag); + if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) { + return NameIsJavaClassName(el, attr, diag); } - diag->error(DiagMessage(el->lineNumber) + diag->Error(DiagMessage(el->line_number) << "<" << el->name << "> is missing attribute 'android:name'"); return false; } -static bool verifyManifest(xml::Element* el, SourcePathDiagnostics* diag) { - xml::Attribute* attr = el->findAttribute({}, "package"); +static bool VerifyManifest(xml::Element* el, SourcePathDiagnostics* diag) { + xml::Attribute* attr = el->FindAttribute({}, "package"); if (!attr) { - diag->error(DiagMessage(el->lineNumber) + diag->Error(DiagMessage(el->line_number) << "<manifest> tag is missing 'package' attribute"); return false; - } else if (ResourceUtils::isReference(attr->value)) { - diag->error( - DiagMessage(el->lineNumber) + } else if (ResourceUtils::IsReference(attr->value)) { + diag->Error( + DiagMessage(el->line_number) << "attribute 'package' in <manifest> tag must not be a reference"); return false; - } else if (!util::isJavaPackageName(attr->value)) { - diag->error(DiagMessage(el->lineNumber) + } else if (!util::IsJavaPackageName(attr->value)) { + diag->Error(DiagMessage(el->line_number) << "attribute 'package' in <manifest> tag is not a valid Java " "package name: '" << attr->value << "'"); @@ -89,242 +93,243 @@ static bool verifyManifest(xml::Element* el, SourcePathDiagnostics* diag) { /** * The coreApp attribute in <manifest> is not a regular AAPT attribute, so type - * checking on it - * is manual. + * checking on it is manual. */ -static bool fixCoreAppAttribute(xml::Element* el, SourcePathDiagnostics* diag) { - if (xml::Attribute* attr = el->findAttribute("", "coreApp")) { +static bool FixCoreAppAttribute(xml::Element* el, SourcePathDiagnostics* diag) { + if (xml::Attribute* attr = el->FindAttribute("", "coreApp")) { std::unique_ptr<BinaryPrimitive> result = - ResourceUtils::tryParseBool(attr->value); + ResourceUtils::TryParseBool(attr->value); if (!result) { - diag->error(DiagMessage(el->lineNumber) + diag->Error(DiagMessage(el->line_number) << "attribute coreApp must be a boolean"); return false; } - attr->compiledValue = std::move(result); + attr->compiled_value = std::move(result); } return true; } -bool ManifestFixer::buildRules(xml::XmlActionExecutor* executor, +bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag) { // First verify some options. - if (mOptions.renameManifestPackage) { - if (!util::isJavaPackageName(mOptions.renameManifestPackage.value())) { - diag->error(DiagMessage() << "invalid manifest package override '" - << mOptions.renameManifestPackage.value() + if (options_.rename_manifest_package) { + if (!util::IsJavaPackageName(options_.rename_manifest_package.value())) { + diag->Error(DiagMessage() << "invalid manifest package override '" + << options_.rename_manifest_package.value() << "'"); return false; } } - if (mOptions.renameInstrumentationTargetPackage) { - if (!util::isJavaPackageName( - mOptions.renameInstrumentationTargetPackage.value())) { - diag->error(DiagMessage() + if (options_.rename_instrumentation_target_package) { + if (!util::IsJavaPackageName( + options_.rename_instrumentation_target_package.value())) { + diag->Error(DiagMessage() << "invalid instrumentation target package override '" - << mOptions.renameInstrumentationTargetPackage.value() + << options_.rename_instrumentation_target_package.value() << "'"); return false; } } // Common intent-filter actions. - xml::XmlNodeAction intentFilterAction; - intentFilterAction["action"]; - intentFilterAction["category"]; - intentFilterAction["data"]; + xml::XmlNodeAction intent_filter_action; + intent_filter_action["action"]; + intent_filter_action["category"]; + intent_filter_action["data"]; // Common meta-data actions. - xml::XmlNodeAction metaDataAction; + xml::XmlNodeAction meta_data_action; // Manifest actions. - xml::XmlNodeAction& manifestAction = (*executor)["manifest"]; - manifestAction.action(verifyManifest); - manifestAction.action(fixCoreAppAttribute); - manifestAction.action([&](xml::Element* el) -> bool { - if (mOptions.versionNameDefault) { - if (el->findAttribute(xml::kSchemaAndroid, "versionName") == nullptr) { + xml::XmlNodeAction& manifest_action = (*executor)["manifest"]; + manifest_action.Action(VerifyManifest); + manifest_action.Action(FixCoreAppAttribute); + manifest_action.Action([&](xml::Element* el) -> bool { + if (options_.version_name_default) { + if (el->FindAttribute(xml::kSchemaAndroid, "versionName") == nullptr) { el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "versionName", - mOptions.versionNameDefault.value()}); + options_.version_name_default.value()}); } } - if (mOptions.versionCodeDefault) { - if (el->findAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) { + if (options_.version_code_default) { + if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) { el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "versionCode", - mOptions.versionCodeDefault.value()}); + options_.version_code_default.value()}); } } return true; }); // Meta tags. - manifestAction["eat-comment"]; + manifest_action["eat-comment"]; // Uses-sdk actions. - manifestAction["uses-sdk"].action([&](xml::Element* el) -> bool { - if (mOptions.minSdkVersionDefault && - el->findAttribute(xml::kSchemaAndroid, "minSdkVersion") == nullptr) { + manifest_action["uses-sdk"].Action([&](xml::Element* el) -> bool { + if (options_.min_sdk_version_default && + el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion") == nullptr) { // There was no minSdkVersion defined and we have a default to assign. el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "minSdkVersion", - mOptions.minSdkVersionDefault.value()}); + options_.min_sdk_version_default.value()}); } - if (mOptions.targetSdkVersionDefault && - el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion") == nullptr) { + if (options_.target_sdk_version_default && + el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion") == nullptr) { // There was no targetSdkVersion defined and we have a default to assign. el->attributes.push_back( xml::Attribute{xml::kSchemaAndroid, "targetSdkVersion", - mOptions.targetSdkVersionDefault.value()}); + options_.target_sdk_version_default.value()}); } return true; }); // Instrumentation actions. - manifestAction["instrumentation"].action([&](xml::Element* el) -> bool { - if (!mOptions.renameInstrumentationTargetPackage) { + manifest_action["instrumentation"].Action([&](xml::Element* el) -> bool { + if (!options_.rename_instrumentation_target_package) { return true; } if (xml::Attribute* attr = - el->findAttribute(xml::kSchemaAndroid, "targetPackage")) { - attr->value = mOptions.renameInstrumentationTargetPackage.value(); + el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) { + attr->value = options_.rename_instrumentation_target_package.value(); } return true; }); - manifestAction["original-package"]; - manifestAction["protected-broadcast"]; - manifestAction["uses-permission"]; - manifestAction["permission"]; - manifestAction["permission-tree"]; - manifestAction["permission-group"]; + manifest_action["original-package"]; + manifest_action["protected-broadcast"]; + manifest_action["uses-permission"]; + manifest_action["permission"]; + manifest_action["permission-tree"]; + manifest_action["permission-group"]; - manifestAction["uses-configuration"]; - manifestAction["uses-feature"]; - manifestAction["supports-screens"]; + manifest_action["uses-configuration"]; + manifest_action["uses-feature"]; + manifest_action["supports-screens"]; - manifestAction["compatible-screens"]; - manifestAction["compatible-screens"]["screen"]; + manifest_action["compatible-screens"]; + manifest_action["compatible-screens"]["screen"]; - manifestAction["supports-gl-texture"]; + manifest_action["supports-gl-texture"]; // Application actions. - xml::XmlNodeAction& applicationAction = manifestAction["application"]; - applicationAction.action(optionalNameIsJavaClassName); + xml::XmlNodeAction& application_action = manifest_action["application"]; + application_action.Action(OptionalNameIsJavaClassName); // Uses library actions. - applicationAction["uses-library"]; + application_action["uses-library"]; // Meta-data. - applicationAction["meta-data"] = metaDataAction; + application_action["meta-data"] = meta_data_action; // Activity actions. - applicationAction["activity"].action(requiredNameIsJavaClassName); - applicationAction["activity"]["intent-filter"] = intentFilterAction; - applicationAction["activity"]["meta-data"] = metaDataAction; + application_action["activity"].Action(RequiredNameIsJavaClassName); + application_action["activity"]["intent-filter"] = intent_filter_action; + application_action["activity"]["meta-data"] = meta_data_action; // Activity alias actions. - applicationAction["activity-alias"]["intent-filter"] = intentFilterAction; - applicationAction["activity-alias"]["meta-data"] = metaDataAction; + application_action["activity-alias"]["intent-filter"] = intent_filter_action; + application_action["activity-alias"]["meta-data"] = meta_data_action; // Service actions. - applicationAction["service"].action(requiredNameIsJavaClassName); - applicationAction["service"]["intent-filter"] = intentFilterAction; - applicationAction["service"]["meta-data"] = metaDataAction; + application_action["service"].Action(RequiredNameIsJavaClassName); + application_action["service"]["intent-filter"] = intent_filter_action; + application_action["service"]["meta-data"] = meta_data_action; // Receiver actions. - applicationAction["receiver"].action(requiredNameIsJavaClassName); - applicationAction["receiver"]["intent-filter"] = intentFilterAction; - applicationAction["receiver"]["meta-data"] = metaDataAction; + application_action["receiver"].Action(RequiredNameIsJavaClassName); + application_action["receiver"]["intent-filter"] = intent_filter_action; + application_action["receiver"]["meta-data"] = meta_data_action; // Provider actions. - applicationAction["provider"].action(requiredNameIsJavaClassName); - applicationAction["provider"]["intent-filter"] = intentFilterAction; - applicationAction["provider"]["meta-data"] = metaDataAction; - applicationAction["provider"]["grant-uri-permissions"]; - applicationAction["provider"]["path-permissions"]; + application_action["provider"].Action(RequiredNameIsJavaClassName); + application_action["provider"]["intent-filter"] = intent_filter_action; + application_action["provider"]["meta-data"] = meta_data_action; + application_action["provider"]["grant-uri-permissions"]; + application_action["provider"]["path-permissions"]; return true; } class FullyQualifiedClassNameVisitor : public xml::Visitor { public: - using xml::Visitor::visit; + using xml::Visitor::Visit; explicit FullyQualifiedClassNameVisitor(const StringPiece& package) - : mPackage(package) {} + : package_(package) {} - void visit(xml::Element* el) override { + void Visit(xml::Element* el) override { for (xml::Attribute& attr : el->attributes) { - if (attr.namespaceUri == xml::kSchemaAndroid && - mClassAttributes.find(attr.name) != mClassAttributes.end()) { - if (Maybe<std::string> newValue = - util::getFullyQualifiedClassName(mPackage, attr.value)) { - attr.value = std::move(newValue.value()); + if (attr.namespace_uri == xml::kSchemaAndroid && + class_attributes_.find(attr.name) != class_attributes_.end()) { + if (Maybe<std::string> new_value = + util::GetFullyQualifiedClassName(package_, attr.value)) { + attr.value = std::move(new_value.value()); } } } // Super implementation to iterate over the children. - xml::Visitor::visit(el); + xml::Visitor::Visit(el); } private: - StringPiece mPackage; - std::unordered_set<StringPiece> mClassAttributes = {"name"}; + StringPiece package_; + std::unordered_set<StringPiece> class_attributes_ = {"name"}; }; -static bool renameManifestPackage(const StringPiece& packageOverride, - xml::Element* manifestEl) { - xml::Attribute* attr = manifestEl->findAttribute({}, "package"); +static bool RenameManifestPackage(const StringPiece& package_override, + xml::Element* manifest_el) { + xml::Attribute* attr = manifest_el->FindAttribute({}, "package"); // We've already verified that the manifest element is present, with a package // name specified. - assert(attr); + CHECK(attr != nullptr); - std::string originalPackage = std::move(attr->value); - attr->value = packageOverride.toString(); + std::string original_package = std::move(attr->value); + attr->value = package_override.ToString(); - FullyQualifiedClassNameVisitor visitor(originalPackage); - manifestEl->accept(&visitor); + FullyQualifiedClassNameVisitor visitor(original_package); + manifest_el->Accept(&visitor); return true; } -bool ManifestFixer::consume(IAaptContext* context, xml::XmlResource* doc) { - xml::Element* root = xml::findRootElement(doc->root.get()); - if (!root || !root->namespaceUri.empty() || root->name != "manifest") { - context->getDiagnostics()->error(DiagMessage(doc->file.source) +bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) { + xml::Element* root = xml::FindRootElement(doc->root.get()); + if (!root || !root->namespace_uri.empty() || root->name != "manifest") { + context->GetDiagnostics()->Error(DiagMessage(doc->file.source) << "root tag must be <manifest>"); return false; } - if ((mOptions.minSdkVersionDefault || mOptions.targetSdkVersionDefault) && - root->findChild({}, "uses-sdk") == nullptr) { + if ((options_.min_sdk_version_default || + options_.target_sdk_version_default) && + root->FindChild({}, "uses-sdk") == nullptr) { // Auto insert a <uses-sdk> element. - std::unique_ptr<xml::Element> usesSdk = util::make_unique<xml::Element>(); - usesSdk->name = "uses-sdk"; - root->addChild(std::move(usesSdk)); + std::unique_ptr<xml::Element> uses_sdk = util::make_unique<xml::Element>(); + uses_sdk->name = "uses-sdk"; + root->AddChild(std::move(uses_sdk)); } xml::XmlActionExecutor executor; - if (!buildRules(&executor, context->getDiagnostics())) { + if (!BuildRules(&executor, context->GetDiagnostics())) { return false; } - if (!executor.execute(xml::XmlActionExecutorPolicy::Whitelist, - context->getDiagnostics(), doc)) { + if (!executor.Execute(xml::XmlActionExecutorPolicy::kWhitelist, + context->GetDiagnostics(), doc)) { return false; } - if (mOptions.renameManifestPackage) { + if (options_.rename_manifest_package) { // Rename manifest package outside of the XmlActionExecutor. // We need to extract the old package name and FullyQualify all class names. - if (!renameManifestPackage(mOptions.renameManifestPackage.value(), root)) { + if (!RenameManifestPackage(options_.rename_manifest_package.value(), + root)) { return false; } } diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h index c3a114be3eb0..470f65eb01c4 100644 --- a/tools/aapt2/link/ManifestFixer.h +++ b/tools/aapt2/link/ManifestFixer.h @@ -17,22 +17,24 @@ #ifndef AAPT_LINK_MANIFESTFIXER_H #define AAPT_LINK_MANIFESTFIXER_H +#include <string> + +#include "android-base/macros.h" + #include "process/IResourceTableConsumer.h" #include "util/Maybe.h" #include "xml/XmlActionExecutor.h" #include "xml/XmlDom.h" -#include <string> - namespace aapt { struct ManifestFixerOptions { - Maybe<std::string> minSdkVersionDefault; - Maybe<std::string> targetSdkVersionDefault; - Maybe<std::string> renameManifestPackage; - Maybe<std::string> renameInstrumentationTargetPackage; - Maybe<std::string> versionNameDefault; - Maybe<std::string> versionCodeDefault; + Maybe<std::string> min_sdk_version_default; + Maybe<std::string> target_sdk_version_default; + Maybe<std::string> rename_manifest_package; + Maybe<std::string> rename_instrumentation_target_package; + Maybe<std::string> version_name_default; + Maybe<std::string> version_code_default; }; /** @@ -42,14 +44,16 @@ struct ManifestFixerOptions { class ManifestFixer : public IXmlResourceConsumer { public: explicit ManifestFixer(const ManifestFixerOptions& options) - : mOptions(options) {} + : options_(options) {} - bool consume(IAaptContext* context, xml::XmlResource* doc) override; + bool Consume(IAaptContext* context, xml::XmlResource* doc) override; private: - bool buildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag); + DISALLOW_COPY_AND_ASSIGN(ManifestFixer); + + bool BuildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag); - ManifestFixerOptions mOptions; + ManifestFixerOptions options_; }; } // namespace aapt diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp index dc78d98aaed6..0e29ba6b6071 100644 --- a/tools/aapt2/link/ManifestFixer_test.cpp +++ b/tools/aapt2/link/ManifestFixer_test.cpp @@ -15,10 +15,8 @@ */ #include "link/ManifestFixer.h" -#include "test/Builders.h" -#include "test/Context.h" -#include <gtest/gtest.h> +#include "test/Test.h" namespace aapt { @@ -28,42 +26,42 @@ struct ManifestFixerTest : public ::testing::Test { void SetUp() override { mContext = test::ContextBuilder() - .setCompilationPackage("android") - .setPackageId(0x01) - .setNameManglerPolicy(NameManglerPolicy{"android"}) - .addSymbolSource( + .SetCompilationPackage("android") + .SetPackageId(0x01) + .SetNameManglerPolicy(NameManglerPolicy{"android"}) + .AddSymbolSource( test::StaticSymbolSourceBuilder() - .addSymbol( + .AddSymbol( "android:attr/package", ResourceId(0x01010000), test::AttributeBuilder() - .setTypeMask(android::ResTable_map::TYPE_STRING) - .build()) - .addSymbol( + .SetTypeMask(android::ResTable_map::TYPE_STRING) + .Build()) + .AddSymbol( "android:attr/minSdkVersion", ResourceId(0x01010001), test::AttributeBuilder() - .setTypeMask(android::ResTable_map::TYPE_STRING | + .SetTypeMask(android::ResTable_map::TYPE_STRING | android::ResTable_map::TYPE_INTEGER) - .build()) - .addSymbol( + .Build()) + .AddSymbol( "android:attr/targetSdkVersion", ResourceId(0x01010002), test::AttributeBuilder() - .setTypeMask(android::ResTable_map::TYPE_STRING | + .SetTypeMask(android::ResTable_map::TYPE_STRING | android::ResTable_map::TYPE_INTEGER) - .build()) - .addSymbol("android:string/str", ResourceId(0x01060000)) - .build()) - .build(); + .Build()) + .AddSymbol("android:string/str", ResourceId(0x01060000)) + .Build()) + .Build(); } - std::unique_ptr<xml::XmlResource> verify(const StringPiece& str) { - return verifyWithOptions(str, {}); + std::unique_ptr<xml::XmlResource> Verify(const StringPiece& str) { + return VerifyWithOptions(str, {}); } - std::unique_ptr<xml::XmlResource> verifyWithOptions( + std::unique_ptr<xml::XmlResource> VerifyWithOptions( const StringPiece& str, const ManifestFixerOptions& options) { - std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(str); + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(str); ManifestFixer fixer(options); - if (fixer.consume(mContext.get(), doc.get())) { + if (fixer.Consume(mContext.get(), doc.get())) { return doc; } return {}; @@ -71,28 +69,28 @@ struct ManifestFixerTest : public ::testing::Test { }; TEST_F(ManifestFixerTest, EnsureManifestIsRootTag) { - EXPECT_EQ(nullptr, verify("<other-tag />")); - EXPECT_EQ(nullptr, verify("<ns:manifest xmlns:ns=\"com\" />")); - EXPECT_NE(nullptr, verify("<manifest package=\"android\"></manifest>")); + EXPECT_EQ(nullptr, Verify("<other-tag />")); + EXPECT_EQ(nullptr, Verify("<ns:manifest xmlns:ns=\"com\" />")); + EXPECT_NE(nullptr, Verify("<manifest package=\"android\"></manifest>")); } TEST_F(ManifestFixerTest, EnsureManifestHasPackage) { - EXPECT_NE(nullptr, verify("<manifest package=\"android\" />")); - EXPECT_NE(nullptr, verify("<manifest package=\"com.android\" />")); - EXPECT_NE(nullptr, verify("<manifest package=\"com.android.google\" />")); + EXPECT_NE(nullptr, Verify("<manifest package=\"android\" />")); + EXPECT_NE(nullptr, Verify("<manifest package=\"com.android\" />")); + EXPECT_NE(nullptr, Verify("<manifest package=\"com.android.google\" />")); EXPECT_EQ(nullptr, - verify("<manifest package=\"com.android.google.Class$1\" />")); - EXPECT_EQ(nullptr, verify("<manifest " + Verify("<manifest package=\"com.android.google.Class$1\" />")); + EXPECT_EQ(nullptr, Verify("<manifest " "xmlns:android=\"http://schemas.android.com/apk/" "res/android\" " "android:package=\"com.android\" />")); - EXPECT_EQ(nullptr, verify("<manifest package=\"@string/str\" />")); + EXPECT_EQ(nullptr, Verify("<manifest package=\"@string/str\" />")); } TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) { ManifestFixerOptions options = {std::string("8"), std::string("22")}; - std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF( + std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" /> @@ -103,18 +101,18 @@ TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) { xml::Element* el; xml::Attribute* attr; - el = xml::findRootElement(doc.get()); + el = xml::FindRootElement(doc.get()); ASSERT_NE(nullptr, el); - el = el->findChild({}, "uses-sdk"); + el = el->FindChild({}, "uses-sdk"); ASSERT_NE(nullptr, el); - attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion"); + attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion"); ASSERT_NE(nullptr, attr); EXPECT_EQ("7", attr->value); - attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion"); + attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion"); ASSERT_NE(nullptr, attr); EXPECT_EQ("21", attr->value); - doc = verifyWithOptions(R"EOF( + doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <uses-sdk android:targetSdkVersion="21" /> @@ -122,18 +120,18 @@ TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) { options); ASSERT_NE(nullptr, doc); - el = xml::findRootElement(doc.get()); + el = xml::FindRootElement(doc.get()); ASSERT_NE(nullptr, el); - el = el->findChild({}, "uses-sdk"); + el = el->FindChild({}, "uses-sdk"); ASSERT_NE(nullptr, el); - attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion"); + attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion"); ASSERT_NE(nullptr, attr); EXPECT_EQ("8", attr->value); - attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion"); + attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion"); ASSERT_NE(nullptr, attr); EXPECT_EQ("21", attr->value); - doc = verifyWithOptions(R"EOF( + doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <uses-sdk /> @@ -141,40 +139,40 @@ TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) { options); ASSERT_NE(nullptr, doc); - el = xml::findRootElement(doc.get()); + el = xml::FindRootElement(doc.get()); ASSERT_NE(nullptr, el); - el = el->findChild({}, "uses-sdk"); + el = el->FindChild({}, "uses-sdk"); ASSERT_NE(nullptr, el); - attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion"); + attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion"); ASSERT_NE(nullptr, attr); EXPECT_EQ("8", attr->value); - attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion"); + attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion"); ASSERT_NE(nullptr, attr); EXPECT_EQ("22", attr->value); - doc = verifyWithOptions(R"EOF( + doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" />)EOF", options); ASSERT_NE(nullptr, doc); - el = xml::findRootElement(doc.get()); + el = xml::FindRootElement(doc.get()); ASSERT_NE(nullptr, el); - el = el->findChild({}, "uses-sdk"); + el = el->FindChild({}, "uses-sdk"); ASSERT_NE(nullptr, el); - attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion"); + attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion"); ASSERT_NE(nullptr, attr); EXPECT_EQ("8", attr->value); - attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion"); + attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion"); ASSERT_NE(nullptr, attr); EXPECT_EQ("22", attr->value); } TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) { ManifestFixerOptions options; - options.renameManifestPackage = std::string("com.android"); + options.rename_manifest_package = std::string("com.android"); - std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF( + std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <application android:name=".MainApplication" text="hello"> @@ -185,38 +183,38 @@ TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) { options); ASSERT_NE(nullptr, doc); - xml::Element* manifestEl = xml::findRootElement(doc.get()); + xml::Element* manifestEl = xml::FindRootElement(doc.get()); ASSERT_NE(nullptr, manifestEl); xml::Attribute* attr = nullptr; - attr = manifestEl->findAttribute({}, "package"); + attr = manifestEl->FindAttribute({}, "package"); ASSERT_NE(nullptr, attr); EXPECT_EQ(std::string("com.android"), attr->value); - xml::Element* applicationEl = manifestEl->findChild({}, "application"); + xml::Element* applicationEl = manifestEl->FindChild({}, "application"); ASSERT_NE(nullptr, applicationEl); - attr = applicationEl->findAttribute(xml::kSchemaAndroid, "name"); + attr = applicationEl->FindAttribute(xml::kSchemaAndroid, "name"); ASSERT_NE(nullptr, attr); EXPECT_EQ(std::string("android.MainApplication"), attr->value); - attr = applicationEl->findAttribute({}, "text"); + attr = applicationEl->FindAttribute({}, "text"); ASSERT_NE(nullptr, attr); EXPECT_EQ(std::string("hello"), attr->value); xml::Element* el; - el = applicationEl->findChild({}, "activity"); + el = applicationEl->FindChild({}, "activity"); ASSERT_NE(nullptr, el); - attr = el->findAttribute(xml::kSchemaAndroid, "name"); + attr = el->FindAttribute(xml::kSchemaAndroid, "name"); ASSERT_NE(nullptr, el); EXPECT_EQ(std::string("android.activity.Start"), attr->value); - el = applicationEl->findChild({}, "receiver"); + el = applicationEl->FindChild({}, "receiver"); ASSERT_NE(nullptr, el); - attr = el->findAttribute(xml::kSchemaAndroid, "name"); + attr = el->FindAttribute(xml::kSchemaAndroid, "name"); ASSERT_NE(nullptr, el); EXPECT_EQ(std::string("com.google.android.Receiver"), attr->value); } @@ -224,9 +222,9 @@ TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) { TEST_F(ManifestFixerTest, RenameManifestInstrumentationPackageAndFullyQualifyTarget) { ManifestFixerOptions options; - options.renameInstrumentationTargetPackage = std::string("com.android"); + options.rename_instrumentation_target_package = std::string("com.android"); - std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF( + std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> <instrumentation android:targetPackage="android" /> @@ -234,63 +232,63 @@ TEST_F(ManifestFixerTest, options); ASSERT_NE(nullptr, doc); - xml::Element* manifestEl = xml::findRootElement(doc.get()); - ASSERT_NE(nullptr, manifestEl); + xml::Element* manifest_el = xml::FindRootElement(doc.get()); + ASSERT_NE(nullptr, manifest_el); - xml::Element* instrumentationEl = - manifestEl->findChild({}, "instrumentation"); - ASSERT_NE(nullptr, instrumentationEl); + xml::Element* instrumentation_el = + manifest_el->FindChild({}, "instrumentation"); + ASSERT_NE(nullptr, instrumentation_el); xml::Attribute* attr = - instrumentationEl->findAttribute(xml::kSchemaAndroid, "targetPackage"); + instrumentation_el->FindAttribute(xml::kSchemaAndroid, "targetPackage"); ASSERT_NE(nullptr, attr); EXPECT_EQ(std::string("com.android"), attr->value); } TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) { ManifestFixerOptions options; - options.versionNameDefault = std::string("Beta"); - options.versionCodeDefault = std::string("0x10000000"); + options.version_name_default = std::string("Beta"); + options.version_code_default = std::string("0x10000000"); - std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF( + std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" />)EOF", options); ASSERT_NE(nullptr, doc); - xml::Element* manifestEl = xml::findRootElement(doc.get()); - ASSERT_NE(nullptr, manifestEl); + xml::Element* manifest_el = xml::FindRootElement(doc.get()); + ASSERT_NE(nullptr, manifest_el); xml::Attribute* attr = - manifestEl->findAttribute(xml::kSchemaAndroid, "versionName"); + manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); ASSERT_NE(nullptr, attr); EXPECT_EQ(std::string("Beta"), attr->value); - attr = manifestEl->findAttribute(xml::kSchemaAndroid, "versionCode"); + attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); ASSERT_NE(nullptr, attr); EXPECT_EQ(std::string("0x10000000"), attr->value); } TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) { EXPECT_EQ(nullptr, - verify("<manifest package=\"android\" coreApp=\"hello\" />")); + Verify("<manifest package=\"android\" coreApp=\"hello\" />")); EXPECT_EQ(nullptr, - verify("<manifest package=\"android\" coreApp=\"1dp\" />")); + Verify("<manifest package=\"android\" coreApp=\"1dp\" />")); std::unique_ptr<xml::XmlResource> doc = - verify("<manifest package=\"android\" coreApp=\"true\" />"); + Verify("<manifest package=\"android\" coreApp=\"true\" />"); ASSERT_NE(nullptr, doc); - xml::Element* el = xml::findRootElement(doc.get()); + xml::Element* el = xml::FindRootElement(doc.get()); ASSERT_NE(nullptr, el); EXPECT_EQ("manifest", el->name); - xml::Attribute* attr = el->findAttribute("", "coreApp"); + xml::Attribute* attr = el->FindAttribute("", "coreApp"); ASSERT_NE(nullptr, attr); - EXPECT_NE(nullptr, attr->compiledValue); - EXPECT_NE(nullptr, valueCast<BinaryPrimitive>(attr->compiledValue.get())); + EXPECT_NE(nullptr, attr->compiled_value); + EXPECT_NE(nullptr, ValueCast<BinaryPrimitive>(attr->compiled_value.get())); } } // namespace aapt diff --git a/tools/aapt2/link/PrivateAttributeMover.cpp b/tools/aapt2/link/PrivateAttributeMover.cpp index 174b41f20d5e..cc07a6e1925b 100644 --- a/tools/aapt2/link/PrivateAttributeMover.cpp +++ b/tools/aapt2/link/PrivateAttributeMover.cpp @@ -14,27 +14,30 @@ * limitations under the License. */ -#include "ResourceTable.h" #include "link/Linkers.h" #include <algorithm> #include <iterator> +#include "android-base/logging.h" + +#include "ResourceTable.h" + namespace aapt { template <typename InputContainer, typename OutputIterator, typename Predicate> -OutputIterator moveIf(InputContainer& inputContainer, OutputIterator result, - Predicate pred) { - const auto last = inputContainer.end(); - auto newEnd = - std::find_if(inputContainer.begin(), inputContainer.end(), pred); - if (newEnd == last) { +OutputIterator move_if(InputContainer& input_container, OutputIterator result, + Predicate pred) { + const auto last = input_container.end(); + auto new_end = + std::find_if(input_container.begin(), input_container.end(), pred); + if (new_end == last) { return result; } - *result = std::move(*newEnd); + *result = std::move(*new_end); - auto first = newEnd; + auto first = new_end; ++first; for (; first != last; ++first) { @@ -44,39 +47,38 @@ OutputIterator moveIf(InputContainer& inputContainer, OutputIterator result, ++result; } else { // We want to keep this guy, but we will need to move it up the list to - // replace - // missing items. - *newEnd = std::move(*first); - ++newEnd; + // replace missing items. + *new_end = std::move(*first); + ++new_end; } } - inputContainer.erase(newEnd, last); + input_container.erase(new_end, last); return result; } -bool PrivateAttributeMover::consume(IAaptContext* context, +bool PrivateAttributeMover::Consume(IAaptContext* context, ResourceTable* table) { for (auto& package : table->packages) { - ResourceTableType* type = package->findType(ResourceType::kAttr); + ResourceTableType* type = package->FindType(ResourceType::kAttr); if (!type) { continue; } - if (type->symbolStatus.state != SymbolState::kPublic) { + if (type->symbol_status.state != SymbolState::kPublic) { // No public attributes, so we can safely leave these private attributes // where they are. return true; } - ResourceTableType* privAttrType = - package->findOrCreateType(ResourceType::kAttrPrivate); - assert(privAttrType->entries.empty()); + ResourceTableType* priv_attr_type = + package->FindOrCreateType(ResourceType::kAttrPrivate); + CHECK(priv_attr_type->entries.empty()); - moveIf(type->entries, std::back_inserter(privAttrType->entries), - [](const std::unique_ptr<ResourceEntry>& entry) -> bool { - return entry->symbolStatus.state != SymbolState::kPublic; - }); + move_if(type->entries, std::back_inserter(priv_attr_type->entries), + [](const std::unique_ptr<ResourceEntry>& entry) -> bool { + return entry->symbol_status.state != SymbolState::kPublic; + }); break; } return true; diff --git a/tools/aapt2/link/PrivateAttributeMover_test.cpp b/tools/aapt2/link/PrivateAttributeMover_test.cpp index a7a1013fd809..90c4922625be 100644 --- a/tools/aapt2/link/PrivateAttributeMover_test.cpp +++ b/tools/aapt2/link/PrivateAttributeMover_test.cpp @@ -15,64 +15,65 @@ */ #include "link/Linkers.h" + #include "test/Test.h" namespace aapt { TEST(PrivateAttributeMoverTest, MovePrivateAttributes) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addSimple("android:attr/publicA") - .addSimple("android:attr/privateA") - .addSimple("android:attr/publicB") - .addSimple("android:attr/privateB") - .setSymbolState("android:attr/publicA", ResourceId(0x01010000), + .AddSimple("android:attr/publicA") + .AddSimple("android:attr/privateA") + .AddSimple("android:attr/publicB") + .AddSimple("android:attr/privateB") + .SetSymbolState("android:attr/publicA", ResourceId(0x01010000), SymbolState::kPublic) - .setSymbolState("android:attr/publicB", ResourceId(0x01010000), + .SetSymbolState("android:attr/publicB", ResourceId(0x01010000), SymbolState::kPublic) - .build(); + .Build(); PrivateAttributeMover mover; - ASSERT_TRUE(mover.consume(context.get(), table.get())); + ASSERT_TRUE(mover.Consume(context.get(), table.get())); - ResourceTablePackage* package = table->findPackage("android"); + ResourceTablePackage* package = table->FindPackage("android"); ASSERT_NE(package, nullptr); - ResourceTableType* type = package->findType(ResourceType::kAttr); + ResourceTableType* type = package->FindType(ResourceType::kAttr); ASSERT_NE(type, nullptr); ASSERT_EQ(type->entries.size(), 2u); - EXPECT_NE(type->findEntry("publicA"), nullptr); - EXPECT_NE(type->findEntry("publicB"), nullptr); + EXPECT_NE(type->FindEntry("publicA"), nullptr); + EXPECT_NE(type->FindEntry("publicB"), nullptr); - type = package->findType(ResourceType::kAttrPrivate); + type = package->FindType(ResourceType::kAttrPrivate); ASSERT_NE(type, nullptr); ASSERT_EQ(type->entries.size(), 2u); - EXPECT_NE(type->findEntry("privateA"), nullptr); - EXPECT_NE(type->findEntry("privateB"), nullptr); + EXPECT_NE(type->FindEntry("privateA"), nullptr); + EXPECT_NE(type->FindEntry("privateB"), nullptr); } TEST(PrivateAttributeMoverTest, LeavePrivateAttributesWhenNoPublicAttributesDefined) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addSimple("android:attr/privateA") - .addSimple("android:attr/privateB") - .build(); + .AddSimple("android:attr/privateA") + .AddSimple("android:attr/privateB") + .Build(); PrivateAttributeMover mover; - ASSERT_TRUE(mover.consume(context.get(), table.get())); + ASSERT_TRUE(mover.Consume(context.get(), table.get())); - ResourceTablePackage* package = table->findPackage("android"); + ResourceTablePackage* package = table->FindPackage("android"); ASSERT_NE(package, nullptr); - ResourceTableType* type = package->findType(ResourceType::kAttr); + ResourceTableType* type = package->FindType(ResourceType::kAttr); ASSERT_NE(type, nullptr); ASSERT_EQ(type->entries.size(), 2u); - type = package->findType(ResourceType::kAttrPrivate); + type = package->FindType(ResourceType::kAttrPrivate); ASSERT_EQ(type, nullptr); } diff --git a/tools/aapt2/link/ProductFilter.cpp b/tools/aapt2/link/ProductFilter.cpp index d59b6820fdef..c1a95ee1bcec 100644 --- a/tools/aapt2/link/ProductFilter.cpp +++ b/tools/aapt2/link/ProductFilter.cpp @@ -14,103 +14,106 @@ * limitations under the License. */ -#include "link/ProductFilter.h" +#include "link/Linkers.h" + +#include "ResourceTable.h" namespace aapt { -ProductFilter::ResourceConfigValueIter ProductFilter::selectProductToKeep( +ProductFilter::ResourceConfigValueIter ProductFilter::SelectProductToKeep( const ResourceNameRef& name, const ResourceConfigValueIter begin, const ResourceConfigValueIter end, IDiagnostics* diag) { - ResourceConfigValueIter defaultProductIter = end; - ResourceConfigValueIter selectedProductIter = end; + ResourceConfigValueIter default_product_iter = end; + ResourceConfigValueIter selected_product_iter = end; for (ResourceConfigValueIter iter = begin; iter != end; ++iter) { - ResourceConfigValue* configValue = iter->get(); - if (mProducts.find(configValue->product) != mProducts.end()) { - if (selectedProductIter != end) { + ResourceConfigValue* config_value = iter->get(); + if (products_.find(config_value->product) != products_.end()) { + if (selected_product_iter != end) { // We have two possible values for this product! - diag->error(DiagMessage(configValue->value->getSource()) - << "selection of product '" << configValue->product + diag->Error(DiagMessage(config_value->value->GetSource()) + << "selection of product '" << config_value->product << "' for resource " << name << " is ambiguous"); - ResourceConfigValue* previouslySelectedConfigValue = - selectedProductIter->get(); - diag->note( - DiagMessage(previouslySelectedConfigValue->value->getSource()) - << "product '" << previouslySelectedConfigValue->product + ResourceConfigValue* previously_selected_config_value = + selected_product_iter->get(); + diag->Note( + DiagMessage(previously_selected_config_value->value->GetSource()) + << "product '" << previously_selected_config_value->product << "' is also a candidate"); return end; } // Select this product. - selectedProductIter = iter; + selected_product_iter = iter; } - if (configValue->product.empty() || configValue->product == "default") { - if (defaultProductIter != end) { + if (config_value->product.empty() || config_value->product == "default") { + if (default_product_iter != end) { // We have two possible default values. - diag->error(DiagMessage(configValue->value->getSource()) + diag->Error(DiagMessage(config_value->value->GetSource()) << "multiple default products defined for resource " << name); - ResourceConfigValue* previouslyDefaultConfigValue = - defaultProductIter->get(); - diag->note(DiagMessage(previouslyDefaultConfigValue->value->getSource()) - << "default product also defined here"); + ResourceConfigValue* previously_default_config_value = + default_product_iter->get(); + diag->Note( + DiagMessage(previously_default_config_value->value->GetSource()) + << "default product also defined here"); return end; } // Mark the default. - defaultProductIter = iter; + default_product_iter = iter; } } - if (defaultProductIter == end) { - diag->error(DiagMessage() << "no default product defined for resource " + if (default_product_iter == end) { + diag->Error(DiagMessage() << "no default product defined for resource " << name); return end; } - if (selectedProductIter == end) { - selectedProductIter = defaultProductIter; + if (selected_product_iter == end) { + selected_product_iter = default_product_iter; } - return selectedProductIter; + return selected_product_iter; } -bool ProductFilter::consume(IAaptContext* context, ResourceTable* table) { +bool ProductFilter::Consume(IAaptContext* context, ResourceTable* table) { bool error = false; for (auto& pkg : table->packages) { for (auto& type : pkg->types) { for (auto& entry : type->entries) { - std::vector<std::unique_ptr<ResourceConfigValue>> newValues; + std::vector<std::unique_ptr<ResourceConfigValue>> new_values; ResourceConfigValueIter iter = entry->values.begin(); - ResourceConfigValueIter startRangeIter = iter; + ResourceConfigValueIter start_range_iter = iter; while (iter != entry->values.end()) { ++iter; if (iter == entry->values.end() || - (*iter)->config != (*startRangeIter)->config) { + (*iter)->config != (*start_range_iter)->config) { // End of the array, or we saw a different config, // so this must be the end of a range of products. // Select the product to keep from the set of products defined. ResourceNameRef name(pkg->name, type->type, entry->name); - auto valueToKeep = selectProductToKeep(name, startRangeIter, iter, - context->getDiagnostics()); - if (valueToKeep == iter) { + auto value_to_keep = SelectProductToKeep( + name, start_range_iter, iter, context->GetDiagnostics()); + if (value_to_keep == iter) { // An error occurred, we could not pick a product. error = true; } else { // We selected a product to keep. Move it to the new array. - newValues.push_back(std::move(*valueToKeep)); + new_values.push_back(std::move(*value_to_keep)); } // Start the next range of products. - startRangeIter = iter; + start_range_iter = iter; } } // Now move the new values in to place. - entry->values = std::move(newValues); + entry->values = std::move(new_values); } } } diff --git a/tools/aapt2/link/ProductFilter.h b/tools/aapt2/link/ProductFilter.h deleted file mode 100644 index cc8b8c279208..000000000000 --- a/tools/aapt2/link/ProductFilter.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2016 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_LINK_PRODUCTFILTER_H -#define AAPT_LINK_PRODUCTFILTER_H - -#include "ResourceTable.h" -#include "process/IResourceTableConsumer.h" - -#include <android-base/macros.h> -#include <unordered_set> - -namespace aapt { - -class ProductFilter { - public: - using ResourceConfigValueIter = - std::vector<std::unique_ptr<ResourceConfigValue>>::iterator; - - explicit ProductFilter(std::unordered_set<std::string> products) - : mProducts(products) {} - - ResourceConfigValueIter selectProductToKeep( - const ResourceNameRef& name, const ResourceConfigValueIter begin, - const ResourceConfigValueIter end, IDiagnostics* diag); - - bool consume(IAaptContext* context, ResourceTable* table); - - private: - std::unordered_set<std::string> mProducts; - - DISALLOW_COPY_AND_ASSIGN(ProductFilter); -}; - -} // namespace aapt - -#endif /* AAPT_LINK_PRODUCTFILTER_H */ diff --git a/tools/aapt2/link/ProductFilter_test.cpp b/tools/aapt2/link/ProductFilter_test.cpp index 7f78f8bd4693..379ad26836e8 100644 --- a/tools/aapt2/link/ProductFilter_test.cpp +++ b/tools/aapt2/link/ProductFilter_test.cpp @@ -14,116 +14,117 @@ * limitations under the License. */ -#include "link/ProductFilter.h" +#include "link/Linkers.h" + #include "test/Test.h" namespace aapt { TEST(ProductFilterTest, SelectTwoProducts) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); - const ConfigDescription land = test::parseConfigOrDie("land"); - const ConfigDescription port = test::parseConfigOrDie("port"); + const ConfigDescription land = test::ParseConfigOrDie("land"); + const ConfigDescription port = test::ParseConfigOrDie("port"); ResourceTable table; - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), land, "", - test::ValueBuilder<Id>().setSource(Source("land/default.xml")).build(), - context->getDiagnostics())); - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), land, "tablet", - test::ValueBuilder<Id>().setSource(Source("land/tablet.xml")).build(), - context->getDiagnostics())); - - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), port, "", - test::ValueBuilder<Id>().setSource(Source("port/default.xml")).build(), - context->getDiagnostics())); - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), port, "tablet", - test::ValueBuilder<Id>().setSource(Source("port/tablet.xml")).build(), - context->getDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), land, "", + test::ValueBuilder<Id>().SetSource(Source("land/default.xml")).Build(), + context->GetDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), land, "tablet", + test::ValueBuilder<Id>().SetSource(Source("land/tablet.xml")).Build(), + context->GetDiagnostics())); + + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), port, "", + test::ValueBuilder<Id>().SetSource(Source("port/default.xml")).Build(), + context->GetDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), port, "tablet", + test::ValueBuilder<Id>().SetSource(Source("port/tablet.xml")).Build(), + context->GetDiagnostics())); ProductFilter filter({"tablet"}); - ASSERT_TRUE(filter.consume(context.get(), &table)); + ASSERT_TRUE(filter.Consume(context.get(), &table)); - EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>( + EXPECT_EQ(nullptr, test::GetValueForConfigAndProduct<Id>( &table, "android:string/one", land, "")); - EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>( + EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>( &table, "android:string/one", land, "tablet")); - EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>( + EXPECT_EQ(nullptr, test::GetValueForConfigAndProduct<Id>( &table, "android:string/one", port, "")); - EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>( + EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>( &table, "android:string/one", port, "tablet")); } TEST(ProductFilterTest, SelectDefaultProduct) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); ResourceTable table; - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), - ConfigDescription::defaultConfig(), "", - test::ValueBuilder<Id>().setSource(Source("default.xml")).build(), - context->getDiagnostics())); - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), - ConfigDescription::defaultConfig(), "tablet", - test::ValueBuilder<Id>().setSource(Source("tablet.xml")).build(), - context->getDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), + ConfigDescription::DefaultConfig(), "", + test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(), + context->GetDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), + ConfigDescription::DefaultConfig(), "tablet", + test::ValueBuilder<Id>().SetSource(Source("tablet.xml")).Build(), + context->GetDiagnostics())); ProductFilter filter({}); - ASSERT_TRUE(filter.consume(context.get(), &table)); + ASSERT_TRUE(filter.Consume(context.get(), &table)); - EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>( + EXPECT_NE(nullptr, test::GetValueForConfigAndProduct<Id>( &table, "android:string/one", - ConfigDescription::defaultConfig(), "")); - EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>( + ConfigDescription::DefaultConfig(), "")); + EXPECT_EQ(nullptr, test::GetValueForConfigAndProduct<Id>( &table, "android:string/one", - ConfigDescription::defaultConfig(), "tablet")); + ConfigDescription::DefaultConfig(), "tablet")); } TEST(ProductFilterTest, FailOnAmbiguousProduct) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); ResourceTable table; - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), - ConfigDescription::defaultConfig(), "", - test::ValueBuilder<Id>().setSource(Source("default.xml")).build(), - context->getDiagnostics())); - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), - ConfigDescription::defaultConfig(), "tablet", - test::ValueBuilder<Id>().setSource(Source("tablet.xml")).build(), - context->getDiagnostics())); - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), - ConfigDescription::defaultConfig(), "no-sdcard", - test::ValueBuilder<Id>().setSource(Source("no-sdcard.xml")).build(), - context->getDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), + ConfigDescription::DefaultConfig(), "", + test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(), + context->GetDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), + ConfigDescription::DefaultConfig(), "tablet", + test::ValueBuilder<Id>().SetSource(Source("tablet.xml")).Build(), + context->GetDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), + ConfigDescription::DefaultConfig(), "no-sdcard", + test::ValueBuilder<Id>().SetSource(Source("no-sdcard.xml")).Build(), + context->GetDiagnostics())); ProductFilter filter({"tablet", "no-sdcard"}); - ASSERT_FALSE(filter.consume(context.get(), &table)); + ASSERT_FALSE(filter.Consume(context.get(), &table)); } TEST(ProductFilterTest, FailOnMultipleDefaults) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); ResourceTable table; - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), - ConfigDescription::defaultConfig(), "", - test::ValueBuilder<Id>().setSource(Source(".xml")).build(), - context->getDiagnostics())); - ASSERT_TRUE(table.addResource( - test::parseNameOrDie("android:string/one"), - ConfigDescription::defaultConfig(), "default", - test::ValueBuilder<Id>().setSource(Source("default.xml")).build(), - context->getDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), + ConfigDescription::DefaultConfig(), "", + test::ValueBuilder<Id>().SetSource(Source(".xml")).Build(), + context->GetDiagnostics())); + ASSERT_TRUE(table.AddResource( + test::ParseNameOrDie("android:string/one"), + ConfigDescription::DefaultConfig(), "default", + test::ValueBuilder<Id>().SetSource(Source("default.xml")).Build(), + context->GetDiagnostics())); ProductFilter filter({}); - ASSERT_FALSE(filter.consume(context.get(), &table)); + ASSERT_FALSE(filter.Consume(context.get(), &table)); } } // namespace aapt diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp index 7fe09565816a..be787b2727ad 100644 --- a/tools/aapt2/link/ReferenceLinker.cpp +++ b/tools/aapt2/link/ReferenceLinker.cpp @@ -14,7 +14,11 @@ * limitations under the License. */ -#include "ReferenceLinker.h" +#include "link/ReferenceLinker.h" + +#include "android-base/logging.h" +#include "androidfw/ResourceTypes.h" + #include "Diagnostics.h" #include "ResourceTable.h" #include "ResourceUtils.h" @@ -26,9 +30,6 @@ #include "util/Util.h" #include "xml/XmlUtil.h" -#include <androidfw/ResourceTypes.h> -#include <cassert> - namespace aapt { namespace { @@ -46,21 +47,21 @@ namespace { */ class ReferenceLinkerVisitor : public ValueVisitor { public: - using ValueVisitor::visit; + using ValueVisitor::Visit; ReferenceLinkerVisitor(IAaptContext* context, SymbolTable* symbols, - StringPool* stringPool, xml::IPackageDeclStack* decl, - CallSite* callSite) - : mContext(context), - mSymbols(symbols), - mPackageDecls(decl), - mStringPool(stringPool), - mCallSite(callSite) {} - - void visit(Reference* ref) override { - if (!ReferenceLinker::linkReference(ref, mContext, mSymbols, mPackageDecls, - mCallSite)) { - mError = true; + StringPool* string_pool, xml::IPackageDeclStack* decl, + CallSite* callsite) + : context_(context), + symbols_(symbols), + package_decls_(decl), + string_pool_(string_pool), + callsite_(callsite) {} + + void Visit(Reference* ref) override { + if (!ReferenceLinker::LinkReference(ref, context_, symbols_, package_decls_, + callsite_)) { + error_ = true; } } @@ -72,13 +73,13 @@ class ReferenceLinkerVisitor : public ValueVisitor { * lookup the attributes to find out which types are allowed for the * attributes' values. */ - void visit(Style* style) override { + void Visit(Style* style) override { if (style->parent) { - visit(&style->parent.value()); + Visit(&style->parent.value()); } for (Style::Entry& entry : style->entries) { - std::string errStr; + std::string err_str; // Transform the attribute reference so that it is using the fully // qualified package @@ -86,17 +87,17 @@ class ReferenceLinkerVisitor : public ValueVisitor { // resources if // there was a '*' in the reference or if the package came from the // private namespace. - Reference transformedReference = entry.key; - transformReferenceFromNamespace(mPackageDecls, - mContext->getCompilationPackage(), - &transformedReference); + Reference transformed_reference = entry.key; + TransformReferenceFromNamespace(package_decls_, + context_->GetCompilationPackage(), + &transformed_reference); // Find the attribute in the symbol table and check if it is visible from // this callsite. const SymbolTable::Symbol* symbol = - ReferenceLinker::resolveAttributeCheckVisibility( - transformedReference, mContext->getNameMangler(), mSymbols, - mCallSite, &errStr); + ReferenceLinker::ResolveAttributeCheckVisibility( + transformed_reference, context_->GetNameMangler(), symbols_, + callsite_, &err_str); if (symbol) { // Assign our style key the correct ID. // The ID may not exist. @@ -104,11 +105,11 @@ class ReferenceLinkerVisitor : public ValueVisitor { // Try to convert the value to a more specific, typed value based on the // attribute it is set to. - entry.value = parseValueWithAttribute(std::move(entry.value), + entry.value = ParseValueWithAttribute(std::move(entry.value), symbol->attribute.get()); // Link/resolve the final value (mostly if it's a reference). - entry.value->accept(this); + entry.value->Accept(this); // Now verify that the type of this item is compatible with the // attribute it @@ -116,39 +117,34 @@ class ReferenceLinkerVisitor : public ValueVisitor { // check is // fast and we avoid creating a DiagMessage when the match is // successful. - if (!symbol->attribute->matches(entry.value.get(), nullptr)) { + if (!symbol->attribute->Matches(entry.value.get(), nullptr)) { // The actual type of this item is incompatible with the attribute. - DiagMessage msg(entry.key.getSource()); + DiagMessage msg(entry.key.GetSource()); // Call the matches method again, this time with a DiagMessage so we // fill // in the actual error message. - symbol->attribute->matches(entry.value.get(), &msg); - mContext->getDiagnostics()->error(msg); - mError = true; + symbol->attribute->Matches(entry.value.get(), &msg); + context_->GetDiagnostics()->Error(msg); + error_ = true; } } else { - DiagMessage msg(entry.key.getSource()); + DiagMessage msg(entry.key.GetSource()); msg << "style attribute '"; - ReferenceLinker::writeResourceName(&msg, entry.key, - transformedReference); - msg << "' " << errStr; - mContext->getDiagnostics()->error(msg); - mError = true; + ReferenceLinker::WriteResourceName(&msg, entry.key, + transformed_reference); + msg << "' " << err_str; + context_->GetDiagnostics()->Error(msg); + error_ = true; } } } - bool hasError() { return mError; } + bool HasError() { return error_; } private: - IAaptContext* mContext; - SymbolTable* mSymbols; - xml::IPackageDeclStack* mPackageDecls; - StringPool* mStringPool; - CallSite* mCallSite; - bool mError = false; + DISALLOW_COPY_AND_ASSIGN(ReferenceLinkerVisitor); /** * Transform a RawString value into a more specific, appropriate value, based @@ -156,20 +152,20 @@ class ReferenceLinkerVisitor : public ValueVisitor { * Attribute. If a non RawString value is passed in, this is an identity * transform. */ - std::unique_ptr<Item> parseValueWithAttribute(std::unique_ptr<Item> value, + std::unique_ptr<Item> ParseValueWithAttribute(std::unique_ptr<Item> value, const Attribute* attr) { - if (RawString* rawString = valueCast<RawString>(value.get())) { + if (RawString* raw_string = ValueCast<RawString>(value.get())) { std::unique_ptr<Item> transformed = - ResourceUtils::tryParseItemForAttribute(*rawString->value, attr); + ResourceUtils::TryParseItemForAttribute(*raw_string->value, attr); // If we could not parse as any specific type, try a basic STRING. if (!transformed && - (attr->typeMask & android::ResTable_map::TYPE_STRING)) { - util::StringBuilder stringBuilder; - stringBuilder.append(*rawString->value); - if (stringBuilder) { + (attr->type_mask & android::ResTable_map::TYPE_STRING)) { + util::StringBuilder string_builder; + string_builder.Append(*raw_string->value); + if (string_builder) { transformed = util::make_unique<String>( - mStringPool->makeRef(stringBuilder.str())); + string_pool_->MakeRef(string_builder.ToString())); } } @@ -179,6 +175,31 @@ class ReferenceLinkerVisitor : public ValueVisitor { }; return value; } + + IAaptContext* context_; + SymbolTable* symbols_; + xml::IPackageDeclStack* package_decls_; + StringPool* string_pool_; + CallSite* callsite_; + bool error_ = false; +}; + +class EmptyDeclStack : public xml::IPackageDeclStack { + public: + EmptyDeclStack() = default; + + Maybe<xml::ExtractedPackage> TransformPackageAlias( + const StringPiece& alias, + const StringPiece& local_package) const override { + if (alias.empty()) { + return xml::ExtractedPackage{local_package.ToString(), + true /* private */}; + } + return {}; + } + + private: + DISALLOW_COPY_AND_ASSIGN(EmptyDeclStack); }; } // namespace @@ -188,14 +209,14 @@ class ReferenceLinkerVisitor : public ValueVisitor { * requesting private access * or if the callsite comes from the same package. */ -bool ReferenceLinker::isSymbolVisible(const SymbolTable::Symbol& symbol, +bool ReferenceLinker::IsSymbolVisible(const SymbolTable::Symbol& symbol, const Reference& ref, - const CallSite& callSite) { - if (!symbol.isPublic && !ref.privateReference) { + const CallSite& callsite) { + if (!symbol.is_public && !ref.private_reference) { if (ref.name) { - return callSite.resource.package == ref.name.value().package; + return callsite.resource.package == ref.name.value().package; } else if (ref.id && symbol.id) { - return ref.id.value().packageId() == symbol.id.value().packageId(); + return ref.id.value().package_id() == symbol.id.value().package_id(); } else { return false; } @@ -203,160 +224,144 @@ bool ReferenceLinker::isSymbolVisible(const SymbolTable::Symbol& symbol, return true; } -const SymbolTable::Symbol* ReferenceLinker::resolveSymbol( +const SymbolTable::Symbol* ReferenceLinker::ResolveSymbol( const Reference& reference, NameMangler* mangler, SymbolTable* symbols) { if (reference.name) { - Maybe<ResourceName> mangled = mangler->mangleName(reference.name.value()); - return symbols->findByName(mangled ? mangled.value() + Maybe<ResourceName> mangled = mangler->MangleName(reference.name.value()); + return symbols->FindByName(mangled ? mangled.value() : reference.name.value()); } else if (reference.id) { - return symbols->findById(reference.id.value()); + return symbols->FindById(reference.id.value()); } else { return nullptr; } } -const SymbolTable::Symbol* ReferenceLinker::resolveSymbolCheckVisibility( - const Reference& reference, NameMangler* nameMangler, SymbolTable* symbols, - CallSite* callSite, std::string* outError) { +const SymbolTable::Symbol* ReferenceLinker::ResolveSymbolCheckVisibility( + const Reference& reference, NameMangler* name_mangler, SymbolTable* symbols, + CallSite* callsite, std::string* out_error) { const SymbolTable::Symbol* symbol = - resolveSymbol(reference, nameMangler, symbols); + ResolveSymbol(reference, name_mangler, symbols); if (!symbol) { - if (outError) *outError = "not found"; + if (out_error) *out_error = "not found"; return nullptr; } - if (!isSymbolVisible(*symbol, reference, *callSite)) { - if (outError) *outError = "is private"; + if (!IsSymbolVisible(*symbol, reference, *callsite)) { + if (out_error) *out_error = "is private"; return nullptr; } return symbol; } -const SymbolTable::Symbol* ReferenceLinker::resolveAttributeCheckVisibility( - const Reference& reference, NameMangler* nameMangler, SymbolTable* symbols, - CallSite* callSite, std::string* outError) { - const SymbolTable::Symbol* symbol = resolveSymbolCheckVisibility( - reference, nameMangler, symbols, callSite, outError); +const SymbolTable::Symbol* ReferenceLinker::ResolveAttributeCheckVisibility( + const Reference& reference, NameMangler* name_mangler, SymbolTable* symbols, + CallSite* callsite, std::string* out_error) { + const SymbolTable::Symbol* symbol = ResolveSymbolCheckVisibility( + reference, name_mangler, symbols, callsite, out_error); if (!symbol) { return nullptr; } if (!symbol->attribute) { - if (outError) *outError = "is not an attribute"; + if (out_error) *out_error = "is not an attribute"; return nullptr; } return symbol; } -Maybe<xml::AaptAttribute> ReferenceLinker::compileXmlAttribute( - const Reference& reference, NameMangler* nameMangler, SymbolTable* symbols, - CallSite* callSite, std::string* outError) { +Maybe<xml::AaptAttribute> ReferenceLinker::CompileXmlAttribute( + const Reference& reference, NameMangler* name_mangler, SymbolTable* symbols, + CallSite* callsite, std::string* out_error) { const SymbolTable::Symbol* symbol = - resolveSymbol(reference, nameMangler, symbols); + ResolveSymbol(reference, name_mangler, symbols); if (!symbol) { - if (outError) *outError = "not found"; + if (out_error) *out_error = "not found"; return {}; } if (!symbol->attribute) { - if (outError) *outError = "is not an attribute"; + if (out_error) *out_error = "is not an attribute"; return {}; } return xml::AaptAttribute{symbol->id, *symbol->attribute}; } -void ReferenceLinker::writeResourceName(DiagMessage* outMsg, +void ReferenceLinker::WriteResourceName(DiagMessage* out_msg, const Reference& orig, const Reference& transformed) { - assert(outMsg); + CHECK(out_msg != nullptr); if (orig.name) { - *outMsg << orig.name.value(); + *out_msg << orig.name.value(); if (transformed.name.value() != orig.name.value()) { - *outMsg << " (aka " << transformed.name.value() << ")"; + *out_msg << " (aka " << transformed.name.value() << ")"; } } else { - *outMsg << orig.id.value(); + *out_msg << orig.id.value(); } } -bool ReferenceLinker::linkReference(Reference* reference, IAaptContext* context, +bool ReferenceLinker::LinkReference(Reference* reference, IAaptContext* context, SymbolTable* symbols, xml::IPackageDeclStack* decls, - CallSite* callSite) { - assert(reference); - assert(reference->name || reference->id); - - Reference transformedReference = *reference; - transformReferenceFromNamespace(decls, context->getCompilationPackage(), - &transformedReference); - - std::string errStr; - const SymbolTable::Symbol* s = resolveSymbolCheckVisibility( - transformedReference, context->getNameMangler(), symbols, callSite, - &errStr); + CallSite* callsite) { + CHECK(reference != nullptr); + CHECK(reference->name || reference->id); + + Reference transformed_reference = *reference; + TransformReferenceFromNamespace(decls, context->GetCompilationPackage(), + &transformed_reference); + + std::string err_str; + const SymbolTable::Symbol* s = ResolveSymbolCheckVisibility( + transformed_reference, context->GetNameMangler(), symbols, callsite, + &err_str); if (s) { // The ID may not exist. This is fine because of the possibility of building - // against - // libraries without assigned IDs. + // against libraries without assigned IDs. // Ex: Linking against own resources when building a static library. reference->id = s->id; return true; } - DiagMessage errorMsg(reference->getSource()); - errorMsg << "resource "; - writeResourceName(&errorMsg, *reference, transformedReference); - errorMsg << " " << errStr; - context->getDiagnostics()->error(errorMsg); + DiagMessage error_msg(reference->GetSource()); + error_msg << "resource "; + WriteResourceName(&error_msg, *reference, transformed_reference); + error_msg << " " << err_str; + context->GetDiagnostics()->Error(error_msg); return false; } -namespace { - -struct EmptyDeclStack : public xml::IPackageDeclStack { - Maybe<xml::ExtractedPackage> transformPackageAlias( - const StringPiece& alias, - const StringPiece& localPackage) const override { - if (alias.empty()) { - return xml::ExtractedPackage{localPackage.toString(), true /* private */}; - } - return {}; - } -}; - -} // namespace - -bool ReferenceLinker::consume(IAaptContext* context, ResourceTable* table) { - EmptyDeclStack declStack; +bool ReferenceLinker::Consume(IAaptContext* context, ResourceTable* table) { + EmptyDeclStack decl_stack; bool error = false; for (auto& package : table->packages) { for (auto& type : package->types) { for (auto& entry : type->entries) { // Symbol state information may be lost if there is no value for the // resource. - if (entry->symbolStatus.state != SymbolState::kUndefined && + if (entry->symbol_status.state != SymbolState::kUndefined && entry->values.empty()) { - context->getDiagnostics()->error( - DiagMessage(entry->symbolStatus.source) + context->GetDiagnostics()->Error( + DiagMessage(entry->symbol_status.source) << "no definition for declared symbol '" << ResourceNameRef(package->name, type->type, entry->name) << "'"); error = true; } - CallSite callSite = { + CallSite callsite = { ResourceNameRef(package->name, type->type, entry->name)}; - ReferenceLinkerVisitor visitor(context, context->getExternalSymbols(), - &table->stringPool, &declStack, - &callSite); + ReferenceLinkerVisitor visitor(context, context->GetExternalSymbols(), + &table->string_pool, &decl_stack, + &callsite); - for (auto& configValue : entry->values) { - configValue->value->accept(&visitor); + for (auto& config_value : entry->values) { + config_value->value->Accept(&visitor); } - if (visitor.hasError()) { + if (visitor.HasError()) { error = true; } } diff --git a/tools/aapt2/link/ReferenceLinker.h b/tools/aapt2/link/ReferenceLinker.h index 8f6604f8d9d6..bdabf249709d 100644 --- a/tools/aapt2/link/ReferenceLinker.h +++ b/tools/aapt2/link/ReferenceLinker.h @@ -17,6 +17,8 @@ #ifndef AAPT_LINKER_REFERENCELINKER_H #define AAPT_LINKER_REFERENCELINKER_H +#include "android-base/macros.h" + #include "Resource.h" #include "ResourceValues.h" #include "ValueVisitor.h" @@ -25,8 +27,6 @@ #include "process/SymbolTable.h" #include "xml/XmlDom.h" -#include <cassert> - namespace aapt { /** @@ -36,33 +36,33 @@ namespace aapt { * Once the ResourceTable is processed by this linker, it is ready to be * flattened. */ -struct ReferenceLinker : public IResourceTableConsumer { +class ReferenceLinker : public IResourceTableConsumer { + public: + ReferenceLinker() = default; + /** * Returns true if the symbol is visible by the reference and from the * callsite. */ - static bool isSymbolVisible(const SymbolTable::Symbol& symbol, - const Reference& ref, const CallSite& callSite); + static bool IsSymbolVisible(const SymbolTable::Symbol& symbol, + const Reference& ref, const CallSite& callsite); /** * Performs name mangling and looks up the resource in the symbol table. - * Returns nullptr - * if the symbol was not found. + * Returns nullptr if the symbol was not found. */ - static const SymbolTable::Symbol* resolveSymbol(const Reference& reference, + static const SymbolTable::Symbol* ResolveSymbol(const Reference& reference, NameMangler* mangler, SymbolTable* symbols); /** * Performs name mangling and looks up the resource in the symbol table. If - * the symbol is - * not visible by the reference at the callsite, nullptr is returned. outError - * holds - * the error message. + * the symbol is not visible by the reference at the callsite, nullptr is + * returned. out_error holds the error message. */ - static const SymbolTable::Symbol* resolveSymbolCheckVisibility( - const Reference& reference, NameMangler* nameMangler, - SymbolTable* symbols, CallSite* callSite, std::string* outError); + static const SymbolTable::Symbol* ResolveSymbolCheckVisibility( + const Reference& reference, NameMangler* name_mangler, + SymbolTable* symbols, CallSite* callsite, std::string* out_error); /** * Same as resolveSymbolCheckVisibility(), but also makes sure the symbol is @@ -70,25 +70,24 @@ struct ReferenceLinker : public IResourceTableConsumer { * That is, the return value will have a non-null value for * ISymbolTable::Symbol::attribute. */ - static const SymbolTable::Symbol* resolveAttributeCheckVisibility( - const Reference& reference, NameMangler* nameMangler, - SymbolTable* symbols, CallSite* callSite, std::string* outError); + static const SymbolTable::Symbol* ResolveAttributeCheckVisibility( + const Reference& reference, NameMangler* name_mangler, + SymbolTable* symbols, CallSite* callsite, std::string* out_error); /** * Resolves the attribute reference and returns an xml::AaptAttribute if * successful. * If resolution fails, outError holds the error message. */ - static Maybe<xml::AaptAttribute> compileXmlAttribute( - const Reference& reference, NameMangler* nameMangler, - SymbolTable* symbols, CallSite* callSite, std::string* outError); + static Maybe<xml::AaptAttribute> CompileXmlAttribute( + const Reference& reference, NameMangler* name_mangler, + SymbolTable* symbols, CallSite* callsite, std::string* out_error); /** - * Writes the resource name to the DiagMessage, using the "orig_name (aka - * <transformed_name>)" - * syntax. + * Writes the resource name to the DiagMessage, using the + * "orig_name (aka <transformed_name>)" syntax. */ - static void writeResourceName(DiagMessage* outMsg, const Reference& orig, + static void WriteResourceName(DiagMessage* out_msg, const Reference& orig, const Reference& transformed); /** @@ -100,14 +99,17 @@ struct ReferenceLinker : public IResourceTableConsumer { * Returns false on failure, and an error message is logged to the * IDiagnostics in the context. */ - static bool linkReference(Reference* reference, IAaptContext* context, + static bool LinkReference(Reference* reference, IAaptContext* context, SymbolTable* symbols, xml::IPackageDeclStack* decls, - CallSite* callSite); + CallSite* callsite); /** * Links all references in the ResourceTable. */ - bool consume(IAaptContext* context, ResourceTable* table) override; + bool Consume(IAaptContext* context, ResourceTable* table) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ReferenceLinker); }; } // namespace aapt diff --git a/tools/aapt2/link/ReferenceLinker_test.cpp b/tools/aapt2/link/ReferenceLinker_test.cpp index 8aa361605384..4ca36a9e2b22 100644 --- a/tools/aapt2/link/ReferenceLinker_test.cpp +++ b/tools/aapt2/link/ReferenceLinker_test.cpp @@ -15,6 +15,7 @@ */ #include "link/ReferenceLinker.h" + #include "test/Test.h" using android::ResTable_map; @@ -24,46 +25,46 @@ namespace aapt { TEST(ReferenceLinkerTest, LinkSimpleReferences) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("com.app.test", 0x7f) - .addReference("com.app.test:string/foo", ResourceId(0x7f020000), + .SetPackageId("com.app.test", 0x7f) + .AddReference("com.app.test:string/foo", ResourceId(0x7f020000), "com.app.test:string/bar") // Test use of local reference (w/o package name). - .addReference("com.app.test:string/bar", ResourceId(0x7f020001), + .AddReference("com.app.test:string/bar", ResourceId(0x7f020001), "string/baz") - .addReference("com.app.test:string/baz", ResourceId(0x7f020002), + .AddReference("com.app.test:string/baz", ResourceId(0x7f020002), "android:string/ok") - .build(); + .Build(); std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .setCompilationPackage("com.app.test") - .setPackageId(0x7f) - .setNameManglerPolicy(NameManglerPolicy{"com.app.test"}) - .addSymbolSource( + .SetCompilationPackage("com.app.test") + .SetPackageId(0x7f) + .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"}) + .AddSymbolSource( util::make_unique<ResourceTableSymbolSource>(table.get())) - .addSymbolSource( + .AddSymbolSource( test::StaticSymbolSourceBuilder() - .addPublicSymbol("android:string/ok", ResourceId(0x01040034)) - .build()) - .build(); + .AddPublicSymbol("android:string/ok", ResourceId(0x01040034)) + .Build()) + .Build(); ReferenceLinker linker; - ASSERT_TRUE(linker.consume(context.get(), table.get())); + ASSERT_TRUE(linker.Consume(context.get(), table.get())); Reference* ref = - test::getValue<Reference>(table.get(), "com.app.test:string/foo"); + test::GetValue<Reference>(table.get(), "com.app.test:string/foo"); ASSERT_NE(ref, nullptr); AAPT_ASSERT_TRUE(ref->id); EXPECT_EQ(ref->id.value(), ResourceId(0x7f020001)); - ref = test::getValue<Reference>(table.get(), "com.app.test:string/bar"); + ref = test::GetValue<Reference>(table.get(), "com.app.test:string/bar"); ASSERT_NE(ref, nullptr); AAPT_ASSERT_TRUE(ref->id); EXPECT_EQ(ref->id.value(), ResourceId(0x7f020002)); - ref = test::getValue<Reference>(table.get(), "com.app.test:string/baz"); + ref = test::GetValue<Reference>(table.get(), "com.app.test:string/baz"); ASSERT_NE(ref, nullptr); AAPT_ASSERT_TRUE(ref->id); EXPECT_EQ(ref->id.value(), ResourceId(0x01040034)); @@ -72,53 +73,53 @@ TEST(ReferenceLinkerTest, LinkSimpleReferences) { TEST(ReferenceLinkerTest, LinkStyleAttributes) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("com.app.test", 0x7f) - .addValue("com.app.test:style/Theme", + .SetPackageId("com.app.test", 0x7f) + .AddValue("com.app.test:style/Theme", test::StyleBuilder() - .setParent("android:style/Theme.Material") - .addItem("android:attr/foo", - ResourceUtils::tryParseColor("#ff00ff")) - .addItem("android:attr/bar", {} /* placeholder */) - .build()) - .build(); + .SetParent("android:style/Theme.Material") + .AddItem("android:attr/foo", + ResourceUtils::TryParseColor("#ff00ff")) + .AddItem("android:attr/bar", {} /* placeholder */) + .Build()) + .Build(); { // We need to fill in the value for the attribute android:attr/bar after we // build the // table, because we need access to the string pool. Style* style = - test::getValue<Style>(table.get(), "com.app.test:style/Theme"); + test::GetValue<Style>(table.get(), "com.app.test:style/Theme"); ASSERT_NE(style, nullptr); style->entries.back().value = - util::make_unique<RawString>(table->stringPool.makeRef("one|two")); + util::make_unique<RawString>(table->string_pool.MakeRef("one|two")); } std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .setCompilationPackage("com.app.test") - .setPackageId(0x7f) - .setNameManglerPolicy(NameManglerPolicy{"com.app.test"}) - .addSymbolSource( + .SetCompilationPackage("com.app.test") + .SetPackageId(0x7f) + .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"}) + .AddSymbolSource( test::StaticSymbolSourceBuilder() - .addPublicSymbol("android:style/Theme.Material", + .AddPublicSymbol("android:style/Theme.Material", ResourceId(0x01060000)) - .addPublicSymbol("android:attr/foo", ResourceId(0x01010001), + .AddPublicSymbol("android:attr/foo", ResourceId(0x01010001), test::AttributeBuilder() - .setTypeMask(ResTable_map::TYPE_COLOR) - .build()) - .addPublicSymbol("android:attr/bar", ResourceId(0x01010002), + .SetTypeMask(ResTable_map::TYPE_COLOR) + .Build()) + .AddPublicSymbol("android:attr/bar", ResourceId(0x01010002), test::AttributeBuilder() - .setTypeMask(ResTable_map::TYPE_FLAGS) - .addItem("one", 0x01) - .addItem("two", 0x02) - .build()) - .build()) - .build(); + .SetTypeMask(ResTable_map::TYPE_FLAGS) + .AddItem("one", 0x01) + .AddItem("two", 0x02) + .Build()) + .Build()) + .Build(); ReferenceLinker linker; - ASSERT_TRUE(linker.consume(context.get(), table.get())); + ASSERT_TRUE(linker.Consume(context.get(), table.get())); - Style* style = test::getValue<Style>(table.get(), "com.app.test:style/Theme"); + Style* style = test::GetValue<Style>(table.get(), "com.app.test:style/Theme"); ASSERT_NE(style, nullptr); AAPT_ASSERT_TRUE(style->parent); AAPT_ASSERT_TRUE(style->parent.value().id); @@ -128,44 +129,44 @@ TEST(ReferenceLinkerTest, LinkStyleAttributes) { AAPT_ASSERT_TRUE(style->entries[0].key.id); EXPECT_EQ(style->entries[0].key.id.value(), ResourceId(0x01010001)); - ASSERT_NE(valueCast<BinaryPrimitive>(style->entries[0].value.get()), nullptr); + ASSERT_NE(ValueCast<BinaryPrimitive>(style->entries[0].value.get()), nullptr); AAPT_ASSERT_TRUE(style->entries[1].key.id); EXPECT_EQ(style->entries[1].key.id.value(), ResourceId(0x01010002)); - ASSERT_NE(valueCast<BinaryPrimitive>(style->entries[1].value.get()), nullptr); + ASSERT_NE(ValueCast<BinaryPrimitive>(style->entries[1].value.get()), nullptr); } TEST(ReferenceLinkerTest, LinkMangledReferencesAndAttributes) { std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .setCompilationPackage("com.app.test") - .setPackageId(0x7f) - .setNameManglerPolicy( + .SetCompilationPackage("com.app.test") + .SetPackageId(0x7f) + .SetNameManglerPolicy( NameManglerPolicy{"com.app.test", {"com.android.support"}}) - .addSymbolSource( + .AddSymbolSource( test::StaticSymbolSourceBuilder() - .addPublicSymbol("com.app.test:attr/com.android.support$foo", + .AddPublicSymbol("com.app.test:attr/com.android.support$foo", ResourceId(0x7f010000), test::AttributeBuilder() - .setTypeMask(ResTable_map::TYPE_COLOR) - .build()) - .build()) - .build(); + .SetTypeMask(ResTable_map::TYPE_COLOR) + .Build()) + .Build()) + .Build(); std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("com.app.test", 0x7f) - .addValue("com.app.test:style/Theme", ResourceId(0x7f020000), + .SetPackageId("com.app.test", 0x7f) + .AddValue("com.app.test:style/Theme", ResourceId(0x7f020000), test::StyleBuilder() - .addItem("com.android.support:attr/foo", - ResourceUtils::tryParseColor("#ff0000")) - .build()) - .build(); + .AddItem("com.android.support:attr/foo", + ResourceUtils::TryParseColor("#ff0000")) + .Build()) + .Build(); ReferenceLinker linker; - ASSERT_TRUE(linker.consume(context.get(), table.get())); + ASSERT_TRUE(linker.Consume(context.get(), table.get())); - Style* style = test::getValue<Style>(table.get(), "com.app.test:style/Theme"); + Style* style = test::GetValue<Style>(table.get(), "com.app.test:style/Theme"); ASSERT_NE(style, nullptr); ASSERT_EQ(1u, style->entries.size()); AAPT_ASSERT_TRUE(style->entries.front().key.id); @@ -175,85 +176,85 @@ TEST(ReferenceLinkerTest, LinkMangledReferencesAndAttributes) { TEST(ReferenceLinkerTest, FailToLinkPrivateSymbols) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("com.app.test", 0x7f) - .addReference("com.app.test:string/foo", ResourceId(0x7f020000), + .SetPackageId("com.app.test", 0x7f) + .AddReference("com.app.test:string/foo", ResourceId(0x7f020000), "android:string/hidden") - .build(); + .Build(); std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .setCompilationPackage("com.app.test") - .setPackageId(0x7f) - .setNameManglerPolicy(NameManglerPolicy{"com.app.test"}) - .addSymbolSource( + .SetCompilationPackage("com.app.test") + .SetPackageId(0x7f) + .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"}) + .AddSymbolSource( util::make_unique<ResourceTableSymbolSource>(table.get())) - .addSymbolSource( + .AddSymbolSource( test::StaticSymbolSourceBuilder() - .addSymbol("android:string/hidden", ResourceId(0x01040034)) - .build()) - .build(); + .AddSymbol("android:string/hidden", ResourceId(0x01040034)) + .Build()) + .Build(); ReferenceLinker linker; - ASSERT_FALSE(linker.consume(context.get(), table.get())); + ASSERT_FALSE(linker.Consume(context.get(), table.get())); } TEST(ReferenceLinkerTest, FailToLinkPrivateMangledSymbols) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("com.app.test", 0x7f) - .addReference("com.app.test:string/foo", ResourceId(0x7f020000), + .SetPackageId("com.app.test", 0x7f) + .AddReference("com.app.test:string/foo", ResourceId(0x7f020000), "com.app.lib:string/hidden") - .build(); + .Build(); std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .setCompilationPackage("com.app.test") - .setPackageId(0x7f) - .setNameManglerPolicy( + .SetCompilationPackage("com.app.test") + .SetPackageId(0x7f) + .SetNameManglerPolicy( NameManglerPolicy{"com.app.test", {"com.app.lib"}}) - .addSymbolSource( + .AddSymbolSource( util::make_unique<ResourceTableSymbolSource>(table.get())) - .addSymbolSource( + .AddSymbolSource( test::StaticSymbolSourceBuilder() - .addSymbol("com.app.test:string/com.app.lib$hidden", + .AddSymbol("com.app.test:string/com.app.lib$hidden", ResourceId(0x7f040034)) - .build()) + .Build()) - .build(); + .Build(); ReferenceLinker linker; - ASSERT_FALSE(linker.consume(context.get(), table.get())); + ASSERT_FALSE(linker.Consume(context.get(), table.get())); } TEST(ReferenceLinkerTest, FailToLinkPrivateStyleAttributes) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("com.app.test", 0x7f) - .addValue("com.app.test:style/Theme", + .SetPackageId("com.app.test", 0x7f) + .AddValue("com.app.test:style/Theme", test::StyleBuilder() - .addItem("android:attr/hidden", - ResourceUtils::tryParseColor("#ff00ff")) - .build()) - .build(); + .AddItem("android:attr/hidden", + ResourceUtils::TryParseColor("#ff00ff")) + .Build()) + .Build(); std::unique_ptr<IAaptContext> context = test::ContextBuilder() - .setCompilationPackage("com.app.test") - .setPackageId(0x7f) - .setNameManglerPolicy(NameManglerPolicy{"com.app.test"}) - .addSymbolSource( + .SetCompilationPackage("com.app.test") + .SetPackageId(0x7f) + .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"}) + .AddSymbolSource( util::make_unique<ResourceTableSymbolSource>(table.get())) - .addSymbolSource( + .AddSymbolSource( test::StaticSymbolSourceBuilder() - .addSymbol("android:attr/hidden", ResourceId(0x01010001), + .AddSymbol("android:attr/hidden", ResourceId(0x01010001), test::AttributeBuilder() - .setTypeMask(android::ResTable_map::TYPE_COLOR) - .build()) - .build()) - .build(); + .SetTypeMask(android::ResTable_map::TYPE_COLOR) + .Build()) + .Build()) + .Build(); ReferenceLinker linker; - ASSERT_FALSE(linker.consume(context.get(), table.get())); + ASSERT_FALSE(linker.Consume(context.get(), table.get())); } } // namespace aapt diff --git a/tools/aapt2/link/ResourceDeduper.cpp b/tools/aapt2/link/ResourceDeduper.cpp index f565359daaca..9431dcee9714 100644 --- a/tools/aapt2/link/ResourceDeduper.cpp +++ b/tools/aapt2/link/ResourceDeduper.cpp @@ -14,12 +14,13 @@ * limitations under the License. */ -#include "DominatorTree.h" -#include "ResourceTable.h" #include "link/Linkers.h" #include <algorithm> +#include "DominatorTree.h" +#include "ResourceTable.h" + namespace aapt { namespace { @@ -40,55 +41,57 @@ class DominatedKeyValueRemover : public DominatorTree::BottomUpVisitor { using Node = DominatorTree::Node; explicit DominatedKeyValueRemover(IAaptContext* context, ResourceEntry* entry) - : mContext(context), mEntry(entry) {} + : context_(context), entry_(entry) {} - void visitConfig(Node* node) { + void VisitConfig(Node* node) { Node* parent = node->parent(); if (!parent) { return; } - ResourceConfigValue* nodeValue = node->value(); - ResourceConfigValue* parentValue = parent->value(); - if (!nodeValue || !parentValue) { + ResourceConfigValue* node_value = node->value(); + ResourceConfigValue* parent_value = parent->value(); + if (!node_value || !parent_value) { return; } - if (!nodeValue->value->equals(parentValue->value.get())) { + if (!node_value->value->Equals(parent_value->value.get())) { return; } // Compare compatible configs for this entry and ensure the values are // equivalent. - const ConfigDescription& nodeConfiguration = nodeValue->config; - for (const auto& sibling : mEntry->values) { + const ConfigDescription& node_configuration = node_value->config; + for (const auto& sibling : entry_->values) { if (!sibling->value) { // Sibling was already removed. continue; } - if (nodeConfiguration.isCompatibleWith(sibling->config) && - !nodeValue->value->equals(sibling->value.get())) { + if (node_configuration.IsCompatibleWith(sibling->config) && + !node_value->value->Equals(sibling->value.get())) { // The configurations are compatible, but the value is // different, so we can't remove this value. return; } } - if (mContext->verbose()) { - mContext->getDiagnostics()->note( - DiagMessage(nodeValue->value->getSource()) + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note( + DiagMessage(node_value->value->GetSource()) << "removing dominated duplicate resource with name \"" - << mEntry->name << "\""); + << entry_->name << "\""); } - nodeValue->value = {}; + node_value->value = {}; } private: - IAaptContext* mContext; - ResourceEntry* mEntry; + DISALLOW_COPY_AND_ASSIGN(DominatedKeyValueRemover); + + IAaptContext* context_; + ResourceEntry* entry_; }; -static void dedupeEntry(IAaptContext* context, ResourceEntry* entry) { +static void DedupeEntry(IAaptContext* context, ResourceEntry* entry) { DominatorTree tree(entry->values); DominatedKeyValueRemover remover(context, entry); - tree.accept(&remover); + tree.Accept(&remover); // Erase the values that were removed. entry->values.erase( @@ -102,15 +105,15 @@ static void dedupeEntry(IAaptContext* context, ResourceEntry* entry) { } // namespace -bool ResourceDeduper::consume(IAaptContext* context, ResourceTable* table) { +bool ResourceDeduper::Consume(IAaptContext* context, ResourceTable* table) { for (auto& package : table->packages) { for (auto& type : package->types) { for (auto& entry : type->entries) { - dedupeEntry(context, entry.get()); + DedupeEntry(context, entry.get()); } } } return true; } -} // aapt +} // namespace aapt diff --git a/tools/aapt2/link/ResourceDeduper_test.cpp b/tools/aapt2/link/ResourceDeduper_test.cpp index 7e2d47665c85..d38059ddd391 100644 --- a/tools/aapt2/link/ResourceDeduper_test.cpp +++ b/tools/aapt2/link/ResourceDeduper_test.cpp @@ -14,70 +14,74 @@ * limitations under the License. */ -#include "ResourceTable.h" #include "link/Linkers.h" + +#include "ResourceTable.h" #include "test/Test.h" namespace aapt { TEST(ResourceDeduperTest, SameValuesAreDeduped) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); - const ConfigDescription defaultConfig = {}; - const ConfigDescription enConfig = test::parseConfigOrDie("en"); - const ConfigDescription enV21Config = test::parseConfigOrDie("en-v21"); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + const ConfigDescription default_config = {}; + const ConfigDescription en_config = test::ParseConfigOrDie("en"); + const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21"); // Chosen because this configuration is compatible with en. - const ConfigDescription landConfig = test::parseConfigOrDie("land"); + const ConfigDescription land_config = test::ParseConfigOrDie("land"); std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addString("android:string/dedupe", ResourceId{}, defaultConfig, + .AddString("android:string/dedupe", ResourceId{}, default_config, "dedupe") - .addString("android:string/dedupe", ResourceId{}, enConfig, "dedupe") - .addString("android:string/dedupe", ResourceId{}, landConfig, + .AddString("android:string/dedupe", ResourceId{}, en_config, "dedupe") + .AddString("android:string/dedupe", ResourceId{}, land_config, "dedupe") - .addString("android:string/dedupe2", ResourceId{}, defaultConfig, + .AddString("android:string/dedupe2", ResourceId{}, default_config, "dedupe") - .addString("android:string/dedupe2", ResourceId{}, enConfig, "dedupe") - .addString("android:string/dedupe2", ResourceId{}, enV21Config, + .AddString("android:string/dedupe2", ResourceId{}, en_config, + "dedupe") + .AddString("android:string/dedupe2", ResourceId{}, en_v21_config, "keep") - .addString("android:string/dedupe2", ResourceId{}, landConfig, + .AddString("android:string/dedupe2", ResourceId{}, land_config, "dedupe") - .build(); + .Build(); - ASSERT_TRUE(ResourceDeduper().consume(context.get(), table.get())); - EXPECT_EQ(nullptr, test::getValueForConfig<String>( - table.get(), "android:string/dedupe", enConfig)); - EXPECT_EQ(nullptr, test::getValueForConfig<String>( - table.get(), "android:string/dedupe", landConfig)); - EXPECT_EQ(nullptr, test::getValueForConfig<String>( - table.get(), "android:string/dedupe2", enConfig)); - EXPECT_NE(nullptr, test::getValueForConfig<String>( - table.get(), "android:string/dedupe2", enV21Config)); + ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get())); + EXPECT_EQ(nullptr, test::GetValueForConfig<String>( + table.get(), "android:string/dedupe", en_config)); + EXPECT_EQ(nullptr, test::GetValueForConfig<String>( + table.get(), "android:string/dedupe", land_config)); + EXPECT_EQ(nullptr, test::GetValueForConfig<String>( + table.get(), "android:string/dedupe2", en_config)); + EXPECT_NE(nullptr, test::GetValueForConfig<String>( + table.get(), "android:string/dedupe2", en_v21_config)); } TEST(ResourceDeduperTest, DifferentValuesAreKept) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); - const ConfigDescription defaultConfig = {}; - const ConfigDescription enConfig = test::parseConfigOrDie("en"); - const ConfigDescription enV21Config = test::parseConfigOrDie("en-v21"); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + const ConfigDescription default_config = {}; + const ConfigDescription en_config = test::ParseConfigOrDie("en"); + const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21"); // Chosen because this configuration is compatible with en. - const ConfigDescription landConfig = test::parseConfigOrDie("land"); + const ConfigDescription land_config = test::ParseConfigOrDie("land"); std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addString("android:string/keep", ResourceId{}, defaultConfig, "keep") - .addString("android:string/keep", ResourceId{}, enConfig, "keep") - .addString("android:string/keep", ResourceId{}, enV21Config, "keep2") - .addString("android:string/keep", ResourceId{}, landConfig, "keep2") - .build(); + .AddString("android:string/keep", ResourceId{}, default_config, + "keep") + .AddString("android:string/keep", ResourceId{}, en_config, "keep") + .AddString("android:string/keep", ResourceId{}, en_v21_config, + "keep2") + .AddString("android:string/keep", ResourceId{}, land_config, "keep2") + .Build(); - ASSERT_TRUE(ResourceDeduper().consume(context.get(), table.get())); - EXPECT_NE(nullptr, test::getValueForConfig<String>( - table.get(), "android:string/keep", enConfig)); - EXPECT_NE(nullptr, test::getValueForConfig<String>( - table.get(), "android:string/keep", enV21Config)); - EXPECT_NE(nullptr, test::getValueForConfig<String>( - table.get(), "android:string/keep", landConfig)); + ASSERT_TRUE(ResourceDeduper().Consume(context.get(), table.get())); + EXPECT_NE(nullptr, test::GetValueForConfig<String>( + table.get(), "android:string/keep", en_config)); + EXPECT_NE(nullptr, test::GetValueForConfig<String>( + table.get(), "android:string/keep", en_v21_config)); + EXPECT_NE(nullptr, test::GetValueForConfig<String>( + table.get(), "android:string/keep", land_config)); } } // namespace aapt diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp index adf83a468ccc..d808da31d3b3 100644 --- a/tools/aapt2/link/TableMerger.cpp +++ b/tools/aapt2/link/TableMerger.cpp @@ -15,51 +15,52 @@ */ #include "link/TableMerger.h" + +#include "android-base/logging.h" + #include "ResourceTable.h" #include "ResourceUtils.h" #include "ResourceValues.h" #include "ValueVisitor.h" #include "util/Util.h" -#include <cassert> - namespace aapt { -TableMerger::TableMerger(IAaptContext* context, ResourceTable* outTable, +TableMerger::TableMerger(IAaptContext* context, ResourceTable* out_table, const TableMergerOptions& options) - : mContext(context), mMasterTable(outTable), mOptions(options) { + : context_(context), master_table_(out_table), options_(options) { // Create the desired package that all tables will be merged into. - mMasterPackage = mMasterTable->createPackage( - mContext->getCompilationPackage(), mContext->getPackageId()); - assert(mMasterPackage && "package name or ID already taken"); + master_package_ = master_table_->CreatePackage( + context_->GetCompilationPackage(), context_->GetPackageId()); + CHECK(master_package_ != nullptr) << "package name or ID already taken"; } -bool TableMerger::merge(const Source& src, ResourceTable* table, +bool TableMerger::Merge(const Source& src, ResourceTable* table, io::IFileCollection* collection) { - return mergeImpl(src, table, collection, false /* overlay */, + return MergeImpl(src, table, collection, false /* overlay */, true /* allow new */); } -bool TableMerger::mergeOverlay(const Source& src, ResourceTable* table, +bool TableMerger::MergeOverlay(const Source& src, ResourceTable* table, io::IFileCollection* collection) { - return mergeImpl(src, table, collection, true /* overlay */, - mOptions.autoAddOverlay); + return MergeImpl(src, table, collection, true /* overlay */, + options_.auto_add_overlay); } /** * This will merge packages with the same package name (or no package name). */ -bool TableMerger::mergeImpl(const Source& src, ResourceTable* table, +bool TableMerger::MergeImpl(const Source& src, ResourceTable* table, io::IFileCollection* collection, bool overlay, - bool allowNew) { - const uint8_t desiredPackageId = mContext->getPackageId(); + bool allow_new) { + const uint8_t desired_package_id = context_->GetPackageId(); bool error = false; for (auto& package : table->packages) { // Warn of packages with an unrelated ID. const Maybe<ResourceId>& id = package->id; - if (id && id.value() != 0x0 && id.value() != desiredPackageId) { - mContext->getDiagnostics()->warn(DiagMessage(src) << "ignoring package " + if (id && id.value() != 0x0 && id.value() != desired_package_id) { + context_->GetDiagnostics()->Warn(DiagMessage(src) << "ignoring package " << package->name); continue; } @@ -70,22 +71,22 @@ bool TableMerger::mergeImpl(const Source& src, ResourceTable* table, // simply // uses of the attribute or definitions. if (package->name.empty() || - mContext->getCompilationPackage() == package->name) { + context_->GetCompilationPackage() == package->name) { FileMergeCallback callback; if (collection) { callback = [&](const ResourceNameRef& name, - const ConfigDescription& config, FileReference* newFile, - FileReference* oldFile) -> bool { + const ConfigDescription& config, FileReference* new_file, + FileReference* old_file) -> bool { // The old file's path points inside the APK, so we can use it as is. - io::IFile* f = collection->findFile(*oldFile->path); + io::IFile* f = collection->FindFile(*old_file->path); if (!f) { - mContext->getDiagnostics()->error(DiagMessage(src) - << "file '" << *oldFile->path + context_->GetDiagnostics()->Error(DiagMessage(src) + << "file '" << *old_file->path << "' not found"); return false; } - newFile->file = f; + new_file->file = f; return true; }; } @@ -95,8 +96,8 @@ bool TableMerger::mergeImpl(const Source& src, ResourceTable* table, // mangled, then looked up at resolution time. // Also, when linking, we convert references with no package name to use // the compilation package name. - error |= !doMerge(src, table, package.get(), false /* mangle */, overlay, - allowNew, callback); + error |= !DoMerge(src, table, package.get(), false /* mangle */, overlay, + allow_new, callback); } } return !error; @@ -105,86 +106,87 @@ bool TableMerger::mergeImpl(const Source& src, ResourceTable* table, /** * This will merge and mangle resources from a static library. */ -bool TableMerger::mergeAndMangle(const Source& src, - const StringPiece& packageName, +bool TableMerger::MergeAndMangle(const Source& src, + const StringPiece& package_name, ResourceTable* table, io::IFileCollection* collection) { bool error = false; for (auto& package : table->packages) { // Warn of packages with an unrelated ID. - if (packageName != package->name) { - mContext->getDiagnostics()->warn(DiagMessage(src) << "ignoring package " + if (package_name != package->name) { + context_->GetDiagnostics()->Warn(DiagMessage(src) << "ignoring package " << package->name); continue; } - bool mangle = packageName != mContext->getCompilationPackage(); - mMergedPackages.insert(package->name); + bool mangle = package_name != context_->GetCompilationPackage(); + merged_packages_.insert(package->name); - auto callback = [&](const ResourceNameRef& name, - const ConfigDescription& config, FileReference* newFile, - FileReference* oldFile) -> bool { + auto callback = [&]( + const ResourceNameRef& name, const ConfigDescription& config, + FileReference* new_file, FileReference* old_file) -> bool { // The old file's path points inside the APK, so we can use it as is. - io::IFile* f = collection->findFile(*oldFile->path); + io::IFile* f = collection->FindFile(*old_file->path); if (!f) { - mContext->getDiagnostics()->error( - DiagMessage(src) << "file '" << *oldFile->path << "' not found"); + context_->GetDiagnostics()->Error( + DiagMessage(src) << "file '" << *old_file->path << "' not found"); return false; } - newFile->file = f; + new_file->file = f; return true; }; - error |= !doMerge(src, table, package.get(), mangle, false /* overlay */, + error |= !DoMerge(src, table, package.get(), mangle, false /* overlay */, true /* allow new */, callback); } return !error; } -static bool mergeType(IAaptContext* context, const Source& src, - ResourceTableType* dstType, ResourceTableType* srcType) { - if (dstType->symbolStatus.state < srcType->symbolStatus.state) { +static bool MergeType(IAaptContext* context, const Source& src, + ResourceTableType* dst_type, + ResourceTableType* src_type) { + if (dst_type->symbol_status.state < src_type->symbol_status.state) { // The incoming type's visibility is stronger, so we should override // the visibility. - if (srcType->symbolStatus.state == SymbolState::kPublic) { + if (src_type->symbol_status.state == SymbolState::kPublic) { // Only copy the ID if the source is public, or else the ID is // meaningless. - dstType->id = srcType->id; + dst_type->id = src_type->id; } - dstType->symbolStatus = std::move(srcType->symbolStatus); - } else if (dstType->symbolStatus.state == SymbolState::kPublic && - srcType->symbolStatus.state == SymbolState::kPublic && - dstType->id && srcType->id && - dstType->id.value() != srcType->id.value()) { + dst_type->symbol_status = std::move(src_type->symbol_status); + } else if (dst_type->symbol_status.state == SymbolState::kPublic && + src_type->symbol_status.state == SymbolState::kPublic && + dst_type->id && src_type->id && + dst_type->id.value() != src_type->id.value()) { // Both types are public and have different IDs. - context->getDiagnostics()->error(DiagMessage(src) - << "cannot merge type '" << srcType->type + context->GetDiagnostics()->Error(DiagMessage(src) + << "cannot merge type '" << src_type->type << "': conflicting public IDs"); return false; } return true; } -static bool mergeEntry(IAaptContext* context, const Source& src, - ResourceEntry* dstEntry, ResourceEntry* srcEntry) { - if (dstEntry->symbolStatus.state < srcEntry->symbolStatus.state) { +static bool MergeEntry(IAaptContext* context, const Source& src, + ResourceEntry* dst_entry, ResourceEntry* src_entry) { + if (dst_entry->symbol_status.state < src_entry->symbol_status.state) { // The incoming type's visibility is stronger, so we should override // the visibility. - if (srcEntry->symbolStatus.state == SymbolState::kPublic) { + if (src_entry->symbol_status.state == SymbolState::kPublic) { // Only copy the ID if the source is public, or else the ID is // meaningless. - dstEntry->id = srcEntry->id; + dst_entry->id = src_entry->id; } - dstEntry->symbolStatus = std::move(srcEntry->symbolStatus); - } else if (srcEntry->symbolStatus.state == SymbolState::kPublic && - dstEntry->symbolStatus.state == SymbolState::kPublic && - dstEntry->id && srcEntry->id && - dstEntry->id.value() != srcEntry->id.value()) { + dst_entry->symbol_status = std::move(src_entry->symbol_status); + } else if (src_entry->symbol_status.state == SymbolState::kPublic && + dst_entry->symbol_status.state == SymbolState::kPublic && + dst_entry->id && src_entry->id && + dst_entry->id.value() != src_entry->id.value()) { // Both entries are public and have different IDs. - context->getDiagnostics()->error(DiagMessage(src) - << "cannot merge entry '" << srcEntry->name - << "': conflicting public IDs"); + context->GetDiagnostics()->Error( + DiagMessage(src) << "cannot merge entry '" << src_entry->name + << "': conflicting public IDs"); return false; } return true; @@ -199,141 +201,145 @@ static bool mergeEntry(IAaptContext* context, const Source& src, * and accumulate. If both values are Styleables, we just merge them into the * existing value. */ -static ResourceTable::CollisionResult resolveMergeCollision(Value* existing, +static ResourceTable::CollisionResult ResolveMergeCollision(Value* existing, Value* incoming) { - if (Styleable* existingStyleable = valueCast<Styleable>(existing)) { - if (Styleable* incomingStyleable = valueCast<Styleable>(incoming)) { + if (Styleable* existing_styleable = ValueCast<Styleable>(existing)) { + if (Styleable* incoming_styleable = ValueCast<Styleable>(incoming)) { // Styleables get merged. - existingStyleable->mergeWith(incomingStyleable); + existing_styleable->MergeWith(incoming_styleable); return ResourceTable::CollisionResult::kKeepOriginal; } } // Delegate to the default handler. - return ResourceTable::resolveValueCollision(existing, incoming); + return ResourceTable::ResolveValueCollision(existing, incoming); } -static ResourceTable::CollisionResult mergeConfigValue( - IAaptContext* context, const ResourceNameRef& resName, const bool overlay, - ResourceConfigValue* dstConfigValue, ResourceConfigValue* srcConfigValue) { +static ResourceTable::CollisionResult MergeConfigValue( + IAaptContext* context, const ResourceNameRef& res_name, const bool overlay, + ResourceConfigValue* dst_config_value, + ResourceConfigValue* src_config_value) { using CollisionResult = ResourceTable::CollisionResult; - Value* dstValue = dstConfigValue->value.get(); - Value* srcValue = srcConfigValue->value.get(); + Value* dst_value = dst_config_value->value.get(); + Value* src_value = src_config_value->value.get(); - CollisionResult collisionResult; + CollisionResult collision_result; if (overlay) { - collisionResult = resolveMergeCollision(dstValue, srcValue); + collision_result = ResolveMergeCollision(dst_value, src_value); } else { - collisionResult = ResourceTable::resolveValueCollision(dstValue, srcValue); + collision_result = + ResourceTable::ResolveValueCollision(dst_value, src_value); } - if (collisionResult == CollisionResult::kConflict) { + if (collision_result == CollisionResult::kConflict) { if (overlay) { return CollisionResult::kTakeNew; } // Error! - context->getDiagnostics()->error( - DiagMessage(srcValue->getSource()) - << "resource '" << resName << "' has a conflicting value for " - << "configuration (" << srcConfigValue->config << ")"); - context->getDiagnostics()->note(DiagMessage(dstValue->getSource()) + context->GetDiagnostics()->Error( + DiagMessage(src_value->GetSource()) + << "resource '" << res_name << "' has a conflicting value for " + << "configuration (" << src_config_value->config << ")"); + context->GetDiagnostics()->Note(DiagMessage(dst_value->GetSource()) << "originally defined here"); return CollisionResult::kConflict; } - return collisionResult; + return collision_result; } -bool TableMerger::doMerge(const Source& src, ResourceTable* srcTable, - ResourceTablePackage* srcPackage, - const bool manglePackage, const bool overlay, - const bool allowNewResources, +bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table, + ResourceTablePackage* src_package, + const bool mangle_package, const bool overlay, + const bool allow_new_resources, const FileMergeCallback& callback) { bool error = false; - for (auto& srcType : srcPackage->types) { - ResourceTableType* dstType = - mMasterPackage->findOrCreateType(srcType->type); - if (!mergeType(mContext, src, dstType, srcType.get())) { + for (auto& src_type : src_package->types) { + ResourceTableType* dst_type = + master_package_->FindOrCreateType(src_type->type); + if (!MergeType(context_, src, dst_type, src_type.get())) { error = true; continue; } - for (auto& srcEntry : srcType->entries) { - std::string entryName = srcEntry->name; - if (manglePackage) { - entryName = NameMangler::mangleEntry(srcPackage->name, srcEntry->name); + for (auto& src_entry : src_type->entries) { + std::string entry_name = src_entry->name; + if (mangle_package) { + entry_name = + NameMangler::MangleEntry(src_package->name, src_entry->name); } - ResourceEntry* dstEntry; - if (allowNewResources) { - dstEntry = dstType->findOrCreateEntry(entryName); + ResourceEntry* dst_entry; + if (allow_new_resources) { + dst_entry = dst_type->FindOrCreateEntry(entry_name); } else { - dstEntry = dstType->findEntry(entryName); + dst_entry = dst_type->FindEntry(entry_name); } - const ResourceNameRef resName(srcPackage->name, srcType->type, - srcEntry->name); + const ResourceNameRef res_name(src_package->name, src_type->type, + src_entry->name); - if (!dstEntry) { - mContext->getDiagnostics()->error( - DiagMessage(src) << "resource " << resName + if (!dst_entry) { + context_->GetDiagnostics()->Error( + DiagMessage(src) << "resource " << res_name << " does not override an existing resource"); - mContext->getDiagnostics()->note( + context_->GetDiagnostics()->Note( DiagMessage(src) << "define an <add-resource> tag or use " << "--auto-add-overlay"); error = true; continue; } - if (!mergeEntry(mContext, src, dstEntry, srcEntry.get())) { + if (!MergeEntry(context_, src, dst_entry, src_entry.get())) { error = true; continue; } - for (auto& srcConfigValue : srcEntry->values) { + for (auto& src_config_value : src_entry->values) { using CollisionResult = ResourceTable::CollisionResult; - ResourceConfigValue* dstConfigValue = dstEntry->findValue( - srcConfigValue->config, srcConfigValue->product); - if (dstConfigValue) { - CollisionResult collisionResult = mergeConfigValue( - mContext, resName, overlay, dstConfigValue, srcConfigValue.get()); - if (collisionResult == CollisionResult::kConflict) { + ResourceConfigValue* dst_config_value = dst_entry->FindValue( + src_config_value->config, src_config_value->product); + if (dst_config_value) { + CollisionResult collision_result = + MergeConfigValue(context_, res_name, overlay, dst_config_value, + src_config_value.get()); + if (collision_result == CollisionResult::kConflict) { error = true; continue; - } else if (collisionResult == CollisionResult::kKeepOriginal) { + } else if (collision_result == CollisionResult::kKeepOriginal) { continue; } } else { - dstConfigValue = dstEntry->findOrCreateValue(srcConfigValue->config, - srcConfigValue->product); + dst_config_value = dst_entry->FindOrCreateValue( + src_config_value->config, src_config_value->product); } // Continue if we're taking the new resource. if (FileReference* f = - valueCast<FileReference>(srcConfigValue->value.get())) { - std::unique_ptr<FileReference> newFileRef; - if (manglePackage) { - newFileRef = cloneAndMangleFile(srcPackage->name, *f); + ValueCast<FileReference>(src_config_value->value.get())) { + std::unique_ptr<FileReference> new_file_ref; + if (mangle_package) { + new_file_ref = CloneAndMangleFile(src_package->name, *f); } else { - newFileRef = std::unique_ptr<FileReference>( - f->clone(&mMasterTable->stringPool)); + new_file_ref = std::unique_ptr<FileReference>( + f->Clone(&master_table_->string_pool)); } if (callback) { - if (!callback(resName, srcConfigValue->config, newFileRef.get(), - f)) { + if (!callback(res_name, src_config_value->config, + new_file_ref.get(), f)) { error = true; continue; } } - dstConfigValue->value = std::move(newFileRef); + dst_config_value->value = std::move(new_file_ref); } else { - dstConfigValue->value = std::unique_ptr<Value>( - srcConfigValue->value->clone(&mMasterTable->stringPool)); + dst_config_value->value = std::unique_ptr<Value>( + src_config_value->value->Clone(&master_table_->string_pool)); } } } @@ -341,50 +347,50 @@ bool TableMerger::doMerge(const Source& src, ResourceTable* srcTable, return !error; } -std::unique_ptr<FileReference> TableMerger::cloneAndMangleFile( - const std::string& package, const FileReference& fileRef) { +std::unique_ptr<FileReference> TableMerger::CloneAndMangleFile( + const std::string& package, const FileReference& file_ref) { StringPiece prefix, entry, suffix; - if (util::extractResFilePathParts(*fileRef.path, &prefix, &entry, &suffix)) { - std::string mangledEntry = - NameMangler::mangleEntry(package, entry.toString()); - std::string newPath = prefix.toString() + mangledEntry + suffix.toString(); - std::unique_ptr<FileReference> newFileRef = + if (util::ExtractResFilePathParts(*file_ref.path, &prefix, &entry, &suffix)) { + std::string mangled_entry = + NameMangler::MangleEntry(package, entry.ToString()); + std::string newPath = prefix.ToString() + mangled_entry + suffix.ToString(); + std::unique_ptr<FileReference> new_file_ref = util::make_unique<FileReference>( - mMasterTable->stringPool.makeRef(newPath)); - newFileRef->setComment(fileRef.getComment()); - newFileRef->setSource(fileRef.getSource()); - return newFileRef; + master_table_->string_pool.MakeRef(newPath)); + new_file_ref->SetComment(file_ref.GetComment()); + new_file_ref->SetSource(file_ref.GetSource()); + return new_file_ref; } return std::unique_ptr<FileReference>( - fileRef.clone(&mMasterTable->stringPool)); + file_ref.Clone(&master_table_->string_pool)); } -bool TableMerger::mergeFileImpl(const ResourceFile& fileDesc, io::IFile* file, +bool TableMerger::MergeFileImpl(const ResourceFile& file_desc, io::IFile* file, bool overlay) { ResourceTable table; - std::string path = ResourceUtils::buildResourceFileName(fileDesc, nullptr); - std::unique_ptr<FileReference> fileRef = - util::make_unique<FileReference>(table.stringPool.makeRef(path)); - fileRef->setSource(fileDesc.source); - fileRef->file = file; - - ResourceTablePackage* pkg = table.createPackage(fileDesc.name.package, 0x0); - pkg->findOrCreateType(fileDesc.name.type) - ->findOrCreateEntry(fileDesc.name.entry) - ->findOrCreateValue(fileDesc.config, {}) - ->value = std::move(fileRef); - - return doMerge(file->getSource(), &table, pkg, false /* mangle */, - overlay /* overlay */, true /* allow new */, {}); + std::string path = ResourceUtils::BuildResourceFileName(file_desc); + std::unique_ptr<FileReference> file_ref = + util::make_unique<FileReference>(table.string_pool.MakeRef(path)); + file_ref->SetSource(file_desc.source); + file_ref->file = file; + + ResourceTablePackage* pkg = table.CreatePackage(file_desc.name.package, 0x0); + pkg->FindOrCreateType(file_desc.name.type) + ->FindOrCreateEntry(file_desc.name.entry) + ->FindOrCreateValue(file_desc.config, {}) + ->value = std::move(file_ref); + + return DoMerge(file->GetSource(), &table, pkg, false /* mangle */, + overlay /* overlay */, true /* allow_new */, {}); } -bool TableMerger::mergeFile(const ResourceFile& fileDesc, io::IFile* file) { - return mergeFileImpl(fileDesc, file, false /* overlay */); +bool TableMerger::MergeFile(const ResourceFile& file_desc, io::IFile* file) { + return MergeFileImpl(file_desc, file, false /* overlay */); } -bool TableMerger::mergeFileOverlay(const ResourceFile& fileDesc, +bool TableMerger::MergeFileOverlay(const ResourceFile& file_desc, io::IFile* file) { - return mergeFileImpl(fileDesc, file, true /* overlay */); + return MergeFileImpl(file_desc, file, true /* overlay */); } } // namespace aapt diff --git a/tools/aapt2/link/TableMerger.h b/tools/aapt2/link/TableMerger.h index c2e7181692d4..4ab83c3f2de3 100644 --- a/tools/aapt2/link/TableMerger.h +++ b/tools/aapt2/link/TableMerger.h @@ -17,6 +17,11 @@ #ifndef AAPT_TABLEMERGER_H #define AAPT_TABLEMERGER_H +#include <functional> +#include <map> + +#include "android-base/macros.h" + #include "Resource.h" #include "ResourceTable.h" #include "ResourceValues.h" @@ -25,9 +30,6 @@ #include "process/IResourceTableConsumer.h" #include "util/Util.h" -#include <functional> -#include <map> - namespace aapt { struct TableMergerOptions { @@ -35,7 +37,7 @@ struct TableMergerOptions { * If true, resources in overlays can be added without previously having * existed. */ - bool autoAddOverlay = false; + bool auto_add_overlay = false; }; /** @@ -62,15 +64,14 @@ struct TableMergerOptions { class TableMerger { public: /** - * Note: The outTable ResourceTable must live longer than this TableMerger. - * References - * are made to this ResourceTable for efficiency reasons. + * Note: The out_table ResourceTable must live longer than this TableMerger. + * References are made to this ResourceTable for efficiency reasons. */ - TableMerger(IAaptContext* context, ResourceTable* outTable, + TableMerger(IAaptContext* context, ResourceTable* out_table, const TableMergerOptions& options); - const std::set<std::string>& getMergedPackages() const { - return mMergedPackages; + const std::set<std::string>& merged_packages() const { + return merged_packages_; } /** @@ -78,7 +79,7 @@ class TableMerger { * An io::IFileCollection is optional and used to find the referenced Files * and process them. */ - bool merge(const Source& src, ResourceTable* table, + bool Merge(const Source& src, ResourceTable* table, io::IFileCollection* collection = nullptr); /** @@ -86,7 +87,7 @@ class TableMerger { * An io::IFileCollection is optional and used to find the referenced Files * and process them. */ - bool mergeOverlay(const Source& src, ResourceTable* table, + bool MergeOverlay(const Source& src, ResourceTable* table, io::IFileCollection* collection = nullptr); /** @@ -95,44 +96,45 @@ class TableMerger { * An io::IFileCollection is needed in order to find the referenced Files and * process them. */ - bool mergeAndMangle(const Source& src, const StringPiece& package, + bool MergeAndMangle(const Source& src, const StringPiece& package, ResourceTable* table, io::IFileCollection* collection); /** * Merges a compiled file that belongs to this same or empty package. This is * for local sources. */ - bool mergeFile(const ResourceFile& fileDesc, io::IFile* file); + bool MergeFile(const ResourceFile& fileDesc, io::IFile* file); /** * Merges a compiled file from an overlay, overriding an existing definition. */ - bool mergeFileOverlay(const ResourceFile& fileDesc, io::IFile* file); + bool MergeFileOverlay(const ResourceFile& fileDesc, io::IFile* file); private: + DISALLOW_COPY_AND_ASSIGN(TableMerger); + using FileMergeCallback = std::function<bool(const ResourceNameRef&, const ConfigDescription& config, FileReference*, FileReference*)>; - IAaptContext* mContext; - ResourceTable* mMasterTable; - TableMergerOptions mOptions; - ResourceTablePackage* mMasterPackage; - - std::set<std::string> mMergedPackages; + IAaptContext* context_; + ResourceTable* master_table_; + TableMergerOptions options_; + ResourceTablePackage* master_package_; + std::set<std::string> merged_packages_; - bool mergeFileImpl(const ResourceFile& fileDesc, io::IFile* file, + bool MergeFileImpl(const ResourceFile& file_desc, io::IFile* file, bool overlay); - bool mergeImpl(const Source& src, ResourceTable* srcTable, - io::IFileCollection* collection, bool overlay, bool allowNew); + bool MergeImpl(const Source& src, ResourceTable* src_table, + io::IFileCollection* collection, bool overlay, bool allow_new); - bool doMerge(const Source& src, ResourceTable* srcTable, - ResourceTablePackage* srcPackage, const bool manglePackage, - const bool overlay, const bool allowNewResources, + bool DoMerge(const Source& src, ResourceTable* src_table, + ResourceTablePackage* src_package, const bool mangle_package, + const bool overlay, const bool allow_new_resources, const FileMergeCallback& callback); - std::unique_ptr<FileReference> cloneAndMangleFile(const std::string& package, + std::unique_ptr<FileReference> CloneAndMangleFile(const std::string& package, const FileReference& value); }; diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp index e0b2b6615d28..742f5a7a570a 100644 --- a/tools/aapt2/link/TableMerger_test.cpp +++ b/tools/aapt2/link/TableMerger_test.cpp @@ -15,139 +15,137 @@ */ #include "link/TableMerger.h" + #include "filter/ConfigFilter.h" #include "io/FileSystem.h" -#include "test/Builders.h" -#include "test/Context.h" - -#include <gtest/gtest.h> +#include "test/Test.h" namespace aapt { struct TableMergerTest : public ::testing::Test { - std::unique_ptr<IAaptContext> mContext; + std::unique_ptr<IAaptContext> context_; void SetUp() override { - mContext = + context_ = test::ContextBuilder() // We are compiling this package. - .setCompilationPackage("com.app.a") + .SetCompilationPackage("com.app.a") // Merge all packages that have this package ID. - .setPackageId(0x7f) + .SetPackageId(0x7f) // Mangle all packages that do not have this package name. - .setNameManglerPolicy(NameManglerPolicy{"com.app.a", {"com.app.b"}}) + .SetNameManglerPolicy(NameManglerPolicy{"com.app.a", {"com.app.b"}}) - .build(); + .Build(); } }; TEST_F(TableMergerTest, SimpleMerge) { - std::unique_ptr<ResourceTable> tableA = + std::unique_ptr<ResourceTable> table_a = test::ResourceTableBuilder() - .setPackageId("com.app.a", 0x7f) - .addReference("com.app.a:id/foo", "com.app.a:id/bar") - .addReference("com.app.a:id/bar", "com.app.b:id/foo") - .addValue( + .SetPackageId("com.app.a", 0x7f) + .AddReference("com.app.a:id/foo", "com.app.a:id/bar") + .AddReference("com.app.a:id/bar", "com.app.b:id/foo") + .AddValue( "com.app.a:styleable/view", - test::StyleableBuilder().addItem("com.app.b:id/foo").build()) - .build(); + test::StyleableBuilder().AddItem("com.app.b:id/foo").Build()) + .Build(); - std::unique_ptr<ResourceTable> tableB = test::ResourceTableBuilder() - .setPackageId("com.app.b", 0x7f) - .addSimple("com.app.b:id/foo") - .build(); + std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder() + .SetPackageId("com.app.b", 0x7f) + .AddSimple("com.app.b:id/foo") + .Build(); - ResourceTable finalTable; - TableMerger merger(mContext.get(), &finalTable, TableMergerOptions{}); + ResourceTable final_table; + TableMerger merger(context_.get(), &final_table, TableMergerOptions{}); io::FileCollection collection; - ASSERT_TRUE(merger.merge({}, tableA.get())); + ASSERT_TRUE(merger.Merge({}, table_a.get())); ASSERT_TRUE( - merger.mergeAndMangle({}, "com.app.b", tableB.get(), &collection)); + merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection)); - EXPECT_TRUE(merger.getMergedPackages().count("com.app.b") != 0); + EXPECT_TRUE(merger.merged_packages().count("com.app.b") != 0); // Entries from com.app.a should not be mangled. AAPT_EXPECT_TRUE( - finalTable.findResource(test::parseNameOrDie("com.app.a:id/foo"))); + final_table.FindResource(test::ParseNameOrDie("com.app.a:id/foo"))); AAPT_EXPECT_TRUE( - finalTable.findResource(test::parseNameOrDie("com.app.a:id/bar"))); - AAPT_EXPECT_TRUE(finalTable.findResource( - test::parseNameOrDie("com.app.a:styleable/view"))); + final_table.FindResource(test::ParseNameOrDie("com.app.a:id/bar"))); + AAPT_EXPECT_TRUE(final_table.FindResource( + test::ParseNameOrDie("com.app.a:styleable/view"))); // The unmangled name should not be present. AAPT_EXPECT_FALSE( - finalTable.findResource(test::parseNameOrDie("com.app.b:id/foo"))); + final_table.FindResource(test::ParseNameOrDie("com.app.b:id/foo"))); // Look for the mangled name. - AAPT_EXPECT_TRUE(finalTable.findResource( - test::parseNameOrDie("com.app.a:id/com.app.b$foo"))); + AAPT_EXPECT_TRUE(final_table.FindResource( + test::ParseNameOrDie("com.app.a:id/com.app.b$foo"))); } TEST_F(TableMergerTest, MergeFile) { - ResourceTable finalTable; + ResourceTable final_table; TableMergerOptions options; - options.autoAddOverlay = false; - TableMerger merger(mContext.get(), &finalTable, options); + options.auto_add_overlay = false; + TableMerger merger(context_.get(), &final_table, options); - ResourceFile fileDesc; - fileDesc.config = test::parseConfigOrDie("hdpi-v4"); - fileDesc.name = test::parseNameOrDie("layout/main"); - fileDesc.source = Source("res/layout-hdpi/main.xml"); - test::TestFile testFile("path/to/res/layout-hdpi/main.xml.flat"); + ResourceFile file_desc; + file_desc.config = test::ParseConfigOrDie("hdpi-v4"); + file_desc.name = test::ParseNameOrDie("layout/main"); + file_desc.source = Source("res/layout-hdpi/main.xml"); + test::TestFile test_file("path/to/res/layout-hdpi/main.xml.flat"); - ASSERT_TRUE(merger.mergeFile(fileDesc, &testFile)); + ASSERT_TRUE(merger.MergeFile(file_desc, &test_file)); - FileReference* file = test::getValueForConfig<FileReference>( - &finalTable, "com.app.a:layout/main", test::parseConfigOrDie("hdpi-v4")); + FileReference* file = test::GetValueForConfig<FileReference>( + &final_table, "com.app.a:layout/main", test::ParseConfigOrDie("hdpi-v4")); ASSERT_NE(nullptr, file); EXPECT_EQ(std::string("res/layout-hdpi-v4/main.xml"), *file->path); } TEST_F(TableMergerTest, MergeFileOverlay) { - ResourceTable finalTable; - TableMergerOptions tableMergerOptions; - tableMergerOptions.autoAddOverlay = false; - TableMerger merger(mContext.get(), &finalTable, tableMergerOptions); - - ResourceFile fileDesc; - fileDesc.name = test::parseNameOrDie("xml/foo"); - test::TestFile fileA("path/to/fileA.xml.flat"); - test::TestFile fileB("path/to/fileB.xml.flat"); - - ASSERT_TRUE(merger.mergeFile(fileDesc, &fileA)); - ASSERT_TRUE(merger.mergeFileOverlay(fileDesc, &fileB)); + ResourceTable final_table; + TableMergerOptions options; + options.auto_add_overlay = false; + TableMerger merger(context_.get(), &final_table, options); + + ResourceFile file_desc; + file_desc.name = test::ParseNameOrDie("xml/foo"); + test::TestFile file_a("path/to/fileA.xml.flat"); + test::TestFile file_b("path/to/fileB.xml.flat"); + + ASSERT_TRUE(merger.MergeFile(file_desc, &file_a)); + ASSERT_TRUE(merger.MergeFileOverlay(file_desc, &file_b)); } TEST_F(TableMergerTest, MergeFileReferences) { - std::unique_ptr<ResourceTable> tableA = + std::unique_ptr<ResourceTable> table_a = test::ResourceTableBuilder() - .setPackageId("com.app.a", 0x7f) - .addFileReference("com.app.a:xml/file", "res/xml/file.xml") - .build(); - std::unique_ptr<ResourceTable> tableB = + .SetPackageId("com.app.a", 0x7f) + .AddFileReference("com.app.a:xml/file", "res/xml/file.xml") + .Build(); + std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder() - .setPackageId("com.app.b", 0x7f) - .addFileReference("com.app.b:xml/file", "res/xml/file.xml") - .build(); + .SetPackageId("com.app.b", 0x7f) + .AddFileReference("com.app.b:xml/file", "res/xml/file.xml") + .Build(); - ResourceTable finalTable; - TableMerger merger(mContext.get(), &finalTable, TableMergerOptions{}); + ResourceTable final_table; + TableMerger merger(context_.get(), &final_table, TableMergerOptions{}); io::FileCollection collection; - collection.insertFile("res/xml/file.xml"); + collection.InsertFile("res/xml/file.xml"); - ASSERT_TRUE(merger.merge({}, tableA.get())); + ASSERT_TRUE(merger.Merge({}, table_a.get())); ASSERT_TRUE( - merger.mergeAndMangle({}, "com.app.b", tableB.get(), &collection)); + merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection)); FileReference* f = - test::getValue<FileReference>(&finalTable, "com.app.a:xml/file"); + test::GetValue<FileReference>(&final_table, "com.app.a:xml/file"); ASSERT_NE(f, nullptr); EXPECT_EQ(std::string("res/xml/file.xml"), *f->path); - f = test::getValue<FileReference>(&finalTable, + f = test::GetValue<FileReference>(&final_table, "com.app.a:xml/com.app.b$file"); ASSERT_NE(f, nullptr); EXPECT_EQ(std::string("res/xml/com.app.b$file.xml"), *f->path); @@ -156,25 +154,25 @@ TEST_F(TableMergerTest, MergeFileReferences) { TEST_F(TableMergerTest, OverrideResourceWithOverlay) { std::unique_ptr<ResourceTable> base = test::ResourceTableBuilder() - .setPackageId("", 0x00) - .addValue("bool/foo", ResourceUtils::tryParseBool("true")) - .build(); + .SetPackageId("", 0x00) + .AddValue("bool/foo", ResourceUtils::TryParseBool("true")) + .Build(); std::unique_ptr<ResourceTable> overlay = test::ResourceTableBuilder() - .setPackageId("", 0x00) - .addValue("bool/foo", ResourceUtils::tryParseBool("false")) - .build(); + .SetPackageId("", 0x00) + .AddValue("bool/foo", ResourceUtils::TryParseBool("false")) + .Build(); - ResourceTable finalTable; - TableMergerOptions tableMergerOptions; - tableMergerOptions.autoAddOverlay = false; - TableMerger merger(mContext.get(), &finalTable, tableMergerOptions); + ResourceTable final_table; + TableMergerOptions options; + options.auto_add_overlay = false; + TableMerger merger(context_.get(), &final_table, options); - ASSERT_TRUE(merger.merge({}, base.get())); - ASSERT_TRUE(merger.mergeOverlay({}, overlay.get())); + ASSERT_TRUE(merger.Merge({}, base.get())); + ASSERT_TRUE(merger.MergeOverlay({}, overlay.get())); BinaryPrimitive* foo = - test::getValue<BinaryPrimitive>(&finalTable, "com.app.a:bool/foo"); + test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo"); ASSERT_NE(nullptr, foo); EXPECT_EQ(0x0u, foo->value.data); } @@ -182,170 +180,168 @@ TEST_F(TableMergerTest, OverrideResourceWithOverlay) { TEST_F(TableMergerTest, OverrideSameResourceIdsWithOverlay) { std::unique_ptr<ResourceTable> base = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), + .SetPackageId("", 0x7f) + .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), SymbolState::kPublic) - .build(); + .Build(); std::unique_ptr<ResourceTable> overlay = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), + .SetPackageId("", 0x7f) + .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), SymbolState::kPublic) - .build(); + .Build(); - ResourceTable finalTable; - TableMergerOptions tableMergerOptions; - tableMergerOptions.autoAddOverlay = false; - TableMerger merger(mContext.get(), &finalTable, tableMergerOptions); + ResourceTable final_table; + TableMergerOptions options; + options.auto_add_overlay = false; + TableMerger merger(context_.get(), &final_table, options); - ASSERT_TRUE(merger.merge({}, base.get())); - ASSERT_TRUE(merger.mergeOverlay({}, overlay.get())); + ASSERT_TRUE(merger.Merge({}, base.get())); + ASSERT_TRUE(merger.MergeOverlay({}, overlay.get())); } TEST_F(TableMergerTest, FailToOverrideConflictingTypeIdsWithOverlay) { std::unique_ptr<ResourceTable> base = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), + .SetPackageId("", 0x7f) + .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), SymbolState::kPublic) - .build(); + .Build(); std::unique_ptr<ResourceTable> overlay = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .setSymbolState("bool/foo", ResourceId(0x7f, 0x02, 0x0001), + .SetPackageId("", 0x7f) + .SetSymbolState("bool/foo", ResourceId(0x7f, 0x02, 0x0001), SymbolState::kPublic) - .build(); + .Build(); - ResourceTable finalTable; - TableMergerOptions tableMergerOptions; - tableMergerOptions.autoAddOverlay = false; - TableMerger merger(mContext.get(), &finalTable, tableMergerOptions); + ResourceTable final_table; + TableMergerOptions options; + options.auto_add_overlay = false; + TableMerger merger(context_.get(), &final_table, options); - ASSERT_TRUE(merger.merge({}, base.get())); - ASSERT_FALSE(merger.mergeOverlay({}, overlay.get())); + ASSERT_TRUE(merger.Merge({}, base.get())); + ASSERT_FALSE(merger.MergeOverlay({}, overlay.get())); } TEST_F(TableMergerTest, FailToOverrideConflictingEntryIdsWithOverlay) { std::unique_ptr<ResourceTable> base = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), + .SetPackageId("", 0x7f) + .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0001), SymbolState::kPublic) - .build(); + .Build(); std::unique_ptr<ResourceTable> overlay = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .setSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0002), + .SetPackageId("", 0x7f) + .SetSymbolState("bool/foo", ResourceId(0x7f, 0x01, 0x0002), SymbolState::kPublic) - .build(); + .Build(); - ResourceTable finalTable; - TableMergerOptions tableMergerOptions; - tableMergerOptions.autoAddOverlay = false; - TableMerger merger(mContext.get(), &finalTable, tableMergerOptions); + ResourceTable final_table; + TableMergerOptions options; + options.auto_add_overlay = false; + TableMerger merger(context_.get(), &final_table, options); - ASSERT_TRUE(merger.merge({}, base.get())); - ASSERT_FALSE(merger.mergeOverlay({}, overlay.get())); + ASSERT_TRUE(merger.Merge({}, base.get())); + ASSERT_FALSE(merger.MergeOverlay({}, overlay.get())); } TEST_F(TableMergerTest, MergeAddResourceFromOverlay) { - std::unique_ptr<ResourceTable> tableA = + std::unique_ptr<ResourceTable> table_a = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .setSymbolState("bool/foo", {}, SymbolState::kUndefined) - .build(); - std::unique_ptr<ResourceTable> tableB = + .SetPackageId("", 0x7f) + .SetSymbolState("bool/foo", {}, SymbolState::kUndefined) + .Build(); + std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .addValue("bool/foo", ResourceUtils::tryParseBool("true")) - .build(); + .SetPackageId("", 0x7f) + .AddValue("bool/foo", ResourceUtils::TryParseBool("true")) + .Build(); - ResourceTable finalTable; - TableMerger merger(mContext.get(), &finalTable, TableMergerOptions{}); + ResourceTable final_table; + TableMerger merger(context_.get(), &final_table, TableMergerOptions{}); - ASSERT_TRUE(merger.merge({}, tableA.get())); - ASSERT_TRUE(merger.mergeOverlay({}, tableB.get())); + ASSERT_TRUE(merger.Merge({}, table_a.get())); + ASSERT_TRUE(merger.MergeOverlay({}, table_b.get())); } TEST_F(TableMergerTest, MergeAddResourceFromOverlayWithAutoAddOverlay) { - std::unique_ptr<ResourceTable> tableA = - test::ResourceTableBuilder().setPackageId("", 0x7f).build(); - std::unique_ptr<ResourceTable> tableB = + std::unique_ptr<ResourceTable> table_a = + test::ResourceTableBuilder().SetPackageId("", 0x7f).Build(); + std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .addValue("bool/foo", ResourceUtils::tryParseBool("true")) - .build(); + .SetPackageId("", 0x7f) + .AddValue("bool/foo", ResourceUtils::TryParseBool("true")) + .Build(); - ResourceTable finalTable; + ResourceTable final_table; TableMergerOptions options; - options.autoAddOverlay = true; - TableMerger merger(mContext.get(), &finalTable, options); + options.auto_add_overlay = true; + TableMerger merger(context_.get(), &final_table, options); - ASSERT_TRUE(merger.merge({}, tableA.get())); - ASSERT_TRUE(merger.mergeOverlay({}, tableB.get())); + ASSERT_TRUE(merger.Merge({}, table_a.get())); + ASSERT_TRUE(merger.MergeOverlay({}, table_b.get())); } TEST_F(TableMergerTest, FailToMergeNewResourceWithoutAutoAddOverlay) { - std::unique_ptr<ResourceTable> tableA = - test::ResourceTableBuilder().setPackageId("", 0x7f).build(); - std::unique_ptr<ResourceTable> tableB = + std::unique_ptr<ResourceTable> table_a = + test::ResourceTableBuilder().SetPackageId("", 0x7f).Build(); + std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder() - .setPackageId("", 0x7f) - .addValue("bool/foo", ResourceUtils::tryParseBool("true")) - .build(); + .SetPackageId("", 0x7f) + .AddValue("bool/foo", ResourceUtils::TryParseBool("true")) + .Build(); - ResourceTable finalTable; + ResourceTable final_table; TableMergerOptions options; - options.autoAddOverlay = false; - TableMerger merger(mContext.get(), &finalTable, options); + options.auto_add_overlay = false; + TableMerger merger(context_.get(), &final_table, options); - ASSERT_TRUE(merger.merge({}, tableA.get())); - ASSERT_FALSE(merger.mergeOverlay({}, tableB.get())); + ASSERT_TRUE(merger.Merge({}, table_a.get())); + ASSERT_FALSE(merger.MergeOverlay({}, table_b.get())); } TEST_F(TableMergerTest, OverlaidStyleablesShouldBeMerged) { - std::unique_ptr<ResourceTable> tableA = + std::unique_ptr<ResourceTable> table_a = test::ResourceTableBuilder() - .setPackageId("com.app.a", 0x7f) - .addValue("com.app.a:styleable/Foo", + .SetPackageId("com.app.a", 0x7f) + .AddValue("com.app.a:styleable/Foo", test::StyleableBuilder() - .addItem("com.app.a:attr/bar") - .addItem("com.app.a:attr/foo", ResourceId(0x01010000)) - .build()) - .build(); + .AddItem("com.app.a:attr/bar") + .AddItem("com.app.a:attr/foo", ResourceId(0x01010000)) + .Build()) + .Build(); - std::unique_ptr<ResourceTable> tableB = + std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder() - .setPackageId("com.app.a", 0x7f) - .addValue("com.app.a:styleable/Foo", + .SetPackageId("com.app.a", 0x7f) + .AddValue("com.app.a:styleable/Foo", test::StyleableBuilder() - .addItem("com.app.a:attr/bat") - .addItem("com.app.a:attr/foo") - .build()) - .build(); + .AddItem("com.app.a:attr/bat") + .AddItem("com.app.a:attr/foo") + .Build()) + .Build(); - ResourceTable finalTable; + ResourceTable final_table; TableMergerOptions options; - options.autoAddOverlay = true; - TableMerger merger(mContext.get(), &finalTable, options); - - ASSERT_TRUE(merger.merge({}, tableA.get())); - ASSERT_TRUE(merger.mergeOverlay({}, tableB.get())); + options.auto_add_overlay = true; + TableMerger merger(context_.get(), &final_table, options); - Debug::printTable(&finalTable, {}); + ASSERT_TRUE(merger.Merge({}, table_a.get())); + ASSERT_TRUE(merger.MergeOverlay({}, table_b.get())); Styleable* styleable = - test::getValue<Styleable>(&finalTable, "com.app.a:styleable/Foo"); + test::GetValue<Styleable>(&final_table, "com.app.a:styleable/Foo"); ASSERT_NE(nullptr, styleable); - std::vector<Reference> expectedRefs = { - Reference(test::parseNameOrDie("com.app.a:attr/bar")), - Reference(test::parseNameOrDie("com.app.a:attr/bat")), - Reference(test::parseNameOrDie("com.app.a:attr/foo"), + std::vector<Reference> expected_refs = { + Reference(test::ParseNameOrDie("com.app.a:attr/bar")), + Reference(test::ParseNameOrDie("com.app.a:attr/bat")), + Reference(test::ParseNameOrDie("com.app.a:attr/foo"), ResourceId(0x01010000)), }; - EXPECT_EQ(expectedRefs, styleable->entries); + EXPECT_EQ(expected_refs, styleable->entries); } } // namespace aapt diff --git a/tools/aapt2/link/VersionCollapser.cpp b/tools/aapt2/link/VersionCollapser.cpp index 61a1f86028c6..3df58994333f 100644 --- a/tools/aapt2/link/VersionCollapser.cpp +++ b/tools/aapt2/link/VersionCollapser.cpp @@ -14,50 +14,51 @@ * limitations under the License. */ -#include "ResourceTable.h" #include "link/Linkers.h" #include <algorithm> #include <vector> +#include "ResourceTable.h" + namespace aapt { template <typename Iterator, typename Pred> class FilterIterator { public: FilterIterator(Iterator begin, Iterator end, Pred pred = Pred()) - : mCurrent(begin), mEnd(end), mPred(pred) { - advance(); + : current_(begin), end_(end), pred_(pred) { + Advance(); } - bool hasNext() { return mCurrent != mEnd; } + bool HasNext() { return current_ != end_; } - Iterator nextIter() { - Iterator iter = mCurrent; - ++mCurrent; - advance(); + Iterator NextIter() { + Iterator iter = current_; + ++current_; + Advance(); return iter; } - typename Iterator::reference next() { return *nextIter(); } + typename Iterator::reference Next() { return *NextIter(); } private: - void advance() { - for (; mCurrent != mEnd; ++mCurrent) { - if (mPred(*mCurrent)) { + void Advance() { + for (; current_ != end_; ++current_) { + if (pred_(*current_)) { return; } } } - Iterator mCurrent, mEnd; - Pred mPred; + Iterator current_, end_; + Pred pred_; }; template <typename Iterator, typename Pred> -FilterIterator<Iterator, Pred> makeFilterIterator(Iterator begin, - Iterator end = Iterator(), - Pred pred = Pred()) { +FilterIterator<Iterator, Pred> make_filter_iterator(Iterator begin, + Iterator end = Iterator(), + Pred pred = Pred()) { return FilterIterator<Iterator, Pred>(begin, end, pred); } @@ -68,7 +69,7 @@ FilterIterator<Iterator, Pred> makeFilterIterator(Iterator begin, * next smallest * one will be kept. */ -static void collapseVersions(int minSdk, ResourceEntry* entry) { +static void CollapseVersions(int min_sdk, ResourceEntry* entry) { // First look for all sdks less than minSdk. for (auto iter = entry->values.rbegin(); iter != entry->values.rend(); ++iter) { @@ -78,15 +79,14 @@ static void collapseVersions(int minSdk, ResourceEntry* entry) { } const ConfigDescription& config = (*iter)->config; - if (config.sdkVersion <= minSdk) { + if (config.sdkVersion <= min_sdk) { // This is the first configuration we've found with a smaller or equal SDK // level // to the minimum. We MUST keep this one, but remove all others we find, // which get // overridden by this one. - ConfigDescription configWithoutSdk = config; - configWithoutSdk.sdkVersion = 0; + ConfigDescription config_without_sdk = config.CopyWithoutSdkVersion(); auto pred = [&](const std::unique_ptr<ResourceConfigValue>& val) -> bool { // Check that the value hasn't already been marked for removal. if (!val) { @@ -94,16 +94,16 @@ static void collapseVersions(int minSdk, ResourceEntry* entry) { } // Only return Configs that differ in SDK version. - configWithoutSdk.sdkVersion = val->config.sdkVersion; - return configWithoutSdk == val->config && - val->config.sdkVersion <= minSdk; + config_without_sdk.sdkVersion = val->config.sdkVersion; + return config_without_sdk == val->config && + val->config.sdkVersion <= min_sdk; }; // Remove the rest that match. - auto filterIter = - makeFilterIterator(iter + 1, entry->values.rend(), pred); - while (filterIter.hasNext()) { - filterIter.next() = {}; + auto filter_iter = + make_filter_iterator(iter + 1, entry->values.rend(), pred); + while (filter_iter.HasNext()) { + filter_iter.Next() = {}; } } } @@ -121,16 +121,16 @@ static void collapseVersions(int minSdk, ResourceEntry* entry) { // struct // and take up less space in the resources.arsc table. bool modified = false; - for (std::unique_ptr<ResourceConfigValue>& configValue : entry->values) { - if (configValue->config.sdkVersion != 0 && - configValue->config.sdkVersion <= minSdk) { + for (std::unique_ptr<ResourceConfigValue>& config_value : entry->values) { + if (config_value->config.sdkVersion != 0 && + config_value->config.sdkVersion <= min_sdk) { // Override the resource with a Configuration without an SDK. - std::unique_ptr<ResourceConfigValue> newValue = + std::unique_ptr<ResourceConfigValue> new_value = util::make_unique<ResourceConfigValue>( - configValue->config.copyWithoutSdkVersion(), - configValue->product); - newValue->value = std::move(configValue->value); - configValue = std::move(newValue); + config_value->config.CopyWithoutSdkVersion(), + config_value->product); + new_value->value = std::move(config_value->value); + config_value = std::move(new_value); modified = true; } @@ -138,8 +138,7 @@ static void collapseVersions(int minSdk, ResourceEntry* entry) { if (modified) { // We've modified the keys (ConfigDescription) by changing the sdkVersion to - // 0. - // We MUST re-sort to ensure ordering guarantees hold. + // 0. We MUST re-sort to ensure ordering guarantees hold. std::sort(entry->values.begin(), entry->values.end(), [](const std::unique_ptr<ResourceConfigValue>& a, const std::unique_ptr<ResourceConfigValue>& b) -> bool { @@ -148,12 +147,12 @@ static void collapseVersions(int minSdk, ResourceEntry* entry) { } } -bool VersionCollapser::consume(IAaptContext* context, ResourceTable* table) { - const int minSdk = context->getMinSdkVersion(); +bool VersionCollapser::Consume(IAaptContext* context, ResourceTable* table) { + const int min_sdk = context->GetMinSdkVersion(); for (auto& package : table->packages) { for (auto& type : package->types) { for (auto& entry : type->entries) { - collapseVersions(minSdk, entry.get()); + CollapseVersions(min_sdk, entry.get()); } } } diff --git a/tools/aapt2/link/VersionCollapser_test.cpp b/tools/aapt2/link/VersionCollapser_test.cpp index c0e0ddb2d318..1b5592f717d9 100644 --- a/tools/aapt2/link/VersionCollapser_test.cpp +++ b/tools/aapt2/link/VersionCollapser_test.cpp @@ -15,103 +15,103 @@ */ #include "link/Linkers.h" + #include "test/Test.h" namespace aapt { -template <typename T> -using uptr = std::unique_ptr<T>; - -static uptr<ResourceTable> buildTableWithConfigs( +static std::unique_ptr<ResourceTable> BuildTableWithConfigs( const StringPiece& name, std::initializer_list<std::string> list) { test::ResourceTableBuilder builder; for (const std::string& item : list) { - builder.addSimple(name, test::parseConfigOrDie(item)); + builder.AddSimple(name, test::ParseConfigOrDie(item)); } - return builder.build(); + return builder.Build(); } TEST(VersionCollapserTest, CollapseVersions) { - uptr<IAaptContext> context = - test::ContextBuilder().setMinSdkVersion(7).build(); + std::unique_ptr<IAaptContext> context = + test::ContextBuilder().SetMinSdkVersion(7).Build(); - const StringPiece resName = "@android:string/foo"; + const StringPiece res_name = "@android:string/foo"; - uptr<ResourceTable> table = buildTableWithConfigs( - resName, + std::unique_ptr<ResourceTable> table = BuildTableWithConfigs( + res_name, {"land-v4", "land-v5", "sw600dp", "land-v6", "land-v14", "land-v21"}); VersionCollapser collapser; - ASSERT_TRUE(collapser.consume(context.get(), table.get())); + ASSERT_TRUE(collapser.Consume(context.get(), table.get())); // These should be removed. EXPECT_EQ(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v4"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v4"))); EXPECT_EQ(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v5"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v5"))); // This one should be removed because it was renamed to 'land', with the // version dropped. EXPECT_EQ(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v6"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v6"))); // These should remain. EXPECT_NE(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("sw600dp"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("sw600dp"))); // 'land' should be present because it was renamed from 'land-v6'. - EXPECT_NE(nullptr, test::getValueForConfig<Id>( - table.get(), resName, test::parseConfigOrDie("land"))); EXPECT_NE(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v14"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land"))); EXPECT_NE(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v21"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v14"))); + EXPECT_NE(nullptr, + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v21"))); } TEST(VersionCollapserTest, CollapseVersionsWhenMinSdkIsHighest) { - uptr<IAaptContext> context = - test::ContextBuilder().setMinSdkVersion(21).build(); + std::unique_ptr<IAaptContext> context = + test::ContextBuilder().SetMinSdkVersion(21).Build(); - const StringPiece resName = "@android:string/foo"; + const StringPiece res_name = "@android:string/foo"; - uptr<ResourceTable> table = buildTableWithConfigs( - resName, {"land-v4", "land-v5", "sw600dp", "land-v6", "land-v14", - "land-v21", "land-v22"}); + std::unique_ptr<ResourceTable> table = BuildTableWithConfigs( + res_name, {"land-v4", "land-v5", "sw600dp", "land-v6", "land-v14", + "land-v21", "land-v22"}); VersionCollapser collapser; - ASSERT_TRUE(collapser.consume(context.get(), table.get())); + ASSERT_TRUE(collapser.Consume(context.get(), table.get())); // These should all be removed. EXPECT_EQ(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v4"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v4"))); EXPECT_EQ(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v5"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v5"))); EXPECT_EQ(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v6"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v6"))); EXPECT_EQ(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v14"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v14"))); // These should remain. EXPECT_NE(nullptr, - test::getValueForConfig<Id>( - table.get(), resName, - test::parseConfigOrDie("sw600dp").copyWithoutSdkVersion())); + test::GetValueForConfig<Id>( + table.get(), res_name, + test::ParseConfigOrDie("sw600dp").CopyWithoutSdkVersion())); // land-v21 should have been converted to land. - EXPECT_NE(nullptr, test::getValueForConfig<Id>( - table.get(), resName, test::parseConfigOrDie("land"))); + EXPECT_NE(nullptr, + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land"))); // land-v22 should remain as-is. EXPECT_NE(nullptr, - test::getValueForConfig<Id>(table.get(), resName, - test::parseConfigOrDie("land-v22"))); + test::GetValueForConfig<Id>(table.get(), res_name, + test::ParseConfigOrDie("land-v22"))); } } // namespace aapt diff --git a/tools/aapt2/link/XmlNamespaceRemover.cpp b/tools/aapt2/link/XmlNamespaceRemover.cpp index 6e8d80d04e74..24aa5660ae30 100644 --- a/tools/aapt2/link/XmlNamespaceRemover.cpp +++ b/tools/aapt2/link/XmlNamespaceRemover.cpp @@ -14,11 +14,12 @@ * limitations under the License. */ -#include "ResourceTable.h" #include "link/Linkers.h" #include <algorithm> +#include "ResourceTable.h" + namespace aapt { namespace { @@ -28,12 +29,12 @@ namespace { */ class XmlVisitor : public xml::Visitor { public: - XmlVisitor(bool keepUris) : mKeepUris(keepUris) {} + explicit XmlVisitor(bool keep_uris) : keep_uris_(keep_uris) {} - void visit(xml::Element* el) override { + void Visit(xml::Element* el) override { // Strip namespaces for (auto& child : el->children) { - while (child && xml::nodeCast<xml::Namespace>(child.get())) { + while (child && xml::NodeCast<xml::Namespace>(child.get())) { if (child->children.empty()) { child = {}; } else { @@ -49,36 +50,38 @@ class XmlVisitor : public xml::Visitor { }), el->children.end()); - if (!mKeepUris) { + if (!keep_uris_) { for (xml::Attribute& attr : el->attributes) { - attr.namespaceUri = std::string(); + attr.namespace_uri = std::string(); } - el->namespaceUri = std::string(); + el->namespace_uri = std::string(); } - xml::Visitor::visit(el); + xml::Visitor::Visit(el); } private: - bool mKeepUris; + DISALLOW_COPY_AND_ASSIGN(XmlVisitor); + + bool keep_uris_; }; } // namespace -bool XmlNamespaceRemover::consume(IAaptContext* context, +bool XmlNamespaceRemover::Consume(IAaptContext* context, xml::XmlResource* resource) { if (!resource->root) { return false; } // Replace any root namespaces until the root is a non-namespace node - while (xml::nodeCast<xml::Namespace>(resource->root.get())) { + while (xml::NodeCast<xml::Namespace>(resource->root.get())) { if (resource->root->children.empty()) { break; } resource->root = std::move(resource->root->children.front()); resource->root->parent = nullptr; } - XmlVisitor visitor(mKeepUris); - resource->root->accept(&visitor); + XmlVisitor visitor(keep_uris_); + resource->root->Accept(&visitor); return true; } diff --git a/tools/aapt2/link/XmlNamespaceRemover_test.cpp b/tools/aapt2/link/XmlNamespaceRemover_test.cpp index d2daaeeca7db..a176c03a6432 100644 --- a/tools/aapt2/link/XmlNamespaceRemover_test.cpp +++ b/tools/aapt2/link/XmlNamespaceRemover_test.cpp @@ -15,83 +15,94 @@ */ #include "link/Linkers.h" + #include "test/Test.h" namespace aapt { class XmlUriTestVisitor : public xml::Visitor { public: - void visit(xml::Element* el) override { + XmlUriTestVisitor() = default; + + void Visit(xml::Element* el) override { for (const auto& attr : el->attributes) { - EXPECT_EQ(std::string(), attr.namespaceUri); + EXPECT_EQ(std::string(), attr.namespace_uri); } - EXPECT_EQ(std::string(), el->namespaceUri); - xml::Visitor::visit(el); + EXPECT_EQ(std::string(), el->namespace_uri); + xml::Visitor::Visit(el); } - void visit(xml::Namespace* ns) override { - EXPECT_EQ(std::string(), ns->namespaceUri); - xml::Visitor::visit(ns); + void Visit(xml::Namespace* ns) override { + EXPECT_EQ(std::string(), ns->namespace_uri); + xml::Visitor::Visit(ns); } + + private: + DISALLOW_COPY_AND_ASSIGN(XmlUriTestVisitor); }; class XmlNamespaceTestVisitor : public xml::Visitor { public: - void visit(xml::Namespace* ns) override { - ADD_FAILURE() << "Detected namespace: " << ns->namespacePrefix << "=\"" - << ns->namespaceUri << "\""; - xml::Visitor::visit(ns); + XmlNamespaceTestVisitor() = default; + + void Visit(xml::Namespace* ns) override { + ADD_FAILURE() << "Detected namespace: " << ns->namespace_prefix << "=\"" + << ns->namespace_uri << "\""; + xml::Visitor::Visit(ns); } + + private: + DISALLOW_COPY_AND_ASSIGN(XmlNamespaceTestVisitor); }; class XmlNamespaceRemoverTest : public ::testing::Test { public: void SetUp() override { - mContext = - test::ContextBuilder().setCompilationPackage("com.app.test").build(); + context_ = + test::ContextBuilder().SetCompilationPackage("com.app.test").Build(); } protected: - std::unique_ptr<IAaptContext> mContext; + std::unique_ptr<IAaptContext> context_; }; TEST_F(XmlNamespaceRemoverTest, RemoveUris) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" android:text="hello" />)EOF"); XmlNamespaceRemover remover; - ASSERT_TRUE(remover.consume(mContext.get(), doc.get())); + ASSERT_TRUE(remover.Consume(context_.get(), doc.get())); xml::Node* root = doc.get()->root.get(); ASSERT_NE(root, nullptr); XmlUriTestVisitor visitor; - root->accept(&visitor); + root->Accept(&visitor); } TEST_F(XmlNamespaceRemoverTest, RemoveNamespaces) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" xmlns:foo="http://schemas.android.com/apk/res/foo" foo:bar="foobar" android:text="hello" />)EOF"); XmlNamespaceRemover remover; - ASSERT_TRUE(remover.consume(mContext.get(), doc.get())); + ASSERT_TRUE(remover.Consume(context_.get(), doc.get())); xml::Node* root = doc.get()->root.get(); ASSERT_NE(root, nullptr); XmlNamespaceTestVisitor visitor; - root->accept(&visitor); + root->Accept(&visitor); } TEST_F(XmlNamespaceRemoverTest, RemoveNestedNamespaces) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" android:text="hello"> <View xmlns:foo="http://schemas.example.com/foo" @@ -99,13 +110,13 @@ TEST_F(XmlNamespaceRemoverTest, RemoveNestedNamespaces) { </View>)EOF"); XmlNamespaceRemover remover; - ASSERT_TRUE(remover.consume(mContext.get(), doc.get())); + ASSERT_TRUE(remover.Consume(context_.get(), doc.get())); xml::Node* root = doc.get()->root.get(); ASSERT_NE(root, nullptr); XmlNamespaceTestVisitor visitor; - root->accept(&visitor); + root->Accept(&visitor); } } // namespace aapt diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp index 945f98a95577..a8198318b69e 100644 --- a/tools/aapt2/link/XmlReferenceLinker.cpp +++ b/tools/aapt2/link/XmlReferenceLinker.cpp @@ -14,10 +14,11 @@ * limitations under the License. */ +#include "link/Linkers.h" + #include "Diagnostics.h" #include "ResourceUtils.h" #include "SdkConstants.h" -#include "link/Linkers.h" #include "link/ReferenceLinker.h" #include "process/IResourceTableConsumer.h" #include "process/SymbolTable.h" @@ -37,31 +38,33 @@ namespace { */ class ReferenceVisitor : public ValueVisitor { public: - using ValueVisitor::visit; + using ValueVisitor::Visit; ReferenceVisitor(IAaptContext* context, SymbolTable* symbols, - xml::IPackageDeclStack* decls, CallSite* callSite) - : mContext(context), - mSymbols(symbols), - mDecls(decls), - mCallSite(callSite), - mError(false) {} - - void visit(Reference* ref) override { - if (!ReferenceLinker::linkReference(ref, mContext, mSymbols, mDecls, - mCallSite)) { - mError = true; + xml::IPackageDeclStack* decls, CallSite* callsite) + : context_(context), + symbols_(symbols), + decls_(decls), + callsite_(callsite), + error_(false) {} + + void Visit(Reference* ref) override { + if (!ReferenceLinker::LinkReference(ref, context_, symbols_, decls_, + callsite_)) { + error_ = true; } } - bool hasError() const { return mError; } + bool HasError() const { return error_; } private: - IAaptContext* mContext; - SymbolTable* mSymbols; - xml::IPackageDeclStack* mDecls; - CallSite* mCallSite; - bool mError; + DISALLOW_COPY_AND_ASSIGN(ReferenceVisitor); + + IAaptContext* context_; + SymbolTable* symbols_; + xml::IPackageDeclStack* decls_; + CallSite* callsite_; + bool error_; }; /** @@ -69,114 +72,117 @@ class ReferenceVisitor : public ValueVisitor { */ class XmlVisitor : public xml::PackageAwareVisitor { public: - using xml::PackageAwareVisitor::visit; + using xml::PackageAwareVisitor::Visit; XmlVisitor(IAaptContext* context, SymbolTable* symbols, const Source& source, - std::set<int>* sdkLevelsFound, CallSite* callSite) - : mContext(context), - mSymbols(symbols), - mSource(source), - mSdkLevelsFound(sdkLevelsFound), - mCallSite(callSite), - mReferenceVisitor(context, symbols, this, callSite) {} - - void visit(xml::Element* el) override { - const Source source = mSource.withLine(el->lineNumber); + std::set<int>* sdk_levels_found, CallSite* callsite) + : context_(context), + symbols_(symbols), + source_(source), + sdk_levels_found_(sdk_levels_found), + callsite_(callsite), + reference_visitor_(context, symbols, this, callsite) {} + + void Visit(xml::Element* el) override { + const Source source = source_.WithLine(el->line_number); for (xml::Attribute& attr : el->attributes) { - Maybe<xml::ExtractedPackage> maybePackage = - xml::extractPackageFromNamespace(attr.namespaceUri); - if (maybePackage) { + Maybe<xml::ExtractedPackage> maybe_package = + xml::ExtractPackageFromNamespace(attr.namespace_uri); + if (maybe_package) { // There is a valid package name for this attribute. We will look this // up. - StringPiece package = maybePackage.value().package; + StringPiece package = maybe_package.value().package; if (package.empty()) { // Empty package means the 'current' or 'local' package. - package = mContext->getCompilationPackage(); + package = context_->GetCompilationPackage(); } - Reference attrRef( + Reference attr_ref( ResourceNameRef(package, ResourceType::kAttr, attr.name)); - attrRef.privateReference = maybePackage.value().privateNamespace; + attr_ref.private_reference = maybe_package.value().private_namespace; - std::string errStr; - attr.compiledAttribute = ReferenceLinker::compileXmlAttribute( - attrRef, mContext->getNameMangler(), mSymbols, mCallSite, &errStr); + std::string err_str; + attr.compiled_attribute = ReferenceLinker::CompileXmlAttribute( + attr_ref, context_->GetNameMangler(), symbols_, callsite_, + &err_str); // Convert the string value into a compiled Value if this is a valid // attribute. - if (attr.compiledAttribute) { - if (attr.compiledAttribute.value().id) { + if (attr.compiled_attribute) { + if (attr.compiled_attribute.value().id) { // Record all SDK levels from which the attributes were defined. - const size_t sdkLevel = findAttributeSdkLevel( - attr.compiledAttribute.value().id.value()); - if (sdkLevel > 1) { - mSdkLevelsFound->insert(sdkLevel); + const size_t sdk_level = FindAttributeSdkLevel( + attr.compiled_attribute.value().id.value()); + if (sdk_level > 1) { + sdk_levels_found_->insert(sdk_level); } } const Attribute* attribute = - &attr.compiledAttribute.value().attribute; - attr.compiledValue = - ResourceUtils::tryParseItemForAttribute(attr.value, attribute); - if (!attr.compiledValue && - !(attribute->typeMask & android::ResTable_map::TYPE_STRING)) { + &attr.compiled_attribute.value().attribute; + attr.compiled_value = + ResourceUtils::TryParseItemForAttribute(attr.value, attribute); + if (!attr.compiled_value && + !(attribute->type_mask & android::ResTable_map::TYPE_STRING)) { // We won't be able to encode this as a string. - mContext->getDiagnostics()->error( + context_->GetDiagnostics()->Error( DiagMessage(source) << "'" << attr.value << "' " << "is incompatible with attribute " << package << ":" << attr.name << " " << *attribute); - mError = true; + error_ = true; } } else { - mContext->getDiagnostics()->error(DiagMessage(source) + context_->GetDiagnostics()->Error(DiagMessage(source) << "attribute '" << package << ":" - << attr.name << "' " << errStr); - mError = true; + << attr.name << "' " << err_str); + error_ = true; } - } else if (!attr.compiledValue) { + } else if (!attr.compiled_value) { // We still encode references, but only if we haven't manually set this // to // another compiled value. - attr.compiledValue = ResourceUtils::tryParseReference(attr.value); + attr.compiled_value = ResourceUtils::TryParseReference(attr.value); } - if (attr.compiledValue) { + if (attr.compiled_value) { // With a compiledValue, we must resolve the reference and assign it an // ID. - attr.compiledValue->setSource(source); - attr.compiledValue->accept(&mReferenceVisitor); + attr.compiled_value->SetSource(source); + attr.compiled_value->Accept(&reference_visitor_); } } // Call the super implementation. - xml::PackageAwareVisitor::visit(el); + xml::PackageAwareVisitor::Visit(el); } - bool hasError() { return mError || mReferenceVisitor.hasError(); } + bool HasError() { return error_ || reference_visitor_.HasError(); } private: - IAaptContext* mContext; - SymbolTable* mSymbols; - Source mSource; - std::set<int>* mSdkLevelsFound; - CallSite* mCallSite; - ReferenceVisitor mReferenceVisitor; - bool mError = false; + DISALLOW_COPY_AND_ASSIGN(XmlVisitor); + + IAaptContext* context_; + SymbolTable* symbols_; + Source source_; + std::set<int>* sdk_levels_found_; + CallSite* callsite_; + ReferenceVisitor reference_visitor_; + bool error_ = false; }; } // namespace -bool XmlReferenceLinker::consume(IAaptContext* context, +bool XmlReferenceLinker::Consume(IAaptContext* context, xml::XmlResource* resource) { - mSdkLevelsFound.clear(); - CallSite callSite = {resource->file.name}; - XmlVisitor visitor(context, context->getExternalSymbols(), - resource->file.source, &mSdkLevelsFound, &callSite); + sdk_levels_found_.clear(); + CallSite callsite = {resource->file.name}; + XmlVisitor visitor(context, context->GetExternalSymbols(), + resource->file.source, &sdk_levels_found_, &callsite); if (resource->root) { - resource->root->accept(&visitor); - return !visitor.hasError(); + resource->root->Accept(&visitor); + return !visitor.HasError(); } return false; } diff --git a/tools/aapt2/link/XmlReferenceLinker_test.cpp b/tools/aapt2/link/XmlReferenceLinker_test.cpp index 35d479f48569..810f63c0410e 100644 --- a/tools/aapt2/link/XmlReferenceLinker_test.cpp +++ b/tools/aapt2/link/XmlReferenceLinker_test.cpp @@ -15,6 +15,7 @@ */ #include "link/Linkers.h" + #include "test/Test.h" namespace aapt { @@ -22,72 +23,72 @@ namespace aapt { class XmlReferenceLinkerTest : public ::testing::Test { public: void SetUp() override { - mContext = + context_ = test::ContextBuilder() - .setCompilationPackage("com.app.test") - .setNameManglerPolicy( + .SetCompilationPackage("com.app.test") + .SetNameManglerPolicy( NameManglerPolicy{"com.app.test", {"com.android.support"}}) - .addSymbolSource( + .AddSymbolSource( test::StaticSymbolSourceBuilder() - .addPublicSymbol( + .AddPublicSymbol( "android:attr/layout_width", ResourceId(0x01010000), test::AttributeBuilder() - .setTypeMask(android::ResTable_map::TYPE_ENUM | + .SetTypeMask(android::ResTable_map::TYPE_ENUM | android::ResTable_map::TYPE_DIMENSION) - .addItem("match_parent", 0xffffffff) - .build()) - .addPublicSymbol( + .AddItem("match_parent", 0xffffffff) + .Build()) + .AddPublicSymbol( "android:attr/background", ResourceId(0x01010001), test::AttributeBuilder() - .setTypeMask(android::ResTable_map::TYPE_COLOR) - .build()) - .addPublicSymbol("android:attr/attr", + .SetTypeMask(android::ResTable_map::TYPE_COLOR) + .Build()) + .AddPublicSymbol("android:attr/attr", ResourceId(0x01010002), - test::AttributeBuilder().build()) - .addPublicSymbol( + test::AttributeBuilder().Build()) + .AddPublicSymbol( "android:attr/text", ResourceId(0x01010003), test::AttributeBuilder() - .setTypeMask(android::ResTable_map::TYPE_STRING) - .build()) + .SetTypeMask(android::ResTable_map::TYPE_STRING) + .Build()) // Add one real symbol that was introduces in v21 - .addPublicSymbol("android:attr/colorAccent", + .AddPublicSymbol("android:attr/colorAccent", ResourceId(0x01010435), - test::AttributeBuilder().build()) + test::AttributeBuilder().Build()) // Private symbol. - .addSymbol("android:color/hidden", ResourceId(0x01020001)) + .AddSymbol("android:color/hidden", ResourceId(0x01020001)) - .addPublicSymbol("android:id/id", ResourceId(0x01030000)) - .addSymbol("com.app.test:id/id", ResourceId(0x7f030000)) - .addSymbol("com.app.test:color/green", + .AddPublicSymbol("android:id/id", ResourceId(0x01030000)) + .AddSymbol("com.app.test:id/id", ResourceId(0x7f030000)) + .AddSymbol("com.app.test:color/green", ResourceId(0x7f020000)) - .addSymbol("com.app.test:color/red", ResourceId(0x7f020001)) - .addSymbol( + .AddSymbol("com.app.test:color/red", ResourceId(0x7f020001)) + .AddSymbol( "com.app.test:attr/colorAccent", ResourceId(0x7f010000), test::AttributeBuilder() - .setTypeMask(android::ResTable_map::TYPE_COLOR) - .build()) - .addPublicSymbol( + .SetTypeMask(android::ResTable_map::TYPE_COLOR) + .Build()) + .AddPublicSymbol( "com.app.test:attr/com.android.support$colorAccent", ResourceId(0x7f010001), test::AttributeBuilder() - .setTypeMask(android::ResTable_map::TYPE_COLOR) - .build()) - .addPublicSymbol("com.app.test:attr/attr", + .SetTypeMask(android::ResTable_map::TYPE_COLOR) + .Build()) + .AddPublicSymbol("com.app.test:attr/attr", ResourceId(0x7f010002), - test::AttributeBuilder().build()) - .build()) - .build(); + test::AttributeBuilder().Build()) + .Build()) + .Build(); } protected: - std::unique_ptr<IAaptContext> mContext; + std::unique_ptr<IAaptContext> context_; }; TEST_F(XmlReferenceLinkerTest, LinkBasicAttributes) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:background="@color/green" @@ -95,123 +96,125 @@ TEST_F(XmlReferenceLinkerTest, LinkBasicAttributes) { class="hello" />)EOF"); XmlReferenceLinker linker; - ASSERT_TRUE(linker.consume(mContext.get(), doc.get())); + ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); - xml::Element* viewEl = xml::findRootElement(doc.get()); - ASSERT_NE(viewEl, nullptr); + xml::Element* view_el = xml::FindRootElement(doc.get()); + ASSERT_NE(view_el, nullptr); - xml::Attribute* xmlAttr = - viewEl->findAttribute(xml::kSchemaAndroid, "layout_width"); - ASSERT_NE(xmlAttr, nullptr); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id); - EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), + xml::Attribute* xml_attr = + view_el->FindAttribute(xml::kSchemaAndroid, "layout_width"); + ASSERT_NE(xml_attr, nullptr); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id); + EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(), ResourceId(0x01010000)); - ASSERT_NE(xmlAttr->compiledValue, nullptr); - ASSERT_NE(valueCast<BinaryPrimitive>(xmlAttr->compiledValue.get()), nullptr); - - xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "background"); - ASSERT_NE(xmlAttr, nullptr); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id); - EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), + ASSERT_NE(xml_attr->compiled_value, nullptr); + ASSERT_NE(ValueCast<BinaryPrimitive>(xml_attr->compiled_value.get()), + nullptr); + + xml_attr = view_el->FindAttribute(xml::kSchemaAndroid, "background"); + ASSERT_NE(xml_attr, nullptr); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id); + EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(), ResourceId(0x01010001)); - ASSERT_NE(xmlAttr->compiledValue, nullptr); - Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get()); + ASSERT_NE(xml_attr->compiled_value, nullptr); + Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get()); ASSERT_NE(ref, nullptr); AAPT_ASSERT_TRUE(ref->name); EXPECT_EQ(ref->name.value(), - test::parseNameOrDie("color/green")); // Make sure the name + test::ParseNameOrDie("color/green")); // Make sure the name // didn't change. AAPT_ASSERT_TRUE(ref->id); EXPECT_EQ(ref->id.value(), ResourceId(0x7f020000)); - xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "text"); - ASSERT_NE(xmlAttr, nullptr); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute); + xml_attr = view_el->FindAttribute(xml::kSchemaAndroid, "text"); + ASSERT_NE(xml_attr, nullptr); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute); ASSERT_FALSE( - xmlAttr->compiledValue); // Strings don't get compiled for memory sake. + xml_attr->compiled_value); // Strings don't get compiled for memory sake. - xmlAttr = viewEl->findAttribute("", "class"); - ASSERT_NE(xmlAttr, nullptr); - AAPT_ASSERT_FALSE(xmlAttr->compiledAttribute); - ASSERT_EQ(xmlAttr->compiledValue, nullptr); + xml_attr = view_el->FindAttribute("", "class"); + ASSERT_NE(xml_attr, nullptr); + AAPT_ASSERT_FALSE(xml_attr->compiled_attribute); + ASSERT_EQ(xml_attr->compiled_value, nullptr); } TEST_F(XmlReferenceLinkerTest, PrivateSymbolsAreNotLinked) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" android:colorAccent="@android:color/hidden" />)EOF"); XmlReferenceLinker linker; - ASSERT_FALSE(linker.consume(mContext.get(), doc.get())); + ASSERT_FALSE(linker.Consume(context_.get(), doc.get())); } TEST_F(XmlReferenceLinkerTest, PrivateSymbolsAreLinkedWhenReferenceHasStarPrefix) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" android:colorAccent="@*android:color/hidden" />)EOF"); XmlReferenceLinker linker; - ASSERT_TRUE(linker.consume(mContext.get(), doc.get())); + ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); } TEST_F(XmlReferenceLinkerTest, SdkLevelsAreRecorded) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/android" android:colorAccent="#ffffff" />)EOF"); XmlReferenceLinker linker; - ASSERT_TRUE(linker.consume(mContext.get(), doc.get())); - EXPECT_TRUE(linker.getSdkLevels().count(21) == 1); + ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); + EXPECT_TRUE(linker.sdk_levels().count(21) == 1); } TEST_F(XmlReferenceLinkerTest, LinkMangledAttributes) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:support="http://schemas.android.com/apk/res/com.android.support" support:colorAccent="#ff0000" />)EOF"); XmlReferenceLinker linker; - ASSERT_TRUE(linker.consume(mContext.get(), doc.get())); + ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); - xml::Element* viewEl = xml::findRootElement(doc.get()); - ASSERT_NE(viewEl, nullptr); + xml::Element* view_el = xml::FindRootElement(doc.get()); + ASSERT_NE(view_el, nullptr); - xml::Attribute* xmlAttr = viewEl->findAttribute( - xml::buildPackageNamespace("com.android.support"), "colorAccent"); - ASSERT_NE(xmlAttr, nullptr); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id); - EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), + xml::Attribute* xml_attr = view_el->FindAttribute( + xml::BuildPackageNamespace("com.android.support"), "colorAccent"); + ASSERT_NE(xml_attr, nullptr); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id); + EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(), ResourceId(0x7f010001)); - ASSERT_NE(valueCast<BinaryPrimitive>(xmlAttr->compiledValue.get()), nullptr); + ASSERT_NE(ValueCast<BinaryPrimitive>(xml_attr->compiled_value.get()), + nullptr); } TEST_F(XmlReferenceLinkerTest, LinkAutoResReference) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:app="http://schemas.android.com/apk/res-auto" app:colorAccent="@app:color/red" />)EOF"); XmlReferenceLinker linker; - ASSERT_TRUE(linker.consume(mContext.get(), doc.get())); + ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); - xml::Element* viewEl = xml::findRootElement(doc.get()); - ASSERT_NE(viewEl, nullptr); + xml::Element* view_el = xml::FindRootElement(doc.get()); + ASSERT_NE(view_el, nullptr); - xml::Attribute* xmlAttr = - viewEl->findAttribute(xml::kSchemaAuto, "colorAccent"); - ASSERT_NE(xmlAttr, nullptr); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id); - EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), + xml::Attribute* xml_attr = + view_el->FindAttribute(xml::kSchemaAuto, "colorAccent"); + ASSERT_NE(xml_attr, nullptr); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id); + EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(), ResourceId(0x7f010000)); - Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get()); + Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get()); ASSERT_NE(ref, nullptr); AAPT_ASSERT_TRUE(ref->name); AAPT_ASSERT_TRUE(ref->id); @@ -220,7 +223,7 @@ TEST_F(XmlReferenceLinkerTest, LinkAutoResReference) { TEST_F(XmlReferenceLinkerTest, LinkViewWithShadowedPackageAlias) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:app="http://schemas.android.com/apk/res/android" app:attr="@app:id/id"> <View xmlns:app="http://schemas.android.com/apk/res/com.app.test" @@ -228,38 +231,39 @@ TEST_F(XmlReferenceLinkerTest, LinkViewWithShadowedPackageAlias) { </View>)EOF"); XmlReferenceLinker linker; - ASSERT_TRUE(linker.consume(mContext.get(), doc.get())); + ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); - xml::Element* viewEl = xml::findRootElement(doc.get()); - ASSERT_NE(viewEl, nullptr); + xml::Element* view_el = xml::FindRootElement(doc.get()); + ASSERT_NE(view_el, nullptr); // All attributes and references in this element should be referring to // "android" (0x01). - xml::Attribute* xmlAttr = viewEl->findAttribute(xml::kSchemaAndroid, "attr"); - ASSERT_NE(xmlAttr, nullptr); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id); - EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), + xml::Attribute* xml_attr = + view_el->FindAttribute(xml::kSchemaAndroid, "attr"); + ASSERT_NE(xml_attr, nullptr); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id); + EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(), ResourceId(0x01010002)); - Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get()); + Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get()); ASSERT_NE(ref, nullptr); AAPT_ASSERT_TRUE(ref->id); EXPECT_EQ(ref->id.value(), ResourceId(0x01030000)); - ASSERT_FALSE(viewEl->getChildElements().empty()); - viewEl = viewEl->getChildElements().front(); - ASSERT_NE(viewEl, nullptr); + ASSERT_FALSE(view_el->GetChildElements().empty()); + view_el = view_el->GetChildElements().front(); + ASSERT_NE(view_el, nullptr); // All attributes and references in this element should be referring to // "com.app.test" (0x7f). - xmlAttr = - viewEl->findAttribute(xml::buildPackageNamespace("com.app.test"), "attr"); - ASSERT_NE(xmlAttr, nullptr); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id); - EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), + xml_attr = view_el->FindAttribute(xml::BuildPackageNamespace("com.app.test"), + "attr"); + ASSERT_NE(xml_attr, nullptr); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id); + EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(), ResourceId(0x7f010002)); - ref = valueCast<Reference>(xmlAttr->compiledValue.get()); + ref = ValueCast<Reference>(xml_attr->compiled_value.get()); ASSERT_NE(ref, nullptr); AAPT_ASSERT_TRUE(ref->id); EXPECT_EQ(ref->id.value(), ResourceId(0x7f030000)); @@ -267,26 +271,26 @@ TEST_F(XmlReferenceLinkerTest, LinkViewWithShadowedPackageAlias) { TEST_F(XmlReferenceLinkerTest, LinkViewWithLocalPackageAndAliasOfTheSameName) { std::unique_ptr<xml::XmlResource> doc = - test::buildXmlDomForPackageName(mContext.get(), R"EOF( + test::BuildXmlDomForPackageName(context_.get(), R"EOF( <View xmlns:android="http://schemas.android.com/apk/res/com.app.test" android:attr="@id/id"/>)EOF"); XmlReferenceLinker linker; - ASSERT_TRUE(linker.consume(mContext.get(), doc.get())); + ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); - xml::Element* viewEl = xml::findRootElement(doc.get()); - ASSERT_NE(viewEl, nullptr); + xml::Element* view_el = xml::FindRootElement(doc.get()); + ASSERT_NE(view_el, nullptr); // All attributes and references in this element should be referring to // "com.app.test" (0x7f). - xml::Attribute* xmlAttr = - viewEl->findAttribute(xml::buildPackageNamespace("com.app.test"), "attr"); - ASSERT_NE(xmlAttr, nullptr); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute); - AAPT_ASSERT_TRUE(xmlAttr->compiledAttribute.value().id); - EXPECT_EQ(xmlAttr->compiledAttribute.value().id.value(), + xml::Attribute* xml_attr = view_el->FindAttribute( + xml::BuildPackageNamespace("com.app.test"), "attr"); + ASSERT_NE(xml_attr, nullptr); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute); + AAPT_ASSERT_TRUE(xml_attr->compiled_attribute.value().id); + EXPECT_EQ(xml_attr->compiled_attribute.value().id.value(), ResourceId(0x7f010002)); - Reference* ref = valueCast<Reference>(xmlAttr->compiledValue.get()); + Reference* ref = ValueCast<Reference>(xml_attr->compiled_value.get()); ASSERT_NE(ref, nullptr); AAPT_ASSERT_TRUE(ref->id); EXPECT_EQ(ref->id.value(), ResourceId(0x7f030000)); diff --git a/tools/aapt2/process/IResourceTableConsumer.h b/tools/aapt2/process/IResourceTableConsumer.h index a9bde396cc55..4526a79577d9 100644 --- a/tools/aapt2/process/IResourceTableConsumer.h +++ b/tools/aapt2/process/IResourceTableConsumer.h @@ -17,16 +17,16 @@ #ifndef AAPT_PROCESS_IRESOURCETABLECONSUMER_H #define AAPT_PROCESS_IRESOURCETABLECONSUMER_H +#include <iostream> +#include <list> +#include <sstream> + #include "Diagnostics.h" #include "NameMangler.h" #include "Resource.h" #include "ResourceValues.h" #include "Source.h" -#include <iostream> -#include <list> -#include <sstream> - namespace aapt { class ResourceTable; @@ -35,19 +35,19 @@ class SymbolTable; struct IAaptContext { virtual ~IAaptContext() = default; - virtual SymbolTable* getExternalSymbols() = 0; - virtual IDiagnostics* getDiagnostics() = 0; - virtual const std::string& getCompilationPackage() = 0; - virtual uint8_t getPackageId() = 0; - virtual NameMangler* getNameMangler() = 0; - virtual bool verbose() = 0; - virtual int getMinSdkVersion() = 0; + virtual SymbolTable* GetExternalSymbols() = 0; + virtual IDiagnostics* GetDiagnostics() = 0; + virtual const std::string& GetCompilationPackage() = 0; + virtual uint8_t GetPackageId() = 0; + virtual NameMangler* GetNameMangler() = 0; + virtual bool IsVerbose() = 0; + virtual int GetMinSdkVersion() = 0; }; struct IResourceTableConsumer { virtual ~IResourceTableConsumer() = default; - virtual bool consume(IAaptContext* context, ResourceTable* table) = 0; + virtual bool Consume(IAaptContext* context, ResourceTable* table) = 0; }; namespace xml { @@ -57,7 +57,7 @@ class XmlResource; struct IXmlResourceConsumer { virtual ~IXmlResourceConsumer() = default; - virtual bool consume(IAaptContext* context, xml::XmlResource* resource) = 0; + virtual bool Consume(IAaptContext* context, xml::XmlResource* resource) = 0; }; } // namespace aapt diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp index 00ffeb25c3e1..767384d8d956 100644 --- a/tools/aapt2/process/SymbolTable.cpp +++ b/tools/aapt2/process/SymbolTable.cpp @@ -15,80 +15,81 @@ */ #include "process/SymbolTable.h" + +#include "androidfw/AssetManager.h" +#include "androidfw/ResourceTypes.h" + #include "ConfigDescription.h" #include "Resource.h" #include "ResourceUtils.h" #include "ValueVisitor.h" #include "util/Util.h" -#include <androidfw/AssetManager.h> -#include <androidfw/ResourceTypes.h> - namespace aapt { -void SymbolTable::appendSource(std::unique_ptr<ISymbolSource> source) { - mSources.push_back(std::move(source)); +void SymbolTable::AppendSource(std::unique_ptr<ISymbolSource> source) { + sources_.push_back(std::move(source)); // We do not clear the cache, because sources earlier in the list take // precedent. } -void SymbolTable::prependSource(std::unique_ptr<ISymbolSource> source) { - mSources.insert(mSources.begin(), std::move(source)); +void SymbolTable::PrependSource(std::unique_ptr<ISymbolSource> source) { + sources_.insert(sources_.begin(), std::move(source)); // We must clear the cache in case we did a lookup before adding this // resource. - mCache.clear(); + cache_.clear(); } -const SymbolTable::Symbol* SymbolTable::findByName(const ResourceName& name) { - if (const std::shared_ptr<Symbol>& s = mCache.get(name)) { +const SymbolTable::Symbol* SymbolTable::FindByName(const ResourceName& name) { + if (const std::shared_ptr<Symbol>& s = cache_.get(name)) { return s.get(); } // We did not find it in the cache, so look through the sources. - for (auto& symbolSource : mSources) { - std::unique_ptr<Symbol> symbol = symbolSource->findByName(name); + for (auto& symbolSource : sources_) { + std::unique_ptr<Symbol> symbol = symbolSource->FindByName(name); if (symbol) { // Take ownership of the symbol into a shared_ptr. We do this because // LruCache // doesn't support unique_ptr. - std::shared_ptr<Symbol> sharedSymbol = + std::shared_ptr<Symbol> shared_symbol = std::shared_ptr<Symbol>(symbol.release()); - mCache.put(name, sharedSymbol); + cache_.put(name, shared_symbol); - if (sharedSymbol->id) { + if (shared_symbol->id) { // The symbol has an ID, so we can also cache this! - mIdCache.put(sharedSymbol->id.value(), sharedSymbol); + id_cache_.put(shared_symbol->id.value(), shared_symbol); } - return sharedSymbol.get(); + return shared_symbol.get(); } } return nullptr; } -const SymbolTable::Symbol* SymbolTable::findById(const ResourceId& id) { - if (const std::shared_ptr<Symbol>& s = mIdCache.get(id)) { +const SymbolTable::Symbol* SymbolTable::FindById(const ResourceId& id) { + if (const std::shared_ptr<Symbol>& s = id_cache_.get(id)) { return s.get(); } // We did not find it in the cache, so look through the sources. - for (auto& symbolSource : mSources) { - std::unique_ptr<Symbol> symbol = symbolSource->findById(id); + for (auto& symbolSource : sources_) { + std::unique_ptr<Symbol> symbol = symbolSource->FindById(id); if (symbol) { // Take ownership of the symbol into a shared_ptr. We do this because // LruCache // doesn't support unique_ptr. - std::shared_ptr<Symbol> sharedSymbol = + std::shared_ptr<Symbol> shared_symbol = std::shared_ptr<Symbol>(symbol.release()); - mIdCache.put(id, sharedSymbol); - return sharedSymbol.get(); + id_cache_.put(id, shared_symbol); + return shared_symbol.get(); } } return nullptr; } -const SymbolTable::Symbol* SymbolTable::findByReference(const Reference& ref) { +const SymbolTable::Symbol* SymbolTable::FindByReference(const Reference& ref) { // First try the ID. This is because when we lookup by ID, we only fill in the // ID cache. // Looking up by name fills in the name and ID cache. So a cache miss will @@ -102,22 +103,22 @@ const SymbolTable::Symbol* SymbolTable::findByReference(const Reference& ref) { // succeeded to lookup by ID. Subsequent lookups will miss then hit. const SymbolTable::Symbol* symbol = nullptr; if (ref.id) { - symbol = findById(ref.id.value()); + symbol = FindById(ref.id.value()); } if (ref.name && !symbol) { - symbol = findByName(ref.name.value()); + symbol = FindByName(ref.name.value()); } return symbol; } -std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::findByName( +std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::FindByName( const ResourceName& name) { - Maybe<ResourceTable::SearchResult> result = mTable->findResource(name); + Maybe<ResourceTable::SearchResult> result = table_->FindResource(name); if (!result) { if (name.type == ResourceType::kAttr) { // Recurse and try looking up a private attribute. - return findByName( + return FindByName( ResourceName(name.package, ResourceType::kAttrPrivate, name.entry)); } return {}; @@ -127,7 +128,7 @@ std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::findByName( std::unique_ptr<SymbolTable::Symbol> symbol = util::make_unique<SymbolTable::Symbol>(); - symbol->isPublic = (sr.entry->symbolStatus.state == SymbolState::kPublic); + symbol->is_public = (sr.entry->symbol_status.state == SymbolState::kPublic); if (sr.package->id && sr.type->id && sr.entry->id) { symbol->id = ResourceId(sr.package->id.value(), sr.type->id.value(), @@ -137,10 +138,10 @@ std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::findByName( if (name.type == ResourceType::kAttr || name.type == ResourceType::kAttrPrivate) { const ConfigDescription kDefaultConfig; - ResourceConfigValue* configValue = sr.entry->findValue(kDefaultConfig); - if (configValue) { + ResourceConfigValue* config_value = sr.entry->FindValue(kDefaultConfig); + if (config_value) { // This resource has an Attribute. - if (Attribute* attr = valueCast<Attribute>(configValue->value.get())) { + if (Attribute* attr = ValueCast<Attribute>(config_value->value.get())) { symbol->attribute = std::make_shared<Attribute>(*attr); } else { return {}; @@ -150,13 +151,13 @@ std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::findByName( return symbol; } -bool AssetManagerSymbolSource::addAssetPath(const StringPiece& path) { +bool AssetManagerSymbolSource::AddAssetPath(const StringPiece& path) { int32_t cookie = 0; - return mAssets.addAssetPath(android::String8(path.data(), path.size()), + return assets_.addAssetPath(android::String8(path.data(), path.size()), &cookie); } -static std::unique_ptr<SymbolTable::Symbol> lookupAttributeInTable( +static std::unique_ptr<SymbolTable::Symbol> LookupAttributeInTable( const android::ResTable& table, ResourceId id) { // Try as a bag. const android::ResTable::bag_entry* entry; @@ -175,41 +176,42 @@ static std::unique_ptr<SymbolTable::Symbol> lookupAttributeInTable( for (size_t i = 0; i < (size_t)count; i++) { if (entry[i].map.name.ident == android::ResTable_map::ATTR_TYPE) { s->attribute = std::make_shared<Attribute>(false); - s->attribute->typeMask = entry[i].map.value.data; + s->attribute->type_mask = entry[i].map.value.data; break; } } if (s->attribute) { for (size_t i = 0; i < (size_t)count; i++) { - const android::ResTable_map& mapEntry = entry[i].map; - if (Res_INTERNALID(mapEntry.name.ident)) { - switch (mapEntry.name.ident) { + const android::ResTable_map& map_entry = entry[i].map; + if (Res_INTERNALID(map_entry.name.ident)) { + switch (map_entry.name.ident) { case android::ResTable_map::ATTR_MIN: - s->attribute->minInt = static_cast<int32_t>(mapEntry.value.data); + s->attribute->min_int = static_cast<int32_t>(map_entry.value.data); break; case android::ResTable_map::ATTR_MAX: - s->attribute->maxInt = static_cast<int32_t>(mapEntry.value.data); + s->attribute->max_int = static_cast<int32_t>(map_entry.value.data); break; } continue; } - android::ResTable::resource_name entryName; - if (!table.getResourceName(mapEntry.name.ident, false, &entryName)) { + android::ResTable::resource_name entry_name; + if (!table.getResourceName(map_entry.name.ident, false, &entry_name)) { table.unlockBag(entry); return nullptr; } - Maybe<ResourceName> parsedName = ResourceUtils::toResourceName(entryName); - if (!parsedName) { + Maybe<ResourceName> parsed_name = + ResourceUtils::ToResourceName(entry_name); + if (!parsed_name) { return nullptr; } Attribute::Symbol symbol; - symbol.symbol.name = parsedName.value(); - symbol.symbol.id = ResourceId(mapEntry.name.ident); - symbol.value = mapEntry.value.data; + symbol.symbol.name = parsed_name.value(); + symbol.symbol.id = ResourceId(map_entry.name.ident); + symbol.value = map_entry.value.data; s->attribute->symbols.push_back(std::move(symbol)); } } @@ -217,81 +219,81 @@ static std::unique_ptr<SymbolTable::Symbol> lookupAttributeInTable( return s; } -std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findByName( +std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindByName( const ResourceName& name) { - const android::ResTable& table = mAssets.getResources(false); + const android::ResTable& table = assets_.getResources(false); - const std::u16string package16 = util::utf8ToUtf16(name.package); - const std::u16string type16 = util::utf8ToUtf16(toString(name.type)); - const std::u16string entry16 = util::utf8ToUtf16(name.entry); + const std::u16string package16 = util::Utf8ToUtf16(name.package); + const std::u16string type16 = util::Utf8ToUtf16(ToString(name.type)); + const std::u16string entry16 = util::Utf8ToUtf16(name.entry); - uint32_t typeSpecFlags = 0; - ResourceId resId = table.identifierForName( + uint32_t type_spec_flags = 0; + ResourceId res_id = table.identifierForName( entry16.data(), entry16.size(), type16.data(), type16.size(), - package16.data(), package16.size(), &typeSpecFlags); - if (!resId.isValid()) { + package16.data(), package16.size(), &type_spec_flags); + if (!res_id.is_valid()) { return {}; } std::unique_ptr<SymbolTable::Symbol> s; if (name.type == ResourceType::kAttr) { - s = lookupAttributeInTable(table, resId); + s = LookupAttributeInTable(table, res_id); } else { s = util::make_unique<SymbolTable::Symbol>(); - s->id = resId; + s->id = res_id; } if (s) { - s->isPublic = - (typeSpecFlags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0; + s->is_public = + (type_spec_flags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0; return s; } return {}; } -static Maybe<ResourceName> getResourceName(const android::ResTable& table, +static Maybe<ResourceName> GetResourceName(const android::ResTable& table, ResourceId id) { - android::ResTable::resource_name resName = {}; - if (!table.getResourceName(id.id, true, &resName)) { + android::ResTable::resource_name res_name = {}; + if (!table.getResourceName(id.id, true, &res_name)) { return {}; } - return ResourceUtils::toResourceName(resName); + return ResourceUtils::ToResourceName(res_name); } -std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findById( +std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindById( ResourceId id) { - const android::ResTable& table = mAssets.getResources(false); - Maybe<ResourceName> maybeName = getResourceName(table, id); - if (!maybeName) { + const android::ResTable& table = assets_.getResources(false); + Maybe<ResourceName> maybe_name = GetResourceName(table, id); + if (!maybe_name) { return {}; } - uint32_t typeSpecFlags = 0; - table.getResourceFlags(id.id, &typeSpecFlags); + uint32_t type_spec_flags = 0; + table.getResourceFlags(id.id, &type_spec_flags); std::unique_ptr<SymbolTable::Symbol> s; - if (maybeName.value().type == ResourceType::kAttr) { - s = lookupAttributeInTable(table, id); + if (maybe_name.value().type == ResourceType::kAttr) { + s = LookupAttributeInTable(table, id); } else { s = util::make_unique<SymbolTable::Symbol>(); s->id = id; } if (s) { - s->isPublic = - (typeSpecFlags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0; + s->is_public = + (type_spec_flags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0; return s; } return {}; } -std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findByReference( +std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindByReference( const Reference& ref) { // AssetManager always prefers IDs. if (ref.id) { - return findById(ref.id.value()); + return FindById(ref.id.value()); } else if (ref.name) { - return findByName(ref.name.value()); + return FindByName(ref.name.value()); } return {}; } diff --git a/tools/aapt2/process/SymbolTable.h b/tools/aapt2/process/SymbolTable.h index 89d87dec7269..25f756522580 100644 --- a/tools/aapt2/process/SymbolTable.h +++ b/tools/aapt2/process/SymbolTable.h @@ -17,28 +17,28 @@ #ifndef AAPT_PROCESS_SYMBOLTABLE_H #define AAPT_PROCESS_SYMBOLTABLE_H +#include <algorithm> +#include <memory> +#include <vector> + +#include "android-base/macros.h" +#include "androidfw/AssetManager.h" +#include "utils/JenkinsHash.h" +#include "utils/LruCache.h" + #include "Resource.h" #include "ResourceTable.h" #include "ResourceValues.h" #include "util/Util.h" -#include <utils/JenkinsHash.h> -#include <utils/LruCache.h> - -#include <android-base/macros.h> -#include <androidfw/AssetManager.h> -#include <algorithm> -#include <memory> -#include <vector> - namespace aapt { inline android::hash_t hash_type(const ResourceName& name) { - std::hash<std::string> strHash; + std::hash<std::string> str_hash; android::hash_t hash = 0; - hash = android::JenkinsHashMix(hash, (uint32_t)strHash(name.package)); + hash = android::JenkinsHashMix(hash, (uint32_t)str_hash(name.package)); hash = android::JenkinsHashMix(hash, (uint32_t)name.type); - hash = android::JenkinsHashMix(hash, (uint32_t)strHash(name.entry)); + hash = android::JenkinsHashMix(hash, (uint32_t)str_hash(name.entry)); return hash; } @@ -60,7 +60,7 @@ class SymbolTable { Symbol(const Maybe<ResourceId>& i, const std::shared_ptr<Attribute>& attr, bool pub) - : id(i), attribute(attr), isPublic(pub) {} + : id(i), attribute(attr), is_public(pub) {} Symbol(const Symbol&) = default; Symbol(Symbol&&) = default; @@ -69,36 +69,34 @@ class SymbolTable { Maybe<ResourceId> id; std::shared_ptr<Attribute> attribute; - bool isPublic = false; + bool is_public = false; }; - SymbolTable() : mCache(200), mIdCache(200) {} + SymbolTable() : cache_(200), id_cache_(200) {} - void appendSource(std::unique_ptr<ISymbolSource> source); - void prependSource(std::unique_ptr<ISymbolSource> source); + void AppendSource(std::unique_ptr<ISymbolSource> source); + void PrependSource(std::unique_ptr<ISymbolSource> source); /** - * Never hold on to the result between calls to findByName or findById. The - * results - * are typically stored in a cache which may evict entries. + * Never hold on to the result between calls to FindByName or FindById. The + * results stored in a cache which may evict entries. */ - const Symbol* findByName(const ResourceName& name); - const Symbol* findById(const ResourceId& id); + const Symbol* FindByName(const ResourceName& name); + const Symbol* FindById(const ResourceId& id); /** * Let's the ISymbolSource decide whether looking up by name or ID is faster, - * if both - * are available. + * if both are available. */ - const Symbol* findByReference(const Reference& ref); + const Symbol* FindByReference(const Reference& ref); private: - std::vector<std::unique_ptr<ISymbolSource>> mSources; + std::vector<std::unique_ptr<ISymbolSource>> sources_; // We use shared_ptr because unique_ptr is not supported and // we need automatic deletion. - android::LruCache<ResourceName, std::shared_ptr<Symbol>> mCache; - android::LruCache<ResourceId, std::shared_ptr<Symbol>> mIdCache; + android::LruCache<ResourceName, std::shared_ptr<Symbol>> cache_; + android::LruCache<ResourceId, std::shared_ptr<Symbol>> id_cache_; DISALLOW_COPY_AND_ASSIGN(SymbolTable); }; @@ -112,19 +110,19 @@ class ISymbolSource { public: virtual ~ISymbolSource() = default; - virtual std::unique_ptr<SymbolTable::Symbol> findByName( + virtual std::unique_ptr<SymbolTable::Symbol> FindByName( const ResourceName& name) = 0; - virtual std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) = 0; + virtual std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) = 0; /** * Default implementation tries the name if it exists, else the ID. */ - virtual std::unique_ptr<SymbolTable::Symbol> findByReference( + virtual std::unique_ptr<SymbolTable::Symbol> FindByReference( const Reference& ref) { if (ref.name) { - return findByName(ref.name.value()); + return FindByName(ref.name.value()); } else if (ref.id) { - return findById(ref.id.value()); + return FindById(ref.id.value()); } return {}; } @@ -137,17 +135,17 @@ class ISymbolSource { */ class ResourceTableSymbolSource : public ISymbolSource { public: - explicit ResourceTableSymbolSource(ResourceTable* table) : mTable(table) {} + explicit ResourceTableSymbolSource(ResourceTable* table) : table_(table) {} - std::unique_ptr<SymbolTable::Symbol> findByName( + std::unique_ptr<SymbolTable::Symbol> FindByName( const ResourceName& name) override; - std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override { + std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override { return {}; } private: - ResourceTable* mTable; + ResourceTable* table_; DISALLOW_COPY_AND_ASSIGN(ResourceTableSymbolSource); }; @@ -156,16 +154,16 @@ class AssetManagerSymbolSource : public ISymbolSource { public: AssetManagerSymbolSource() = default; - bool addAssetPath(const StringPiece& path); + bool AddAssetPath(const StringPiece& path); - std::unique_ptr<SymbolTable::Symbol> findByName( + std::unique_ptr<SymbolTable::Symbol> FindByName( const ResourceName& name) override; - std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override; - std::unique_ptr<SymbolTable::Symbol> findByReference( + std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override; + std::unique_ptr<SymbolTable::Symbol> FindByReference( const Reference& ref) override; private: - android::AssetManager mAssets; + android::AssetManager assets_; DISALLOW_COPY_AND_ASSIGN(AssetManagerSymbolSource); }; diff --git a/tools/aapt2/process/SymbolTable_test.cpp b/tools/aapt2/process/SymbolTable_test.cpp index 00474f7d2341..9ea0786cbc8e 100644 --- a/tools/aapt2/process/SymbolTable_test.cpp +++ b/tools/aapt2/process/SymbolTable_test.cpp @@ -15,6 +15,7 @@ */ #include "process/SymbolTable.h" + #include "test/Test.h" namespace aapt { @@ -22,20 +23,20 @@ namespace aapt { TEST(ResourceTableSymbolSourceTest, FindSymbols) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addSimple("android:id/foo", ResourceId(0x01020000)) - .addSimple("android:id/bar") - .addValue("android:attr/foo", ResourceId(0x01010000), - test::AttributeBuilder().build()) - .build(); + .AddSimple("android:id/foo", ResourceId(0x01020000)) + .AddSimple("android:id/bar") + .AddValue("android:attr/foo", ResourceId(0x01010000), + test::AttributeBuilder().Build()) + .Build(); - ResourceTableSymbolSource symbolSource(table.get()); + ResourceTableSymbolSource symbol_source(table.get()); EXPECT_NE(nullptr, - symbolSource.findByName(test::parseNameOrDie("android:id/foo"))); + symbol_source.FindByName(test::ParseNameOrDie("android:id/foo"))); EXPECT_NE(nullptr, - symbolSource.findByName(test::parseNameOrDie("android:id/bar"))); + symbol_source.FindByName(test::ParseNameOrDie("android:id/bar"))); std::unique_ptr<SymbolTable::Symbol> s = - symbolSource.findByName(test::parseNameOrDie("android:attr/foo")); + symbol_source.FindByName(test::ParseNameOrDie("android:attr/foo")); ASSERT_NE(nullptr, s); EXPECT_NE(nullptr, s->attribute); } @@ -43,13 +44,13 @@ TEST(ResourceTableSymbolSourceTest, FindSymbols) { TEST(ResourceTableSymbolSourceTest, FindPrivateAttrSymbol) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addValue("android:^attr-private/foo", ResourceId(0x01010000), - test::AttributeBuilder().build()) - .build(); + .AddValue("android:^attr-private/foo", ResourceId(0x01010000), + test::AttributeBuilder().Build()) + .Build(); - ResourceTableSymbolSource symbolSource(table.get()); + ResourceTableSymbolSource symbol_source(table.get()); std::unique_ptr<SymbolTable::Symbol> s = - symbolSource.findByName(test::parseNameOrDie("android:attr/foo")); + symbol_source.FindByName(test::ParseNameOrDie("android:attr/foo")); ASSERT_NE(nullptr, s); EXPECT_NE(nullptr, s->attribute); } diff --git a/tools/aapt2/proto/ProtoHelpers.cpp b/tools/aapt2/proto/ProtoHelpers.cpp index 2aa8aa500387..38bf4e3bd8eb 100644 --- a/tools/aapt2/proto/ProtoHelpers.cpp +++ b/tools/aapt2/proto/ProtoHelpers.cpp @@ -18,120 +18,151 @@ namespace aapt { -void serializeStringPoolToPb(const StringPool& pool, pb::StringPool* outPbPool) { - BigBuffer buffer(1024); - StringPool::flattenUtf8(&buffer, pool); - - std::string* data = outPbPool->mutable_data(); - data->reserve(buffer.size()); - - size_t offset = 0; - for (const BigBuffer::Block& block : buffer) { - data->insert(data->begin() + offset, block.buffer.get(), block.buffer.get() + block.size); - offset += block.size; - } +void SerializeStringPoolToPb(const StringPool& pool, + pb::StringPool* out_pb_pool) { + BigBuffer buffer(1024); + StringPool::FlattenUtf8(&buffer, pool); + + std::string* data = out_pb_pool->mutable_data(); + data->reserve(buffer.size()); + + size_t offset = 0; + for (const BigBuffer::Block& block : buffer) { + data->insert(data->begin() + offset, block.buffer.get(), + block.buffer.get() + block.size); + offset += block.size; + } } -void serializeSourceToPb(const Source& source, StringPool* srcPool, pb::Source* outPbSource) { - StringPool::Ref ref = srcPool->makeRef(source.path); - outPbSource->set_path_idx(static_cast<uint32_t>(ref.getIndex())); - if (source.line) { - outPbSource->set_line_no(static_cast<uint32_t>(source.line.value())); - } +void SerializeSourceToPb(const Source& source, StringPool* src_pool, + pb::Source* out_pb_source) { + StringPool::Ref ref = src_pool->MakeRef(source.path); + out_pb_source->set_path_idx(static_cast<uint32_t>(ref.index())); + if (source.line) { + out_pb_source->set_line_no(static_cast<uint32_t>(source.line.value())); + } } -void deserializeSourceFromPb(const pb::Source& pbSource, const android::ResStringPool& srcPool, - Source* outSource) { - if (pbSource.has_path_idx()) { - outSource->path = util::getString(srcPool, pbSource.path_idx()); - } +void DeserializeSourceFromPb(const pb::Source& pb_source, + const android::ResStringPool& src_pool, + Source* out_source) { + if (pb_source.has_path_idx()) { + out_source->path = util::GetString(src_pool, pb_source.path_idx()); + } - if (pbSource.has_line_no()) { - outSource->line = static_cast<size_t>(pbSource.line_no()); - } + if (pb_source.has_line_no()) { + out_source->line = static_cast<size_t>(pb_source.line_no()); + } } -pb::SymbolStatus_Visibility serializeVisibilityToPb(SymbolState state) { - switch (state) { - case SymbolState::kPrivate: return pb::SymbolStatus_Visibility_Private; - case SymbolState::kPublic: return pb::SymbolStatus_Visibility_Public; - default: break; - } - return pb::SymbolStatus_Visibility_Unknown; +pb::SymbolStatus_Visibility SerializeVisibilityToPb(SymbolState state) { + switch (state) { + case SymbolState::kPrivate: + return pb::SymbolStatus_Visibility_Private; + case SymbolState::kPublic: + return pb::SymbolStatus_Visibility_Public; + default: + break; + } + return pb::SymbolStatus_Visibility_Unknown; } -SymbolState deserializeVisibilityFromPb(pb::SymbolStatus_Visibility pbVisibility) { - switch (pbVisibility) { - case pb::SymbolStatus_Visibility_Private: return SymbolState::kPrivate; - case pb::SymbolStatus_Visibility_Public: return SymbolState::kPublic; - default: break; - } - return SymbolState::kUndefined; +SymbolState DeserializeVisibilityFromPb( + pb::SymbolStatus_Visibility pb_visibility) { + switch (pb_visibility) { + case pb::SymbolStatus_Visibility_Private: + return SymbolState::kPrivate; + case pb::SymbolStatus_Visibility_Public: + return SymbolState::kPublic; + default: + break; + } + return SymbolState::kUndefined; } -void serializeConfig(const ConfigDescription& config, pb::ConfigDescription* outPbConfig) { - android::ResTable_config flatConfig = config; - flatConfig.size = sizeof(flatConfig); - flatConfig.swapHtoD(); - outPbConfig->set_data(&flatConfig, sizeof(flatConfig)); +void SerializeConfig(const ConfigDescription& config, + pb::ConfigDescription* out_pb_config) { + android::ResTable_config flat_config = config; + flat_config.size = sizeof(flat_config); + flat_config.swapHtoD(); + out_pb_config->set_data(&flat_config, sizeof(flat_config)); } -bool deserializeConfigDescriptionFromPb(const pb::ConfigDescription& pbConfig, - ConfigDescription* outConfig) { - if (!pbConfig.has_data()) { - return false; - } - - const android::ResTable_config* config; - if (pbConfig.data().size() > sizeof(*config)) { - return false; - } - - config = reinterpret_cast<const android::ResTable_config*>(pbConfig.data().data()); - outConfig->copyFromDtoH(*config); - return true; +bool DeserializeConfigDescriptionFromPb(const pb::ConfigDescription& pb_config, + ConfigDescription* out_config) { + if (!pb_config.has_data()) { + return false; + } + + const android::ResTable_config* config; + if (pb_config.data().size() > sizeof(*config)) { + return false; + } + + config = reinterpret_cast<const android::ResTable_config*>( + pb_config.data().data()); + out_config->copyFromDtoH(*config); + return true; } -pb::Reference_Type serializeReferenceTypeToPb(Reference::Type type) { - switch (type) { - case Reference::Type::kResource: return pb::Reference_Type_Ref; - case Reference::Type::kAttribute: return pb::Reference_Type_Attr; - default: break; - } - return pb::Reference_Type_Ref; +pb::Reference_Type SerializeReferenceTypeToPb(Reference::Type type) { + switch (type) { + case Reference::Type::kResource: + return pb::Reference_Type_Ref; + case Reference::Type::kAttribute: + return pb::Reference_Type_Attr; + default: + break; + } + return pb::Reference_Type_Ref; } -Reference::Type deserializeReferenceTypeFromPb(pb::Reference_Type pbType) { - switch (pbType) { - case pb::Reference_Type_Ref: return Reference::Type::kResource; - case pb::Reference_Type_Attr: return Reference::Type::kAttribute; - default: break; - } - return Reference::Type::kResource; +Reference::Type DeserializeReferenceTypeFromPb(pb::Reference_Type pb_type) { + switch (pb_type) { + case pb::Reference_Type_Ref: + return Reference::Type::kResource; + case pb::Reference_Type_Attr: + return Reference::Type::kAttribute; + default: + break; + } + return Reference::Type::kResource; } -pb::Plural_Arity serializePluralEnumToPb(size_t pluralIdx) { - switch (pluralIdx) { - case Plural::Zero: return pb::Plural_Arity_Zero; - case Plural::One: return pb::Plural_Arity_One; - case Plural::Two: return pb::Plural_Arity_Two; - case Plural::Few: return pb::Plural_Arity_Few; - case Plural::Many: return pb::Plural_Arity_Many; - default: break; - } - return pb::Plural_Arity_Other; +pb::Plural_Arity SerializePluralEnumToPb(size_t plural_idx) { + switch (plural_idx) { + case Plural::Zero: + return pb::Plural_Arity_Zero; + case Plural::One: + return pb::Plural_Arity_One; + case Plural::Two: + return pb::Plural_Arity_Two; + case Plural::Few: + return pb::Plural_Arity_Few; + case Plural::Many: + return pb::Plural_Arity_Many; + default: + break; + } + return pb::Plural_Arity_Other; } -size_t deserializePluralEnumFromPb(pb::Plural_Arity arity) { - switch (arity) { - case pb::Plural_Arity_Zero: return Plural::Zero; - case pb::Plural_Arity_One: return Plural::One; - case pb::Plural_Arity_Two: return Plural::Two; - case pb::Plural_Arity_Few: return Plural::Few; - case pb::Plural_Arity_Many: return Plural::Many; - default: break; - } - return Plural::Other; +size_t DeserializePluralEnumFromPb(pb::Plural_Arity arity) { + switch (arity) { + case pb::Plural_Arity_Zero: + return Plural::Zero; + case pb::Plural_Arity_One: + return Plural::One; + case pb::Plural_Arity_Two: + return Plural::Two; + case pb::Plural_Arity_Few: + return Plural::Few; + case pb::Plural_Arity_Many: + return Plural::Many; + default: + break; + } + return Plural::Other; } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/proto/ProtoHelpers.h b/tools/aapt2/proto/ProtoHelpers.h index 7271e8bd7238..735cda0bde78 100644 --- a/tools/aapt2/proto/ProtoHelpers.h +++ b/tools/aapt2/proto/ProtoHelpers.h @@ -17,39 +17,44 @@ #ifndef AAPT_PROTO_PROTOHELPERS_H #define AAPT_PROTO_PROTOHELPERS_H +#include "androidfw/ResourceTypes.h" + #include "ConfigDescription.h" #include "ResourceTable.h" #include "Source.h" #include "StringPool.h" - #include "proto/frameworks/base/tools/aapt2/Format.pb.h" -#include <androidfw/ResourceTypes.h> - namespace aapt { -void serializeStringPoolToPb(const StringPool& pool, pb::StringPool* outPbPool); +void SerializeStringPoolToPb(const StringPool& pool, + pb::StringPool* out_pb_pool); + +void SerializeSourceToPb(const Source& source, StringPool* src_pool, + pb::Source* out_pb_source); + +void DeserializeSourceFromPb(const pb::Source& pb_source, + const android::ResStringPool& src_pool, + Source* out_source); + +pb::SymbolStatus_Visibility SerializeVisibilityToPb(SymbolState state); + +SymbolState DeserializeVisibilityFromPb( + pb::SymbolStatus_Visibility pb_visibility); + +void SerializeConfig(const ConfigDescription& config, + pb::ConfigDescription* out_pb_config); -void serializeSourceToPb(const Source& source, StringPool* srcPool, - pb::Source* outPbSource); -void deserializeSourceFromPb(const pb::Source& pbSource, - const android::ResStringPool& srcPool, - Source* outSource); +bool DeserializeConfigDescriptionFromPb(const pb::ConfigDescription& pb_config, + ConfigDescription* out_config); -pb::SymbolStatus_Visibility serializeVisibilityToPb(SymbolState state); -SymbolState deserializeVisibilityFromPb( - pb::SymbolStatus_Visibility pbVisibility); +pb::Reference_Type SerializeReferenceTypeToPb(Reference::Type type); -void serializeConfig(const ConfigDescription& config, - pb::ConfigDescription* outPbConfig); -bool deserializeConfigDescriptionFromPb(const pb::ConfigDescription& pbConfig, - ConfigDescription* outConfig); +Reference::Type DeserializeReferenceTypeFromPb(pb::Reference_Type pb_type); -pb::Reference_Type serializeReferenceTypeToPb(Reference::Type type); -Reference::Type deserializeReferenceTypeFromPb(pb::Reference_Type pbType); +pb::Plural_Arity SerializePluralEnumToPb(size_t plural_idx); -pb::Plural_Arity serializePluralEnumToPb(size_t pluralIdx); -size_t deserializePluralEnumFromPb(pb::Plural_Arity arity); +size_t DeserializePluralEnumFromPb(pb::Plural_Arity arity); } // namespace aapt diff --git a/tools/aapt2/proto/ProtoSerialize.h b/tools/aapt2/proto/ProtoSerialize.h index 378dafdb4dc6..39c50038d599 100644 --- a/tools/aapt2/proto/ProtoSerialize.h +++ b/tools/aapt2/proto/ProtoSerialize.h @@ -17,15 +17,15 @@ #ifndef AAPT_FLATTEN_TABLEPROTOSERIALIZER_H #define AAPT_FLATTEN_TABLEPROTOSERIALIZER_H +#include "android-base/macros.h" +#include "google/protobuf/io/coded_stream.h" +#include "google/protobuf/io/zero_copy_stream_impl_lite.h" + #include "Diagnostics.h" #include "ResourceTable.h" #include "Source.h" #include "proto/ProtoHelpers.h" -#include <android-base/macros.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl_lite.h> - namespace aapt { class CompiledFileOutputStream { @@ -42,9 +42,9 @@ class CompiledFileOutputStream { private: DISALLOW_COPY_AND_ASSIGN(CompiledFileOutputStream); - void ensureAlignedWrite(); + void EnsureAlignedWrite(); - google::protobuf::io::CodedOutputStream mOut; + google::protobuf::io::CodedOutputStream out_; }; class CompiledFileInputStream { @@ -58,18 +58,18 @@ class CompiledFileInputStream { private: DISALLOW_COPY_AND_ASSIGN(CompiledFileInputStream); - void ensureAlignedRead(); + void EnsureAlignedRead(); - google::protobuf::io::CodedInputStream mIn; + google::protobuf::io::CodedInputStream in_; }; -std::unique_ptr<pb::ResourceTable> serializeTableToPb(ResourceTable* table); -std::unique_ptr<ResourceTable> deserializeTableFromPb( +std::unique_ptr<pb::ResourceTable> SerializeTableToPb(ResourceTable* table); +std::unique_ptr<ResourceTable> DeserializeTableFromPb( const pb::ResourceTable& pbTable, const Source& source, IDiagnostics* diag); -std::unique_ptr<pb::CompiledFile> serializeCompiledFileToPb( +std::unique_ptr<pb::CompiledFile> SerializeCompiledFileToPb( const ResourceFile& file); -std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb( +std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb( const pb::CompiledFile& pbFile, const Source& source, IDiagnostics* diag); } // namespace aapt diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp index 0dfb01c181c6..d93d495b106f 100644 --- a/tools/aapt2/proto/TableProtoDeserializer.cpp +++ b/tools/aapt2/proto/TableProtoDeserializer.cpp @@ -14,13 +14,15 @@ * limitations under the License. */ +#include "proto/ProtoSerialize.h" + +#include "android-base/logging.h" +#include "androidfw/ResourceTypes.h" + #include "ResourceTable.h" #include "ResourceUtils.h" #include "ValueVisitor.h" #include "proto/ProtoHelpers.h" -#include "proto/ProtoSerialize.h" - -#include <androidfw/ResourceTypes.h> namespace aapt { @@ -28,28 +30,28 @@ namespace { class ReferenceIdToNameVisitor : public ValueVisitor { public: - using ValueVisitor::visit; + using ValueVisitor::Visit; explicit ReferenceIdToNameVisitor( const std::map<ResourceId, ResourceNameRef>* mapping) - : mMapping(mapping) { - assert(mMapping); + : mapping_(mapping) { + CHECK(mapping_ != nullptr); } - void visit(Reference* reference) override { - if (!reference->id || !reference->id.value().isValid()) { + void Visit(Reference* reference) override { + if (!reference->id || !reference->id.value().is_valid()) { return; } ResourceId id = reference->id.value(); - auto cacheIter = mMapping->find(id); - if (cacheIter != mMapping->end()) { - reference->name = cacheIter->second.toResourceName(); + auto cache_iter = mapping_->find(id); + if (cache_iter != mapping_->end()) { + reference->name = cache_iter->second.ToResourceName(); } } private: - const std::map<ResourceId, ResourceNameRef>* mMapping; + const std::map<ResourceId, ResourceNameRef>* mapping_; }; class PackagePbDeserializer { @@ -58,14 +60,14 @@ class PackagePbDeserializer { const android::ResStringPool* sourcePool, const android::ResStringPool* symbolPool, const Source& source, IDiagnostics* diag) - : mValuePool(valuePool), - mSourcePool(sourcePool), - mSymbolPool(symbolPool), - mSource(source), - mDiag(diag) {} + : value_pool_(valuePool), + source_pool_(sourcePool), + symbol_pool_(symbolPool), + source_(source), + diag_(diag) {} public: - bool deserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) { + bool DeserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) { Maybe<uint8_t> id; if (pbPackage.has_package_id()) { id = static_cast<uint8_t>(pbPackage.package_id()); @@ -74,36 +76,36 @@ class PackagePbDeserializer { std::map<ResourceId, ResourceNameRef> idIndex; ResourceTablePackage* pkg = - table->createPackage(pbPackage.package_name(), id); + table->CreatePackage(pbPackage.package_name(), id); for (const pb::Type& pbType : pbPackage.types()) { - const ResourceType* resType = parseResourceType(pbType.name()); + const ResourceType* resType = ParseResourceType(pbType.name()); if (!resType) { - mDiag->error(DiagMessage(mSource) << "unknown type '" << pbType.name() + diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name() << "'"); return {}; } - ResourceTableType* type = pkg->findOrCreateType(*resType); + ResourceTableType* type = pkg->FindOrCreateType(*resType); for (const pb::Entry& pbEntry : pbType.entries()) { - ResourceEntry* entry = type->findOrCreateEntry(pbEntry.name()); + ResourceEntry* entry = type->FindOrCreateEntry(pbEntry.name()); // Deserialize the symbol status (public/private with source and // comments). if (pbEntry.has_symbol_status()) { const pb::SymbolStatus& pbStatus = pbEntry.symbol_status(); if (pbStatus.has_source()) { - deserializeSourceFromPb(pbStatus.source(), *mSourcePool, - &entry->symbolStatus.source); + DeserializeSourceFromPb(pbStatus.source(), *source_pool_, + &entry->symbol_status.source); } if (pbStatus.has_comment()) { - entry->symbolStatus.comment = pbStatus.comment(); + entry->symbol_status.comment = pbStatus.comment(); } SymbolState visibility = - deserializeVisibilityFromPb(pbStatus.visibility()); - entry->symbolStatus.state = visibility; + DeserializeVisibilityFromPb(pbStatus.visibility()); + entry->symbol_status.state = visibility; if (visibility == SymbolState::kPublic) { // This is a public symbol, we must encode the ID now if there is @@ -112,22 +114,22 @@ class PackagePbDeserializer { entry->id = static_cast<uint16_t>(pbEntry.id()); } - if (type->symbolStatus.state != SymbolState::kPublic) { + if (type->symbol_status.state != SymbolState::kPublic) { // If the type has not been made public, do so now. - type->symbolStatus.state = SymbolState::kPublic; + type->symbol_status.state = SymbolState::kPublic; if (pbType.has_id()) { type->id = static_cast<uint8_t>(pbType.id()); } } } else if (visibility == SymbolState::kPrivate) { - if (type->symbolStatus.state == SymbolState::kUndefined) { - type->symbolStatus.state = SymbolState::kPrivate; + if (type->symbol_status.state == SymbolState::kUndefined) { + type->symbol_status.state = SymbolState::kPrivate; } } } ResourceId resId(pbPackage.package_id(), pbType.id(), pbEntry.id()); - if (resId.isValid()) { + if (resId.is_valid()) { idIndex[resId] = ResourceNameRef(pkg->name, type->type, entry->name); } @@ -135,21 +137,21 @@ class PackagePbDeserializer { const pb::ConfigDescription& pbConfig = pbConfigValue.config(); ConfigDescription config; - if (!deserializeConfigDescriptionFromPb(pbConfig, &config)) { - mDiag->error(DiagMessage(mSource) << "invalid configuration"); + if (!DeserializeConfigDescriptionFromPb(pbConfig, &config)) { + diag_->Error(DiagMessage(source_) << "invalid configuration"); return {}; } ResourceConfigValue* configValue = - entry->findOrCreateValue(config, pbConfig.product()); + entry->FindOrCreateValue(config, pbConfig.product()); if (configValue->value) { // Duplicate config. - mDiag->error(DiagMessage(mSource) << "duplicate configuration"); + diag_->Error(DiagMessage(source_) << "duplicate configuration"); return {}; } - configValue->value = deserializeValueFromPb( - pbConfigValue.value(), config, &table->stringPool); + configValue->value = DeserializeValueFromPb( + pbConfigValue.value(), config, &table->string_pool); if (!configValue->value) { return {}; } @@ -158,247 +160,247 @@ class PackagePbDeserializer { } ReferenceIdToNameVisitor visitor(&idIndex); - visitAllValuesInPackage(pkg, &visitor); + VisitAllValuesInPackage(pkg, &visitor); return true; } private: - std::unique_ptr<Item> deserializeItemFromPb(const pb::Item& pbItem, + std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item, const ConfigDescription& config, StringPool* pool) { - if (pbItem.has_ref()) { - const pb::Reference& pbRef = pbItem.ref(); + if (pb_item.has_ref()) { + const pb::Reference& pb_ref = pb_item.ref(); std::unique_ptr<Reference> ref = util::make_unique<Reference>(); - if (!deserializeReferenceFromPb(pbRef, ref.get())) { + if (!DeserializeReferenceFromPb(pb_ref, ref.get())) { return {}; } return std::move(ref); - } else if (pbItem.has_prim()) { - const pb::Primitive& pbPrim = pbItem.prim(); + } else if (pb_item.has_prim()) { + const pb::Primitive& pb_prim = pb_item.prim(); android::Res_value prim = {}; - prim.dataType = static_cast<uint8_t>(pbPrim.type()); - prim.data = pbPrim.data(); + prim.dataType = static_cast<uint8_t>(pb_prim.type()); + prim.data = pb_prim.data(); return util::make_unique<BinaryPrimitive>(prim); - } else if (pbItem.has_id()) { + } else if (pb_item.has_id()) { return util::make_unique<Id>(); - } else if (pbItem.has_str()) { - const uint32_t idx = pbItem.str().idx(); - const std::string str = util::getString(*mValuePool, idx); + } else if (pb_item.has_str()) { + const uint32_t idx = pb_item.str().idx(); + const std::string str = util::GetString(*value_pool_, idx); - const android::ResStringPool_span* spans = mValuePool->styleAt(idx); + const android::ResStringPool_span* spans = value_pool_->styleAt(idx); if (spans && spans->name.index != android::ResStringPool_span::END) { - StyleString styleStr = {str}; + StyleString style_str = {str}; while (spans->name.index != android::ResStringPool_span::END) { - styleStr.spans.push_back( - Span{util::getString(*mValuePool, spans->name.index), + style_str.spans.push_back( + Span{util::GetString(*value_pool_, spans->name.index), spans->firstChar, spans->lastChar}); spans++; } - return util::make_unique<StyledString>(pool->makeRef( - styleStr, + return util::make_unique<StyledString>(pool->MakeRef( + style_str, StringPool::Context(StringPool::Context::kStylePriority, config))); } return util::make_unique<String>( - pool->makeRef(str, StringPool::Context(config))); + pool->MakeRef(str, StringPool::Context(config))); - } else if (pbItem.has_raw_str()) { - const uint32_t idx = pbItem.raw_str().idx(); - const std::string str = util::getString(*mValuePool, idx); + } else if (pb_item.has_raw_str()) { + const uint32_t idx = pb_item.raw_str().idx(); + const std::string str = util::GetString(*value_pool_, idx); return util::make_unique<RawString>( - pool->makeRef(str, StringPool::Context(config))); + pool->MakeRef(str, StringPool::Context(config))); - } else if (pbItem.has_file()) { - const uint32_t idx = pbItem.file().path_idx(); - const std::string str = util::getString(*mValuePool, idx); - return util::make_unique<FileReference>(pool->makeRef( + } else if (pb_item.has_file()) { + const uint32_t idx = pb_item.file().path_idx(); + const std::string str = util::GetString(*value_pool_, idx); + return util::make_unique<FileReference>(pool->MakeRef( str, StringPool::Context(StringPool::Context::kHighPriority, config))); } else { - mDiag->error(DiagMessage(mSource) << "unknown item"); + diag_->Error(DiagMessage(source_) << "unknown item"); } return {}; } - std::unique_ptr<Value> deserializeValueFromPb(const pb::Value& pbValue, + std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value, const ConfigDescription& config, StringPool* pool) { - const bool isWeak = pbValue.has_weak() ? pbValue.weak() : false; + const bool is_weak = pb_value.has_weak() ? pb_value.weak() : false; std::unique_ptr<Value> value; - if (pbValue.has_item()) { - value = deserializeItemFromPb(pbValue.item(), config, pool); + if (pb_value.has_item()) { + value = DeserializeItemFromPb(pb_value.item(), config, pool); if (!value) { return {}; } - } else if (pbValue.has_compound_value()) { - const pb::CompoundValue& pbCompoundValue = pbValue.compound_value(); - if (pbCompoundValue.has_attr()) { - const pb::Attribute& pbAttr = pbCompoundValue.attr(); - std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(isWeak); - attr->typeMask = pbAttr.format_flags(); - attr->minInt = pbAttr.min_int(); - attr->maxInt = pbAttr.max_int(); - for (const pb::Attribute_Symbol& pbSymbol : pbAttr.symbols()) { + } else if (pb_value.has_compound_value()) { + const pb::CompoundValue& pb_compound_value = pb_value.compound_value(); + if (pb_compound_value.has_attr()) { + const pb::Attribute& pb_attr = pb_compound_value.attr(); + std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(is_weak); + attr->type_mask = pb_attr.format_flags(); + attr->min_int = pb_attr.min_int(); + attr->max_int = pb_attr.max_int(); + for (const pb::Attribute_Symbol& pb_symbol : pb_attr.symbols()) { Attribute::Symbol symbol; - deserializeItemCommon(pbSymbol, &symbol.symbol); - if (!deserializeReferenceFromPb(pbSymbol.name(), &symbol.symbol)) { + DeserializeItemCommon(pb_symbol, &symbol.symbol); + if (!DeserializeReferenceFromPb(pb_symbol.name(), &symbol.symbol)) { return {}; } - symbol.value = pbSymbol.value(); + symbol.value = pb_symbol.value(); attr->symbols.push_back(std::move(symbol)); } value = std::move(attr); - } else if (pbCompoundValue.has_style()) { - const pb::Style& pbStyle = pbCompoundValue.style(); + } else if (pb_compound_value.has_style()) { + const pb::Style& pb_style = pb_compound_value.style(); std::unique_ptr<Style> style = util::make_unique<Style>(); - if (pbStyle.has_parent()) { + if (pb_style.has_parent()) { style->parent = Reference(); - if (!deserializeReferenceFromPb(pbStyle.parent(), + if (!DeserializeReferenceFromPb(pb_style.parent(), &style->parent.value())) { return {}; } - if (pbStyle.has_parent_source()) { - Source parentSource; - deserializeSourceFromPb(pbStyle.parent_source(), *mSourcePool, - &parentSource); - style->parent.value().setSource(std::move(parentSource)); + if (pb_style.has_parent_source()) { + Source parent_source; + DeserializeSourceFromPb(pb_style.parent_source(), *source_pool_, + &parent_source); + style->parent.value().SetSource(std::move(parent_source)); } } - for (const pb::Style_Entry& pbEntry : pbStyle.entries()) { + for (const pb::Style_Entry& pb_entry : pb_style.entries()) { Style::Entry entry; - deserializeItemCommon(pbEntry, &entry.key); - if (!deserializeReferenceFromPb(pbEntry.key(), &entry.key)) { + DeserializeItemCommon(pb_entry, &entry.key); + if (!DeserializeReferenceFromPb(pb_entry.key(), &entry.key)) { return {}; } - entry.value = deserializeItemFromPb(pbEntry.item(), config, pool); + entry.value = DeserializeItemFromPb(pb_entry.item(), config, pool); if (!entry.value) { return {}; } - deserializeItemCommon(pbEntry, entry.value.get()); + DeserializeItemCommon(pb_entry, entry.value.get()); style->entries.push_back(std::move(entry)); } value = std::move(style); - } else if (pbCompoundValue.has_styleable()) { - const pb::Styleable& pbStyleable = pbCompoundValue.styleable(); + } else if (pb_compound_value.has_styleable()) { + const pb::Styleable& pb_styleable = pb_compound_value.styleable(); std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>(); - for (const pb::Styleable_Entry& pbEntry : pbStyleable.entries()) { - Reference attrRef; - deserializeItemCommon(pbEntry, &attrRef); - deserializeReferenceFromPb(pbEntry.attr(), &attrRef); - styleable->entries.push_back(std::move(attrRef)); + for (const pb::Styleable_Entry& pb_entry : pb_styleable.entries()) { + Reference attr_ref; + DeserializeItemCommon(pb_entry, &attr_ref); + DeserializeReferenceFromPb(pb_entry.attr(), &attr_ref); + styleable->entries.push_back(std::move(attr_ref)); } value = std::move(styleable); - } else if (pbCompoundValue.has_array()) { - const pb::Array& pbArray = pbCompoundValue.array(); + } else if (pb_compound_value.has_array()) { + const pb::Array& pb_array = pb_compound_value.array(); std::unique_ptr<Array> array = util::make_unique<Array>(); - for (const pb::Array_Entry& pbEntry : pbArray.entries()) { + for (const pb::Array_Entry& pb_entry : pb_array.entries()) { std::unique_ptr<Item> item = - deserializeItemFromPb(pbEntry.item(), config, pool); + DeserializeItemFromPb(pb_entry.item(), config, pool); if (!item) { return {}; } - deserializeItemCommon(pbEntry, item.get()); + DeserializeItemCommon(pb_entry, item.get()); array->items.push_back(std::move(item)); } value = std::move(array); - } else if (pbCompoundValue.has_plural()) { - const pb::Plural& pbPlural = pbCompoundValue.plural(); + } else if (pb_compound_value.has_plural()) { + const pb::Plural& pb_plural = pb_compound_value.plural(); std::unique_ptr<Plural> plural = util::make_unique<Plural>(); - for (const pb::Plural_Entry& pbEntry : pbPlural.entries()) { - size_t pluralIdx = deserializePluralEnumFromPb(pbEntry.arity()); + for (const pb::Plural_Entry& pb_entry : pb_plural.entries()) { + size_t pluralIdx = DeserializePluralEnumFromPb(pb_entry.arity()); plural->values[pluralIdx] = - deserializeItemFromPb(pbEntry.item(), config, pool); + DeserializeItemFromPb(pb_entry.item(), config, pool); if (!plural->values[pluralIdx]) { return {}; } - deserializeItemCommon(pbEntry, plural->values[pluralIdx].get()); + DeserializeItemCommon(pb_entry, plural->values[pluralIdx].get()); } value = std::move(plural); } else { - mDiag->error(DiagMessage(mSource) << "unknown compound value"); + diag_->Error(DiagMessage(source_) << "unknown compound value"); return {}; } } else { - mDiag->error(DiagMessage(mSource) << "unknown value"); + diag_->Error(DiagMessage(source_) << "unknown value"); return {}; } - assert(value && "forgot to set value"); + CHECK(value) << "forgot to set value"; - value->setWeak(isWeak); - deserializeItemCommon(pbValue, value.get()); + value->SetWeak(is_weak); + DeserializeItemCommon(pb_value, value.get()); return value; } - bool deserializeReferenceFromPb(const pb::Reference& pbRef, - Reference* outRef) { - outRef->referenceType = deserializeReferenceTypeFromPb(pbRef.type()); - outRef->privateReference = pbRef.private_(); + bool DeserializeReferenceFromPb(const pb::Reference& pb_ref, + Reference* out_ref) { + out_ref->reference_type = DeserializeReferenceTypeFromPb(pb_ref.type()); + out_ref->private_reference = pb_ref.private_(); - if (!pbRef.has_id() && !pbRef.has_symbol_idx()) { + if (!pb_ref.has_id() && !pb_ref.has_symbol_idx()) { return false; } - if (pbRef.has_id()) { - outRef->id = ResourceId(pbRef.id()); + if (pb_ref.has_id()) { + out_ref->id = ResourceId(pb_ref.id()); } - if (pbRef.has_symbol_idx()) { - const std::string strSymbol = - util::getString(*mSymbolPool, pbRef.symbol_idx()); - ResourceNameRef nameRef; - if (!ResourceUtils::parseResourceName(strSymbol, &nameRef, nullptr)) { - mDiag->error(DiagMessage(mSource) << "invalid reference name '" - << strSymbol << "'"); + if (pb_ref.has_symbol_idx()) { + const std::string str_symbol = + util::GetString(*symbol_pool_, pb_ref.symbol_idx()); + ResourceNameRef name_ref; + if (!ResourceUtils::ParseResourceName(str_symbol, &name_ref, nullptr)) { + diag_->Error(DiagMessage(source_) << "invalid reference name '" + << str_symbol << "'"); return false; } - outRef->name = nameRef.toResourceName(); + out_ref->name = name_ref.ToResourceName(); } return true; } template <typename T> - void deserializeItemCommon(const T& pbItem, Value* outValue) { - if (pbItem.has_source()) { + void DeserializeItemCommon(const T& pb_item, Value* out_value) { + if (pb_item.has_source()) { Source source; - deserializeSourceFromPb(pbItem.source(), *mSourcePool, &source); - outValue->setSource(std::move(source)); + DeserializeSourceFromPb(pb_item.source(), *source_pool_, &source); + out_value->SetSource(std::move(source)); } - if (pbItem.has_comment()) { - outValue->setComment(pbItem.comment()); + if (pb_item.has_comment()) { + out_value->SetComment(pb_item.comment()); } } private: - const android::ResStringPool* mValuePool; - const android::ResStringPool* mSourcePool; - const android::ResStringPool* mSymbolPool; - const Source mSource; - IDiagnostics* mDiag; + const android::ResStringPool* value_pool_; + const android::ResStringPool* source_pool_; + const android::ResStringPool* symbol_pool_; + const Source source_; + IDiagnostics* diag_; }; } // namespace -std::unique_ptr<ResourceTable> deserializeTableFromPb( - const pb::ResourceTable& pbTable, const Source& source, +std::unique_ptr<ResourceTable> DeserializeTableFromPb( + const pb::ResourceTable& pb_table, const Source& source, IDiagnostics* diag) { // We import the android namespace because on Windows NO_ERROR is a macro, not // an enum, which @@ -407,78 +409,79 @@ std::unique_ptr<ResourceTable> deserializeTableFromPb( std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>(); - if (!pbTable.has_string_pool()) { - diag->error(DiagMessage(source) << "no string pool found"); + if (!pb_table.has_string_pool()) { + diag->Error(DiagMessage(source) << "no string pool found"); return {}; } - ResStringPool valuePool; - status_t result = valuePool.setTo(pbTable.string_pool().data().data(), - pbTable.string_pool().data().size()); + ResStringPool value_pool; + status_t result = value_pool.setTo(pb_table.string_pool().data().data(), + pb_table.string_pool().data().size()); if (result != NO_ERROR) { - diag->error(DiagMessage(source) << "invalid string pool"); + diag->Error(DiagMessage(source) << "invalid string pool"); return {}; } - ResStringPool sourcePool; - if (pbTable.has_source_pool()) { - result = sourcePool.setTo(pbTable.source_pool().data().data(), - pbTable.source_pool().data().size()); + ResStringPool source_pool; + if (pb_table.has_source_pool()) { + result = source_pool.setTo(pb_table.source_pool().data().data(), + pb_table.source_pool().data().size()); if (result != NO_ERROR) { - diag->error(DiagMessage(source) << "invalid source pool"); + diag->Error(DiagMessage(source) << "invalid source pool"); return {}; } } - ResStringPool symbolPool; - if (pbTable.has_symbol_pool()) { - result = symbolPool.setTo(pbTable.symbol_pool().data().data(), - pbTable.symbol_pool().data().size()); + ResStringPool symbol_pool; + if (pb_table.has_symbol_pool()) { + result = symbol_pool.setTo(pb_table.symbol_pool().data().data(), + pb_table.symbol_pool().data().size()); if (result != NO_ERROR) { - diag->error(DiagMessage(source) << "invalid symbol pool"); + diag->Error(DiagMessage(source) << "invalid symbol pool"); return {}; } } - PackagePbDeserializer packagePbDeserializer(&valuePool, &sourcePool, - &symbolPool, source, diag); - for (const pb::Package& pbPackage : pbTable.packages()) { - if (!packagePbDeserializer.deserializeFromPb(pbPackage, table.get())) { + PackagePbDeserializer package_pb_deserializer(&value_pool, &source_pool, + &symbol_pool, source, diag); + for (const pb::Package& pb_package : pb_table.packages()) { + if (!package_pb_deserializer.DeserializeFromPb(pb_package, table.get())) { return {}; } } return table; } -std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb( - const pb::CompiledFile& pbFile, const Source& source, IDiagnostics* diag) { +std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb( + const pb::CompiledFile& pb_file, const Source& source, IDiagnostics* diag) { std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>(); - ResourceNameRef nameRef; + ResourceNameRef name_ref; // Need to create an lvalue here so that nameRef can point to something real. - if (!ResourceUtils::parseResourceName(pbFile.resource_name(), &nameRef)) { - diag->error(DiagMessage(source) + if (!ResourceUtils::ParseResourceName(pb_file.resource_name(), &name_ref)) { + diag->Error(DiagMessage(source) << "invalid resource name in compiled file header: " - << pbFile.resource_name()); + << pb_file.resource_name()); return {}; } - file->name = nameRef.toResourceName(); - file->source.path = pbFile.source_path(); - deserializeConfigDescriptionFromPb(pbFile.config(), &file->config); + file->name = name_ref.ToResourceName(); + file->source.path = pb_file.source_path(); + DeserializeConfigDescriptionFromPb(pb_file.config(), &file->config); - for (const pb::CompiledFile_Symbol& pbSymbol : pbFile.exported_symbols()) { + for (const pb::CompiledFile_Symbol& pb_symbol : pb_file.exported_symbols()) { // Need to create an lvalue here so that nameRef can point to something // real. - if (!ResourceUtils::parseResourceName(pbSymbol.resource_name(), &nameRef)) { - diag->error(DiagMessage(source) + if (!ResourceUtils::ParseResourceName(pb_symbol.resource_name(), + &name_ref)) { + diag->Error(DiagMessage(source) << "invalid resource name for exported symbol in " "compiled file header: " - << pbFile.resource_name()); + << pb_file.resource_name()); return {}; } - file->exportedSymbols.push_back( - SourcedResourceName{nameRef.toResourceName(), pbSymbol.line_no()}); + file->exported_symbols.push_back( + SourcedResourceName{name_ref.ToResourceName(), pb_symbol.line_no()}); } return file; } diff --git a/tools/aapt2/proto/TableProtoSerializer.cpp b/tools/aapt2/proto/TableProtoSerializer.cpp index a5c2cbc0277b..68db6b333bdc 100644 --- a/tools/aapt2/proto/TableProtoSerializer.cpp +++ b/tools/aapt2/proto/TableProtoSerializer.cpp @@ -22,6 +22,8 @@ #include "proto/ProtoSerialize.h" #include "util/BigBuffer.h" +#include <android-base/logging.h> + using google::protobuf::io::CodedOutputStream; using google::protobuf::io::CodedInputStream; using google::protobuf::io::ZeroCopyOutputStream; @@ -31,179 +33,185 @@ namespace aapt { namespace { class PbSerializerVisitor : public RawValueVisitor { -public: - using RawValueVisitor::visit; - - /** - * Constructor to use when expecting to serialize any value. - */ - PbSerializerVisitor(StringPool* sourcePool, StringPool* symbolPool, pb::Value* outPbValue) : - mSourcePool(sourcePool), mSymbolPool(symbolPool), mOutPbValue(outPbValue), - mOutPbItem(nullptr) { - } - - /** - * Constructor to use when expecting to serialize an Item. - */ - PbSerializerVisitor(StringPool* sourcePool, StringPool* symbolPool, pb::Item* outPbItem) : - mSourcePool(sourcePool), mSymbolPool(symbolPool), mOutPbValue(nullptr), - mOutPbItem(outPbItem) { - } - - void visit(Reference* ref) override { - serializeReferenceToPb(*ref, getPbItem()->mutable_ref()); - } - - void visit(String* str) override { - getPbItem()->mutable_str()->set_idx(str->value.getIndex()); + public: + using RawValueVisitor::Visit; + + /** + * Constructor to use when expecting to serialize any value. + */ + PbSerializerVisitor(StringPool* source_pool, StringPool* symbol_pool, + pb::Value* out_pb_value) + : source_pool_(source_pool), + symbol_pool_(symbol_pool), + out_pb_value_(out_pb_value), + out_pb_item_(nullptr) {} + + /** + * Constructor to use when expecting to serialize an Item. + */ + PbSerializerVisitor(StringPool* sourcePool, StringPool* symbolPool, + pb::Item* outPbItem) + : source_pool_(sourcePool), + symbol_pool_(symbolPool), + out_pb_value_(nullptr), + out_pb_item_(outPbItem) {} + + void Visit(Reference* ref) override { + SerializeReferenceToPb(*ref, pb_item()->mutable_ref()); + } + + void Visit(String* str) override { + pb_item()->mutable_str()->set_idx(str->value.index()); + } + + void Visit(StyledString* str) override { + pb_item()->mutable_str()->set_idx(str->value.index()); + } + + void Visit(FileReference* file) override { + pb_item()->mutable_file()->set_path_idx(file->path.index()); + } + + void Visit(Id* id) override { pb_item()->mutable_id(); } + + void Visit(RawString* raw_str) override { + pb_item()->mutable_raw_str()->set_idx(raw_str->value.index()); + } + + void Visit(BinaryPrimitive* prim) override { + android::Res_value val = {}; + prim->Flatten(&val); + + pb::Primitive* pb_prim = pb_item()->mutable_prim(); + pb_prim->set_type(val.dataType); + pb_prim->set_data(val.data); + } + + void VisitItem(Item* item) override { LOG(FATAL) << "unimplemented item"; } + + void Visit(Attribute* attr) override { + pb::Attribute* pb_attr = pb_compound_value()->mutable_attr(); + pb_attr->set_format_flags(attr->type_mask); + pb_attr->set_min_int(attr->min_int); + pb_attr->set_max_int(attr->max_int); + + for (auto& symbol : attr->symbols) { + pb::Attribute_Symbol* pb_symbol = pb_attr->add_symbols(); + SerializeItemCommonToPb(symbol.symbol, pb_symbol); + SerializeReferenceToPb(symbol.symbol, pb_symbol->mutable_name()); + pb_symbol->set_value(symbol.value); } - - void visit(StyledString* str) override { - getPbItem()->mutable_str()->set_idx(str->value.getIndex()); + } + + void Visit(Style* style) override { + pb::Style* pb_style = pb_compound_value()->mutable_style(); + if (style->parent) { + SerializeReferenceToPb(style->parent.value(), pb_style->mutable_parent()); + SerializeSourceToPb(style->parent.value().GetSource(), source_pool_, + pb_style->mutable_parent_source()); } - void visit(FileReference* file) override { - getPbItem()->mutable_file()->set_path_idx(file->path.getIndex()); - } + for (Style::Entry& entry : style->entries) { + pb::Style_Entry* pb_entry = pb_style->add_entries(); + SerializeReferenceToPb(entry.key, pb_entry->mutable_key()); - void visit(Id* id) override { - getPbItem()->mutable_id(); + pb::Item* pb_item = pb_entry->mutable_item(); + SerializeItemCommonToPb(entry.key, pb_entry); + PbSerializerVisitor sub_visitor(source_pool_, symbol_pool_, pb_item); + entry.value->Accept(&sub_visitor); } - - void visit(RawString* rawStr) override { - getPbItem()->mutable_raw_str()->set_idx(rawStr->value.getIndex()); + } + + void Visit(Styleable* styleable) override { + pb::Styleable* pb_styleable = pb_compound_value()->mutable_styleable(); + for (Reference& entry : styleable->entries) { + pb::Styleable_Entry* pb_entry = pb_styleable->add_entries(); + SerializeItemCommonToPb(entry, pb_entry); + SerializeReferenceToPb(entry, pb_entry->mutable_attr()); } - - void visit(BinaryPrimitive* prim) override { - android::Res_value val = {}; - prim->flatten(&val); - - pb::Primitive* pbPrim = getPbItem()->mutable_prim(); - pbPrim->set_type(val.dataType); - pbPrim->set_data(val.data); - } - - void visitItem(Item* item) override { - assert(false && "unimplemented item"); + } + + void Visit(Array* array) override { + pb::Array* pb_array = pb_compound_value()->mutable_array(); + for (auto& value : array->items) { + pb::Array_Entry* pb_entry = pb_array->add_entries(); + SerializeItemCommonToPb(*value, pb_entry); + PbSerializerVisitor sub_visitor(source_pool_, symbol_pool_, + pb_entry->mutable_item()); + value->Accept(&sub_visitor); } - - void visit(Attribute* attr) override { - pb::Attribute* pbAttr = getPbCompoundValue()->mutable_attr(); - pbAttr->set_format_flags(attr->typeMask); - pbAttr->set_min_int(attr->minInt); - pbAttr->set_max_int(attr->maxInt); - - for (auto& symbol : attr->symbols) { - pb::Attribute_Symbol* pbSymbol = pbAttr->add_symbols(); - serializeItemCommonToPb(symbol.symbol, pbSymbol); - serializeReferenceToPb(symbol.symbol, pbSymbol->mutable_name()); - pbSymbol->set_value(symbol.value); - } + } + + void Visit(Plural* plural) override { + pb::Plural* pb_plural = pb_compound_value()->mutable_plural(); + const size_t count = plural->values.size(); + for (size_t i = 0; i < count; i++) { + if (!plural->values[i]) { + // No plural value set here. + continue; + } + + pb::Plural_Entry* pb_entry = pb_plural->add_entries(); + pb_entry->set_arity(SerializePluralEnumToPb(i)); + pb::Item* pb_element = pb_entry->mutable_item(); + SerializeItemCommonToPb(*plural->values[i], pb_entry); + PbSerializerVisitor sub_visitor(source_pool_, symbol_pool_, pb_element); + plural->values[i]->Accept(&sub_visitor); } + } - void visit(Style* style) override { - pb::Style* pbStyle = getPbCompoundValue()->mutable_style(); - if (style->parent) { - serializeReferenceToPb(style->parent.value(), pbStyle->mutable_parent()); - serializeSourceToPb(style->parent.value().getSource(), - mSourcePool, - pbStyle->mutable_parent_source()); - } - - for (Style::Entry& entry : style->entries) { - pb::Style_Entry* pbEntry = pbStyle->add_entries(); - serializeReferenceToPb(entry.key, pbEntry->mutable_key()); - - pb::Item* pbItem = pbEntry->mutable_item(); - serializeItemCommonToPb(entry.key, pbEntry); - PbSerializerVisitor subVisitor(mSourcePool, mSymbolPool, pbItem); - entry.value->accept(&subVisitor); - } - } + private: + DISALLOW_COPY_AND_ASSIGN(PbSerializerVisitor); - void visit(Styleable* styleable) override { - pb::Styleable* pbStyleable = getPbCompoundValue()->mutable_styleable(); - for (Reference& entry : styleable->entries) { - pb::Styleable_Entry* pbEntry = pbStyleable->add_entries(); - serializeItemCommonToPb(entry, pbEntry); - serializeReferenceToPb(entry, pbEntry->mutable_attr()); - } + pb::Item* pb_item() { + if (out_pb_value_) { + return out_pb_value_->mutable_item(); } - - void visit(Array* array) override { - pb::Array* pbArray = getPbCompoundValue()->mutable_array(); - for (auto& value : array->items) { - pb::Array_Entry* pbEntry = pbArray->add_entries(); - serializeItemCommonToPb(*value, pbEntry); - PbSerializerVisitor subVisitor(mSourcePool, mSymbolPool, pbEntry->mutable_item()); - value->accept(&subVisitor); - } + return out_pb_item_; + } + + pb::CompoundValue* pb_compound_value() { + CHECK(out_pb_value_ != nullptr); + return out_pb_value_->mutable_compound_value(); + } + + template <typename T> + void SerializeItemCommonToPb(const Item& item, T* pb_item) { + SerializeSourceToPb(item.GetSource(), source_pool_, + pb_item->mutable_source()); + if (!item.GetComment().empty()) { + pb_item->set_comment(item.GetComment()); } + } - void visit(Plural* plural) override { - pb::Plural* pbPlural = getPbCompoundValue()->mutable_plural(); - const size_t count = plural->values.size(); - for (size_t i = 0; i < count; i++) { - if (!plural->values[i]) { - // No plural value set here. - continue; - } - - pb::Plural_Entry* pbEntry = pbPlural->add_entries(); - pbEntry->set_arity(serializePluralEnumToPb(i)); - pb::Item* pbElement = pbEntry->mutable_item(); - serializeItemCommonToPb(*plural->values[i], pbEntry); - PbSerializerVisitor subVisitor(mSourcePool, mSymbolPool, pbElement); - plural->values[i]->accept(&subVisitor); - } + void SerializeReferenceToPb(const Reference& ref, pb::Reference* pb_ref) { + if (ref.id) { + pb_ref->set_id(ref.id.value().id); } -private: - pb::Item* getPbItem() { - if (mOutPbValue) { - return mOutPbValue->mutable_item(); - } - return mOutPbItem; + if (ref.name) { + StringPool::Ref symbol_ref = + symbol_pool_->MakeRef(ref.name.value().ToString()); + pb_ref->set_symbol_idx(static_cast<uint32_t>(symbol_ref.index())); } - pb::CompoundValue* getPbCompoundValue() { - assert(mOutPbValue); - return mOutPbValue->mutable_compound_value(); - } + pb_ref->set_private_(ref.private_reference); + pb_ref->set_type(SerializeReferenceTypeToPb(ref.reference_type)); + } - template <typename T> - void serializeItemCommonToPb(const Item& item, T* pbItem) { - serializeSourceToPb(item.getSource(), mSourcePool, pbItem->mutable_source()); - if (!item.getComment().empty()) { - pbItem->set_comment(item.getComment()); - } - } - - void serializeReferenceToPb(const Reference& ref, pb::Reference* pbRef) { - if (ref.id) { - pbRef->set_id(ref.id.value().id); - } - - if (ref.name) { - StringPool::Ref symbolRef = mSymbolPool->makeRef(ref.name.value().toString()); - pbRef->set_symbol_idx(static_cast<uint32_t>(symbolRef.getIndex())); - } - - pbRef->set_private_(ref.privateReference); - pbRef->set_type(serializeReferenceTypeToPb(ref.referenceType)); - } - - StringPool* mSourcePool; - StringPool* mSymbolPool; - pb::Value* mOutPbValue; - pb::Item* mOutPbItem; + StringPool* source_pool_; + StringPool* symbol_pool_; + pb::Value* out_pb_value_; + pb::Item* out_pb_item_; }; -} // namespace +} // namespace -std::unique_ptr<pb::ResourceTable> serializeTableToPb(ResourceTable* table) { - // We must do this before writing the resources, since the string pool IDs may change. - table->stringPool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { +std::unique_ptr<pb::ResourceTable> SerializeTableToPb(ResourceTable* table) { + // We must do this before writing the resources, since the string pool IDs may + // change. + table->string_pool.Sort( + [](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { int diff = a.context.priority - b.context.priority; if (diff < 0) return true; if (diff > 0) return false; @@ -211,192 +219,195 @@ std::unique_ptr<pb::ResourceTable> serializeTableToPb(ResourceTable* table) { if (diff < 0) return true; if (diff > 0) return false; return a.value < b.value; - }); - table->stringPool.prune(); + }); + table->string_pool.Prune(); - auto pbTable = util::make_unique<pb::ResourceTable>(); - serializeStringPoolToPb(table->stringPool, pbTable->mutable_string_pool()); + auto pb_table = util::make_unique<pb::ResourceTable>(); + SerializeStringPoolToPb(table->string_pool, pb_table->mutable_string_pool()); - StringPool sourcePool, symbolPool; + StringPool source_pool, symbol_pool; - for (auto& package : table->packages) { - pb::Package* pbPackage = pbTable->add_packages(); - if (package->id) { - pbPackage->set_package_id(package->id.value()); + for (auto& package : table->packages) { + pb::Package* pb_package = pb_table->add_packages(); + if (package->id) { + pb_package->set_package_id(package->id.value()); + } + pb_package->set_package_name(package->name); + + for (auto& type : package->types) { + pb::Type* pb_type = pb_package->add_types(); + if (type->id) { + pb_type->set_id(type->id.value()); + } + pb_type->set_name(ToString(type->type).ToString()); + + for (auto& entry : type->entries) { + pb::Entry* pb_entry = pb_type->add_entries(); + if (entry->id) { + pb_entry->set_id(entry->id.value()); } - pbPackage->set_package_name(package->name); - - for (auto& type : package->types) { - pb::Type* pbType = pbPackage->add_types(); - if (type->id) { - pbType->set_id(type->id.value()); - } - pbType->set_name(toString(type->type).toString()); - - for (auto& entry : type->entries) { - pb::Entry* pbEntry = pbType->add_entries(); - if (entry->id) { - pbEntry->set_id(entry->id.value()); - } - pbEntry->set_name(entry->name); - - // Write the SymbolStatus struct. - pb::SymbolStatus* pbStatus = pbEntry->mutable_symbol_status(); - pbStatus->set_visibility(serializeVisibilityToPb(entry->symbolStatus.state)); - serializeSourceToPb(entry->symbolStatus.source, &sourcePool, - pbStatus->mutable_source()); - pbStatus->set_comment(entry->symbolStatus.comment); - - for (auto& configValue : entry->values) { - pb::ConfigValue* pbConfigValue = pbEntry->add_config_values(); - serializeConfig(configValue->config, pbConfigValue->mutable_config()); - if (!configValue->product.empty()) { - pbConfigValue->mutable_config()->set_product(configValue->product); - } - - pb::Value* pbValue = pbConfigValue->mutable_value(); - serializeSourceToPb(configValue->value->getSource(), &sourcePool, - pbValue->mutable_source()); - if (!configValue->value->getComment().empty()) { - pbValue->set_comment(configValue->value->getComment()); - } - - if (configValue->value->isWeak()) { - pbValue->set_weak(true); - } - - PbSerializerVisitor visitor(&sourcePool, &symbolPool, pbValue); - configValue->value->accept(&visitor); - } - } + pb_entry->set_name(entry->name); + + // Write the SymbolStatus struct. + pb::SymbolStatus* pb_status = pb_entry->mutable_symbol_status(); + pb_status->set_visibility( + SerializeVisibilityToPb(entry->symbol_status.state)); + SerializeSourceToPb(entry->symbol_status.source, &source_pool, + pb_status->mutable_source()); + pb_status->set_comment(entry->symbol_status.comment); + + for (auto& config_value : entry->values) { + pb::ConfigValue* pb_config_value = pb_entry->add_config_values(); + SerializeConfig(config_value->config, + pb_config_value->mutable_config()); + if (!config_value->product.empty()) { + pb_config_value->mutable_config()->set_product( + config_value->product); + } + + pb::Value* pb_value = pb_config_value->mutable_value(); + SerializeSourceToPb(config_value->value->GetSource(), &source_pool, + pb_value->mutable_source()); + if (!config_value->value->GetComment().empty()) { + pb_value->set_comment(config_value->value->GetComment()); + } + + if (config_value->value->IsWeak()) { + pb_value->set_weak(true); + } + + PbSerializerVisitor visitor(&source_pool, &symbol_pool, pb_value); + config_value->value->Accept(&visitor); } + } } + } - serializeStringPoolToPb(sourcePool, pbTable->mutable_source_pool()); - serializeStringPoolToPb(symbolPool, pbTable->mutable_symbol_pool()); - return pbTable; + SerializeStringPoolToPb(source_pool, pb_table->mutable_source_pool()); + SerializeStringPoolToPb(symbol_pool, pb_table->mutable_symbol_pool()); + return pb_table; } -std::unique_ptr<pb::CompiledFile> serializeCompiledFileToPb(const ResourceFile& file) { - auto pbFile = util::make_unique<pb::CompiledFile>(); - pbFile->set_resource_name(file.name.toString()); - pbFile->set_source_path(file.source.path); - serializeConfig(file.config, pbFile->mutable_config()); - - for (const SourcedResourceName& exported : file.exportedSymbols) { - pb::CompiledFile_Symbol* pbSymbol = pbFile->add_exported_symbols(); - pbSymbol->set_resource_name(exported.name.toString()); - pbSymbol->set_line_no(exported.line); - } - return pbFile; +std::unique_ptr<pb::CompiledFile> SerializeCompiledFileToPb( + const ResourceFile& file) { + auto pb_file = util::make_unique<pb::CompiledFile>(); + pb_file->set_resource_name(file.name.ToString()); + pb_file->set_source_path(file.source.path); + SerializeConfig(file.config, pb_file->mutable_config()); + + for (const SourcedResourceName& exported : file.exported_symbols) { + pb::CompiledFile_Symbol* pb_symbol = pb_file->add_exported_symbols(); + pb_symbol->set_resource_name(exported.name.ToString()); + pb_symbol->set_line_no(exported.line); + } + return pb_file; } -CompiledFileOutputStream::CompiledFileOutputStream(ZeroCopyOutputStream* out) : mOut(out) { -} +CompiledFileOutputStream::CompiledFileOutputStream(ZeroCopyOutputStream* out) + : out_(out) {} -void CompiledFileOutputStream::ensureAlignedWrite() { - const int padding = mOut.ByteCount() % 4; - if (padding > 0) { - uint32_t zero = 0u; - mOut.WriteRaw(&zero, padding); - } +void CompiledFileOutputStream::EnsureAlignedWrite() { + const int padding = out_.ByteCount() % 4; + if (padding > 0) { + uint32_t zero = 0u; + out_.WriteRaw(&zero, padding); + } } void CompiledFileOutputStream::WriteLittleEndian32(uint32_t val) { - ensureAlignedWrite(); - mOut.WriteLittleEndian32(val); + EnsureAlignedWrite(); + out_.WriteLittleEndian32(val); } -void CompiledFileOutputStream::WriteCompiledFile(const pb::CompiledFile* compiledFile) { - ensureAlignedWrite(); - mOut.WriteLittleEndian64(static_cast<uint64_t>(compiledFile->ByteSize())); - compiledFile->SerializeWithCachedSizes(&mOut); +void CompiledFileOutputStream::WriteCompiledFile( + const pb::CompiledFile* compiled_file) { + EnsureAlignedWrite(); + out_.WriteLittleEndian64(static_cast<uint64_t>(compiled_file->ByteSize())); + compiled_file->SerializeWithCachedSizes(&out_); } void CompiledFileOutputStream::WriteData(const BigBuffer* buffer) { - ensureAlignedWrite(); - mOut.WriteLittleEndian64(static_cast<uint64_t>(buffer->size())); - for (const BigBuffer::Block& block : *buffer) { - mOut.WriteRaw(block.buffer.get(), block.size); - } + EnsureAlignedWrite(); + out_.WriteLittleEndian64(static_cast<uint64_t>(buffer->size())); + for (const BigBuffer::Block& block : *buffer) { + out_.WriteRaw(block.buffer.get(), block.size); + } } void CompiledFileOutputStream::WriteData(const void* data, size_t len) { - ensureAlignedWrite(); - mOut.WriteLittleEndian64(static_cast<uint64_t>(len)); - mOut.WriteRaw(data, len); + EnsureAlignedWrite(); + out_.WriteLittleEndian64(static_cast<uint64_t>(len)); + out_.WriteRaw(data, len); } -bool CompiledFileOutputStream::HadError() { - return mOut.HadError(); -} +bool CompiledFileOutputStream::HadError() { return out_.HadError(); } -CompiledFileInputStream::CompiledFileInputStream(const void* data, size_t size) : - mIn(static_cast<const uint8_t*>(data), size) { -} +CompiledFileInputStream::CompiledFileInputStream(const void* data, size_t size) + : in_(static_cast<const uint8_t*>(data), size) {} -void CompiledFileInputStream::ensureAlignedRead() { - const int padding = mIn.CurrentPosition() % 4; - if (padding > 0) { - // Reads are always 4 byte aligned. - mIn.Skip(padding); - } +void CompiledFileInputStream::EnsureAlignedRead() { + const int padding = in_.CurrentPosition() % 4; + if (padding > 0) { + // Reads are always 4 byte aligned. + in_.Skip(padding); + } } -bool CompiledFileInputStream::ReadLittleEndian32(uint32_t* outVal) { - ensureAlignedRead(); - return mIn.ReadLittleEndian32(outVal); +bool CompiledFileInputStream::ReadLittleEndian32(uint32_t* out_val) { + EnsureAlignedRead(); + return in_.ReadLittleEndian32(out_val); } -bool CompiledFileInputStream::ReadCompiledFile(pb::CompiledFile* outVal) { - ensureAlignedRead(); +bool CompiledFileInputStream::ReadCompiledFile(pb::CompiledFile* out_val) { + EnsureAlignedRead(); - uint64_t pbSize = 0u; - if (!mIn.ReadLittleEndian64(&pbSize)) { - return false; - } + uint64_t pb_size = 0u; + if (!in_.ReadLittleEndian64(&pb_size)) { + return false; + } - CodedInputStream::Limit l = mIn.PushLimit(static_cast<int>(pbSize)); + CodedInputStream::Limit l = in_.PushLimit(static_cast<int>(pb_size)); - // Check that we haven't tried to read past the end. - if (static_cast<uint64_t>(mIn.BytesUntilLimit()) != pbSize) { - mIn.PopLimit(l); - mIn.PushLimit(0); - return false; - } + // Check that we haven't tried to read past the end. + if (static_cast<uint64_t>(in_.BytesUntilLimit()) != pb_size) { + in_.PopLimit(l); + in_.PushLimit(0); + return false; + } - if (!outVal->ParsePartialFromCodedStream(&mIn)) { - mIn.PopLimit(l); - mIn.PushLimit(0); - return false; - } + if (!out_val->ParsePartialFromCodedStream(&in_)) { + in_.PopLimit(l); + in_.PushLimit(0); + return false; + } - mIn.PopLimit(l); - return true; + in_.PopLimit(l); + return true; } -bool CompiledFileInputStream::ReadDataMetaData(uint64_t* outOffset, uint64_t* outLen) { - ensureAlignedRead(); - - uint64_t pbSize = 0u; - if (!mIn.ReadLittleEndian64(&pbSize)) { - return false; - } - - // Check that we aren't trying to read past the end. - if (pbSize > static_cast<uint64_t>(mIn.BytesUntilLimit())) { - mIn.PushLimit(0); - return false; - } - - uint64_t offset = static_cast<uint64_t>(mIn.CurrentPosition()); - if (!mIn.Skip(pbSize)) { - return false; - } - - *outOffset = offset; - *outLen = pbSize; - return true; +bool CompiledFileInputStream::ReadDataMetaData(uint64_t* out_offset, + uint64_t* out_len) { + EnsureAlignedRead(); + + uint64_t pb_size = 0u; + if (!in_.ReadLittleEndian64(&pb_size)) { + return false; + } + + // Check that we aren't trying to read past the end. + if (pb_size > static_cast<uint64_t>(in_.BytesUntilLimit())) { + in_.PushLimit(0); + return false; + } + + uint64_t offset = static_cast<uint64_t>(in_.CurrentPosition()); + if (!in_.Skip(pb_size)) { + return false; + } + + *out_offset = offset; + *out_len = pb_size; + return true; } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/proto/TableProtoSerializer_test.cpp b/tools/aapt2/proto/TableProtoSerializer_test.cpp index 2bd976796f53..fdd5197167ef 100644 --- a/tools/aapt2/proto/TableProtoSerializer_test.cpp +++ b/tools/aapt2/proto/TableProtoSerializer_test.cpp @@ -14,200 +14,211 @@ * limitations under the License. */ -#include "ResourceTable.h" #include "proto/ProtoSerialize.h" + +#include "ResourceTable.h" #include "test/Test.h" -using namespace google::protobuf::io; +using ::google::protobuf::io::StringOutputStream; namespace aapt { TEST(TableProtoSerializer, SerializeSinglePackage) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .setPackageId("com.app.a", 0x7f) - .addFileReference("com.app.a:layout/main", ResourceId(0x7f020000), - "res/layout/main.xml") - .addReference("com.app.a:layout/other", ResourceId(0x7f020001), - "com.app.a:layout/main") - .addString("com.app.a:string/text", {}, "hi") - .addValue("com.app.a:id/foo", {}, util::make_unique<Id>()) - .build(); - - Symbol publicSymbol; - publicSymbol.state = SymbolState::kPublic; - ASSERT_TRUE(table->setSymbolState(test::parseNameOrDie("com.app.a:layout/main"), - ResourceId(0x7f020000), - publicSymbol, context->getDiagnostics())); - - Id* id = test::getValue<Id>(table.get(), "com.app.a:id/foo"); - ASSERT_NE(nullptr, id); - - // Make a plural. - std::unique_ptr<Plural> plural = util::make_unique<Plural>(); - plural->values[Plural::One] = util::make_unique<String>(table->stringPool.makeRef("one")); - ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:plurals/hey"), - ConfigDescription{}, {}, std::move(plural), - context->getDiagnostics())); - - // Make a resource with different products. - ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:integer/one"), - test::parseConfigOrDie("land"), {}, - test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 123u), - context->getDiagnostics())); - ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:integer/one"), - test::parseConfigOrDie("land"), "tablet", - test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 321u), - context->getDiagnostics())); - - // Make a reference with both resource name and resource ID. - // The reference should point to a resource outside of this table to test that both - // name and id get serialized. - Reference expectedRef; - expectedRef.name = test::parseNameOrDie("android:layout/main"); - expectedRef.id = ResourceId(0x01020000); - ASSERT_TRUE(table->addResource(test::parseNameOrDie("com.app.a:layout/abc"), - ConfigDescription::defaultConfig(), {}, - util::make_unique<Reference>(expectedRef), - context->getDiagnostics())); - - std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(table.get()); - ASSERT_NE(nullptr, pbTable); - - std::unique_ptr<ResourceTable> newTable = deserializeTableFromPb(*pbTable, - Source{ "test" }, - context->getDiagnostics()); - ASSERT_NE(nullptr, newTable); - - Id* newId = test::getValue<Id>(newTable.get(), "com.app.a:id/foo"); - ASSERT_NE(nullptr, newId); - EXPECT_EQ(id->isWeak(), newId->isWeak()); - - Maybe<ResourceTable::SearchResult> result = newTable->findResource( - test::parseNameOrDie("com.app.a:layout/main")); - AAPT_ASSERT_TRUE(result); - EXPECT_EQ(SymbolState::kPublic, result.value().type->symbolStatus.state); - EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbolStatus.state); - - // Find the product-dependent values - BinaryPrimitive* prim = test::getValueForConfigAndProduct<BinaryPrimitive>( - newTable.get(), "com.app.a:integer/one", test::parseConfigOrDie("land"), ""); - ASSERT_NE(nullptr, prim); - EXPECT_EQ(123u, prim->value.data); - - prim = test::getValueForConfigAndProduct<BinaryPrimitive>( - newTable.get(), "com.app.a:integer/one", test::parseConfigOrDie("land"), "tablet"); - ASSERT_NE(nullptr, prim); - EXPECT_EQ(321u, prim->value.data); - - Reference* actualRef = test::getValue<Reference>(newTable.get(), "com.app.a:layout/abc"); - ASSERT_NE(nullptr, actualRef); - AAPT_ASSERT_TRUE(actualRef->name); - AAPT_ASSERT_TRUE(actualRef->id); - EXPECT_EQ(expectedRef.name.value(), actualRef->name.value()); - EXPECT_EQ(expectedRef.id.value(), actualRef->id.value()); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .SetPackageId("com.app.a", 0x7f) + .AddFileReference("com.app.a:layout/main", ResourceId(0x7f020000), + "res/layout/main.xml") + .AddReference("com.app.a:layout/other", ResourceId(0x7f020001), + "com.app.a:layout/main") + .AddString("com.app.a:string/text", {}, "hi") + .AddValue("com.app.a:id/foo", {}, util::make_unique<Id>()) + .Build(); + + Symbol public_symbol; + public_symbol.state = SymbolState::kPublic; + ASSERT_TRUE(table->SetSymbolState( + test::ParseNameOrDie("com.app.a:layout/main"), ResourceId(0x7f020000), + public_symbol, context->GetDiagnostics())); + + Id* id = test::GetValue<Id>(table.get(), "com.app.a:id/foo"); + ASSERT_NE(nullptr, id); + + // Make a plural. + std::unique_ptr<Plural> plural = util::make_unique<Plural>(); + plural->values[Plural::One] = + util::make_unique<String>(table->string_pool.MakeRef("one")); + ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("com.app.a:plurals/hey"), + ConfigDescription{}, {}, std::move(plural), + context->GetDiagnostics())); + + // Make a resource with different products. + ASSERT_TRUE(table->AddResource( + test::ParseNameOrDie("com.app.a:integer/one"), + test::ParseConfigOrDie("land"), {}, + test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 123u), + context->GetDiagnostics())); + ASSERT_TRUE(table->AddResource( + test::ParseNameOrDie("com.app.a:integer/one"), + test::ParseConfigOrDie("land"), "tablet", + test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 321u), + context->GetDiagnostics())); + + // Make a reference with both resource name and resource ID. + // The reference should point to a resource outside of this table to test that + // both + // name and id get serialized. + Reference expected_ref; + expected_ref.name = test::ParseNameOrDie("android:layout/main"); + expected_ref.id = ResourceId(0x01020000); + ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("com.app.a:layout/abc"), + ConfigDescription::DefaultConfig(), {}, + util::make_unique<Reference>(expected_ref), + context->GetDiagnostics())); + + std::unique_ptr<pb::ResourceTable> pb_table = SerializeTableToPb(table.get()); + ASSERT_NE(nullptr, pb_table); + + std::unique_ptr<ResourceTable> new_table = DeserializeTableFromPb( + *pb_table, Source{"test"}, context->GetDiagnostics()); + ASSERT_NE(nullptr, new_table); + + Id* new_id = test::GetValue<Id>(new_table.get(), "com.app.a:id/foo"); + ASSERT_NE(nullptr, new_id); + EXPECT_EQ(id->IsWeak(), new_id->IsWeak()); + + Maybe<ResourceTable::SearchResult> result = + new_table->FindResource(test::ParseNameOrDie("com.app.a:layout/main")); + AAPT_ASSERT_TRUE(result); + EXPECT_EQ(SymbolState::kPublic, result.value().type->symbol_status.state); + EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbol_status.state); + + // Find the product-dependent values + BinaryPrimitive* prim = test::GetValueForConfigAndProduct<BinaryPrimitive>( + new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"), + ""); + ASSERT_NE(nullptr, prim); + EXPECT_EQ(123u, prim->value.data); + + prim = test::GetValueForConfigAndProduct<BinaryPrimitive>( + new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"), + "tablet"); + ASSERT_NE(nullptr, prim); + EXPECT_EQ(321u, prim->value.data); + + Reference* actual_ref = + test::GetValue<Reference>(new_table.get(), "com.app.a:layout/abc"); + ASSERT_NE(nullptr, actual_ref); + AAPT_ASSERT_TRUE(actual_ref->name); + AAPT_ASSERT_TRUE(actual_ref->id); + EXPECT_EQ(expected_ref.name.value(), actual_ref->name.value()); + EXPECT_EQ(expected_ref.id.value(), actual_ref->id.value()); } TEST(TableProtoSerializer, SerializeFileHeader) { - std::unique_ptr<IAaptContext> context = test::ContextBuilder().build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); - ResourceFile f; - f.config = test::parseConfigOrDie("hdpi-v9"); - f.name = test::parseNameOrDie("com.app.a:layout/main"); - f.source.path = "res/layout-hdpi-v9/main.xml"; - f.exportedSymbols.push_back(SourcedResourceName{ test::parseNameOrDie("id/unchecked"), 23u }); + ResourceFile f; + f.config = test::ParseConfigOrDie("hdpi-v9"); + f.name = test::ParseNameOrDie("com.app.a:layout/main"); + f.source.path = "res/layout-hdpi-v9/main.xml"; + f.exported_symbols.push_back( + SourcedResourceName{test::ParseNameOrDie("id/unchecked"), 23u}); - const std::string expectedData1 = "123"; - const std::string expectedData2 = "1234"; + const std::string expected_data1 = "123"; + const std::string expected_data2 = "1234"; - std::string outputStr; - { - std::unique_ptr<pb::CompiledFile> pbFile1 = serializeCompiledFileToPb(f); + std::string output_str; + { + std::unique_ptr<pb::CompiledFile> pb_file1 = SerializeCompiledFileToPb(f); - f.name.entry = "__" + f.name.entry + "$0"; - std::unique_ptr<pb::CompiledFile> pbFile2 = serializeCompiledFileToPb(f); + f.name.entry = "__" + f.name.entry + "$0"; + std::unique_ptr<pb::CompiledFile> pb_file2 = SerializeCompiledFileToPb(f); - StringOutputStream outStream(&outputStr); - CompiledFileOutputStream outFileStream(&outStream); - outFileStream.WriteLittleEndian32(2); - outFileStream.WriteCompiledFile(pbFile1.get()); - outFileStream.WriteData(expectedData1.data(), expectedData1.size()); - outFileStream.WriteCompiledFile(pbFile2.get()); - outFileStream.WriteData(expectedData2.data(), expectedData2.size()); - ASSERT_FALSE(outFileStream.HadError()); - } + StringOutputStream out_stream(&output_str); + CompiledFileOutputStream out_file_stream(&out_stream); + out_file_stream.WriteLittleEndian32(2); + out_file_stream.WriteCompiledFile(pb_file1.get()); + out_file_stream.WriteData(expected_data1.data(), expected_data1.size()); + out_file_stream.WriteCompiledFile(pb_file2.get()); + out_file_stream.WriteData(expected_data2.data(), expected_data2.size()); + ASSERT_FALSE(out_file_stream.HadError()); + } - CompiledFileInputStream inFileStream(outputStr.data(), outputStr.size()); - uint32_t numFiles = 0; - ASSERT_TRUE(inFileStream.ReadLittleEndian32(&numFiles)); - ASSERT_EQ(2u, numFiles); + CompiledFileInputStream in_file_stream(output_str.data(), output_str.size()); + uint32_t num_files = 0; + ASSERT_TRUE(in_file_stream.ReadLittleEndian32(&num_files)); + ASSERT_EQ(2u, num_files); - // Read the first compiled file. + // Read the first compiled file. - pb::CompiledFile newPbFile; - ASSERT_TRUE(inFileStream.ReadCompiledFile(&newPbFile)); + pb::CompiledFile new_pb_file; + ASSERT_TRUE(in_file_stream.ReadCompiledFile(&new_pb_file)); - std::unique_ptr<ResourceFile> file = deserializeCompiledFileFromPb(newPbFile, Source("test"), - context->getDiagnostics()); - ASSERT_NE(nullptr, file); + std::unique_ptr<ResourceFile> file = DeserializeCompiledFileFromPb( + new_pb_file, Source("test"), context->GetDiagnostics()); + ASSERT_NE(nullptr, file); - uint64_t offset, len; - ASSERT_TRUE(inFileStream.ReadDataMetaData(&offset, &len)); + uint64_t offset, len; + ASSERT_TRUE(in_file_stream.ReadDataMetaData(&offset, &len)); - std::string actualData(outputStr.data() + offset, len); - EXPECT_EQ(expectedData1, actualData); + std::string actual_data(output_str.data() + offset, len); + EXPECT_EQ(expected_data1, actual_data); - // Expect the data to be aligned. - EXPECT_EQ(0u, offset & 0x03); + // Expect the data to be aligned. + EXPECT_EQ(0u, offset & 0x03); - ASSERT_EQ(1u, file->exportedSymbols.size()); - EXPECT_EQ(test::parseNameOrDie("id/unchecked"), file->exportedSymbols[0].name); + ASSERT_EQ(1u, file->exported_symbols.size()); + EXPECT_EQ(test::ParseNameOrDie("id/unchecked"), + file->exported_symbols[0].name); - // Read the second compiled file. + // Read the second compiled file. - ASSERT_TRUE(inFileStream.ReadCompiledFile(&newPbFile)); + ASSERT_TRUE(in_file_stream.ReadCompiledFile(&new_pb_file)); - file = deserializeCompiledFileFromPb(newPbFile, Source("test"), context->getDiagnostics()); - ASSERT_NE(nullptr, file); + file = DeserializeCompiledFileFromPb(new_pb_file, Source("test"), + context->GetDiagnostics()); + ASSERT_NE(nullptr, file); - ASSERT_TRUE(inFileStream.ReadDataMetaData(&offset, &len)); + ASSERT_TRUE(in_file_stream.ReadDataMetaData(&offset, &len)); - actualData = std::string(outputStr.data() + offset, len); - EXPECT_EQ(expectedData2, actualData); + actual_data = std::string(output_str.data() + offset, len); + EXPECT_EQ(expected_data2, actual_data); - // Expect the data to be aligned. - EXPECT_EQ(0u, offset & 0x03); + // Expect the data to be aligned. + EXPECT_EQ(0u, offset & 0x03); } TEST(TableProtoSerializer, DeserializeCorruptHeaderSafely) { - ResourceFile f; - std::unique_ptr<pb::CompiledFile> pbFile = serializeCompiledFileToPb(f); + ResourceFile f; + std::unique_ptr<pb::CompiledFile> pb_file = SerializeCompiledFileToPb(f); - const std::string expectedData = "1234"; + const std::string expected_data = "1234"; - std::string outputStr; - { - StringOutputStream outStream(&outputStr); - CompiledFileOutputStream outFileStream(&outStream); - outFileStream.WriteLittleEndian32(1); - outFileStream.WriteCompiledFile(pbFile.get()); - outFileStream.WriteData(expectedData.data(), expectedData.size()); - ASSERT_FALSE(outFileStream.HadError()); - } + std::string output_str; + { + StringOutputStream out_stream(&output_str); + CompiledFileOutputStream out_file_stream(&out_stream); + out_file_stream.WriteLittleEndian32(1); + out_file_stream.WriteCompiledFile(pb_file.get()); + out_file_stream.WriteData(expected_data.data(), expected_data.size()); + ASSERT_FALSE(out_file_stream.HadError()); + } - outputStr[4] = 0xff; + output_str[4] = 0xff; - CompiledFileInputStream inFileStream(outputStr.data(), outputStr.size()); + CompiledFileInputStream in_file_stream(output_str.data(), output_str.size()); - uint32_t numFiles = 0; - EXPECT_TRUE(inFileStream.ReadLittleEndian32(&numFiles)); - EXPECT_EQ(1u, numFiles); + uint32_t num_files = 0; + EXPECT_TRUE(in_file_stream.ReadLittleEndian32(&num_files)); + EXPECT_EQ(1u, num_files); - pb::CompiledFile newPbFile; - EXPECT_FALSE(inFileStream.ReadCompiledFile(&newPbFile)); + pb::CompiledFile new_pb_file; + EXPECT_FALSE(in_file_stream.ReadCompiledFile(&new_pb_file)); - uint64_t offset, len; - EXPECT_FALSE(inFileStream.ReadDataMetaData(&offset, &len)); + uint64_t offset, len; + EXPECT_FALSE(in_file_stream.ReadDataMetaData(&offset, &len)); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp index 08b9ee9cbe1b..7aad86fa7257 100644 --- a/tools/aapt2/split/TableSplitter.cpp +++ b/tools/aapt2/split/TableSplitter.cpp @@ -14,251 +14,278 @@ * limitations under the License. */ -#include "ConfigDescription.h" -#include "ResourceTable.h" #include "split/TableSplitter.h" -#include "util/Util.h" #include <algorithm> #include <map> #include <set> #include <unordered_map> #include <vector> +#include "android-base/logging.h" + +#include "ConfigDescription.h" +#include "ResourceTable.h" +#include "util/Util.h" namespace aapt { using ConfigClaimedMap = std::unordered_map<ResourceConfigValue*, bool>; -using ConfigDensityGroups = std::map<ConfigDescription, std::vector<ResourceConfigValue*>>; +using ConfigDensityGroups = + std::map<ConfigDescription, std::vector<ResourceConfigValue*>>; -static ConfigDescription copyWithoutDensity(const ConfigDescription& config) { - ConfigDescription withoutDensity = config; - withoutDensity.density = 0; - return withoutDensity; +static ConfigDescription CopyWithoutDensity(const ConfigDescription& config) { + ConfigDescription without_density = config; + without_density.density = 0; + return without_density; } /** * Selects values that match exactly the constraints given. */ class SplitValueSelector { -public: - explicit SplitValueSelector(const SplitConstraints& constraints) { - for (const ConfigDescription& config : constraints.configs) { - if (config.density == 0) { - mDensityIndependentConfigs.insert(config); - } else { - mDensityDependentConfigToDensityMap[copyWithoutDensity(config)] = config.density; - } - } + public: + explicit SplitValueSelector(const SplitConstraints& constraints) { + for (const ConfigDescription& config : constraints.configs) { + if (config.density == 0) { + density_independent_configs_.insert(config); + } else { + density_dependent_config_to_density_map_[CopyWithoutDensity(config)] = + config.density; + } } + } - std::vector<ResourceConfigValue*> selectValues(const ConfigDensityGroups& densityGroups, - ConfigClaimedMap* claimedValues) { - std::vector<ResourceConfigValue*> selected; + std::vector<ResourceConfigValue*> SelectValues( + const ConfigDensityGroups& density_groups, + ConfigClaimedMap* claimed_values) { + std::vector<ResourceConfigValue*> selected; - // Select the regular values. - for (auto& entry : *claimedValues) { - // Check if the entry has a density. - ResourceConfigValue* configValue = entry.first; - if (configValue->config.density == 0 && !entry.second) { - // This is still available. - if (mDensityIndependentConfigs.find(configValue->config) != - mDensityIndependentConfigs.end()) { - selected.push_back(configValue); + // Select the regular values. + for (auto& entry : *claimed_values) { + // Check if the entry has a density. + ResourceConfigValue* config_value = entry.first; + if (config_value->config.density == 0 && !entry.second) { + // This is still available. + if (density_independent_configs_.find(config_value->config) != + density_independent_configs_.end()) { + selected.push_back(config_value); - // Mark the entry as taken. - entry.second = true; - } - } + // Mark the entry as taken. + entry.second = true; } + } + } - // Now examine the densities - for (auto& entry : densityGroups) { - // We do not care if the value is claimed, since density values can be - // in multiple splits. - const ConfigDescription& config = entry.first; - const std::vector<ResourceConfigValue*>& relatedValues = entry.second; - auto densityValueIter = mDensityDependentConfigToDensityMap.find(config); - if (densityValueIter != mDensityDependentConfigToDensityMap.end()) { - // Select the best one! - ConfigDescription targetDensity = config; - targetDensity.density = densityValueIter->second; - - ResourceConfigValue* bestValue = nullptr; - for (ResourceConfigValue* thisValue : relatedValues) { - if (!bestValue || - thisValue->config.isBetterThan(bestValue->config, &targetDensity)) { - bestValue = thisValue; - } - } - assert(bestValue); + // Now examine the densities + for (auto& entry : density_groups) { + // We do not care if the value is claimed, since density values can be + // in multiple splits. + const ConfigDescription& config = entry.first; + const std::vector<ResourceConfigValue*>& related_values = entry.second; + auto density_value_iter = + density_dependent_config_to_density_map_.find(config); + if (density_value_iter != + density_dependent_config_to_density_map_.end()) { + // Select the best one! + ConfigDescription target_density = config; + target_density.density = density_value_iter->second; - // When we select one of these, they are all claimed such that the base - // doesn't include any anymore. - (*claimedValues)[bestValue] = true; - selected.push_back(bestValue); - } + ResourceConfigValue* best_value = nullptr; + for (ResourceConfigValue* this_value : related_values) { + if (!best_value || + this_value->config.isBetterThan(best_value->config, + &target_density)) { + best_value = this_value; + } } - return selected; + CHECK(best_value != nullptr); + + // When we select one of these, they are all claimed such that the base + // doesn't include any anymore. + (*claimed_values)[best_value] = true; + selected.push_back(best_value); + } } + return selected; + } + + private: + DISALLOW_COPY_AND_ASSIGN(SplitValueSelector); -private: - std::set<ConfigDescription> mDensityIndependentConfigs; - std::map<ConfigDescription, uint16_t> mDensityDependentConfigToDensityMap; + std::set<ConfigDescription> density_independent_configs_; + std::map<ConfigDescription, uint16_t> + density_dependent_config_to_density_map_; }; /** - * Marking non-preferred densities as claimed will make sure the base doesn't include them, + * Marking non-preferred densities as claimed will make sure the base doesn't + * include them, * leaving only the preferred density behind. */ -static void markNonPreferredDensitiesAsClaimed(uint16_t preferredDensity, - const ConfigDensityGroups& densityGroups, - ConfigClaimedMap* configClaimedMap) { - for (auto& entry : densityGroups) { - const ConfigDescription& config = entry.first; - const std::vector<ResourceConfigValue*>& relatedValues = entry.second; +static void MarkNonPreferredDensitiesAsClaimed( + uint16_t preferred_density, const ConfigDensityGroups& density_groups, + ConfigClaimedMap* config_claimed_map) { + for (auto& entry : density_groups) { + const ConfigDescription& config = entry.first; + const std::vector<ResourceConfigValue*>& related_values = entry.second; - ConfigDescription targetDensity = config; - targetDensity.density = preferredDensity; - ResourceConfigValue* bestValue = nullptr; - for (ResourceConfigValue* thisValue : relatedValues) { - if (!bestValue) { - bestValue = thisValue; - } else if (thisValue->config.isBetterThan(bestValue->config, &targetDensity)) { - // Claim the previous value so that it is not included in the base. - (*configClaimedMap)[bestValue] = true; - bestValue = thisValue; - } else { - // Claim this value so that it is not included in the base. - (*configClaimedMap)[thisValue] = true; - } - } - assert(bestValue); + ConfigDescription target_density = config; + target_density.density = preferred_density; + ResourceConfigValue* best_value = nullptr; + for (ResourceConfigValue* this_value : related_values) { + if (!best_value) { + best_value = this_value; + } else if (this_value->config.isBetterThan(best_value->config, + &target_density)) { + // Claim the previous value so that it is not included in the base. + (*config_claimed_map)[best_value] = true; + best_value = this_value; + } else { + // Claim this value so that it is not included in the base. + (*config_claimed_map)[this_value] = true; + } } + CHECK(best_value != nullptr); + } } -bool TableSplitter::verifySplitConstraints(IAaptContext* context) { - bool error = false; - for (size_t i = 0; i < mSplitConstraints.size(); i++) { - for (size_t j = i + 1; j < mSplitConstraints.size(); j++) { - for (const ConfigDescription& config : mSplitConstraints[i].configs) { - if (mSplitConstraints[j].configs.find(config) != - mSplitConstraints[j].configs.end()) { - context->getDiagnostics()->error(DiagMessage() << "config '" << config - << "' appears in multiple splits, " - << "target split ambiguous"); - error = true; - } - } +bool TableSplitter::VerifySplitConstraints(IAaptContext* context) { + bool error = false; + for (size_t i = 0; i < split_constraints_.size(); i++) { + for (size_t j = i + 1; j < split_constraints_.size(); j++) { + for (const ConfigDescription& config : split_constraints_[i].configs) { + if (split_constraints_[j].configs.find(config) != + split_constraints_[j].configs.end()) { + context->GetDiagnostics()->Error(DiagMessage() + << "config '" << config + << "' appears in multiple splits, " + << "target split ambiguous"); + error = true; } + } } - return !error; + } + return !error; } -void TableSplitter::splitTable(ResourceTable* originalTable) { - const size_t splitCount = mSplitConstraints.size(); - for (auto& pkg : originalTable->packages) { - // Initialize all packages for splits. - for (size_t idx = 0; idx < splitCount; idx++) { - ResourceTable* splitTable = mSplits[idx].get(); - splitTable->createPackage(pkg->name, pkg->id); - } - - for (auto& type : pkg->types) { - if (type->type == ResourceType::kMipmap) { - // Always keep mipmaps. - continue; - } +void TableSplitter::SplitTable(ResourceTable* original_table) { + const size_t split_count = split_constraints_.size(); + for (auto& pkg : original_table->packages) { + // Initialize all packages for splits. + for (size_t idx = 0; idx < split_count; idx++) { + ResourceTable* split_table = splits_[idx].get(); + split_table->CreatePackage(pkg->name, pkg->id); + } - for (auto& entry : type->entries) { - if (mConfigFilter) { - // First eliminate any resource that we definitely don't want. - for (std::unique_ptr<ResourceConfigValue>& configValue : entry->values) { - if (!mConfigFilter->match(configValue->config)) { - // null out the entry. We will clean up and remove nulls at the end - // for performance reasons. - configValue.reset(); - } - } - } + for (auto& type : pkg->types) { + if (type->type == ResourceType::kMipmap) { + // Always keep mipmaps. + continue; + } - // Organize the values into two separate buckets. Those that are density-dependent - // and those that are density-independent. - // One density technically matches all density, it's just that some densities - // match better. So we need to be aware of the full set of densities to make this - // decision. - ConfigDensityGroups densityGroups; - ConfigClaimedMap configClaimedMap; - for (const std::unique_ptr<ResourceConfigValue>& configValue : entry->values) { - if (configValue) { - configClaimedMap[configValue.get()] = false; + for (auto& entry : type->entries) { + if (options_.config_filter) { + // First eliminate any resource that we definitely don't want. + for (std::unique_ptr<ResourceConfigValue>& config_value : + entry->values) { + if (!options_.config_filter->Match(config_value->config)) { + // null out the entry. We will clean up and remove nulls at the + // end for performance reasons. + config_value.reset(); + } + } + } - if (configValue->config.density != 0) { - // Create a bucket for this density-dependent config. - densityGroups[copyWithoutDensity(configValue->config)] - .push_back(configValue.get()); - } - } - } + // Organize the values into two separate buckets. Those that are + // density-dependent + // and those that are density-independent. + // One density technically matches all density, it's just that some + // densities + // match better. So we need to be aware of the full set of densities to + // make this + // decision. + ConfigDensityGroups density_groups; + ConfigClaimedMap config_claimed_map; + for (const std::unique_ptr<ResourceConfigValue>& config_value : + entry->values) { + if (config_value) { + config_claimed_map[config_value.get()] = false; - // First we check all the splits. If it doesn't match one of the splits, we - // leave it in the base. - for (size_t idx = 0; idx < splitCount; idx++) { - const SplitConstraints& splitConstraint = mSplitConstraints[idx]; - ResourceTable* splitTable = mSplits[idx].get(); + if (config_value->config.density != 0) { + // Create a bucket for this density-dependent config. + density_groups[CopyWithoutDensity(config_value->config)] + .push_back(config_value.get()); + } + } + } - // Select the values we want from this entry for this split. - SplitValueSelector selector(splitConstraint); - std::vector<ResourceConfigValue*> selectedValues = - selector.selectValues(densityGroups, &configClaimedMap); + // First we check all the splits. If it doesn't match one of the splits, + // we + // leave it in the base. + for (size_t idx = 0; idx < split_count; idx++) { + const SplitConstraints& split_constraint = split_constraints_[idx]; + ResourceTable* split_table = splits_[idx].get(); - // No need to do any work if we selected nothing. - if (!selectedValues.empty()) { - // Create the same resource structure in the split. We do this lazily - // because we might not have actual values for each type/entry. - ResourceTablePackage* splitPkg = splitTable->findPackage(pkg->name); - ResourceTableType* splitType = splitPkg->findOrCreateType(type->type); - if (!splitType->id) { - splitType->id = type->id; - splitType->symbolStatus = type->symbolStatus; - } + // Select the values we want from this entry for this split. + SplitValueSelector selector(split_constraint); + std::vector<ResourceConfigValue*> selected_values = + selector.SelectValues(density_groups, &config_claimed_map); - ResourceEntry* splitEntry = splitType->findOrCreateEntry(entry->name); - if (!splitEntry->id) { - splitEntry->id = entry->id; - splitEntry->symbolStatus = entry->symbolStatus; - } + // No need to do any work if we selected nothing. + if (!selected_values.empty()) { + // Create the same resource structure in the split. We do this + // lazily because we might not have actual values for each + // type/entry. + ResourceTablePackage* split_pkg = + split_table->FindPackage(pkg->name); + ResourceTableType* split_type = + split_pkg->FindOrCreateType(type->type); + if (!split_type->id) { + split_type->id = type->id; + split_type->symbol_status = type->symbol_status; + } - // Copy the selected values into the new Split Entry. - for (ResourceConfigValue* configValue : selectedValues) { - ResourceConfigValue* newConfigValue = splitEntry->findOrCreateValue( - configValue->config, configValue->product); - newConfigValue->value = std::unique_ptr<Value>( - configValue->value->clone(&splitTable->stringPool)); - } - } - } + ResourceEntry* split_entry = + split_type->FindOrCreateEntry(entry->name); + if (!split_entry->id) { + split_entry->id = entry->id; + split_entry->symbol_status = entry->symbol_status; + } - if (mPreferredDensity) { - markNonPreferredDensitiesAsClaimed(mPreferredDensity.value(), - densityGroups, - &configClaimedMap); - } + // Copy the selected values into the new Split Entry. + for (ResourceConfigValue* config_value : selected_values) { + ResourceConfigValue* new_config_value = + split_entry->FindOrCreateValue(config_value->config, + config_value->product); + new_config_value->value = std::unique_ptr<Value>( + config_value->value->Clone(&split_table->string_pool)); + } + } + } - // All splits are handled, now check to see what wasn't claimed and remove - // whatever exists in other splits. - for (std::unique_ptr<ResourceConfigValue>& configValue : entry->values) { - if (configValue && configClaimedMap[configValue.get()]) { - // Claimed, remove from base. - configValue.reset(); - } - } + if (options_.preferred_density) { + MarkNonPreferredDensitiesAsClaimed(options_.preferred_density.value(), + density_groups, + &config_claimed_map); + } - // Now erase all nullptrs. - entry->values.erase( - std::remove(entry->values.begin(), entry->values.end(), nullptr), - entry->values.end()); - } + // All splits are handled, now check to see what wasn't claimed and + // remove + // whatever exists in other splits. + for (std::unique_ptr<ResourceConfigValue>& config_value : + entry->values) { + if (config_value && config_claimed_map[config_value.get()]) { + // Claimed, remove from base. + config_value.reset(); + } } + + // Now erase all nullptrs. + entry->values.erase( + std::remove(entry->values.begin(), entry->values.end(), nullptr), + entry->values.end()); + } } + } } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/split/TableSplitter.h b/tools/aapt2/split/TableSplitter.h index d7ecc8245ea8..1ae327120796 100644 --- a/tools/aapt2/split/TableSplitter.h +++ b/tools/aapt2/split/TableSplitter.h @@ -17,15 +17,15 @@ #ifndef AAPT_SPLIT_TABLESPLITTER_H #define AAPT_SPLIT_TABLESPLITTER_H +#include <set> +#include <vector> +#include "android-base/macros.h" + #include "ConfigDescription.h" #include "ResourceTable.h" #include "filter/ConfigFilter.h" #include "process/IResourceTableConsumer.h" -#include <android-base/macros.h> -#include <set> -#include <vector> - namespace aapt { struct SplitConstraints { @@ -36,39 +36,36 @@ struct TableSplitterOptions { /** * The preferred density to keep in the table, stripping out all others. */ - Maybe<uint16_t> preferredDensity; + Maybe<uint16_t> preferred_density; /** * Configuration filter that determines which resource configuration values * end up in * the final table. */ - IConfigFilter* configFilter = nullptr; + IConfigFilter* config_filter = nullptr; }; class TableSplitter { public: TableSplitter(const std::vector<SplitConstraints>& splits, const TableSplitterOptions& options) - : mSplitConstraints(splits), - mPreferredDensity(options.preferredDensity), - mConfigFilter(options.configFilter) { - for (size_t i = 0; i < mSplitConstraints.size(); i++) { - mSplits.push_back(util::make_unique<ResourceTable>()); + : split_constraints_(splits), options_(options) { + for (size_t i = 0; i < split_constraints_.size(); i++) { + splits_.push_back(util::make_unique<ResourceTable>()); } } - bool verifySplitConstraints(IAaptContext* context); + bool VerifySplitConstraints(IAaptContext* context); - void splitTable(ResourceTable* originalTable); + void SplitTable(ResourceTable* original_table); - std::vector<std::unique_ptr<ResourceTable>>& getSplits() { return mSplits; } + std::vector<std::unique_ptr<ResourceTable>>& splits() { return splits_; } private: - std::vector<SplitConstraints> mSplitConstraints; - std::vector<std::unique_ptr<ResourceTable>> mSplits; - Maybe<uint16_t> mPreferredDensity; - IConfigFilter* mConfigFilter; + std::vector<SplitConstraints> split_constraints_; + std::vector<std::unique_ptr<ResourceTable>> splits_; + TableSplitterOptions options_; DISALLOW_COPY_AND_ASSIGN(TableSplitter); }; diff --git a/tools/aapt2/split/TableSplitter_test.cpp b/tools/aapt2/split/TableSplitter_test.cpp index 5150e82b6d93..088dac374458 100644 --- a/tools/aapt2/split/TableSplitter_test.cpp +++ b/tools/aapt2/split/TableSplitter_test.cpp @@ -15,155 +15,192 @@ */ #include "split/TableSplitter.h" + #include "test/Test.h" namespace aapt { TEST(TableSplitterTest, NoSplitPreferredDensity) { - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addFileReference("android:drawable/icon", "res/drawable-mdpi/icon.png", - test::parseConfigOrDie("mdpi")) - .addFileReference("android:drawable/icon", "res/drawable-hdpi/icon.png", - test::parseConfigOrDie("hdpi")) - .addFileReference("android:drawable/icon", "res/drawable-xhdpi/icon.png", - test::parseConfigOrDie("xhdpi")) - .addFileReference("android:drawable/icon", "res/drawable-xxhdpi/icon.png", - test::parseConfigOrDie("xxhdpi")) - .addSimple("android:string/one") - .build(); - - TableSplitterOptions options; - options.preferredDensity = ConfigDescription::DENSITY_XHIGH; - TableSplitter splitter({}, options); - splitter.splitTable(table.get()); - - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), - "android:drawable/icon", - test::parseConfigOrDie("mdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), - "android:drawable/icon", - test::parseConfigOrDie("hdpi"))); - EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(table.get(), - "android:drawable/icon", - test::parseConfigOrDie("xhdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), - "android:drawable/icon", - test::parseConfigOrDie("xxhdpi"))); - EXPECT_NE(nullptr, test::getValue<Id>(table.get(), "android:string/one")); + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .AddFileReference("android:drawable/icon", + "res/drawable-mdpi/icon.png", + test::ParseConfigOrDie("mdpi")) + .AddFileReference("android:drawable/icon", + "res/drawable-hdpi/icon.png", + test::ParseConfigOrDie("hdpi")) + .AddFileReference("android:drawable/icon", + "res/drawable-xhdpi/icon.png", + test::ParseConfigOrDie("xhdpi")) + .AddFileReference("android:drawable/icon", + "res/drawable-xxhdpi/icon.png", + test::ParseConfigOrDie("xxhdpi")) + .AddSimple("android:string/one") + .Build(); + + TableSplitterOptions options; + options.preferred_density = ConfigDescription::DENSITY_XHIGH; + TableSplitter splitter({}, options); + splitter.SplitTable(table.get()); + + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + table.get(), "android:drawable/icon", + test::ParseConfigOrDie("mdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + table.get(), "android:drawable/icon", + test::ParseConfigOrDie("hdpi"))); + EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>( + table.get(), "android:drawable/icon", + test::ParseConfigOrDie("xhdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + table.get(), "android:drawable/icon", + test::ParseConfigOrDie("xxhdpi"))); + EXPECT_NE(nullptr, test::GetValue<Id>(table.get(), "android:string/one")); } TEST(TableSplitterTest, SplitTableByDensity) { - std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() - .addFileReference("android:drawable/foo", "res/drawable-mdpi/foo.png", - test::parseConfigOrDie("mdpi")) - .addFileReference("android:drawable/foo", "res/drawable-hdpi/foo.png", - test::parseConfigOrDie("hdpi")) - .addFileReference("android:drawable/foo", "res/drawable-xhdpi/foo.png", - test::parseConfigOrDie("xhdpi")) - .addFileReference("android:drawable/foo", "res/drawable-xxhdpi/foo.png", - test::parseConfigOrDie("xxhdpi")) - .build(); - - std::vector<SplitConstraints> constraints; - constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("mdpi") } }); - constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("hdpi") } }); - constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("xhdpi") } }); - - TableSplitter splitter(constraints, TableSplitterOptions{}); - splitter.splitTable(table.get()); - - ASSERT_EQ(3u, splitter.getSplits().size()); - - ResourceTable* splitOne = splitter.getSplits()[0].get(); - ResourceTable* splitTwo = splitter.getSplits()[1].get(); - ResourceTable* splitThree = splitter.getSplits()[2].get(); - - // Just xxhdpi should be in the base. - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo", - test::parseConfigOrDie("mdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo", - test::parseConfigOrDie("hdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo", - test::parseConfigOrDie("xhdpi"))); - EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(table.get(), "android:drawable/foo", - test::parseConfigOrDie("xxhdpi"))); - - // Each split should have one and only one drawable. - EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo", - test::parseConfigOrDie("mdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo", - test::parseConfigOrDie("hdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo", - test::parseConfigOrDie("xhdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitOne, "android:drawable/foo", - test::parseConfigOrDie("xxhdpi"))); - - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo", - test::parseConfigOrDie("mdpi"))); - EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo", - test::parseConfigOrDie("hdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo", - test::parseConfigOrDie("xhdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitTwo, "android:drawable/foo", - test::parseConfigOrDie("xxhdpi"))); - - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo", - test::parseConfigOrDie("mdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo", - test::parseConfigOrDie("hdpi"))); - EXPECT_NE(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo", - test::parseConfigOrDie("xhdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<FileReference>(splitThree, "android:drawable/foo", - test::parseConfigOrDie("xxhdpi"))); + std::unique_ptr<ResourceTable> table = + test::ResourceTableBuilder() + .AddFileReference("android:drawable/foo", "res/drawable-mdpi/foo.png", + test::ParseConfigOrDie("mdpi")) + .AddFileReference("android:drawable/foo", "res/drawable-hdpi/foo.png", + test::ParseConfigOrDie("hdpi")) + .AddFileReference("android:drawable/foo", + "res/drawable-xhdpi/foo.png", + test::ParseConfigOrDie("xhdpi")) + .AddFileReference("android:drawable/foo", + "res/drawable-xxhdpi/foo.png", + test::ParseConfigOrDie("xxhdpi")) + .Build(); + + std::vector<SplitConstraints> constraints; + constraints.push_back(SplitConstraints{{test::ParseConfigOrDie("mdpi")}}); + constraints.push_back(SplitConstraints{{test::ParseConfigOrDie("hdpi")}}); + constraints.push_back(SplitConstraints{{test::ParseConfigOrDie("xhdpi")}}); + + TableSplitter splitter(constraints, TableSplitterOptions{}); + splitter.SplitTable(table.get()); + + ASSERT_EQ(3u, splitter.splits().size()); + + ResourceTable* split_one = splitter.splits()[0].get(); + ResourceTable* split_two = splitter.splits()[1].get(); + ResourceTable* split_three = splitter.splits()[2].get(); + + // Just xxhdpi should be in the base. + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + table.get(), "android:drawable/foo", + test::ParseConfigOrDie("mdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + table.get(), "android:drawable/foo", + test::ParseConfigOrDie("hdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + table.get(), "android:drawable/foo", + test::ParseConfigOrDie("xhdpi"))); + EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>( + table.get(), "android:drawable/foo", + test::ParseConfigOrDie("xxhdpi"))); + + // Each split should have one and only one drawable. + EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>( + split_one, "android:drawable/foo", + test::ParseConfigOrDie("mdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + split_one, "android:drawable/foo", + test::ParseConfigOrDie("hdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + split_one, "android:drawable/foo", + test::ParseConfigOrDie("xhdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + split_one, "android:drawable/foo", + test::ParseConfigOrDie("xxhdpi"))); + + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + split_two, "android:drawable/foo", + test::ParseConfigOrDie("mdpi"))); + EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>( + split_two, "android:drawable/foo", + test::ParseConfigOrDie("hdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + split_two, "android:drawable/foo", + test::ParseConfigOrDie("xhdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + split_two, "android:drawable/foo", + test::ParseConfigOrDie("xxhdpi"))); + + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + split_three, "android:drawable/foo", + test::ParseConfigOrDie("mdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + split_three, "android:drawable/foo", + test::ParseConfigOrDie("hdpi"))); + EXPECT_NE(nullptr, test::GetValueForConfig<FileReference>( + split_three, "android:drawable/foo", + test::ParseConfigOrDie("xhdpi"))); + EXPECT_EQ(nullptr, test::GetValueForConfig<FileReference>( + split_three, "android:drawable/foo", + test::ParseConfigOrDie("xxhdpi"))); } TEST(TableSplitterTest, SplitTableByConfigAndDensity) { - ResourceTable table; - - const ResourceName foo = test::parseNameOrDie("android:string/foo"); - ASSERT_TRUE(table.addResource(foo, test::parseConfigOrDie("land-hdpi"), {}, - util::make_unique<Id>(), - test::getDiagnostics())); - ASSERT_TRUE(table.addResource(foo, test::parseConfigOrDie("land-xhdpi"), {}, - util::make_unique<Id>(), - test::getDiagnostics())); - ASSERT_TRUE(table.addResource(foo, test::parseConfigOrDie("land-xxhdpi"), {}, - util::make_unique<Id>(), - test::getDiagnostics())); - - std::vector<SplitConstraints> constraints; - constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("land-mdpi") } }); - constraints.push_back(SplitConstraints{ { test::parseConfigOrDie("land-xhdpi") } }); - - TableSplitter splitter(constraints, TableSplitterOptions{}); - splitter.splitTable(&table); - - ASSERT_EQ(2u, splitter.getSplits().size()); - - ResourceTable* splitOne = splitter.getSplits()[0].get(); - ResourceTable* splitTwo = splitter.getSplits()[1].get(); - - // All but the xxhdpi resource should be gone, since there were closer matches in land-xhdpi. - EXPECT_EQ(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo", - test::parseConfigOrDie("land-hdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo", - test::parseConfigOrDie("land-xhdpi"))); - EXPECT_NE(nullptr, test::getValueForConfig<Id>(&table, "android:string/foo", - test::parseConfigOrDie("land-xxhdpi"))); - - EXPECT_NE(nullptr, test::getValueForConfig<Id>(splitOne, "android:string/foo", - test::parseConfigOrDie("land-hdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<Id>(splitOne, "android:string/foo", - test::parseConfigOrDie("land-xhdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<Id>(splitOne, "android:string/foo", - test::parseConfigOrDie("land-xxhdpi"))); - - EXPECT_EQ(nullptr, test::getValueForConfig<Id>(splitTwo, "android:string/foo", - test::parseConfigOrDie("land-hdpi"))); - EXPECT_NE(nullptr, test::getValueForConfig<Id>(splitTwo, "android:string/foo", - test::parseConfigOrDie("land-xhdpi"))); - EXPECT_EQ(nullptr, test::getValueForConfig<Id>(splitTwo, "android:string/foo", - test::parseConfigOrDie("land-xxhdpi"))); + ResourceTable table; + + const ResourceName foo = test::ParseNameOrDie("android:string/foo"); + ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-hdpi"), {}, + util::make_unique<Id>(), + test::GetDiagnostics())); + ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-xhdpi"), {}, + util::make_unique<Id>(), + test::GetDiagnostics())); + ASSERT_TRUE(table.AddResource(foo, test::ParseConfigOrDie("land-xxhdpi"), {}, + util::make_unique<Id>(), + test::GetDiagnostics())); + + std::vector<SplitConstraints> constraints; + constraints.push_back( + SplitConstraints{{test::ParseConfigOrDie("land-mdpi")}}); + constraints.push_back( + SplitConstraints{{test::ParseConfigOrDie("land-xhdpi")}}); + + TableSplitter splitter(constraints, TableSplitterOptions{}); + splitter.SplitTable(&table); + + ASSERT_EQ(2u, splitter.splits().size()); + + ResourceTable* split_one = splitter.splits()[0].get(); + ResourceTable* split_two = splitter.splits()[1].get(); + + // All but the xxhdpi resource should be gone, since there were closer matches + // in land-xhdpi. + EXPECT_EQ(nullptr, + test::GetValueForConfig<Id>(&table, "android:string/foo", + test::ParseConfigOrDie("land-hdpi"))); + EXPECT_EQ(nullptr, + test::GetValueForConfig<Id>(&table, "android:string/foo", + test::ParseConfigOrDie("land-xhdpi"))); + EXPECT_NE(nullptr, + test::GetValueForConfig<Id>(&table, "android:string/foo", + test::ParseConfigOrDie("land-xxhdpi"))); + + EXPECT_NE(nullptr, + test::GetValueForConfig<Id>(split_one, "android:string/foo", + test::ParseConfigOrDie("land-hdpi"))); + EXPECT_EQ(nullptr, + test::GetValueForConfig<Id>(split_one, "android:string/foo", + test::ParseConfigOrDie("land-xhdpi"))); + EXPECT_EQ(nullptr, + test::GetValueForConfig<Id>(split_one, "android:string/foo", + test::ParseConfigOrDie("land-xxhdpi"))); + + EXPECT_EQ(nullptr, + test::GetValueForConfig<Id>(split_two, "android:string/foo", + test::ParseConfigOrDie("land-hdpi"))); + EXPECT_NE(nullptr, + test::GetValueForConfig<Id>(split_two, "android:string/foo", + test::ParseConfigOrDie("land-xhdpi"))); + EXPECT_EQ(nullptr, + test::GetValueForConfig<Id>(split_two, "android:string/foo", + test::ParseConfigOrDie("land-xxhdpi"))); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h index c64715945b7b..9377306dc1b6 100644 --- a/tools/aapt2/test/Builders.h +++ b/tools/aapt2/test/Builders.h @@ -17,139 +17,142 @@ #ifndef AAPT_TEST_BUILDERS_H #define AAPT_TEST_BUILDERS_H +#include <memory> + +#include "android-base/logging.h" +#include "android-base/macros.h" + #include "ResourceTable.h" #include "ResourceValues.h" #include "test/Common.h" #include "util/Util.h" #include "xml/XmlDom.h" -#include <memory> - namespace aapt { namespace test { class ResourceTableBuilder { - private: - DummyDiagnosticsImpl mDiagnostics; - std::unique_ptr<ResourceTable> mTable = util::make_unique<ResourceTable>(); - public: ResourceTableBuilder() = default; - StringPool* getStringPool() { return &mTable->stringPool; } + StringPool* string_pool() { return &table_->string_pool; } - ResourceTableBuilder& setPackageId(const StringPiece& packageName, + ResourceTableBuilder& SetPackageId(const StringPiece& package_name, uint8_t id) { - ResourceTablePackage* package = mTable->createPackage(packageName, id); - assert(package); + ResourceTablePackage* package = table_->CreatePackage(package_name, id); + CHECK(package != nullptr); return *this; } - ResourceTableBuilder& addSimple(const StringPiece& name, + ResourceTableBuilder& AddSimple(const StringPiece& name, const ResourceId& id = {}) { - return addValue(name, id, util::make_unique<Id>()); + return AddValue(name, id, util::make_unique<Id>()); } - ResourceTableBuilder& addSimple(const StringPiece& name, + ResourceTableBuilder& AddSimple(const StringPiece& name, const ConfigDescription& config, const ResourceId& id = {}) { - return addValue(name, config, id, util::make_unique<Id>()); + return AddValue(name, config, id, util::make_unique<Id>()); } - ResourceTableBuilder& addReference(const StringPiece& name, + ResourceTableBuilder& AddReference(const StringPiece& name, const StringPiece& ref) { - return addReference(name, {}, ref); + return AddReference(name, {}, ref); } - ResourceTableBuilder& addReference(const StringPiece& name, + ResourceTableBuilder& AddReference(const StringPiece& name, const ResourceId& id, const StringPiece& ref) { - return addValue(name, id, - util::make_unique<Reference>(parseNameOrDie(ref))); + return AddValue(name, id, + util::make_unique<Reference>(ParseNameOrDie(ref))); } - ResourceTableBuilder& addString(const StringPiece& name, + ResourceTableBuilder& AddString(const StringPiece& name, const StringPiece& str) { - return addString(name, {}, str); + return AddString(name, {}, str); } - ResourceTableBuilder& addString(const StringPiece& name, const ResourceId& id, + ResourceTableBuilder& AddString(const StringPiece& name, const ResourceId& id, const StringPiece& str) { - return addValue(name, id, - util::make_unique<String>(mTable->stringPool.makeRef(str))); + return AddValue( + name, id, util::make_unique<String>(table_->string_pool.MakeRef(str))); } - ResourceTableBuilder& addString(const StringPiece& name, const ResourceId& id, + ResourceTableBuilder& AddString(const StringPiece& name, const ResourceId& id, const ConfigDescription& config, const StringPiece& str) { - return addValue(name, config, id, - util::make_unique<String>(mTable->stringPool.makeRef(str))); + return AddValue(name, config, id, util::make_unique<String>( + table_->string_pool.MakeRef(str))); } - ResourceTableBuilder& addFileReference(const StringPiece& name, + ResourceTableBuilder& AddFileReference(const StringPiece& name, const StringPiece& path) { - return addFileReference(name, {}, path); + return AddFileReference(name, {}, path); } - ResourceTableBuilder& addFileReference(const StringPiece& name, + ResourceTableBuilder& AddFileReference(const StringPiece& name, const ResourceId& id, const StringPiece& path) { - return addValue(name, id, util::make_unique<FileReference>( - mTable->stringPool.makeRef(path))); + return AddValue(name, id, util::make_unique<FileReference>( + table_->string_pool.MakeRef(path))); } - ResourceTableBuilder& addFileReference(const StringPiece& name, + ResourceTableBuilder& AddFileReference(const StringPiece& name, const StringPiece& path, const ConfigDescription& config) { - return addValue(name, config, {}, util::make_unique<FileReference>( - mTable->stringPool.makeRef(path))); + return AddValue(name, config, {}, util::make_unique<FileReference>( + table_->string_pool.MakeRef(path))); } - ResourceTableBuilder& addValue(const StringPiece& name, + ResourceTableBuilder& AddValue(const StringPiece& name, std::unique_ptr<Value> value) { - return addValue(name, {}, std::move(value)); + return AddValue(name, {}, std::move(value)); } - ResourceTableBuilder& addValue(const StringPiece& name, const ResourceId& id, + ResourceTableBuilder& AddValue(const StringPiece& name, const ResourceId& id, std::unique_ptr<Value> value) { - return addValue(name, {}, id, std::move(value)); + return AddValue(name, {}, id, std::move(value)); } - ResourceTableBuilder& addValue(const StringPiece& name, + ResourceTableBuilder& AddValue(const StringPiece& name, const ConfigDescription& config, const ResourceId& id, std::unique_ptr<Value> value) { - ResourceName resName = parseNameOrDie(name); - bool result = mTable->addResourceAllowMangled( - resName, id, config, {}, std::move(value), &mDiagnostics); - assert(result); + ResourceName res_name = ParseNameOrDie(name); + CHECK(table_->AddResourceAllowMangled(res_name, id, config, {}, + std::move(value), &diagnostics_)); return *this; } - ResourceTableBuilder& setSymbolState(const StringPiece& name, + ResourceTableBuilder& SetSymbolState(const StringPiece& name, const ResourceId& id, SymbolState state) { - ResourceName resName = parseNameOrDie(name); + ResourceName res_name = ParseNameOrDie(name); Symbol symbol; symbol.state = state; - bool result = - mTable->setSymbolStateAllowMangled(resName, id, symbol, &mDiagnostics); - assert(result); + CHECK(table_->SetSymbolStateAllowMangled(res_name, id, symbol, + &diagnostics_)); return *this; } - std::unique_ptr<ResourceTable> build() { return std::move(mTable); } + std::unique_ptr<ResourceTable> Build() { return std::move(table_); } + + private: + DISALLOW_COPY_AND_ASSIGN(ResourceTableBuilder); + + DummyDiagnosticsImpl diagnostics_; + std::unique_ptr<ResourceTable> table_ = util::make_unique<ResourceTable>(); }; -inline std::unique_ptr<Reference> buildReference( +inline std::unique_ptr<Reference> BuildReference( const StringPiece& ref, const Maybe<ResourceId>& id = {}) { std::unique_ptr<Reference> reference = - util::make_unique<Reference>(parseNameOrDie(ref)); + util::make_unique<Reference>(ParseNameOrDie(ref)); reference->id = id; return reference; } -inline std::unique_ptr<BinaryPrimitive> buildPrimitive(uint8_t type, +inline std::unique_ptr<BinaryPrimitive> BuildPrimitive(uint8_t type, uint32_t data) { android::Res_value value = {}; value.size = sizeof(value); @@ -160,107 +163,119 @@ inline std::unique_ptr<BinaryPrimitive> buildPrimitive(uint8_t type, template <typename T> class ValueBuilder { - private: - std::unique_ptr<Value> mValue; - public: template <typename... Args> explicit ValueBuilder(Args&&... args) - : mValue(new T{std::forward<Args>(args)...}) {} + : value_(new T{std::forward<Args>(args)...}) {} template <typename... Args> - ValueBuilder& setSource(Args&&... args) { - mValue->setSource(Source{std::forward<Args>(args)...}); + ValueBuilder& SetSource(Args&&... args) { + value_->SetSource(Source{std::forward<Args>(args)...}); return *this; } - ValueBuilder& setComment(const StringPiece& str) { - mValue->setComment(str); + ValueBuilder& SetComment(const StringPiece& str) { + value_->SetComment(str); return *this; } - std::unique_ptr<Value> build() { return std::move(mValue); } -}; + std::unique_ptr<Value> Build() { return std::move(value_); } -class AttributeBuilder { private: - std::unique_ptr<Attribute> mAttr; + DISALLOW_COPY_AND_ASSIGN(ValueBuilder); + + std::unique_ptr<Value> value_; +}; +class AttributeBuilder { public: explicit AttributeBuilder(bool weak = false) - : mAttr(util::make_unique<Attribute>(weak)) { - mAttr->typeMask = android::ResTable_map::TYPE_ANY; + : attr_(util::make_unique<Attribute>(weak)) { + attr_->type_mask = android::ResTable_map::TYPE_ANY; } - AttributeBuilder& setTypeMask(uint32_t typeMask) { - mAttr->typeMask = typeMask; + AttributeBuilder& SetTypeMask(uint32_t typeMask) { + attr_->type_mask = typeMask; return *this; } - AttributeBuilder& addItem(const StringPiece& name, uint32_t value) { - mAttr->symbols.push_back(Attribute::Symbol{ + AttributeBuilder& AddItem(const StringPiece& name, uint32_t value) { + attr_->symbols.push_back(Attribute::Symbol{ Reference(ResourceName({}, ResourceType::kId, name)), value}); return *this; } - std::unique_ptr<Attribute> build() { return std::move(mAttr); } -}; + std::unique_ptr<Attribute> Build() { return std::move(attr_); } -class StyleBuilder { private: - std::unique_ptr<Style> mStyle = util::make_unique<Style>(); + DISALLOW_COPY_AND_ASSIGN(AttributeBuilder); + + std::unique_ptr<Attribute> attr_; +}; +class StyleBuilder { public: - StyleBuilder& setParent(const StringPiece& str) { - mStyle->parent = Reference(parseNameOrDie(str)); + StyleBuilder() = default; + + StyleBuilder& SetParent(const StringPiece& str) { + style_->parent = Reference(ParseNameOrDie(str)); return *this; } - StyleBuilder& addItem(const StringPiece& str, std::unique_ptr<Item> value) { - mStyle->entries.push_back( - Style::Entry{Reference(parseNameOrDie(str)), std::move(value)}); + StyleBuilder& AddItem(const StringPiece& str, std::unique_ptr<Item> value) { + style_->entries.push_back( + Style::Entry{Reference(ParseNameOrDie(str)), std::move(value)}); return *this; } - StyleBuilder& addItem(const StringPiece& str, const ResourceId& id, + StyleBuilder& AddItem(const StringPiece& str, const ResourceId& id, std::unique_ptr<Item> value) { - addItem(str, std::move(value)); - mStyle->entries.back().key.id = id; + AddItem(str, std::move(value)); + style_->entries.back().key.id = id; return *this; } - std::unique_ptr<Style> build() { return std::move(mStyle); } -}; + std::unique_ptr<Style> Build() { return std::move(style_); } -class StyleableBuilder { private: - std::unique_ptr<Styleable> mStyleable = util::make_unique<Styleable>(); + DISALLOW_COPY_AND_ASSIGN(StyleBuilder); + + std::unique_ptr<Style> style_ = util::make_unique<Style>(); +}; +class StyleableBuilder { public: - StyleableBuilder& addItem(const StringPiece& str, + StyleableBuilder() = default; + + StyleableBuilder& AddItem(const StringPiece& str, const Maybe<ResourceId>& id = {}) { - mStyleable->entries.push_back(Reference(parseNameOrDie(str))); - mStyleable->entries.back().id = id; + styleable_->entries.push_back(Reference(ParseNameOrDie(str))); + styleable_->entries.back().id = id; return *this; } - std::unique_ptr<Styleable> build() { return std::move(mStyleable); } + std::unique_ptr<Styleable> Build() { return std::move(styleable_); } + + private: + DISALLOW_COPY_AND_ASSIGN(StyleableBuilder); + + std::unique_ptr<Styleable> styleable_ = util::make_unique<Styleable>(); }; -inline std::unique_ptr<xml::XmlResource> buildXmlDom(const StringPiece& str) { +inline std::unique_ptr<xml::XmlResource> BuildXmlDom(const StringPiece& str) { std::stringstream in; in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str; StdErrDiagnostics diag; std::unique_ptr<xml::XmlResource> doc = - xml::inflate(&in, &diag, Source("test.xml")); - assert(doc); + xml::Inflate(&in, &diag, Source("test.xml")); + CHECK(doc != nullptr) << "failed to parse inline XML string"; return doc; } -inline std::unique_ptr<xml::XmlResource> buildXmlDomForPackageName( +inline std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName( IAaptContext* context, const StringPiece& str) { - std::unique_ptr<xml::XmlResource> doc = buildXmlDom(str); - doc->file.name.package = context->getCompilationPackage(); + std::unique_ptr<xml::XmlResource> doc = BuildXmlDom(str); + doc->file.name.package = context->GetCompilationPackage(); return doc; } diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h index 2d571e7624e5..36892017f2d3 100644 --- a/tools/aapt2/test/Common.h +++ b/tools/aapt2/test/Common.h @@ -17,6 +17,12 @@ #ifndef AAPT_TEST_COMMON_H #define AAPT_TEST_COMMON_H +#include <iostream> + +#include "android-base/logging.h" +#include "android-base/macros.h" +#include "gtest/gtest.h" + #include "ConfigDescription.h" #include "Debug.h" #include "ResourceTable.h" @@ -26,9 +32,6 @@ #include "process/IResourceTableConsumer.h" #include "util/StringPiece.h" -#include <gtest/gtest.h> -#include <iostream> - // // GTEST 1.7 doesn't explicitly cast to bool, which causes explicit operators to // fail to compile. @@ -42,80 +45,81 @@ namespace aapt { namespace test { struct DummyDiagnosticsImpl : public IDiagnostics { - void log(Level level, DiagMessageActual& actualMsg) override { + void Log(Level level, DiagMessageActual& actual_msg) override { switch (level) { case Level::Note: return; case Level::Warn: - std::cerr << actualMsg.source << ": warn: " << actualMsg.message << "." - << std::endl; + std::cerr << actual_msg.source << ": warn: " << actual_msg.message + << "." << std::endl; break; case Level::Error: - std::cerr << actualMsg.source << ": error: " << actualMsg.message << "." - << std::endl; + std::cerr << actual_msg.source << ": error: " << actual_msg.message + << "." << std::endl; break; } } }; -inline IDiagnostics* getDiagnostics() { +inline IDiagnostics* GetDiagnostics() { static DummyDiagnosticsImpl diag; return &diag; } -inline ResourceName parseNameOrDie(const StringPiece& str) { +inline ResourceName ParseNameOrDie(const StringPiece& str) { ResourceNameRef ref; - bool result = ResourceUtils::parseResourceName(str, &ref); - assert(result && "invalid resource name"); - return ref.toResourceName(); + CHECK(ResourceUtils::ParseResourceName(str, &ref)) << "invalid resource name"; + return ref.ToResourceName(); } -inline ConfigDescription parseConfigOrDie(const StringPiece& str) { +inline ConfigDescription ParseConfigOrDie(const StringPiece& str) { ConfigDescription config; - bool result = ConfigDescription::parse(str, &config); - assert(result && "invalid configuration"); + CHECK(ConfigDescription::Parse(str, &config)) << "invalid configuration"; return config; } template <typename T> -T* getValueForConfigAndProduct(ResourceTable* table, const StringPiece& resName, +T* GetValueForConfigAndProduct(ResourceTable* table, + const StringPiece& res_name, const ConfigDescription& config, const StringPiece& product) { Maybe<ResourceTable::SearchResult> result = - table->findResource(parseNameOrDie(resName)); + table->FindResource(ParseNameOrDie(res_name)); if (result) { - ResourceConfigValue* configValue = - result.value().entry->findValue(config, product); - if (configValue) { - return valueCast<T>(configValue->value.get()); + ResourceConfigValue* config_value = + result.value().entry->FindValue(config, product); + if (config_value) { + return ValueCast<T>(config_value->value.get()); } } return nullptr; } template <typename T> -T* getValueForConfig(ResourceTable* table, const StringPiece& resName, +T* GetValueForConfig(ResourceTable* table, const StringPiece& res_name, const ConfigDescription& config) { - return getValueForConfigAndProduct<T>(table, resName, config, {}); + return GetValueForConfigAndProduct<T>(table, res_name, config, {}); } template <typename T> -T* getValue(ResourceTable* table, const StringPiece& resName) { - return getValueForConfig<T>(table, resName, {}); +T* GetValue(ResourceTable* table, const StringPiece& res_name) { + return GetValueForConfig<T>(table, res_name, {}); } class TestFile : public io::IFile { - private: - Source mSource; - public: - explicit TestFile(const StringPiece& path) : mSource(path) {} + explicit TestFile(const StringPiece& path) : source_(path) {} + + std::unique_ptr<io::IData> OpenAsData() override { return {}; } - std::unique_ptr<io::IData> openAsData() override { return {}; } + const Source& GetSource() const override { return source_; } + + private: + DISALLOW_COPY_AND_ASSIGN(TestFile); - const Source& getSource() const override { return mSource; } + Source source_; }; } // namespace test diff --git a/tools/aapt2/test/Context.h b/tools/aapt2/test/Context.h index 6c7f6f78a71d..7986329ab640 100644 --- a/tools/aapt2/test/Context.h +++ b/tools/aapt2/test/Context.h @@ -17,152 +17,158 @@ #ifndef AAPT_TEST_CONTEXT_H #define AAPT_TEST_CONTEXT_H +#include <list> + +#include "android-base/logging.h" +#include "android-base/macros.h" + #include "NameMangler.h" #include "process/IResourceTableConsumer.h" #include "process/SymbolTable.h" #include "test/Common.h" #include "util/Util.h" -#include <cassert> -#include <list> - namespace aapt { namespace test { class Context : public IAaptContext { public: - SymbolTable* getExternalSymbols() override { return &mSymbols; } + Context() = default; + + SymbolTable* GetExternalSymbols() override { return &symbols_; } - IDiagnostics* getDiagnostics() override { return &mDiagnostics; } + IDiagnostics* GetDiagnostics() override { return &diagnostics_; } - const std::string& getCompilationPackage() override { - assert(mCompilationPackage && "package name not set"); - return mCompilationPackage.value(); + const std::string& GetCompilationPackage() override { + CHECK(bool(compilation_package_)) << "package name not set"; + return compilation_package_.value(); } - uint8_t getPackageId() override { - assert(mPackageId && "package ID not set"); - return mPackageId.value(); + uint8_t GetPackageId() override { + CHECK(bool(package_id_)) << "package ID not set"; + return package_id_.value(); } - NameMangler* getNameMangler() override { return &mNameMangler; } + NameMangler* GetNameMangler() override { return &name_mangler_; } - bool verbose() override { return false; } + bool IsVerbose() override { return false; } - int getMinSdkVersion() override { return mMinSdkVersion; } + int GetMinSdkVersion() override { return min_sdk_version_; } private: + DISALLOW_COPY_AND_ASSIGN(Context); + friend class ContextBuilder; - Maybe<std::string> mCompilationPackage; - Maybe<uint8_t> mPackageId; - StdErrDiagnostics mDiagnostics; - SymbolTable mSymbols; - NameMangler mNameMangler = NameMangler({}); - int mMinSdkVersion = 0; + Maybe<std::string> compilation_package_; + Maybe<uint8_t> package_id_; + StdErrDiagnostics diagnostics_; + SymbolTable symbols_; + NameMangler name_mangler_ = NameMangler({}); + int min_sdk_version_ = 0; }; class ContextBuilder { - private: - std::unique_ptr<Context> mContext = std::unique_ptr<Context>(new Context()); - public: - ContextBuilder& setCompilationPackage(const StringPiece& package) { - mContext->mCompilationPackage = package.toString(); + ContextBuilder& SetCompilationPackage(const StringPiece& package) { + context_->compilation_package_ = package.ToString(); return *this; } - ContextBuilder& setPackageId(uint8_t id) { - mContext->mPackageId = id; + ContextBuilder& SetPackageId(uint8_t id) { + context_->package_id_ = id; return *this; } - ContextBuilder& setNameManglerPolicy(const NameManglerPolicy& policy) { - mContext->mNameMangler = NameMangler(policy); + ContextBuilder& SetNameManglerPolicy(const NameManglerPolicy& policy) { + context_->name_mangler_ = NameMangler(policy); return *this; } - ContextBuilder& addSymbolSource(std::unique_ptr<ISymbolSource> src) { - mContext->getExternalSymbols()->appendSource(std::move(src)); + ContextBuilder& AddSymbolSource(std::unique_ptr<ISymbolSource> src) { + context_->GetExternalSymbols()->AppendSource(std::move(src)); return *this; } - ContextBuilder& setMinSdkVersion(int minSdk) { - mContext->mMinSdkVersion = minSdk; + ContextBuilder& SetMinSdkVersion(int min_sdk) { + context_->min_sdk_version_ = min_sdk; return *this; } - std::unique_ptr<Context> build() { return std::move(mContext); } + std::unique_ptr<Context> Build() { return std::move(context_); } + + private: + std::unique_ptr<Context> context_ = std::unique_ptr<Context>(new Context()); }; class StaticSymbolSourceBuilder { public: - StaticSymbolSourceBuilder& addPublicSymbol( + StaticSymbolSourceBuilder& AddPublicSymbol( const StringPiece& name, ResourceId id, std::unique_ptr<Attribute> attr = {}) { std::unique_ptr<SymbolTable::Symbol> symbol = util::make_unique<SymbolTable::Symbol>(id, std::move(attr), true); - mSymbolSource->mNameMap[parseNameOrDie(name)] = symbol.get(); - mSymbolSource->mIdMap[id] = symbol.get(); - mSymbolSource->mSymbols.push_back(std::move(symbol)); + symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get(); + symbol_source_->id_map_[id] = symbol.get(); + symbol_source_->symbols_.push_back(std::move(symbol)); return *this; } - StaticSymbolSourceBuilder& addSymbol(const StringPiece& name, ResourceId id, + StaticSymbolSourceBuilder& AddSymbol(const StringPiece& name, ResourceId id, std::unique_ptr<Attribute> attr = {}) { std::unique_ptr<SymbolTable::Symbol> symbol = util::make_unique<SymbolTable::Symbol>(id, std::move(attr), false); - mSymbolSource->mNameMap[parseNameOrDie(name)] = symbol.get(); - mSymbolSource->mIdMap[id] = symbol.get(); - mSymbolSource->mSymbols.push_back(std::move(symbol)); + symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get(); + symbol_source_->id_map_[id] = symbol.get(); + symbol_source_->symbols_.push_back(std::move(symbol)); return *this; } - std::unique_ptr<ISymbolSource> build() { return std::move(mSymbolSource); } + std::unique_ptr<ISymbolSource> Build() { return std::move(symbol_source_); } private: class StaticSymbolSource : public ISymbolSource { public: StaticSymbolSource() = default; - std::unique_ptr<SymbolTable::Symbol> findByName( + std::unique_ptr<SymbolTable::Symbol> FindByName( const ResourceName& name) override { - auto iter = mNameMap.find(name); - if (iter != mNameMap.end()) { - return cloneSymbol(iter->second); + auto iter = name_map_.find(name); + if (iter != name_map_.end()) { + return CloneSymbol(iter->second); } return nullptr; } - std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override { - auto iter = mIdMap.find(id); - if (iter != mIdMap.end()) { - return cloneSymbol(iter->second); + std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override { + auto iter = id_map_.find(id); + if (iter != id_map_.end()) { + return CloneSymbol(iter->second); } return nullptr; } - std::list<std::unique_ptr<SymbolTable::Symbol>> mSymbols; - std::map<ResourceName, SymbolTable::Symbol*> mNameMap; - std::map<ResourceId, SymbolTable::Symbol*> mIdMap; + std::list<std::unique_ptr<SymbolTable::Symbol>> symbols_; + std::map<ResourceName, SymbolTable::Symbol*> name_map_; + std::map<ResourceId, SymbolTable::Symbol*> id_map_; private: - std::unique_ptr<SymbolTable::Symbol> cloneSymbol(SymbolTable::Symbol* sym) { + std::unique_ptr<SymbolTable::Symbol> CloneSymbol(SymbolTable::Symbol* sym) { std::unique_ptr<SymbolTable::Symbol> clone = util::make_unique<SymbolTable::Symbol>(); clone->id = sym->id; if (sym->attribute) { clone->attribute = - std::unique_ptr<Attribute>(sym->attribute->clone(nullptr)); + std::unique_ptr<Attribute>(sym->attribute->Clone(nullptr)); } - clone->isPublic = sym->isPublic; + clone->is_public = sym->is_public; return clone; } DISALLOW_COPY_AND_ASSIGN(StaticSymbolSource); }; - std::unique_ptr<StaticSymbolSource> mSymbolSource = + std::unique_ptr<StaticSymbolSource> symbol_source_ = util::make_unique<StaticSymbolSource>(); }; diff --git a/tools/aapt2/test/Test.h b/tools/aapt2/test/Test.h index c9188bf84c68..ec07432fa51e 100644 --- a/tools/aapt2/test/Test.h +++ b/tools/aapt2/test/Test.h @@ -17,14 +17,10 @@ #ifndef AAPT_TEST_TEST_H #define AAPT_TEST_TEST_H +#include "gtest/gtest.h" + #include "test/Builders.h" #include "test/Common.h" #include "test/Context.h" -#include <gtest/gtest.h> - -namespace aapt { -namespace test {} // namespace test -} // namespace aapt - #endif // AAPT_TEST_TEST_H diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp index 546b6078ddb0..aeabcff011ed 100644 --- a/tools/aapt2/unflatten/BinaryResourceParser.cpp +++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp @@ -15,6 +15,16 @@ */ #include "unflatten/BinaryResourceParser.h" + +#include <algorithm> +#include <map> +#include <string> + +#include "android-base/logging.h" +#include "android-base/macros.h" +#include "androidfw/ResourceTypes.h" +#include "androidfw/TypeWrappers.h" + #include "ResourceTable.h" #include "ResourceUtils.h" #include "ResourceValues.h" @@ -23,13 +33,6 @@ #include "unflatten/ResChunkPullParser.h" #include "util/Util.h" -#include <android-base/macros.h> -#include <androidfw/ResourceTypes.h> -#include <androidfw/TypeWrappers.h> -#include <algorithm> -#include <map> -#include <string> - namespace aapt { using namespace android; @@ -41,29 +44,31 @@ namespace { * given a mapping from resource ID to resource name. */ class ReferenceIdToNameVisitor : public ValueVisitor { - private: - const std::map<ResourceId, ResourceName>* mMapping; - public: - using ValueVisitor::visit; + using ValueVisitor::Visit; explicit ReferenceIdToNameVisitor( const std::map<ResourceId, ResourceName>* mapping) - : mMapping(mapping) { - assert(mMapping); + : mapping_(mapping) { + CHECK(mapping_ != nullptr); } - void visit(Reference* reference) override { - if (!reference->id || !reference->id.value().isValid()) { + void Visit(Reference* reference) override { + if (!reference->id || !reference->id.value().is_valid()) { return; } ResourceId id = reference->id.value(); - auto cacheIter = mMapping->find(id); - if (cacheIter != mMapping->end()) { - reference->name = cacheIter->second; + auto cache_iter = mapping_->find(id); + if (cache_iter != mapping_->end()) { + reference->name = cache_iter->second; } } + + private: + DISALLOW_COPY_AND_ASSIGN(ReferenceIdToNameVisitor); + + const std::map<ResourceId, ResourceName>* mapping_; }; } // namespace @@ -72,33 +77,32 @@ BinaryResourceParser::BinaryResourceParser(IAaptContext* context, ResourceTable* table, const Source& source, const void* data, size_t len) - : mContext(context), - mTable(table), - mSource(source), - mData(data), - mDataLen(len) {} + : context_(context), + table_(table), + source_(source), + data_(data), + data_len_(len) {} -bool BinaryResourceParser::parse() { - ResChunkPullParser parser(mData, mDataLen); +bool BinaryResourceParser::Parse() { + ResChunkPullParser parser(data_, data_len_); bool error = false; - while (ResChunkPullParser::isGoodEvent(parser.next())) { - if (parser.getChunk()->type != android::RES_TABLE_TYPE) { - mContext->getDiagnostics()->warn(DiagMessage(mSource) + while (ResChunkPullParser::IsGoodEvent(parser.Next())) { + if (parser.chunk()->type != android::RES_TABLE_TYPE) { + context_->GetDiagnostics()->Warn(DiagMessage(source_) << "unknown chunk of type '" - << (int)parser.getChunk()->type << "'"); + << (int)parser.chunk()->type << "'"); continue; } - if (!parseTable(parser.getChunk())) { + if (!ParseTable(parser.chunk())) { error = true; } } - if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) { - mContext->getDiagnostics()->error(DiagMessage(mSource) - << "corrupt resource table: " - << parser.getLastError()); + if (parser.event() == ResChunkPullParser::Event::kBadDocument) { + context_->GetDiagnostics()->Error( + DiagMessage(source_) << "corrupt resource table: " << parser.error()); return false; } return !error; @@ -108,212 +112,210 @@ bool BinaryResourceParser::parse() { * Parses the resource table, which contains all the packages, types, and * entries. */ -bool BinaryResourceParser::parseTable(const ResChunk_header* chunk) { - const ResTable_header* tableHeader = convertTo<ResTable_header>(chunk); - if (!tableHeader) { - mContext->getDiagnostics()->error(DiagMessage(mSource) +bool BinaryResourceParser::ParseTable(const ResChunk_header* chunk) { + const ResTable_header* table_header = ConvertTo<ResTable_header>(chunk); + if (!table_header) { + context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt ResTable_header chunk"); return false; } - ResChunkPullParser parser(getChunkData(&tableHeader->header), - getChunkDataLen(&tableHeader->header)); - while (ResChunkPullParser::isGoodEvent(parser.next())) { - switch (util::deviceToHost16(parser.getChunk()->type)) { + ResChunkPullParser parser(GetChunkData(&table_header->header), + GetChunkDataLen(&table_header->header)); + while (ResChunkPullParser::IsGoodEvent(parser.Next())) { + switch (util::DeviceToHost16(parser.chunk()->type)) { case android::RES_STRING_POOL_TYPE: - if (mValuePool.getError() == NO_INIT) { - status_t err = mValuePool.setTo( - parser.getChunk(), util::deviceToHost32(parser.getChunk()->size)); + if (value_pool_.getError() == NO_INIT) { + status_t err = value_pool_.setTo( + parser.chunk(), util::DeviceToHost32(parser.chunk()->size)); if (err != NO_ERROR) { - mContext->getDiagnostics()->error( - DiagMessage(mSource) << "corrupt string pool in ResTable: " - << mValuePool.getError()); + context_->GetDiagnostics()->Error( + DiagMessage(source_) << "corrupt string pool in ResTable: " + << value_pool_.getError()); return false; } // Reserve some space for the strings we are going to add. - mTable->stringPool.hintWillAdd(mValuePool.size(), - mValuePool.styleCount()); + table_->string_pool.HintWillAdd(value_pool_.size(), + value_pool_.styleCount()); } else { - mContext->getDiagnostics()->warn( - DiagMessage(mSource) << "unexpected string pool in ResTable"); + context_->GetDiagnostics()->Warn( + DiagMessage(source_) << "unexpected string pool in ResTable"); } break; case android::RES_TABLE_PACKAGE_TYPE: - if (!parsePackage(parser.getChunk())) { + if (!ParsePackage(parser.chunk())) { return false; } break; default: - mContext->getDiagnostics()->warn( - DiagMessage(mSource) + context_->GetDiagnostics()->Warn( + DiagMessage(source_) << "unexpected chunk type " - << (int)util::deviceToHost16(parser.getChunk()->type)); + << (int)util::DeviceToHost16(parser.chunk()->type)); break; } } - if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) { - mContext->getDiagnostics()->error(DiagMessage(mSource) - << "corrupt resource table: " - << parser.getLastError()); + if (parser.event() == ResChunkPullParser::Event::kBadDocument) { + context_->GetDiagnostics()->Error( + DiagMessage(source_) << "corrupt resource table: " << parser.error()); return false; } return true; } -bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) { - const ResTable_package* packageHeader = convertTo<ResTable_package>(chunk); - if (!packageHeader) { - mContext->getDiagnostics()->error(DiagMessage(mSource) +bool BinaryResourceParser::ParsePackage(const ResChunk_header* chunk) { + const ResTable_package* package_header = ConvertTo<ResTable_package>(chunk); + if (!package_header) { + context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt ResTable_package chunk"); return false; } - uint32_t packageId = util::deviceToHost32(packageHeader->id); - if (packageId > std::numeric_limits<uint8_t>::max()) { - mContext->getDiagnostics()->error( - DiagMessage(mSource) << "package ID is too big (" << packageId << ")"); + uint32_t package_id = util::DeviceToHost32(package_header->id); + if (package_id > std::numeric_limits<uint8_t>::max()) { + context_->GetDiagnostics()->Error( + DiagMessage(source_) << "package ID is too big (" << package_id << ")"); return false; } // Extract the package name. - size_t len = strnlen16((const char16_t*)packageHeader->name, - arraysize(packageHeader->name)); - std::u16string packageName; - packageName.resize(len); + size_t len = strnlen16((const char16_t*)package_header->name, + arraysize(package_header->name)); + std::u16string package_name; + package_name.resize(len); for (size_t i = 0; i < len; i++) { - packageName[i] = util::deviceToHost16(packageHeader->name[i]); + package_name[i] = util::DeviceToHost16(package_header->name[i]); } - ResourceTablePackage* package = mTable->createPackage( - util::utf16ToUtf8(packageName), static_cast<uint8_t>(packageId)); + ResourceTablePackage* package = table_->CreatePackage( + util::Utf16ToUtf8(package_name), static_cast<uint8_t>(package_id)); if (!package) { - mContext->getDiagnostics()->error(DiagMessage(mSource) - << "incompatible package '" << packageName - << "' with ID " << packageId); + context_->GetDiagnostics()->Error( + DiagMessage(source_) << "incompatible package '" << package_name + << "' with ID " << package_id); return false; } // There can be multiple packages in a table, so // clear the type and key pool in case they were set from a previous package. - mTypePool.uninit(); - mKeyPool.uninit(); + type_pool_.uninit(); + key_pool_.uninit(); - ResChunkPullParser parser(getChunkData(&packageHeader->header), - getChunkDataLen(&packageHeader->header)); - while (ResChunkPullParser::isGoodEvent(parser.next())) { - switch (util::deviceToHost16(parser.getChunk()->type)) { + ResChunkPullParser parser(GetChunkData(&package_header->header), + GetChunkDataLen(&package_header->header)); + while (ResChunkPullParser::IsGoodEvent(parser.Next())) { + switch (util::DeviceToHost16(parser.chunk()->type)) { case android::RES_STRING_POOL_TYPE: - if (mTypePool.getError() == NO_INIT) { - status_t err = mTypePool.setTo( - parser.getChunk(), util::deviceToHost32(parser.getChunk()->size)); + if (type_pool_.getError() == NO_INIT) { + status_t err = type_pool_.setTo( + parser.chunk(), util::DeviceToHost32(parser.chunk()->size)); if (err != NO_ERROR) { - mContext->getDiagnostics()->error(DiagMessage(mSource) + context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt type string pool in " << "ResTable_package: " - << mTypePool.getError()); + << type_pool_.getError()); return false; } - } else if (mKeyPool.getError() == NO_INIT) { - status_t err = mKeyPool.setTo( - parser.getChunk(), util::deviceToHost32(parser.getChunk()->size)); + } else if (key_pool_.getError() == NO_INIT) { + status_t err = key_pool_.setTo( + parser.chunk(), util::DeviceToHost32(parser.chunk()->size)); if (err != NO_ERROR) { - mContext->getDiagnostics()->error(DiagMessage(mSource) + context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt key string pool in " << "ResTable_package: " - << mKeyPool.getError()); + << key_pool_.getError()); return false; } } else { - mContext->getDiagnostics()->warn(DiagMessage(mSource) + context_->GetDiagnostics()->Warn(DiagMessage(source_) << "unexpected string pool"); } break; case android::RES_TABLE_TYPE_SPEC_TYPE: - if (!parseTypeSpec(parser.getChunk())) { + if (!ParseTypeSpec(parser.chunk())) { return false; } break; case android::RES_TABLE_TYPE_TYPE: - if (!parseType(package, parser.getChunk())) { + if (!ParseType(package, parser.chunk())) { return false; } break; default: - mContext->getDiagnostics()->warn( - DiagMessage(mSource) + context_->GetDiagnostics()->Warn( + DiagMessage(source_) << "unexpected chunk type " - << (int)util::deviceToHost16(parser.getChunk()->type)); + << (int)util::DeviceToHost16(parser.chunk()->type)); break; } } - if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) { - mContext->getDiagnostics()->error(DiagMessage(mSource) - << "corrupt ResTable_package: " - << parser.getLastError()); + if (parser.event() == ResChunkPullParser::Event::kBadDocument) { + context_->GetDiagnostics()->Error( + DiagMessage(source_) << "corrupt ResTable_package: " << parser.error()); return false; } // Now go through the table and change local resource ID references to // symbolic references. - ReferenceIdToNameVisitor visitor(&mIdIndex); - visitAllValuesInTable(mTable, &visitor); + ReferenceIdToNameVisitor visitor(&id_index_); + VisitAllValuesInTable(table_, &visitor); return true; } -bool BinaryResourceParser::parseTypeSpec(const ResChunk_header* chunk) { - if (mTypePool.getError() != NO_ERROR) { - mContext->getDiagnostics()->error(DiagMessage(mSource) +bool BinaryResourceParser::ParseTypeSpec(const ResChunk_header* chunk) { + if (type_pool_.getError() != NO_ERROR) { + context_->GetDiagnostics()->Error(DiagMessage(source_) << "missing type string pool"); return false; } - const ResTable_typeSpec* typeSpec = convertTo<ResTable_typeSpec>(chunk); - if (!typeSpec) { - mContext->getDiagnostics()->error(DiagMessage(mSource) + const ResTable_typeSpec* type_spec = ConvertTo<ResTable_typeSpec>(chunk); + if (!type_spec) { + context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt ResTable_typeSpec chunk"); return false; } - if (typeSpec->id == 0) { - mContext->getDiagnostics()->error(DiagMessage(mSource) + if (type_spec->id == 0) { + context_->GetDiagnostics()->Error(DiagMessage(source_) << "ResTable_typeSpec has invalid id: " - << typeSpec->id); + << type_spec->id); return false; } return true; } -bool BinaryResourceParser::parseType(const ResourceTablePackage* package, +bool BinaryResourceParser::ParseType(const ResourceTablePackage* package, const ResChunk_header* chunk) { - if (mTypePool.getError() != NO_ERROR) { - mContext->getDiagnostics()->error(DiagMessage(mSource) + if (type_pool_.getError() != NO_ERROR) { + context_->GetDiagnostics()->Error(DiagMessage(source_) << "missing type string pool"); return false; } - if (mKeyPool.getError() != NO_ERROR) { - mContext->getDiagnostics()->error(DiagMessage(mSource) + if (key_pool_.getError() != NO_ERROR) { + context_->GetDiagnostics()->Error(DiagMessage(source_) << "missing key string pool"); return false; } - const ResTable_type* type = convertTo<ResTable_type>(chunk); + const ResTable_type* type = ConvertTo<ResTable_type>(chunk); if (!type) { - mContext->getDiagnostics()->error(DiagMessage(mSource) + context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt ResTable_type chunk"); return false; } if (type->id == 0) { - mContext->getDiagnostics()->error(DiagMessage(mSource) + context_->GetDiagnostics()->Error(DiagMessage(source_) << "ResTable_type has invalid id: " << (int)type->id); return false; @@ -322,12 +324,12 @@ bool BinaryResourceParser::parseType(const ResourceTablePackage* package, ConfigDescription config; config.copyFromDtoH(type->config); - const std::string typeStr = util::getString(mTypePool, type->id - 1); + const std::string type_str = util::GetString(type_pool_, type->id - 1); - const ResourceType* parsedType = parseResourceType(typeStr); - if (!parsedType) { - mContext->getDiagnostics()->error( - DiagMessage(mSource) << "invalid type name '" << typeStr + const ResourceType* parsed_type = ParseResourceType(type_str); + if (!parsed_type) { + context_->GetDiagnostics()->Error( + DiagMessage(source_) << "invalid type name '" << type_str << "' for type with ID " << (int)type->id); return false; } @@ -340,91 +342,90 @@ bool BinaryResourceParser::parseType(const ResourceTablePackage* package, } const ResourceName name( - package->name, *parsedType, - util::getString(mKeyPool, util::deviceToHost32(entry->key.index))); + package->name, *parsed_type, + util::GetString(key_pool_, util::DeviceToHost32(entry->key.index))); - const ResourceId resId(package->id.value(), type->id, - static_cast<uint16_t>(it.index())); + const ResourceId res_id(package->id.value(), type->id, + static_cast<uint16_t>(it.index())); - std::unique_ptr<Value> resourceValue; + std::unique_ptr<Value> resource_value; if (entry->flags & ResTable_entry::FLAG_COMPLEX) { const ResTable_map_entry* mapEntry = static_cast<const ResTable_map_entry*>(entry); // TODO(adamlesinski): Check that the entry count is valid. - resourceValue = parseMapEntry(name, config, mapEntry); + resource_value = ParseMapEntry(name, config, mapEntry); } else { const Res_value* value = (const Res_value*)((const uint8_t*)entry + - util::deviceToHost32(entry->size)); - resourceValue = parseValue(name, config, value, entry->flags); + util::DeviceToHost32(entry->size)); + resource_value = ParseValue(name, config, value, entry->flags); } - if (!resourceValue) { - mContext->getDiagnostics()->error( - DiagMessage(mSource) << "failed to parse value for resource " << name - << " (" << resId << ") with configuration '" + if (!resource_value) { + context_->GetDiagnostics()->Error( + DiagMessage(source_) << "failed to parse value for resource " << name + << " (" << res_id << ") with configuration '" << config << "'"); return false; } - if (!mTable->addResourceAllowMangled(name, config, {}, - std::move(resourceValue), - mContext->getDiagnostics())) { + if (!table_->AddResourceAllowMangled(name, config, {}, + std::move(resource_value), + context_->GetDiagnostics())) { return false; } if ((entry->flags & ResTable_entry::FLAG_PUBLIC) != 0) { Symbol symbol; symbol.state = SymbolState::kPublic; - symbol.source = mSource.withLine(0); - if (!mTable->setSymbolStateAllowMangled(name, resId, symbol, - mContext->getDiagnostics())) { + symbol.source = source_.WithLine(0); + if (!table_->SetSymbolStateAllowMangled(name, res_id, symbol, + context_->GetDiagnostics())) { return false; } } // Add this resource name->id mapping to the index so // that we can resolve all ID references to name references. - auto cacheIter = mIdIndex.find(resId); - if (cacheIter == mIdIndex.end()) { - mIdIndex.insert({resId, name}); + auto cache_iter = id_index_.find(res_id); + if (cache_iter == id_index_.end()) { + id_index_.insert({res_id, name}); } } return true; } -std::unique_ptr<Item> BinaryResourceParser::parseValue( +std::unique_ptr<Item> BinaryResourceParser::ParseValue( const ResourceNameRef& name, const ConfigDescription& config, const Res_value* value, uint16_t flags) { if (name.type == ResourceType::kId) { return util::make_unique<Id>(); } - const uint32_t data = util::deviceToHost32(value->data); + const uint32_t data = util::DeviceToHost32(value->data); if (value->dataType == Res_value::TYPE_STRING) { - const std::string str = util::getString(mValuePool, data); + const std::string str = util::GetString(value_pool_, data); - const ResStringPool_span* spans = mValuePool.styleAt(data); + const ResStringPool_span* spans = value_pool_.styleAt(data); // Check if the string has a valid style associated with it. if (spans != nullptr && spans->name.index != ResStringPool_span::END) { - StyleString styleStr = {str}; + StyleString style_str = {str}; while (spans->name.index != ResStringPool_span::END) { - styleStr.spans.push_back( - Span{util::getString(mValuePool, spans->name.index), + style_str.spans.push_back( + Span{util::GetString(value_pool_, spans->name.index), spans->firstChar, spans->lastChar}); spans++; } - return util::make_unique<StyledString>(mTable->stringPool.makeRef( - styleStr, + return util::make_unique<StyledString>(table_->string_pool.MakeRef( + style_str, StringPool::Context(StringPool::Context::kStylePriority, config))); } else { - if (name.type != ResourceType::kString && - util::stringStartsWith(str, "res/")) { + if (name.type != ResourceType::kString && util::StartsWith(str, "res/")) { // This must be a FileReference. - return util::make_unique<FileReference>(mTable->stringPool.makeRef( + return util::make_unique<FileReference>(table_->string_pool.MakeRef( str, StringPool::Context(StringPool::Context::kHighPriority, config))); } @@ -432,7 +433,7 @@ std::unique_ptr<Item> BinaryResourceParser::parseValue( // There are no styles associated with this string, so treat it as // a simple string. return util::make_unique<String>( - mTable->stringPool.makeRef(str, StringPool::Context(config))); + table_->string_pool.MakeRef(str, StringPool::Context(config))); } } @@ -444,9 +445,9 @@ std::unique_ptr<Item> BinaryResourceParser::parseValue( if (data == 0) { // A reference of 0, must be the magic @null reference. - Res_value nullType = {}; - nullType.dataType = Res_value::TYPE_REFERENCE; - return util::make_unique<BinaryPrimitive>(nullType); + Res_value null_type = {}; + null_type.dataType = Res_value::TYPE_REFERENCE; + return util::make_unique<BinaryPrimitive>(null_type); } // This is a normal reference. @@ -457,87 +458,88 @@ std::unique_ptr<Item> BinaryResourceParser::parseValue( return util::make_unique<BinaryPrimitive>(*value); } -std::unique_ptr<Value> BinaryResourceParser::parseMapEntry( +std::unique_ptr<Value> BinaryResourceParser::ParseMapEntry( const ResourceNameRef& name, const ConfigDescription& config, const ResTable_map_entry* map) { switch (name.type) { case ResourceType::kStyle: - return parseStyle(name, config, map); + return ParseStyle(name, config, map); case ResourceType::kAttrPrivate: // fallthrough case ResourceType::kAttr: - return parseAttr(name, config, map); + return ParseAttr(name, config, map); case ResourceType::kArray: - return parseArray(name, config, map); + return ParseArray(name, config, map); case ResourceType::kPlurals: - return parsePlural(name, config, map); + return ParsePlural(name, config, map); default: - assert(false && "unknown map type"); + LOG(FATAL) << "unknown map type"; break; } return {}; } -std::unique_ptr<Style> BinaryResourceParser::parseStyle( +std::unique_ptr<Style> BinaryResourceParser::ParseStyle( const ResourceNameRef& name, const ConfigDescription& config, const ResTable_map_entry* map) { std::unique_ptr<Style> style = util::make_unique<Style>(); - if (util::deviceToHost32(map->parent.ident) != 0) { + if (util::DeviceToHost32(map->parent.ident) != 0) { // The parent is a regular reference to a resource. - style->parent = Reference(util::deviceToHost32(map->parent.ident)); + style->parent = Reference(util::DeviceToHost32(map->parent.ident)); } - for (const ResTable_map& mapEntry : map) { - if (Res_INTERNALID(util::deviceToHost32(mapEntry.name.ident))) { + for (const ResTable_map& map_entry : map) { + if (Res_INTERNALID(util::DeviceToHost32(map_entry.name.ident))) { continue; } - Style::Entry styleEntry; - styleEntry.key = Reference(util::deviceToHost32(mapEntry.name.ident)); - styleEntry.value = parseValue(name, config, &mapEntry.value, 0); - if (!styleEntry.value) { + Style::Entry style_entry; + style_entry.key = Reference(util::DeviceToHost32(map_entry.name.ident)); + style_entry.value = ParseValue(name, config, &map_entry.value, 0); + if (!style_entry.value) { return {}; } - style->entries.push_back(std::move(styleEntry)); + style->entries.push_back(std::move(style_entry)); } return style; } -std::unique_ptr<Attribute> BinaryResourceParser::parseAttr( +std::unique_ptr<Attribute> BinaryResourceParser::ParseAttr( const ResourceNameRef& name, const ConfigDescription& config, const ResTable_map_entry* map) { - const bool isWeak = - (util::deviceToHost16(map->flags) & ResTable_entry::FLAG_WEAK) != 0; - std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(isWeak); + const bool is_weak = + (util::DeviceToHost16(map->flags) & ResTable_entry::FLAG_WEAK) != 0; + std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(is_weak); // First we must discover what type of attribute this is. Find the type mask. - auto typeMaskIter = + auto type_mask_iter = std::find_if(begin(map), end(map), [](const ResTable_map& entry) -> bool { - return util::deviceToHost32(entry.name.ident) == + return util::DeviceToHost32(entry.name.ident) == ResTable_map::ATTR_TYPE; }); - if (typeMaskIter != end(map)) { - attr->typeMask = util::deviceToHost32(typeMaskIter->value.data); + if (type_mask_iter != end(map)) { + attr->type_mask = util::DeviceToHost32(type_mask_iter->value.data); } - for (const ResTable_map& mapEntry : map) { - if (Res_INTERNALID(util::deviceToHost32(mapEntry.name.ident))) { - switch (util::deviceToHost32(mapEntry.name.ident)) { + for (const ResTable_map& map_entry : map) { + if (Res_INTERNALID(util::DeviceToHost32(map_entry.name.ident))) { + switch (util::DeviceToHost32(map_entry.name.ident)) { case ResTable_map::ATTR_MIN: - attr->minInt = static_cast<int32_t>(mapEntry.value.data); + attr->min_int = static_cast<int32_t>(map_entry.value.data); break; case ResTable_map::ATTR_MAX: - attr->maxInt = static_cast<int32_t>(mapEntry.value.data); + attr->max_int = static_cast<int32_t>(map_entry.value.data); break; } continue; } - if (attr->typeMask & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) { + if (attr->type_mask & + (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) { Attribute::Symbol symbol; - symbol.value = util::deviceToHost32(mapEntry.value.data); - symbol.symbol = Reference(util::deviceToHost32(mapEntry.name.ident)); + symbol.value = util::DeviceToHost32(map_entry.value.data); + symbol.symbol = Reference(util::DeviceToHost32(map_entry.name.ident)); attr->symbols.push_back(std::move(symbol)); } } @@ -546,27 +548,27 @@ std::unique_ptr<Attribute> BinaryResourceParser::parseAttr( return attr; } -std::unique_ptr<Array> BinaryResourceParser::parseArray( +std::unique_ptr<Array> BinaryResourceParser::ParseArray( const ResourceNameRef& name, const ConfigDescription& config, const ResTable_map_entry* map) { std::unique_ptr<Array> array = util::make_unique<Array>(); - for (const ResTable_map& mapEntry : map) { - array->items.push_back(parseValue(name, config, &mapEntry.value, 0)); + for (const ResTable_map& map_entry : map) { + array->items.push_back(ParseValue(name, config, &map_entry.value, 0)); } return array; } -std::unique_ptr<Plural> BinaryResourceParser::parsePlural( +std::unique_ptr<Plural> BinaryResourceParser::ParsePlural( const ResourceNameRef& name, const ConfigDescription& config, const ResTable_map_entry* map) { std::unique_ptr<Plural> plural = util::make_unique<Plural>(); - for (const ResTable_map& mapEntry : map) { - std::unique_ptr<Item> item = parseValue(name, config, &mapEntry.value, 0); + for (const ResTable_map& map_entry : map) { + std::unique_ptr<Item> item = ParseValue(name, config, &map_entry.value, 0); if (!item) { return {}; } - switch (util::deviceToHost32(mapEntry.name.ident)) { + switch (util::DeviceToHost32(map_entry.name.ident)) { case ResTable_map::ATTR_ZERO: plural->values[Plural::Zero] = std::move(item); break; diff --git a/tools/aapt2/unflatten/BinaryResourceParser.h b/tools/aapt2/unflatten/BinaryResourceParser.h index 99f2bd4e7e31..dc668fdab7b6 100644 --- a/tools/aapt2/unflatten/BinaryResourceParser.h +++ b/tools/aapt2/unflatten/BinaryResourceParser.h @@ -17,16 +17,17 @@ #ifndef AAPT_BINARY_RESOURCE_PARSER_H #define AAPT_BINARY_RESOURCE_PARSER_H +#include <string> + +#include "android-base/macros.h" +#include "androidfw/ResourceTypes.h" + #include "ResourceTable.h" #include "ResourceValues.h" #include "Source.h" - #include "process/IResourceTableConsumer.h" #include "util/Util.h" -#include <androidfw/ResourceTypes.h> -#include <string> - namespace aapt { struct SymbolTable_entry; @@ -45,44 +46,44 @@ class BinaryResourceParser { * add any resources parsed to `table`. `source` is for logging purposes. */ BinaryResourceParser(IAaptContext* context, ResourceTable* table, - const Source& source, const void* data, size_t dataLen); - - BinaryResourceParser(const BinaryResourceParser&) = delete; // No copy. + const Source& source, const void* data, size_t data_len); /* * Parses the binary resource table and returns true if successful. */ - bool parse(); + bool Parse(); private: - bool parseTable(const android::ResChunk_header* chunk); - bool parsePackage(const android::ResChunk_header* chunk); - bool parseTypeSpec(const android::ResChunk_header* chunk); - bool parseType(const ResourceTablePackage* package, + DISALLOW_COPY_AND_ASSIGN(BinaryResourceParser); + + bool ParseTable(const android::ResChunk_header* chunk); + bool ParsePackage(const android::ResChunk_header* chunk); + bool ParseTypeSpec(const android::ResChunk_header* chunk); + bool ParseType(const ResourceTablePackage* package, const android::ResChunk_header* chunk); - std::unique_ptr<Item> parseValue(const ResourceNameRef& name, + std::unique_ptr<Item> ParseValue(const ResourceNameRef& name, const ConfigDescription& config, const android::Res_value* value, uint16_t flags); - std::unique_ptr<Value> parseMapEntry(const ResourceNameRef& name, + std::unique_ptr<Value> ParseMapEntry(const ResourceNameRef& name, const ConfigDescription& config, const android::ResTable_map_entry* map); - std::unique_ptr<Style> parseStyle(const ResourceNameRef& name, + std::unique_ptr<Style> ParseStyle(const ResourceNameRef& name, const ConfigDescription& config, const android::ResTable_map_entry* map); - std::unique_ptr<Attribute> parseAttr(const ResourceNameRef& name, + std::unique_ptr<Attribute> ParseAttr(const ResourceNameRef& name, const ConfigDescription& config, const android::ResTable_map_entry* map); - std::unique_ptr<Array> parseArray(const ResourceNameRef& name, + std::unique_ptr<Array> ParseArray(const ResourceNameRef& name, const ConfigDescription& config, const android::ResTable_map_entry* map); - std::unique_ptr<Plural> parsePlural(const ResourceNameRef& name, + std::unique_ptr<Plural> ParsePlural(const ResourceNameRef& name, const ConfigDescription& config, const android::ResTable_map_entry* map); @@ -92,30 +93,30 @@ class BinaryResourceParser { * read and added to the Value. * Returns true if the mapEntry was meta data. */ - bool collectMetaData(const android::ResTable_map& mapEntry, Value* value); + bool CollectMetaData(const android::ResTable_map& map_entry, Value* value); - IAaptContext* mContext; - ResourceTable* mTable; + IAaptContext* context_; + ResourceTable* table_; - const Source mSource; + const Source source_; - const void* mData; - const size_t mDataLen; + const void* data_; + const size_t data_len_; // The standard value string pool for resource values. - android::ResStringPool mValuePool; + android::ResStringPool value_pool_; // The string pool that holds the names of the types defined // in this table. - android::ResStringPool mTypePool; + android::ResStringPool type_pool_; // The string pool that holds the names of the entries defined // in this table. - android::ResStringPool mKeyPool; + android::ResStringPool key_pool_; // A mapping of resource ID to resource name. When we finish parsing // we use this to convert all resource IDs to symbolic references. - std::map<ResourceId, ResourceName> mIdIndex; + std::map<ResourceId, ResourceName> id_index_; }; } // namespace aapt @@ -128,11 +129,11 @@ namespace android { inline const ResTable_map* begin(const ResTable_map_entry* map) { return (const ResTable_map*)((const uint8_t*)map + - aapt::util::deviceToHost32(map->size)); + aapt::util::DeviceToHost32(map->size)); } inline const ResTable_map* end(const ResTable_map_entry* map) { - return begin(map) + aapt::util::deviceToHost32(map->count); + return begin(map) + aapt::util::DeviceToHost32(map->count); } } // namespace android diff --git a/tools/aapt2/unflatten/ResChunkPullParser.cpp b/tools/aapt2/unflatten/ResChunkPullParser.cpp index 6f8bb1b29b62..5d71ff315874 100644 --- a/tools/aapt2/unflatten/ResChunkPullParser.cpp +++ b/tools/aapt2/unflatten/ResChunkPullParser.cpp @@ -15,55 +15,60 @@ */ #include "unflatten/ResChunkPullParser.h" -#include "util/Util.h" -#include <androidfw/ResourceTypes.h> #include <cstddef> +#include "android-base/logging.h" +#include "androidfw/ResourceTypes.h" + +#include "util/Util.h" + namespace aapt { using android::ResChunk_header; -ResChunkPullParser::Event ResChunkPullParser::next() { - if (!isGoodEvent(mEvent)) { - return mEvent; - } +ResChunkPullParser::Event ResChunkPullParser::Next() { + if (!IsGoodEvent(event_)) { + return event_; + } - if (mEvent == Event::StartDocument) { - mCurrentChunk = mData; - } else { - mCurrentChunk = (const ResChunk_header*) - (((const char*) mCurrentChunk) + util::deviceToHost32(mCurrentChunk->size)); - } + if (event_ == Event::kStartDocument) { + current_chunk_ = data_; + } else { + current_chunk_ = + (const ResChunk_header*)(((const char*)current_chunk_) + + util::DeviceToHost32(current_chunk_->size)); + } - const std::ptrdiff_t diff = (const char*) mCurrentChunk - (const char*) mData; - assert(diff >= 0 && "diff is negative"); - const size_t offset = static_cast<const size_t>(diff); + const std::ptrdiff_t diff = (const char*)current_chunk_ - (const char*)data_; + CHECK(diff >= 0) << "diff is negative"; + const size_t offset = static_cast<const size_t>(diff); - if (offset == mLen) { - mCurrentChunk = nullptr; - return (mEvent = Event::EndDocument); - } else if (offset + sizeof(ResChunk_header) > mLen) { - mLastError = "chunk is past the end of the document"; - mCurrentChunk = nullptr; - return (mEvent = Event::BadDocument); - } + if (offset == len_) { + current_chunk_ = nullptr; + return (event_ = Event::kEndDocument); + } else if (offset + sizeof(ResChunk_header) > len_) { + error_ = "chunk is past the end of the document"; + current_chunk_ = nullptr; + return (event_ = Event::kBadDocument); + } - if (util::deviceToHost16(mCurrentChunk->headerSize) < sizeof(ResChunk_header)) { - mLastError = "chunk has too small header"; - mCurrentChunk = nullptr; - return (mEvent = Event::BadDocument); - } else if (util::deviceToHost32(mCurrentChunk->size) < - util::deviceToHost16(mCurrentChunk->headerSize)) { - mLastError = "chunk's total size is smaller than header"; - mCurrentChunk = nullptr; - return (mEvent = Event::BadDocument); - } else if (offset + util::deviceToHost32(mCurrentChunk->size) > mLen) { - mLastError = "chunk's data extends past the end of the document"; - mCurrentChunk = nullptr; - return (mEvent = Event::BadDocument); - } - return (mEvent = Event::Chunk); + if (util::DeviceToHost16(current_chunk_->headerSize) < + sizeof(ResChunk_header)) { + error_ = "chunk has too small header"; + current_chunk_ = nullptr; + return (event_ = Event::kBadDocument); + } else if (util::DeviceToHost32(current_chunk_->size) < + util::DeviceToHost16(current_chunk_->headerSize)) { + error_ = "chunk's total size is smaller than header"; + current_chunk_ = nullptr; + return (event_ = Event::kBadDocument); + } else if (offset + util::DeviceToHost32(current_chunk_->size) > len_) { + error_ = "chunk's data extends past the end of the document"; + current_chunk_ = nullptr; + return (event_ = Event::kBadDocument); + } + return (event_ = Event::kChunk); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/unflatten/ResChunkPullParser.h b/tools/aapt2/unflatten/ResChunkPullParser.h index 24fa63d6e5b4..437fc5c8a9b6 100644 --- a/tools/aapt2/unflatten/ResChunkPullParser.h +++ b/tools/aapt2/unflatten/ResChunkPullParser.h @@ -17,11 +17,13 @@ #ifndef AAPT_RES_CHUNK_PULL_PARSER_H #define AAPT_RES_CHUNK_PULL_PARSER_H -#include "util/Util.h" - -#include <androidfw/ResourceTypes.h> #include <string> +#include "android-base/macros.h" +#include "androidfw/ResourceTypes.h" + +#include "util/Util.h" + namespace aapt { /** @@ -39,17 +41,17 @@ namespace aapt { class ResChunkPullParser { public: enum class Event { - StartDocument, - EndDocument, - BadDocument, + kStartDocument, + kEndDocument, + kBadDocument, - Chunk, + kChunk, }; /** * Returns false if the event is EndDocument or BadDocument. */ - static bool isGoodEvent(Event event); + static bool IsGoodEvent(Event event); /** * Create a ResChunkPullParser to read android::ResChunk_headers @@ -57,68 +59,66 @@ class ResChunkPullParser { */ ResChunkPullParser(const void* data, size_t len); - ResChunkPullParser(const ResChunkPullParser&) = delete; - - Event getEvent() const; - const std::string& getLastError() const; - const android::ResChunk_header* getChunk() const; + Event event() const; + const std::string& error() const; + const android::ResChunk_header* chunk() const; /** * Move to the next android::ResChunk_header. */ - Event next(); + Event Next(); private: - Event mEvent; - const android::ResChunk_header* mData; - size_t mLen; - const android::ResChunk_header* mCurrentChunk; - std::string mLastError; + DISALLOW_COPY_AND_ASSIGN(ResChunkPullParser); + + Event event_; + const android::ResChunk_header* data_; + size_t len_; + const android::ResChunk_header* current_chunk_; + std::string error_; }; template <typename T> -inline static const T* convertTo(const android::ResChunk_header* chunk) { - if (util::deviceToHost16(chunk->headerSize) < sizeof(T)) { +inline static const T* ConvertTo(const android::ResChunk_header* chunk) { + if (util::DeviceToHost16(chunk->headerSize) < sizeof(T)) { return nullptr; } return reinterpret_cast<const T*>(chunk); } -inline static const uint8_t* getChunkData( +inline static const uint8_t* GetChunkData( const android::ResChunk_header* chunk) { return reinterpret_cast<const uint8_t*>(chunk) + - util::deviceToHost16(chunk->headerSize); + util::DeviceToHost16(chunk->headerSize); } -inline static uint32_t getChunkDataLen(const android::ResChunk_header* chunk) { - return util::deviceToHost32(chunk->size) - - util::deviceToHost16(chunk->headerSize); +inline static uint32_t GetChunkDataLen(const android::ResChunk_header* chunk) { + return util::DeviceToHost32(chunk->size) - + util::DeviceToHost16(chunk->headerSize); } // // Implementation // -inline bool ResChunkPullParser::isGoodEvent(ResChunkPullParser::Event event) { - return event != Event::EndDocument && event != Event::BadDocument; +inline bool ResChunkPullParser::IsGoodEvent(ResChunkPullParser::Event event) { + return event != Event::kEndDocument && event != Event::kBadDocument; } inline ResChunkPullParser::ResChunkPullParser(const void* data, size_t len) - : mEvent(Event::StartDocument), - mData(reinterpret_cast<const android::ResChunk_header*>(data)), - mLen(len), - mCurrentChunk(nullptr) {} + : event_(Event::kStartDocument), + data_(reinterpret_cast<const android::ResChunk_header*>(data)), + len_(len), + current_chunk_(nullptr) {} -inline ResChunkPullParser::Event ResChunkPullParser::getEvent() const { - return mEvent; +inline ResChunkPullParser::Event ResChunkPullParser::event() const { + return event_; } -inline const std::string& ResChunkPullParser::getLastError() const { - return mLastError; -} +inline const std::string& ResChunkPullParser::error() const { return error_; } -inline const android::ResChunk_header* ResChunkPullParser::getChunk() const { - return mCurrentChunk; +inline const android::ResChunk_header* ResChunkPullParser::chunk() const { + return current_chunk_; } } // namespace aapt diff --git a/tools/aapt2/util/BigBuffer.cpp b/tools/aapt2/util/BigBuffer.cpp index de4ecd21ec2d..ef99dca286a4 100644 --- a/tools/aapt2/util/BigBuffer.cpp +++ b/tools/aapt2/util/BigBuffer.cpp @@ -20,58 +20,60 @@ #include <memory> #include <vector> +#include "android-base/logging.h" + namespace aapt { -void* BigBuffer::nextBlockImpl(size_t size) { - if (!mBlocks.empty()) { - Block& block = mBlocks.back(); - if (block.mBlockSize - block.size >= size) { - void* outBuffer = block.buffer.get() + block.size; - block.size += size; - mSize += size; - return outBuffer; - } +void* BigBuffer::NextBlockImpl(size_t size) { + if (!blocks_.empty()) { + Block& block = blocks_.back(); + if (block.block_size_ - block.size >= size) { + void* out_buffer = block.buffer.get() + block.size; + block.size += size; + size_ += size; + return out_buffer; } + } - const size_t actualSize = std::max(mBlockSize, size); + const size_t actual_size = std::max(block_size_, size); - Block block = {}; + Block block = {}; - // Zero-allocate the block's buffer. - block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[actualSize]()); - assert(block.buffer); + // Zero-allocate the block's buffer. + block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[actual_size]()); + CHECK(block.buffer); - block.size = size; - block.mBlockSize = actualSize; + block.size = size; + block.block_size_ = actual_size; - mBlocks.push_back(std::move(block)); - mSize += size; - return mBlocks.back().buffer.get(); + blocks_.push_back(std::move(block)); + size_ += size; + return blocks_.back().buffer.get(); } -void* BigBuffer::nextBlock(size_t* outSize) { - if (!mBlocks.empty()) { - Block& block = mBlocks.back(); - if (block.size != block.mBlockSize) { - void* outBuffer = block.buffer.get() + block.size; - size_t size = block.mBlockSize - block.size; - block.size = block.mBlockSize; - mSize += size; - *outSize = size; - return outBuffer; - } +void* BigBuffer::NextBlock(size_t* out_size) { + if (!blocks_.empty()) { + Block& block = blocks_.back(); + if (block.size != block.block_size_) { + void* out_buffer = block.buffer.get() + block.size; + size_t size = block.block_size_ - block.size; + block.size = block.block_size_; + size_ += size; + *out_size = size; + return out_buffer; } + } - // Zero-allocate the block's buffer. - Block block = {}; - block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[mBlockSize]()); - assert(block.buffer); - block.size = mBlockSize; - block.mBlockSize = mBlockSize; - mBlocks.push_back(std::move(block)); - mSize += mBlockSize; - *outSize = mBlockSize; - return mBlocks.back().buffer.get(); + // Zero-allocate the block's buffer. + Block block = {}; + block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[block_size_]()); + CHECK(block.buffer); + block.size = block_size_; + block.block_size_ = block_size_; + blocks_.push_back(std::move(block)); + size_ += block_size_; + *out_size = block_size_; + return blocks_.back().buffer.get(); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/util/BigBuffer.h b/tools/aapt2/util/BigBuffer.h index b273733f6489..d23c41d4d6f0 100644 --- a/tools/aapt2/util/BigBuffer.h +++ b/tools/aapt2/util/BigBuffer.h @@ -17,12 +17,14 @@ #ifndef AAPT_BIG_BUFFER_H #define AAPT_BIG_BUFFER_H -#include <cassert> #include <cstring> #include <memory> #include <type_traits> #include <vector> +#include "android-base/logging.h" +#include "android-base/macros.h" + namespace aapt { /** @@ -54,18 +56,16 @@ class BigBuffer { /** * The size of the memory block allocation. */ - size_t mBlockSize; + size_t block_size_; }; typedef std::vector<Block>::const_iterator const_iterator; /** * Create a BigBuffer with block allocation sizes - * of blockSize. + * of block_size. */ - explicit BigBuffer(size_t blockSize); - - BigBuffer(const BigBuffer&) = delete; // No copying. + explicit BigBuffer(size_t block_size); BigBuffer(BigBuffer&& rhs); @@ -79,104 +79,106 @@ class BigBuffer { * a POD type. The elements are zero-initialized. */ template <typename T> - T* nextBlock(size_t count = 1); + T* NextBlock(size_t count = 1); /** - * Returns the next block available and puts the size in outCount. + * Returns the next block available and puts the size in out_count. * This is useful for grabbing blocks where the size doesn't matter. - * Use backUp() to give back any bytes that were not used. + * Use BackUp() to give back any bytes that were not used. */ - void* nextBlock(size_t* outCount); + void* NextBlock(size_t* out_count); /** - * Backs up count bytes. This must only be called after nextBlock() - * and can not be larger than sizeof(T) * count of the last nextBlock() + * Backs up count bytes. This must only be called after NextBlock() + * and can not be larger than sizeof(T) * count of the last NextBlock() * call. */ - void backUp(size_t count); + void BackUp(size_t count); /** * Moves the specified BigBuffer into this one. When this method * returns, buffer is empty. */ - void appendBuffer(BigBuffer&& buffer); + void AppendBuffer(BigBuffer&& buffer); /** * Pads the block with 'bytes' bytes of zero values. */ - void pad(size_t bytes); + void Pad(size_t bytes); /** * Pads the block so that it aligns on a 4 byte boundary. */ - void align4(); + void Align4(); - size_t getBlockSize() const; + size_t block_size() const; const_iterator begin() const; const_iterator end() const; private: + DISALLOW_COPY_AND_ASSIGN(BigBuffer); + /** * Returns a pointer to a buffer of the requested size. * The buffer is zero-initialized. */ - void* nextBlockImpl(size_t size); + void* NextBlockImpl(size_t size); - size_t mBlockSize; - size_t mSize; - std::vector<Block> mBlocks; + size_t block_size_; + size_t size_; + std::vector<Block> blocks_; }; -inline BigBuffer::BigBuffer(size_t blockSize) - : mBlockSize(blockSize), mSize(0) {} +inline BigBuffer::BigBuffer(size_t block_size) + : block_size_(block_size), size_(0) {} inline BigBuffer::BigBuffer(BigBuffer&& rhs) - : mBlockSize(rhs.mBlockSize), - mSize(rhs.mSize), - mBlocks(std::move(rhs.mBlocks)) {} + : block_size_(rhs.block_size_), + size_(rhs.size_), + blocks_(std::move(rhs.blocks_)) {} -inline size_t BigBuffer::size() const { return mSize; } +inline size_t BigBuffer::size() const { return size_; } -inline size_t BigBuffer::getBlockSize() const { return mBlockSize; } +inline size_t BigBuffer::block_size() const { return block_size_; } template <typename T> -inline T* BigBuffer::nextBlock(size_t count) { +inline T* BigBuffer::NextBlock(size_t count) { static_assert(std::is_standard_layout<T>::value, "T must be standard_layout type"); - assert(count != 0); - return reinterpret_cast<T*>(nextBlockImpl(sizeof(T) * count)); + CHECK(count != 0); + return reinterpret_cast<T*>(NextBlockImpl(sizeof(T) * count)); } -inline void BigBuffer::backUp(size_t count) { - Block& block = mBlocks.back(); +inline void BigBuffer::BackUp(size_t count) { + Block& block = blocks_.back(); block.size -= count; - mSize -= count; + size_ -= count; } -inline void BigBuffer::appendBuffer(BigBuffer&& buffer) { - std::move(buffer.mBlocks.begin(), buffer.mBlocks.end(), - std::back_inserter(mBlocks)); - mSize += buffer.mSize; - buffer.mBlocks.clear(); - buffer.mSize = 0; +inline void BigBuffer::AppendBuffer(BigBuffer&& buffer) { + std::move(buffer.blocks_.begin(), buffer.blocks_.end(), + std::back_inserter(blocks_)); + size_ += buffer.size_; + buffer.blocks_.clear(); + buffer.size_ = 0; } -inline void BigBuffer::pad(size_t bytes) { nextBlock<char>(bytes); } +inline void BigBuffer::Pad(size_t bytes) { NextBlock<char>(bytes); } -inline void BigBuffer::align4() { - const size_t unaligned = mSize % 4; +inline void BigBuffer::Align4() { + const size_t unaligned = size_ % 4; if (unaligned != 0) { - pad(4 - unaligned); + Pad(4 - unaligned); } } inline BigBuffer::const_iterator BigBuffer::begin() const { - return mBlocks.begin(); + return blocks_.begin(); } inline BigBuffer::const_iterator BigBuffer::end() const { - return mBlocks.end(); + return blocks_.end(); } } // namespace aapt diff --git a/tools/aapt2/util/BigBuffer_test.cpp b/tools/aapt2/util/BigBuffer_test.cpp index 2a24f123e18e..12c0b3ee3214 100644 --- a/tools/aapt2/util/BigBuffer_test.cpp +++ b/tools/aapt2/util/BigBuffer_test.cpp @@ -16,83 +16,83 @@ #include "util/BigBuffer.h" -#include <gtest/gtest.h> +#include "test/Test.h" namespace aapt { TEST(BigBufferTest, AllocateSingleBlock) { - BigBuffer buffer(4); + BigBuffer buffer(4); - EXPECT_NE(nullptr, buffer.nextBlock<char>(2)); - EXPECT_EQ(2u, buffer.size()); + EXPECT_NE(nullptr, buffer.NextBlock<char>(2)); + EXPECT_EQ(2u, buffer.size()); } TEST(BigBufferTest, ReturnSameBlockIfNextAllocationFits) { - BigBuffer buffer(16); + BigBuffer buffer(16); - char* b1 = buffer.nextBlock<char>(8); - EXPECT_NE(nullptr, b1); + char* b1 = buffer.NextBlock<char>(8); + EXPECT_NE(nullptr, b1); - char* b2 = buffer.nextBlock<char>(4); - EXPECT_NE(nullptr, b2); + char* b2 = buffer.NextBlock<char>(4); + EXPECT_NE(nullptr, b2); - EXPECT_EQ(b1 + 8, b2); + EXPECT_EQ(b1 + 8, b2); } TEST(BigBufferTest, AllocateExactSizeBlockIfLargerThanBlockSize) { - BigBuffer buffer(16); + BigBuffer buffer(16); - EXPECT_NE(nullptr, buffer.nextBlock<char>(32)); - EXPECT_EQ(32u, buffer.size()); + EXPECT_NE(nullptr, buffer.NextBlock<char>(32)); + EXPECT_EQ(32u, buffer.size()); } TEST(BigBufferTest, AppendAndMoveBlock) { - BigBuffer buffer(16); + BigBuffer buffer(16); - uint32_t* b1 = buffer.nextBlock<uint32_t>(); - ASSERT_NE(nullptr, b1); - *b1 = 33; + uint32_t* b1 = buffer.NextBlock<uint32_t>(); + ASSERT_NE(nullptr, b1); + *b1 = 33; - { - BigBuffer buffer2(16); - b1 = buffer2.nextBlock<uint32_t>(); - ASSERT_NE(nullptr, b1); - *b1 = 44; + { + BigBuffer buffer2(16); + b1 = buffer2.NextBlock<uint32_t>(); + ASSERT_NE(nullptr, b1); + *b1 = 44; - buffer.appendBuffer(std::move(buffer2)); - EXPECT_EQ(0u, buffer2.size()); - EXPECT_EQ(buffer2.begin(), buffer2.end()); - } + buffer.AppendBuffer(std::move(buffer2)); + EXPECT_EQ(0u, buffer2.size()); + EXPECT_EQ(buffer2.begin(), buffer2.end()); + } - EXPECT_EQ(2 * sizeof(uint32_t), buffer.size()); + EXPECT_EQ(2 * sizeof(uint32_t), buffer.size()); - auto b = buffer.begin(); - ASSERT_NE(b, buffer.end()); - ASSERT_EQ(sizeof(uint32_t), b->size); - ASSERT_EQ(33u, *reinterpret_cast<uint32_t*>(b->buffer.get())); - ++b; + auto b = buffer.begin(); + ASSERT_NE(b, buffer.end()); + ASSERT_EQ(sizeof(uint32_t), b->size); + ASSERT_EQ(33u, *reinterpret_cast<uint32_t*>(b->buffer.get())); + ++b; - ASSERT_NE(b, buffer.end()); - ASSERT_EQ(sizeof(uint32_t), b->size); - ASSERT_EQ(44u, *reinterpret_cast<uint32_t*>(b->buffer.get())); - ++b; + ASSERT_NE(b, buffer.end()); + ASSERT_EQ(sizeof(uint32_t), b->size); + ASSERT_EQ(44u, *reinterpret_cast<uint32_t*>(b->buffer.get())); + ++b; - ASSERT_EQ(b, buffer.end()); + ASSERT_EQ(b, buffer.end()); } TEST(BigBufferTest, PadAndAlignProperly) { - BigBuffer buffer(16); - - ASSERT_NE(buffer.nextBlock<char>(2), nullptr); - ASSERT_EQ(2u, buffer.size()); - buffer.pad(2); - ASSERT_EQ(4u, buffer.size()); - buffer.align4(); - ASSERT_EQ(4u, buffer.size()); - buffer.pad(2); - ASSERT_EQ(6u, buffer.size()); - buffer.align4(); - ASSERT_EQ(8u, buffer.size()); + BigBuffer buffer(16); + + ASSERT_NE(buffer.NextBlock<char>(2), nullptr); + ASSERT_EQ(2u, buffer.size()); + buffer.Pad(2); + ASSERT_EQ(4u, buffer.size()); + buffer.Align4(); + ASSERT_EQ(4u, buffer.size()); + buffer.Pad(2); + ASSERT_EQ(6u, buffer.size()); + buffer.Align4(); + ASSERT_EQ(8u, buffer.size()); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp index 4cba921eb79f..f034607ea8f5 100644 --- a/tools/aapt2/util/Files.cpp +++ b/tools/aapt2/util/Files.cpp @@ -15,15 +15,20 @@ */ #include "util/Files.h" -#include "util/Util.h" + +#include <dirent.h> +#include <sys/stat.h> #include <algorithm> -#include <android-base/file.h> #include <cerrno> #include <cstdio> -#include <dirent.h> #include <string> -#include <sys/stat.h> + +#include "android-base/errors.h" +#include "android-base/file.h" +#include "android-base/logging.h" + +#include "util/Util.h" #ifdef _WIN32 // Windows includes. @@ -33,244 +38,230 @@ namespace aapt { namespace file { -FileType getFileType(const StringPiece& path) { - struct stat sb; - if (stat(path.data(), &sb) < 0) { - if (errno == ENOENT || errno == ENOTDIR) { - return FileType::kNonexistant; - } - return FileType::kUnknown; +FileType GetFileType(const StringPiece& path) { + struct stat sb; + if (stat(path.data(), &sb) < 0) { + if (errno == ENOENT || errno == ENOTDIR) { + return FileType::kNonexistant; } + return FileType::kUnknown; + } - if (S_ISREG(sb.st_mode)) { - return FileType::kRegular; - } else if (S_ISDIR(sb.st_mode)) { - return FileType::kDirectory; - } else if (S_ISCHR(sb.st_mode)) { - return FileType::kCharDev; - } else if (S_ISBLK(sb.st_mode)) { - return FileType::kBlockDev; - } else if (S_ISFIFO(sb.st_mode)) { - return FileType::kFifo; + if (S_ISREG(sb.st_mode)) { + return FileType::kRegular; + } else if (S_ISDIR(sb.st_mode)) { + return FileType::kDirectory; + } else if (S_ISCHR(sb.st_mode)) { + return FileType::kCharDev; + } else if (S_ISBLK(sb.st_mode)) { + return FileType::kBlockDev; + } else if (S_ISFIFO(sb.st_mode)) { + return FileType::kFifo; #if defined(S_ISLNK) - } else if (S_ISLNK(sb.st_mode)) { - return FileType::kSymlink; + } else if (S_ISLNK(sb.st_mode)) { + return FileType::kSymlink; #endif #if defined(S_ISSOCK) - } else if (S_ISSOCK(sb.st_mode)) { - return FileType::kSocket; + } else if (S_ISSOCK(sb.st_mode)) { + return FileType::kSocket; #endif - } else { - return FileType::kUnknown; - } -} - -std::vector<std::string> listFiles(const StringPiece& root, std::string* outError) { - DIR* dir = opendir(root.data()); - if (dir == nullptr) { - if (outError) { - std::stringstream errorStr; - errorStr << "unable to open file: " << strerror(errno); - *outError = errorStr.str(); - } - return {}; - } - - std::vector<std::string> files; - dirent* entry; - while ((entry = readdir(dir))) { - files.emplace_back(entry->d_name); - } - - closedir(dir); - return files; + } else { + return FileType::kUnknown; + } } -inline static int mkdirImpl(const StringPiece& path) { +inline static int MkdirImpl(const StringPiece& path) { #ifdef _WIN32 - return _mkdir(path.toString().c_str()); + return _mkdir(path.ToString().c_str()); #else - return mkdir(path.toString().c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); + return mkdir(path.ToString().c_str(), + S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP); #endif } bool mkdirs(const StringPiece& path) { - const char* start = path.begin(); - const char* end = path.end(); - for (const char* current = start; current != end; ++current) { - if (*current == sDirSep && current != start) { - StringPiece parentPath(start, current - start); - int result = mkdirImpl(parentPath); - if (result < 0 && errno != EEXIST) { - return false; - } - } + const char* start = path.begin(); + const char* end = path.end(); + for (const char* current = start; current != end; ++current) { + if (*current == sDirSep && current != start) { + StringPiece parent_path(start, current - start); + int result = MkdirImpl(parent_path); + if (result < 0 && errno != EEXIST) { + return false; + } } - return mkdirImpl(path) == 0 || errno == EEXIST; + } + return MkdirImpl(path) == 0 || errno == EEXIST; } -StringPiece getStem(const StringPiece& path) { - const char* start = path.begin(); - const char* end = path.end(); - for (const char* current = end - 1; current != start - 1; --current) { - if (*current == sDirSep) { - return StringPiece(start, current - start); - } +StringPiece GetStem(const StringPiece& path) { + const char* start = path.begin(); + const char* end = path.end(); + for (const char* current = end - 1; current != start - 1; --current) { + if (*current == sDirSep) { + return StringPiece(start, current - start); } - return {}; + } + return {}; } -StringPiece getFilename(const StringPiece& path) { - const char* end = path.end(); - const char* lastDirSep = path.begin(); - for (const char* c = path.begin(); c != end; ++c) { - if (*c == sDirSep) { - lastDirSep = c + 1; - } +StringPiece GetFilename(const StringPiece& path) { + const char* end = path.end(); + const char* last_dir_sep = path.begin(); + for (const char* c = path.begin(); c != end; ++c) { + if (*c == sDirSep) { + last_dir_sep = c + 1; } - return StringPiece(lastDirSep, end - lastDirSep); + } + return StringPiece(last_dir_sep, end - last_dir_sep); } -StringPiece getExtension(const StringPiece& path) { - StringPiece filename = getFilename(path); - const char* const end = filename.end(); - const char* c = std::find(filename.begin(), end, '.'); - if (c != end) { - return StringPiece(c, end - c); - } - return {}; +StringPiece GetExtension(const StringPiece& path) { + StringPiece filename = GetFilename(path); + const char* const end = filename.end(); + const char* c = std::find(filename.begin(), end, '.'); + if (c != end) { + return StringPiece(c, end - c); + } + return {}; } -void appendPath(std::string* base, StringPiece part) { - assert(base); - const bool baseHasTrailingSep = (!base->empty() && *(base->end() - 1) == sDirSep); - const bool partHasLeadingSep = (!part.empty() && *(part.begin()) == sDirSep); - if (baseHasTrailingSep && partHasLeadingSep) { - // Remove the part's leading sep - part = part.substr(1, part.size() - 1); - } else if (!baseHasTrailingSep && !partHasLeadingSep) { - // None of the pieces has a separator. - *base += sDirSep; - } - base->append(part.data(), part.size()); +void AppendPath(std::string* base, StringPiece part) { + CHECK(base != nullptr); + const bool base_has_trailing_sep = + (!base->empty() && *(base->end() - 1) == sDirSep); + const bool part_has_leading_sep = + (!part.empty() && *(part.begin()) == sDirSep); + if (base_has_trailing_sep && part_has_leading_sep) { + // Remove the part's leading sep + part = part.substr(1, part.size() - 1); + } else if (!base_has_trailing_sep && !part_has_leading_sep) { + // None of the pieces has a separator. + *base += sDirSep; + } + base->append(part.data(), part.size()); } -std::string packageToPath(const StringPiece& package) { - std::string outPath; - for (StringPiece part : util::tokenize(package, '.')) { - appendPath(&outPath, part); - } - return outPath; +std::string PackageToPath(const StringPiece& package) { + std::string out_path; + for (StringPiece part : util::Tokenize(package, '.')) { + AppendPath(&out_path, part); + } + return out_path; } -Maybe<android::FileMap> mmapPath(const StringPiece& path, std::string* outError) { - std::unique_ptr<FILE, decltype(fclose)*> f = { fopen(path.data(), "rb"), fclose }; - if (!f) { - if (outError) *outError = strerror(errno); - return {}; - } +Maybe<android::FileMap> MmapPath(const StringPiece& path, + std::string* out_error) { + std::unique_ptr<FILE, decltype(fclose)*> f = {fopen(path.data(), "rb"), + fclose}; + if (!f) { + if (out_error) *out_error = android::base::SystemErrorCodeToString(errno); + return {}; + } - int fd = fileno(f.get()); + int fd = fileno(f.get()); - struct stat fileStats = {}; - if (fstat(fd, &fileStats) != 0) { - if (outError) *outError = strerror(errno); - return {}; - } + struct stat filestats = {}; + if (fstat(fd, &filestats) != 0) { + if (out_error) *out_error = android::base::SystemErrorCodeToString(errno); + return {}; + } - android::FileMap fileMap; - if (fileStats.st_size == 0) { - // mmap doesn't like a length of 0. Instead we return an empty FileMap. - return std::move(fileMap); - } + android::FileMap filemap; + if (filestats.st_size == 0) { + // mmap doesn't like a length of 0. Instead we return an empty FileMap. + return std::move(filemap); + } - if (!fileMap.create(path.data(), fd, 0, fileStats.st_size, true)) { - if (outError) *outError = strerror(errno); - return {}; - } - return std::move(fileMap); + if (!filemap.create(path.data(), fd, 0, filestats.st_size, true)) { + if (out_error) *out_error = android::base::SystemErrorCodeToString(errno); + return {}; + } + return std::move(filemap); } -bool appendArgsFromFile(const StringPiece& path, std::vector<std::string>* outArgList, - std::string* outError) { - std::string contents; - if (!android::base::ReadFileToString(path.toString(), &contents)) { - if (outError) *outError = "failed to read argument-list file"; - return false; - } +bool AppendArgsFromFile(const StringPiece& path, + std::vector<std::string>* out_arglist, + std::string* out_error) { + std::string contents; + if (!android::base::ReadFileToString(path.ToString(), &contents)) { + if (out_error) *out_error = "failed to read argument-list file"; + return false; + } - for (StringPiece line : util::tokenize(contents, ' ')) { - line = util::trimWhitespace(line); - if (!line.empty()) { - outArgList->push_back(line.toString()); - } + for (StringPiece line : util::Tokenize(contents, ' ')) { + line = util::TrimWhitespace(line); + if (!line.empty()) { + out_arglist->push_back(line.ToString()); } - return true; + } + return true; } -bool FileFilter::setPattern(const StringPiece& pattern) { - mPatternTokens = util::splitAndLowercase(pattern, ':'); - return true; +bool FileFilter::SetPattern(const StringPiece& pattern) { + pattern_tokens_ = util::SplitAndLowercase(pattern, ':'); + return true; } bool FileFilter::operator()(const std::string& filename, FileType type) const { - if (filename == "." || filename == "..") { - return false; - } + if (filename == "." || filename == "..") { + return false; + } - const char kDir[] = "dir"; - const char kFile[] = "file"; - const size_t filenameLen = filename.length(); - bool chatty = true; - for (const std::string& token : mPatternTokens) { - const char* tokenStr = token.c_str(); - if (*tokenStr == '!') { - chatty = false; - tokenStr++; - } + const char kDir[] = "dir"; + const char kFile[] = "file"; + const size_t filename_len = filename.length(); + bool chatty = true; + for (const std::string& token : pattern_tokens_) { + const char* token_str = token.c_str(); + if (*token_str == '!') { + chatty = false; + token_str++; + } - if (strncasecmp(tokenStr, kDir, sizeof(kDir)) == 0) { - if (type != FileType::kDirectory) { - continue; - } - tokenStr += sizeof(kDir); - } + if (strncasecmp(token_str, kDir, sizeof(kDir)) == 0) { + if (type != FileType::kDirectory) { + continue; + } + token_str += sizeof(kDir); + } - if (strncasecmp(tokenStr, kFile, sizeof(kFile)) == 0) { - if (type != FileType::kRegular) { - continue; - } - tokenStr += sizeof(kFile); - } + if (strncasecmp(token_str, kFile, sizeof(kFile)) == 0) { + if (type != FileType::kRegular) { + continue; + } + token_str += sizeof(kFile); + } - bool ignore = false; - size_t n = strlen(tokenStr); - if (*tokenStr == '*') { - // Math suffix. - tokenStr++; - n--; - if (n <= filenameLen) { - ignore = strncasecmp(tokenStr, filename.c_str() + filenameLen - n, n) == 0; - } - } else if (n > 1 && tokenStr[n - 1] == '*') { - // Match prefix. - ignore = strncasecmp(tokenStr, filename.c_str(), n - 1) == 0; - } else { - ignore = strcasecmp(tokenStr, filename.c_str()) == 0; - } + bool ignore = false; + size_t n = strlen(token_str); + if (*token_str == '*') { + // Math suffix. + token_str++; + n--; + if (n <= filename_len) { + ignore = + strncasecmp(token_str, filename.c_str() + filename_len - n, n) == 0; + } + } else if (n > 1 && token_str[n - 1] == '*') { + // Match prefix. + ignore = strncasecmp(token_str, filename.c_str(), n - 1) == 0; + } else { + ignore = strcasecmp(token_str, filename.c_str()) == 0; + } - if (ignore) { - if (chatty) { - mDiag->warn(DiagMessage() << "skipping " - << (type == FileType::kDirectory ? "dir '" : "file '") - << filename << "' due to ignore pattern '" - << token << "'"); - } - return false; - } + if (ignore) { + if (chatty) { + diag_->Warn(DiagMessage() + << "skipping " + << (type == FileType::kDirectory ? "dir '" : "file '") + << filename << "' due to ignore pattern '" << token << "'"); + } + return false; } - return true; + } + return true; } -} // namespace file -} // namespace aapt +} // namespace file +} // namespace aapt diff --git a/tools/aapt2/util/Files.h b/tools/aapt2/util/Files.h index d90c6b692a7c..a157dbd80893 100644 --- a/tools/aapt2/util/Files.h +++ b/tools/aapt2/util/Files.h @@ -17,18 +17,18 @@ #ifndef AAPT_FILES_H #define AAPT_FILES_H +#include <memory> +#include <string> +#include <vector> + +#include "android-base/macros.h" +#include "utils/FileMap.h" + #include "Diagnostics.h" #include "Maybe.h" #include "Source.h" - #include "util/StringPiece.h" -#include <utils/FileMap.h> -#include <cassert> -#include <memory> -#include <string> -#include <vector> - namespace aapt { namespace file { @@ -50,18 +50,12 @@ enum class FileType { kSocket, }; -FileType getFileType(const StringPiece& path); - -/* - * Lists files under the directory `root`. Files are listed - * with just their leaf (filename) names. - */ -std::vector<std::string> listFiles(const StringPiece& root); +FileType GetFileType(const StringPiece& path); /* * Appends a path to `base`, separated by the directory separator. */ -void appendPath(std::string* base, StringPiece part); +void AppendPath(std::string* base, StringPiece part); /* * Makes all the directories in `path`. The last element in the path @@ -72,46 +66,45 @@ bool mkdirs(const StringPiece& path); /** * Returns all but the last part of the path. */ -StringPiece getStem(const StringPiece& path); +StringPiece GetStem(const StringPiece& path); /** * Returns the last part of the path with extension. */ -StringPiece getFilename(const StringPiece& path); +StringPiece GetFilename(const StringPiece& path); /** * Returns the extension of the path. This is the entire string after * the first '.' of the last part of the path. */ -StringPiece getExtension(const StringPiece& path); +StringPiece GetExtension(const StringPiece& path); /** * Converts a package name (com.android.app) to a path: com/android/app */ -std::string packageToPath(const StringPiece& package); +std::string PackageToPath(const StringPiece& package); /** * Creates a FileMap for the file at path. */ -Maybe<android::FileMap> mmapPath(const StringPiece& path, - std::string* outError); +Maybe<android::FileMap> MmapPath(const StringPiece& path, + std::string* out_error); /** * Reads the file at path and appends each line to the outArgList vector. */ -bool appendArgsFromFile(const StringPiece& path, - std::vector<std::string>* outArgList, - std::string* outError); +bool AppendArgsFromFile(const StringPiece& path, + std::vector<std::string>* out_arglist, + std::string* out_error); /* * Filter that determines which resource files/directories are * processed by AAPT. Takes a pattern string supplied by the user. - * Pattern format is specified in the - * FileFilter::setPattern(const std::string&) method. + * Pattern format is specified in the FileFilter::SetPattern() method. */ class FileFilter { public: - explicit FileFilter(IDiagnostics* diag) : mDiag(diag) {} + explicit FileFilter(IDiagnostics* diag) : diag_(diag) {} /* * Patterns syntax: @@ -127,7 +120,7 @@ class FileFilter { * - Otherwise the full string is matched. * - match is not case-sensitive. */ - bool setPattern(const StringPiece& pattern); + bool SetPattern(const StringPiece& pattern); /** * Applies the filter, returning true for pass, false for fail. @@ -135,8 +128,10 @@ class FileFilter { bool operator()(const std::string& filename, FileType type) const; private: - IDiagnostics* mDiag; - std::vector<std::string> mPatternTokens; + DISALLOW_COPY_AND_ASSIGN(FileFilter); + + IDiagnostics* diag_; + std::vector<std::string> pattern_tokens_; }; } // namespace file diff --git a/tools/aapt2/util/Files_test.cpp b/tools/aapt2/util/Files_test.cpp index efb04593ff82..219c18397358 100644 --- a/tools/aapt2/util/Files_test.cpp +++ b/tools/aapt2/util/Files_test.cpp @@ -14,45 +14,46 @@ * limitations under the License. */ -#include "test/Test.h" #include "util/Files.h" #include <sstream> +#include "test/Test.h" + namespace aapt { namespace file { class FilesTest : public ::testing::Test { -public: - void SetUp() override { - std::stringstream builder; - builder << "hello" << sDirSep << "there"; - mExpectedPath = builder.str(); - } - -protected: - std::string mExpectedPath; + public: + void SetUp() override { + std::stringstream builder; + builder << "hello" << sDirSep << "there"; + expected_path_ = builder.str(); + } + + protected: + std::string expected_path_; }; -TEST_F(FilesTest, appendPath) { - std::string base = "hello"; - appendPath(&base, "there"); - EXPECT_EQ(mExpectedPath, base); +TEST_F(FilesTest, AppendPath) { + std::string base = "hello"; + AppendPath(&base, "there"); + EXPECT_EQ(expected_path_, base); } -TEST_F(FilesTest, appendPathWithLeadingOrTrailingSeparators) { - std::string base = "hello/"; - appendPath(&base, "there"); - EXPECT_EQ(mExpectedPath, base); +TEST_F(FilesTest, AppendPathWithLeadingOrTrailingSeparators) { + std::string base = "hello/"; + AppendPath(&base, "there"); + EXPECT_EQ(expected_path_, base); - base = "hello"; - appendPath(&base, "/there"); - EXPECT_EQ(mExpectedPath, base); + base = "hello"; + AppendPath(&base, "/there"); + EXPECT_EQ(expected_path_, base); - base = "hello/"; - appendPath(&base, "/there"); - EXPECT_EQ(mExpectedPath, base); + base = "hello/"; + AppendPath(&base, "/there"); + EXPECT_EQ(expected_path_, base); } -} // namespace files -} // namespace aapt +} // namespace files +} // namespace aapt diff --git a/tools/aapt2/util/ImmutableMap.h b/tools/aapt2/util/ImmutableMap.h index 6f48764d6bd4..59858e492c4c 100644 --- a/tools/aapt2/util/ImmutableMap.h +++ b/tools/aapt2/util/ImmutableMap.h @@ -17,39 +17,31 @@ #ifndef AAPT_UTIL_IMMUTABLEMAP_H #define AAPT_UTIL_IMMUTABLEMAP_H -#include "util/TypeTraits.h" - #include <utility> #include <vector> +#include "util/TypeTraits.h" + namespace aapt { template <typename TKey, typename TValue> class ImmutableMap { static_assert(is_comparable<TKey, TKey>::value, "key is not comparable"); - private: - std::vector<std::pair<TKey, TValue>> mData; - - explicit ImmutableMap(std::vector<std::pair<TKey, TValue>> data) - : mData(std::move(data)) {} - public: - using const_iterator = typename decltype(mData)::const_iterator; + using const_iterator = + typename std::vector<std::pair<TKey, TValue>>::const_iterator; ImmutableMap(ImmutableMap&&) = default; ImmutableMap& operator=(ImmutableMap&&) = default; - ImmutableMap(const ImmutableMap&) = delete; - ImmutableMap& operator=(const ImmutableMap&) = delete; - - static ImmutableMap<TKey, TValue> createPreSorted( + static ImmutableMap<TKey, TValue> CreatePreSorted( std::initializer_list<std::pair<TKey, TValue>> list) { return ImmutableMap( std::vector<std::pair<TKey, TValue>>(list.begin(), list.end())); } - static ImmutableMap<TKey, TValue> createAndSort( + static ImmutableMap<TKey, TValue> CreateAndSort( std::initializer_list<std::pair<TKey, TValue>> list) { std::vector<std::pair<TKey, TValue>> data(list.begin(), list.end()); std::sort(data.begin(), data.end()); @@ -64,17 +56,25 @@ class ImmutableMap { return candidate.first < target; }; - const_iterator endIter = end(); - auto iter = std::lower_bound(mData.begin(), endIter, key, cmp); - if (iter == endIter || iter->first == key) { + const_iterator end_iter = end(); + auto iter = std::lower_bound(data_.begin(), end_iter, key, cmp); + if (iter == end_iter || iter->first == key) { return iter; } - return endIter; + return end_iter; } - const_iterator begin() const { return mData.begin(); } + const_iterator begin() const { return data_.begin(); } + + const_iterator end() const { return data_.end(); } + + private: + DISALLOW_COPY_AND_ASSIGN(ImmutableMap); + + explicit ImmutableMap(std::vector<std::pair<TKey, TValue>> data) + : data_(std::move(data)) {} - const_iterator end() const { return mData.end(); } + std::vector<std::pair<TKey, TValue>> data_; }; } // namespace aapt diff --git a/tools/aapt2/util/Maybe.h b/tools/aapt2/util/Maybe.h index 90a0198b4e42..b43f8e87fd68 100644 --- a/tools/aapt2/util/Maybe.h +++ b/tools/aapt2/util/Maybe.h @@ -17,12 +17,13 @@ #ifndef AAPT_MAYBE_H #define AAPT_MAYBE_H -#include "util/TypeTraits.h" - -#include <cassert> #include <type_traits> #include <utility> +#include "android-base/logging.h" + +#include "util/TypeTraits.h" + namespace aapt { /** @@ -88,7 +89,7 @@ class Maybe { */ const T& value() const; - T valueOrDefault(const T& def) const; + T value_or_default(const T& def) const; private: template <typename U> @@ -102,55 +103,55 @@ class Maybe { void destroy(); - bool mNothing; + bool nothing_; - typename std::aligned_storage<sizeof(T), alignof(T)>::type mStorage; + typename std::aligned_storage<sizeof(T), alignof(T)>::type storage_; }; template <typename T> -Maybe<T>::Maybe() : mNothing(true) {} +Maybe<T>::Maybe() : nothing_(true) {} template <typename T> Maybe<T>::~Maybe() { - if (!mNothing) { + if (!nothing_) { destroy(); } } template <typename T> -Maybe<T>::Maybe(const Maybe& rhs) : mNothing(rhs.mNothing) { - if (!rhs.mNothing) { - new (&mStorage) T(reinterpret_cast<const T&>(rhs.mStorage)); +Maybe<T>::Maybe(const Maybe& rhs) : nothing_(rhs.nothing_) { + if (!rhs.nothing_) { + new (&storage_) T(reinterpret_cast<const T&>(rhs.storage_)); } } template <typename T> template <typename U> -Maybe<T>::Maybe(const Maybe<U>& rhs) : mNothing(rhs.mNothing) { - if (!rhs.mNothing) { - new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage)); +Maybe<T>::Maybe(const Maybe<U>& rhs) : nothing_(rhs.nothing_) { + if (!rhs.nothing_) { + new (&storage_) T(reinterpret_cast<const U&>(rhs.storage_)); } } template <typename T> -Maybe<T>::Maybe(Maybe&& rhs) : mNothing(rhs.mNothing) { - if (!rhs.mNothing) { - rhs.mNothing = true; +Maybe<T>::Maybe(Maybe&& rhs) : nothing_(rhs.nothing_) { + if (!rhs.nothing_) { + rhs.nothing_ = true; // Move the value from rhs. - new (&mStorage) T(std::move(reinterpret_cast<T&>(rhs.mStorage))); + new (&storage_) T(std::move(reinterpret_cast<T&>(rhs.storage_))); rhs.destroy(); } } template <typename T> template <typename U> -Maybe<T>::Maybe(Maybe<U>&& rhs) : mNothing(rhs.mNothing) { - if (!rhs.mNothing) { - rhs.mNothing = true; +Maybe<T>::Maybe(Maybe<U>&& rhs) : nothing_(rhs.nothing_) { + if (!rhs.nothing_) { + rhs.nothing_ = true; // Move the value from rhs. - new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage))); + new (&storage_) T(std::move(reinterpret_cast<U&>(rhs.storage_))); rhs.destroy(); } } @@ -170,21 +171,21 @@ inline Maybe<T>& Maybe<T>::operator=(const Maybe<U>& rhs) { template <typename T> template <typename U> Maybe<T>& Maybe<T>::copy(const Maybe<U>& rhs) { - if (mNothing && rhs.mNothing) { + if (nothing_ && rhs.nothing_) { // Both are nothing, nothing to do. return *this; - } else if (!mNothing && !rhs.mNothing) { + } else if (!nothing_ && !rhs.nothing_) { // We both are something, so assign rhs to us. - reinterpret_cast<T&>(mStorage) = reinterpret_cast<const U&>(rhs.mStorage); - } else if (mNothing) { + reinterpret_cast<T&>(storage_) = reinterpret_cast<const U&>(rhs.storage_); + } else if (nothing_) { // We are nothing but rhs is something. - mNothing = rhs.mNothing; + nothing_ = rhs.nothing_; // Copy the value from rhs. - new (&mStorage) T(reinterpret_cast<const U&>(rhs.mStorage)); + new (&storage_) T(reinterpret_cast<const U&>(rhs.storage_)); } else { // We are something but rhs is nothing, so destroy our value. - mNothing = rhs.mNothing; + nothing_ = rhs.nothing_; destroy(); } return *this; @@ -205,69 +206,69 @@ inline Maybe<T>& Maybe<T>::operator=(Maybe<U>&& rhs) { template <typename T> template <typename U> Maybe<T>& Maybe<T>::move(Maybe<U>&& rhs) { - if (mNothing && rhs.mNothing) { + if (nothing_ && rhs.nothing_) { // Both are nothing, nothing to do. return *this; - } else if (!mNothing && !rhs.mNothing) { + } else if (!nothing_ && !rhs.nothing_) { // We both are something, so move assign rhs to us. - rhs.mNothing = true; - reinterpret_cast<T&>(mStorage) = - std::move(reinterpret_cast<U&>(rhs.mStorage)); + rhs.nothing_ = true; + reinterpret_cast<T&>(storage_) = + std::move(reinterpret_cast<U&>(rhs.storage_)); rhs.destroy(); - } else if (mNothing) { + } else if (nothing_) { // We are nothing but rhs is something. - mNothing = false; - rhs.mNothing = true; + nothing_ = false; + rhs.nothing_ = true; // Move the value from rhs. - new (&mStorage) T(std::move(reinterpret_cast<U&>(rhs.mStorage))); + new (&storage_) T(std::move(reinterpret_cast<U&>(rhs.storage_))); rhs.destroy(); } else { // We are something but rhs is nothing, so destroy our value. - mNothing = true; + nothing_ = true; destroy(); } return *this; } template <typename T> -Maybe<T>::Maybe(const T& value) : mNothing(false) { - new (&mStorage) T(value); +Maybe<T>::Maybe(const T& value) : nothing_(false) { + new (&storage_) T(value); } template <typename T> -Maybe<T>::Maybe(T&& value) : mNothing(false) { - new (&mStorage) T(std::forward<T>(value)); +Maybe<T>::Maybe(T&& value) : nothing_(false) { + new (&storage_) T(std::forward<T>(value)); } template <typename T> Maybe<T>::operator bool() const { - return !mNothing; + return !nothing_; } template <typename T> T& Maybe<T>::value() { - assert(!mNothing && "Maybe<T>::value() called on Nothing"); - return reinterpret_cast<T&>(mStorage); + CHECK(!nothing_) << "Maybe<T>::value() called on Nothing"; + return reinterpret_cast<T&>(storage_); } template <typename T> const T& Maybe<T>::value() const { - assert(!mNothing && "Maybe<T>::value() called on Nothing"); - return reinterpret_cast<const T&>(mStorage); + CHECK(!nothing_) << "Maybe<T>::value() called on Nothing"; + return reinterpret_cast<const T&>(storage_); } template <typename T> -T Maybe<T>::valueOrDefault(const T& def) const { - if (mNothing) { +T Maybe<T>::value_or_default(const T& def) const { + if (nothing_) { return def; } - return reinterpret_cast<const T&>(mStorage); + return reinterpret_cast<const T&>(storage_); } template <typename T> void Maybe<T>::destroy() { - reinterpret_cast<T&>(mStorage).~T(); + reinterpret_cast<T&>(storage_).~T(); } template <typename T> diff --git a/tools/aapt2/util/Maybe_test.cpp b/tools/aapt2/util/Maybe_test.cpp index 5d42dc3ac3ab..ca14793dd5c3 100644 --- a/tools/aapt2/util/Maybe_test.cpp +++ b/tools/aapt2/util/Maybe_test.cpp @@ -14,122 +14,116 @@ * limitations under the License. */ -#include "test/Common.h" #include "util/Maybe.h" -#include <gtest/gtest.h> #include <string> +#include "test/Test.h" + namespace aapt { struct Dummy { - Dummy() { - data = new int; - *data = 1; - std::cerr << "Construct Dummy{0x" << (void *) this - << "} with data=0x" << (void*) data - << std::endl; - } - - Dummy(const Dummy& rhs) { - data = nullptr; - if (rhs.data) { - data = new int; - *data = *rhs.data; - } - std::cerr << "CopyConstruct Dummy{0x" << (void *) this - << "} from Dummy{0x" << (const void*) &rhs - << "}" << std::endl; - } - - Dummy(Dummy&& rhs) { - data = rhs.data; - rhs.data = nullptr; - std::cerr << "MoveConstruct Dummy{0x" << (void *) this - << "} from Dummy{0x" << (const void*) &rhs - << "}" << std::endl; - } - - Dummy& operator=(const Dummy& rhs) { - delete data; - data = nullptr; - - if (rhs.data) { - data = new int; - *data = *rhs.data; - } - std::cerr << "CopyAssign Dummy{0x" << (void *) this - << "} from Dummy{0x" << (const void*) &rhs - << "}" << std::endl; - return *this; - } - - Dummy& operator=(Dummy&& rhs) { - delete data; - data = rhs.data; - rhs.data = nullptr; - std::cerr << "MoveAssign Dummy{0x" << (void *) this - << "} from Dummy{0x" << (const void*) &rhs - << "}" << std::endl; - return *this; + Dummy() { + data = new int; + *data = 1; + std::cerr << "Construct Dummy{0x" << (void*)this << "} with data=0x" + << (void*)data << std::endl; + } + + Dummy(const Dummy& rhs) { + data = nullptr; + if (rhs.data) { + data = new int; + *data = *rhs.data; } - - ~Dummy() { - std::cerr << "Destruct Dummy{0x" << (void *) this - << "} with data=0x" << (void*) data - << std::endl; - delete data; + std::cerr << "CopyConstruct Dummy{0x" << (void*)this << "} from Dummy{0x" + << (const void*)&rhs << "}" << std::endl; + } + + Dummy(Dummy&& rhs) { + data = rhs.data; + rhs.data = nullptr; + std::cerr << "MoveConstruct Dummy{0x" << (void*)this << "} from Dummy{0x" + << (const void*)&rhs << "}" << std::endl; + } + + Dummy& operator=(const Dummy& rhs) { + delete data; + data = nullptr; + + if (rhs.data) { + data = new int; + *data = *rhs.data; } - - int* data; + std::cerr << "CopyAssign Dummy{0x" << (void*)this << "} from Dummy{0x" + << (const void*)&rhs << "}" << std::endl; + return *this; + } + + Dummy& operator=(Dummy&& rhs) { + delete data; + data = rhs.data; + rhs.data = nullptr; + std::cerr << "MoveAssign Dummy{0x" << (void*)this << "} from Dummy{0x" + << (const void*)&rhs << "}" << std::endl; + return *this; + } + + ~Dummy() { + std::cerr << "Destruct Dummy{0x" << (void*)this << "} with data=0x" + << (void*)data << std::endl; + delete data; + } + + int* data; }; TEST(MaybeTest, MakeNothing) { - Maybe<int> val = make_nothing<int>(); - AAPT_EXPECT_FALSE(val); + Maybe<int> val = make_nothing<int>(); + AAPT_EXPECT_FALSE(val); - Maybe<std::string> val2 = make_nothing<std::string>(); - AAPT_EXPECT_FALSE(val2); + Maybe<std::string> val2 = make_nothing<std::string>(); + AAPT_EXPECT_FALSE(val2); - val2 = make_nothing<std::string>(); - AAPT_EXPECT_FALSE(val2); + val2 = make_nothing<std::string>(); + AAPT_EXPECT_FALSE(val2); } TEST(MaybeTest, MakeSomething) { - Maybe<int> val = make_value(23); - AAPT_ASSERT_TRUE(val); - EXPECT_EQ(23, val.value()); + Maybe<int> val = make_value(23); + AAPT_ASSERT_TRUE(val); + EXPECT_EQ(23, val.value()); - Maybe<std::string> val2 = make_value(std::string("hey")); - AAPT_ASSERT_TRUE(val2); - EXPECT_EQ(std::string("hey"), val2.value()); + Maybe<std::string> val2 = make_value(std::string("hey")); + AAPT_ASSERT_TRUE(val2); + EXPECT_EQ(std::string("hey"), val2.value()); } TEST(MaybeTest, Lifecycle) { - Maybe<Dummy> val = make_nothing<Dummy>(); + Maybe<Dummy> val = make_nothing<Dummy>(); - Maybe<Dummy> val2 = make_value(Dummy()); + Maybe<Dummy> val2 = make_value(Dummy()); } TEST(MaybeTest, MoveAssign) { - Maybe<Dummy> val; - { - Maybe<Dummy> val2 = Dummy(); - val = std::move(val2); - } + Maybe<Dummy> val; + { + Maybe<Dummy> val2 = Dummy(); + val = std::move(val2); + } } TEST(MaybeTest, Equality) { - Maybe<int> a = 1; - Maybe<int> b = 1; - Maybe<int> c; + Maybe<int> a = 1; + Maybe<int> b = 1; + Maybe<int> c; - Maybe<int> emptyA, emptyB; + Maybe<int> emptyA, emptyB; - EXPECT_EQ(a, b); - EXPECT_EQ(b, a); - EXPECT_NE(a, c); - EXPECT_EQ(emptyA, emptyB); + EXPECT_EQ(a, b); + EXPECT_EQ(b, a); + EXPECT_NE(a, c); + EXPECT_EQ(emptyA, emptyB); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/util/StringPiece.h b/tools/aapt2/util/StringPiece.h index de938228b30d..5144b1f1fd6a 100644 --- a/tools/aapt2/util/StringPiece.h +++ b/tools/aapt2/util/StringPiece.h @@ -17,12 +17,13 @@ #ifndef AAPT_STRING_PIECE_H #define AAPT_STRING_PIECE_H -#include <utils/JenkinsHash.h> -#include <utils/String8.h> -#include <utils/Unicode.h> #include <ostream> #include <string> +#include "utils/JenkinsHash.h" +#include "utils/String8.h" +#include "utils/Unicode.h" + namespace aapt { /** @@ -60,7 +61,7 @@ class BasicStringPiece { size_t length() const; size_t size() const; bool empty() const; - std::basic_string<TChar> toString() const; + std::basic_string<TChar> ToString() const; bool contains(const BasicStringPiece<TChar>& rhs) const; int compare(const BasicStringPiece<TChar>& rhs) const; @@ -73,8 +74,8 @@ class BasicStringPiece { const_iterator end() const; private: - const TChar* mData; - size_t mLength; + const TChar* data_; + size_t length_; }; using StringPiece = BasicStringPiece<char>; @@ -89,43 +90,43 @@ constexpr const size_t BasicStringPiece<TChar>::npos; template <typename TChar> inline BasicStringPiece<TChar>::BasicStringPiece() - : mData(nullptr), mLength(0) {} + : data_(nullptr), length_(0) {} template <typename TChar> inline BasicStringPiece<TChar>::BasicStringPiece( const BasicStringPiece<TChar>& str) - : mData(str.mData), mLength(str.mLength) {} + : data_(str.data_), length_(str.length_) {} template <typename TChar> inline BasicStringPiece<TChar>::BasicStringPiece( const std::basic_string<TChar>& str) - : mData(str.data()), mLength(str.length()) {} + : data_(str.data()), length_(str.length()) {} template <> inline BasicStringPiece<char>::BasicStringPiece(const char* str) - : mData(str), mLength(str != nullptr ? strlen(str) : 0) {} + : data_(str), length_(str != nullptr ? strlen(str) : 0) {} template <> inline BasicStringPiece<char16_t>::BasicStringPiece(const char16_t* str) - : mData(str), mLength(str != nullptr ? strlen16(str) : 0) {} + : data_(str), length_(str != nullptr ? strlen16(str) : 0) {} template <typename TChar> inline BasicStringPiece<TChar>::BasicStringPiece(const TChar* str, size_t len) - : mData(str), mLength(len) {} + : data_(str), length_(len) {} template <typename TChar> inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::operator=( const BasicStringPiece<TChar>& rhs) { - mData = rhs.mData; - mLength = rhs.mLength; + data_ = rhs.data_; + length_ = rhs.length_; return *this; } template <typename TChar> inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::assign( const TChar* str, size_t len) { - mData = str; - mLength = len; + data_ = str; + length_ = len; return *this; } @@ -133,13 +134,13 @@ template <typename TChar> inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr( size_t start, size_t len) const { if (len == npos) { - len = mLength - start; + len = length_ - start; } - if (start > mLength || start + len > mLength) { + if (start > length_ || start + len > length_) { return BasicStringPiece<TChar>(); } - return BasicStringPiece<TChar>(mData + start, len); + return BasicStringPiece<TChar>(data_ + start, len); } template <typename TChar> @@ -151,49 +152,49 @@ inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr( template <typename TChar> inline const TChar* BasicStringPiece<TChar>::data() const { - return mData; + return data_; } template <typename TChar> inline size_t BasicStringPiece<TChar>::length() const { - return mLength; + return length_; } template <typename TChar> inline size_t BasicStringPiece<TChar>::size() const { - return mLength; + return length_; } template <typename TChar> inline bool BasicStringPiece<TChar>::empty() const { - return mLength == 0; + return length_ == 0; } template <typename TChar> -inline std::basic_string<TChar> BasicStringPiece<TChar>::toString() const { - return std::basic_string<TChar>(mData, mLength); +inline std::basic_string<TChar> BasicStringPiece<TChar>::ToString() const { + return std::basic_string<TChar>(data_, length_); } template <> inline bool BasicStringPiece<char>::contains( const BasicStringPiece<char>& rhs) const { - if (!mData || !rhs.mData) { + if (!data_ || !rhs.data_) { return false; } - if (rhs.mLength > mLength) { + if (rhs.length_ > length_) { return false; } - return strstr(mData, rhs.mData) != nullptr; + return strstr(data_, rhs.data_) != nullptr; } template <> inline int BasicStringPiece<char>::compare( const BasicStringPiece<char>& rhs) const { const char nullStr = '\0'; - const char* b1 = mData != nullptr ? mData : &nullStr; - const char* e1 = b1 + mLength; - const char* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr; - const char* e2 = b2 + rhs.mLength; + const char* b1 = data_ != nullptr ? data_ : &nullStr; + const char* e1 = b1 + length_; + const char* b2 = rhs.data_ != nullptr ? rhs.data_ : &nullStr; + const char* e2 = b2 + rhs.length_; while (b1 < e1 && b2 < e2) { const int d = static_cast<int>(*b1++) - static_cast<int>(*b2++); @@ -201,7 +202,7 @@ inline int BasicStringPiece<char>::compare( return d; } } - return static_cast<int>(mLength - rhs.mLength); + return static_cast<int>(length_ - rhs.length_); } inline ::std::ostream& operator<<(::std::ostream& out, @@ -213,22 +214,22 @@ inline ::std::ostream& operator<<(::std::ostream& out, template <> inline bool BasicStringPiece<char16_t>::contains( const BasicStringPiece<char16_t>& rhs) const { - if (!mData || !rhs.mData) { + if (!data_ || !rhs.data_) { return false; } - if (rhs.mLength > mLength) { + if (rhs.length_ > length_) { return false; } - return strstr16(mData, rhs.mData) != nullptr; + return strstr16(data_, rhs.data_) != nullptr; } template <> inline int BasicStringPiece<char16_t>::compare( const BasicStringPiece<char16_t>& rhs) const { const char16_t nullStr = u'\0'; - const char16_t* b1 = mData != nullptr ? mData : &nullStr; - const char16_t* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr; - return strzcmp16(b1, mLength, b2, rhs.mLength); + const char16_t* b1 = data_ != nullptr ? data_ : &nullStr; + const char16_t* b2 = rhs.data_ != nullptr ? rhs.data_ : &nullStr; + return strzcmp16(b1, length_, b2, rhs.length_); } template <typename TChar> @@ -258,13 +259,13 @@ inline bool BasicStringPiece<TChar>::operator!=( template <typename TChar> inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::begin() const { - return mData; + return data_; } template <typename TChar> inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::end() const { - return mData + mLength; + return data_ + length_; } inline ::std::ostream& operator<<(::std::ostream& out, diff --git a/tools/aapt2/util/StringPiece_test.cpp b/tools/aapt2/util/StringPiece_test.cpp index a87065acd3a0..048961d49584 100644 --- a/tools/aapt2/util/StringPiece_test.cpp +++ b/tools/aapt2/util/StringPiece_test.cpp @@ -14,81 +14,82 @@ * limitations under the License. */ +#include "util/StringPiece.h" + #include <algorithm> -#include <gtest/gtest.h> #include <string> #include <vector> -#include "util/StringPiece.h" +#include "test/Test.h" namespace aapt { TEST(StringPieceTest, CompareNonNullTerminatedPiece) { - StringPiece a("hello world", 5); - StringPiece b("hello moon", 5); - EXPECT_EQ(a, b); + StringPiece a("hello world", 5); + StringPiece b("hello moon", 5); + EXPECT_EQ(a, b); - StringPiece16 a16(u"hello world", 5); - StringPiece16 b16(u"hello moon", 5); - EXPECT_EQ(a16, b16); + StringPiece16 a16(u"hello world", 5); + StringPiece16 b16(u"hello moon", 5); + EXPECT_EQ(a16, b16); } TEST(StringPieceTest, PiecesHaveCorrectSortOrder) { - std::string testing("testing"); - std::string banana("banana"); - std::string car("car"); + std::string testing("testing"); + std::string banana("banana"); + std::string car("car"); - EXPECT_TRUE(StringPiece(testing) > banana); - EXPECT_TRUE(StringPiece(testing) > car); - EXPECT_TRUE(StringPiece(banana) < testing); - EXPECT_TRUE(StringPiece(banana) < car); - EXPECT_TRUE(StringPiece(car) < testing); - EXPECT_TRUE(StringPiece(car) > banana); + EXPECT_TRUE(StringPiece(testing) > banana); + EXPECT_TRUE(StringPiece(testing) > car); + EXPECT_TRUE(StringPiece(banana) < testing); + EXPECT_TRUE(StringPiece(banana) < car); + EXPECT_TRUE(StringPiece(car) < testing); + EXPECT_TRUE(StringPiece(car) > banana); } TEST(StringPieceTest, PiecesHaveCorrectSortOrderUtf8) { - std::string testing("testing"); - std::string banana("banana"); - std::string car("car"); + std::string testing("testing"); + std::string banana("banana"); + std::string car("car"); - EXPECT_TRUE(StringPiece(testing) > banana); - EXPECT_TRUE(StringPiece(testing) > car); - EXPECT_TRUE(StringPiece(banana) < testing); - EXPECT_TRUE(StringPiece(banana) < car); - EXPECT_TRUE(StringPiece(car) < testing); - EXPECT_TRUE(StringPiece(car) > banana); + EXPECT_TRUE(StringPiece(testing) > banana); + EXPECT_TRUE(StringPiece(testing) > car); + EXPECT_TRUE(StringPiece(banana) < testing); + EXPECT_TRUE(StringPiece(banana) < car); + EXPECT_TRUE(StringPiece(car) < testing); + EXPECT_TRUE(StringPiece(car) > banana); } TEST(StringPieceTest, ContainsOtherStringPiece) { - StringPiece text("I am a leaf on the wind."); - StringPiece startNeedle("I am"); - StringPiece endNeedle("wind."); - StringPiece middleNeedle("leaf"); - StringPiece emptyNeedle(""); - StringPiece missingNeedle("soar"); - StringPiece longNeedle("This string is longer than the text."); + StringPiece text("I am a leaf on the wind."); + StringPiece start_needle("I am"); + StringPiece end_needle("wind."); + StringPiece middle_needle("leaf"); + StringPiece empty_needle(""); + StringPiece missing_needle("soar"); + StringPiece long_needle("This string is longer than the text."); - EXPECT_TRUE(text.contains(startNeedle)); - EXPECT_TRUE(text.contains(endNeedle)); - EXPECT_TRUE(text.contains(middleNeedle)); - EXPECT_TRUE(text.contains(emptyNeedle)); - EXPECT_FALSE(text.contains(missingNeedle)); - EXPECT_FALSE(text.contains(longNeedle)); + EXPECT_TRUE(text.contains(start_needle)); + EXPECT_TRUE(text.contains(end_needle)); + EXPECT_TRUE(text.contains(middle_needle)); + EXPECT_TRUE(text.contains(empty_needle)); + EXPECT_FALSE(text.contains(missing_needle)); + EXPECT_FALSE(text.contains(long_needle)); - StringPiece16 text16(u"I am a leaf on the wind."); - StringPiece16 startNeedle16(u"I am"); - StringPiece16 endNeedle16(u"wind."); - StringPiece16 middleNeedle16(u"leaf"); - StringPiece16 emptyNeedle16(u""); - StringPiece16 missingNeedle16(u"soar"); - StringPiece16 longNeedle16(u"This string is longer than the text."); + StringPiece16 text16(u"I am a leaf on the wind."); + StringPiece16 start_needle16(u"I am"); + StringPiece16 end_needle16(u"wind."); + StringPiece16 middle_needle16(u"leaf"); + StringPiece16 empty_needle16(u""); + StringPiece16 missing_needle16(u"soar"); + StringPiece16 long_needle16(u"This string is longer than the text."); - EXPECT_TRUE(text16.contains(startNeedle16)); - EXPECT_TRUE(text16.contains(endNeedle16)); - EXPECT_TRUE(text16.contains(middleNeedle16)); - EXPECT_TRUE(text16.contains(emptyNeedle16)); - EXPECT_FALSE(text16.contains(missingNeedle16)); - EXPECT_FALSE(text16.contains(longNeedle16)); + EXPECT_TRUE(text16.contains(start_needle16)); + EXPECT_TRUE(text16.contains(end_needle16)); + EXPECT_TRUE(text16.contains(middle_needle16)); + EXPECT_TRUE(text16.contains(empty_needle16)); + EXPECT_FALSE(text16.contains(missing_needle16)); + EXPECT_FALSE(text16.contains(long_needle16)); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp index b0bec624cc9c..d5c0c8a7a5fe 100644 --- a/tools/aapt2/util/Util.cpp +++ b/tools/aapt2/util/Util.cpp @@ -14,559 +14,558 @@ * limitations under the License. */ +#include "util/Util.h" #include "util/BigBuffer.h" #include "util/Maybe.h" #include "util/StringPiece.h" -#include "util/Util.h" +#include <utils/Unicode.h> #include <algorithm> #include <ostream> #include <string> -#include <utils/Unicode.h> #include <vector> namespace aapt { namespace util { -static std::vector<std::string> splitAndTransform(const StringPiece& str, char sep, - const std::function<char(char)>& f) { - std::vector<std::string> parts; - const StringPiece::const_iterator end = std::end(str); - StringPiece::const_iterator start = std::begin(str); - StringPiece::const_iterator current; - do { - current = std::find(start, end, sep); - parts.emplace_back(str.substr(start, current).toString()); - if (f) { - std::string& part = parts.back(); - std::transform(part.begin(), part.end(), part.begin(), f); - } - start = current + 1; - } while (current != end); - return parts; +static std::vector<std::string> SplitAndTransform( + const StringPiece& str, char sep, const std::function<char(char)>& f) { + std::vector<std::string> parts; + const StringPiece::const_iterator end = std::end(str); + StringPiece::const_iterator start = std::begin(str); + StringPiece::const_iterator current; + do { + current = std::find(start, end, sep); + parts.emplace_back(str.substr(start, current).ToString()); + if (f) { + std::string& part = parts.back(); + std::transform(part.begin(), part.end(), part.begin(), f); + } + start = current + 1; + } while (current != end); + return parts; } -std::vector<std::string> split(const StringPiece& str, char sep) { - return splitAndTransform(str, sep, nullptr); +std::vector<std::string> Split(const StringPiece& str, char sep) { + return SplitAndTransform(str, sep, nullptr); } -std::vector<std::string> splitAndLowercase(const StringPiece& str, char sep) { - return splitAndTransform(str, sep, ::tolower); +std::vector<std::string> SplitAndLowercase(const StringPiece& str, char sep) { + return SplitAndTransform(str, sep, ::tolower); } -bool stringStartsWith(const StringPiece& str, const StringPiece& prefix) { - if (str.size() < prefix.size()) { - return false; - } - return str.substr(0, prefix.size()) == prefix; +bool StartsWith(const StringPiece& str, const StringPiece& prefix) { + if (str.size() < prefix.size()) { + return false; + } + return str.substr(0, prefix.size()) == prefix; } -bool stringEndsWith(const StringPiece& str, const StringPiece& suffix) { - if (str.size() < suffix.size()) { - return false; - } - return str.substr(str.size() - suffix.size(), suffix.size()) == suffix; +bool EndsWith(const StringPiece& str, const StringPiece& suffix) { + if (str.size() < suffix.size()) { + return false; + } + return str.substr(str.size() - suffix.size(), suffix.size()) == suffix; } -StringPiece trimWhitespace(const StringPiece& str) { - if (str.size() == 0 || str.data() == nullptr) { - return str; - } +StringPiece TrimWhitespace(const StringPiece& str) { + if (str.size() == 0 || str.data() == nullptr) { + return str; + } - const char* start = str.data(); - const char* end = str.data() + str.length(); + const char* start = str.data(); + const char* end = str.data() + str.length(); - while (start != end && isspace(*start)) { - start++; - } + while (start != end && isspace(*start)) { + start++; + } - while (end != start && isspace(*(end - 1))) { - end--; - } + while (end != start && isspace(*(end - 1))) { + end--; + } - return StringPiece(start, end - start); + return StringPiece(start, end - start); } -StringPiece::const_iterator findNonAlphaNumericAndNotInSet(const StringPiece& str, - const StringPiece& allowedChars) { - const auto endIter = str.end(); - for (auto iter = str.begin(); iter != endIter; ++iter) { - char c = *iter; - if ((c >= u'a' && c <= u'z') || - (c >= u'A' && c <= u'Z') || - (c >= u'0' && c <= u'9')) { - continue; - } - - bool match = false; - for (char i : allowedChars) { - if (c == i) { - match = true; - break; - } - } - - if (!match) { - return iter; - } +StringPiece::const_iterator FindNonAlphaNumericAndNotInSet( + const StringPiece& str, const StringPiece& allowed_chars) { + const auto end_iter = str.end(); + for (auto iter = str.begin(); iter != end_iter; ++iter) { + char c = *iter; + if ((c >= u'a' && c <= u'z') || (c >= u'A' && c <= u'Z') || + (c >= u'0' && c <= u'9')) { + continue; } - return endIter; -} - -bool isJavaClassName(const StringPiece& str) { - size_t pieces = 0; - for (const StringPiece& piece : tokenize(str, '.')) { - pieces++; - if (piece.empty()) { - return false; - } - // Can't have starting or trailing $ character. - if (piece.data()[0] == '$' || piece.data()[piece.size() - 1] == '$') { - return false; - } + bool match = false; + for (char i : allowed_chars) { + if (c == i) { + match = true; + break; + } + } - if (findNonAlphaNumericAndNotInSet(piece, "$_") != piece.end()) { - return false; - } + if (!match) { + return iter; } - return pieces >= 2; + } + return end_iter; } -bool isJavaPackageName(const StringPiece& str) { - if (str.empty()) { - return false; +bool IsJavaClassName(const StringPiece& str) { + size_t pieces = 0; + for (const StringPiece& piece : Tokenize(str, '.')) { + pieces++; + if (piece.empty()) { + return false; } - size_t pieces = 0; - for (const StringPiece& piece : tokenize(str, '.')) { - pieces++; - if (piece.empty()) { - return false; - } - - if (piece.data()[0] == '_' || piece.data()[piece.size() - 1] == '_') { - return false; - } - - if (findNonAlphaNumericAndNotInSet(piece, "_") != piece.end()) { - return false; - } + // Can't have starting or trailing $ character. + if (piece.data()[0] == '$' || piece.data()[piece.size() - 1] == '$') { + return false; } - return pieces >= 1; -} -Maybe<std::string> getFullyQualifiedClassName(const StringPiece& package, - const StringPiece& className) { - if (className.empty()) { - return {}; + if (FindNonAlphaNumericAndNotInSet(piece, "$_") != piece.end()) { + return false; } + } + return pieces >= 2; +} - if (util::isJavaClassName(className)) { - return className.toString(); - } +bool IsJavaPackageName(const StringPiece& str) { + if (str.empty()) { + return false; + } - if (package.empty()) { - return {}; + size_t pieces = 0; + for (const StringPiece& piece : Tokenize(str, '.')) { + pieces++; + if (piece.empty()) { + return false; } - std::string result(package.data(), package.size()); - if (className.data()[0] != '.') { - result += '.'; + if (piece.data()[0] == '_' || piece.data()[piece.size() - 1] == '_') { + return false; } - result.append(className.data(), className.size()); - if (!isJavaClassName(result)) { - return {}; + if (FindNonAlphaNumericAndNotInSet(piece, "_") != piece.end()) { + return false; } - return result; + } + return pieces >= 1; } -static size_t consumeDigits(const char* start, const char* end) { - const char* c = start; - for (; c != end && *c >= '0' && *c <= '9'; c++) {} - return static_cast<size_t>(c - start); +Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package, + const StringPiece& classname) { + if (classname.empty()) { + return {}; + } + + if (util::IsJavaClassName(classname)) { + return classname.ToString(); + } + + if (package.empty()) { + return {}; + } + + std::string result(package.data(), package.size()); + if (classname.data()[0] != '.') { + result += '.'; + } + + result.append(classname.data(), classname.size()); + if (!IsJavaClassName(result)) { + return {}; + } + return result; } -bool verifyJavaStringFormat(const StringPiece& str) { - const char* c = str.begin(); - const char* const end = str.end(); - - size_t argCount = 0; - bool nonpositional = false; - while (c != end) { - if (*c == '%' && c + 1 < end) { - c++; - - if (*c == '%') { - c++; - continue; - } - - argCount++; - - size_t numDigits = consumeDigits(c, end); - if (numDigits > 0) { - c += numDigits; - if (c != end && *c != '$') { - // The digits were a size, but not a positional argument. - nonpositional = true; - } - } else if (*c == '<') { - // Reusing last argument, bad idea since positions can be moved around - // during translation. - nonpositional = true; - - c++; - - // Optionally we can have a $ after - if (c != end && *c == '$') { - c++; - } - } else { - nonpositional = true; - } - - // Ignore size, width, flags, etc. - while (c != end && (*c == '-' || - *c == '#' || - *c == '+' || - *c == ' ' || - *c == ',' || - *c == '(' || - (*c >= '0' && *c <= '9'))) { - c++; - } - - /* - * This is a shortcut to detect strings that are going to Time.format() - * instead of String.format() - * - * Comparison of String.format() and Time.format() args: - * - * String: ABC E GH ST X abcdefgh nost x - * Time: DEFGHKMS W Za d hkm s w yz - * - * Therefore we know it's definitely Time if we have: - * DFKMWZkmwyz - */ - if (c != end) { - switch (*c) { - case 'D': - case 'F': - case 'K': - case 'M': - case 'W': - case 'Z': - case 'k': - case 'm': - case 'w': - case 'y': - case 'z': - return true; - } - } - } +static size_t ConsumeDigits(const char* start, const char* end) { + const char* c = start; + for (; c != end && *c >= '0' && *c <= '9'; c++) { + } + return static_cast<size_t>(c - start); +} - if (c != end) { - c++; +bool VerifyJavaStringFormat(const StringPiece& str) { + const char* c = str.begin(); + const char* const end = str.end(); + + size_t arg_count = 0; + bool nonpositional = false; + while (c != end) { + if (*c == '%' && c + 1 < end) { + c++; + + if (*c == '%') { + c++; + continue; + } + + arg_count++; + + size_t num_digits = ConsumeDigits(c, end); + if (num_digits > 0) { + c += num_digits; + if (c != end && *c != '$') { + // The digits were a size, but not a positional argument. + nonpositional = true; } - } + } else if (*c == '<') { + // Reusing last argument, bad idea since positions can be moved around + // during translation. + nonpositional = true; - if (argCount > 1 && nonpositional) { - // Multiple arguments were specified, but some or all were non positional. Translated - // strings may rearrange the order of the arguments, which will break the string. - return false; - } - return true; -} + c++; -static Maybe<std::string> parseUnicodeCodepoint(const char** start, const char* end) { - char32_t code = 0; - for (size_t i = 0; i < 4 && *start != end; i++, (*start)++) { - char c = **start; - char32_t a; - if (c >= '0' && c <= '9') { - a = c - '0'; - } else if (c >= 'a' && c <= 'f') { - a = c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - a = c - 'A' + 10; - } else { - return {}; + // Optionally we can have a $ after + if (c != end && *c == '$') { + c++; + } + } else { + nonpositional = true; + } + + // Ignore size, width, flags, etc. + while (c != end && (*c == '-' || *c == '#' || *c == '+' || *c == ' ' || + *c == ',' || *c == '(' || (*c >= '0' && *c <= '9'))) { + c++; + } + + /* + * This is a shortcut to detect strings that are going to Time.format() + * instead of String.format() + * + * Comparison of String.format() and Time.format() args: + * + * String: ABC E GH ST X abcdefgh nost x + * Time: DEFGHKMS W Za d hkm s w yz + * + * Therefore we know it's definitely Time if we have: + * DFKMWZkmwyz + */ + if (c != end) { + switch (*c) { + case 'D': + case 'F': + case 'K': + case 'M': + case 'W': + case 'Z': + case 'k': + case 'm': + case 'w': + case 'y': + case 'z': + return true; } - code = (code << 4) | a; + } } - ssize_t len = utf32_to_utf8_length(&code, 1); - if (len < 0) { - return {}; + if (c != end) { + c++; } + } - std::string resultUtf8; - resultUtf8.resize(len); - utf32_to_utf8(&code, 1, &*resultUtf8.begin(), len + 1); - return resultUtf8; + if (arg_count > 1 && nonpositional) { + // Multiple arguments were specified, but some or all were non positional. + // Translated + // strings may rearrange the order of the arguments, which will break the + // string. + return false; + } + return true; } -StringBuilder& StringBuilder::append(const StringPiece& str) { - if (!mError.empty()) { - return *this; - } +static Maybe<std::string> ParseUnicodeCodepoint(const char** start, + const char* end) { + char32_t code = 0; + for (size_t i = 0; i < 4 && *start != end; i++, (*start)++) { + char c = **start; + char32_t a; + if (c >= '0' && c <= '9') { + a = c - '0'; + } else if (c >= 'a' && c <= 'f') { + a = c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + a = c - 'A' + 10; + } else { + return {}; + } + code = (code << 4) | a; + } + + ssize_t len = utf32_to_utf8_length(&code, 1); + if (len < 0) { + return {}; + } + + std::string result_utf8; + result_utf8.resize(len); + utf32_to_utf8(&code, 1, &*result_utf8.begin(), len + 1); + return result_utf8; +} - // Where the new data will be appended to. - size_t newDataIndex = mStr.size(); - - const char* const end = str.end(); - const char* start = str.begin(); - const char* current = start; - while (current != end) { - if (mLastCharWasEscape) { - switch (*current) { - case 't': - mStr += '\t'; - break; - case 'n': - mStr += '\n'; - break; - case '#': - mStr += '#'; - break; - case '@': - mStr += '@'; - break; - case '?': - mStr += '?'; - break; - case '"': - mStr += '"'; - break; - case '\'': - mStr += '\''; - break; - case '\\': - mStr += '\\'; - break; - case 'u': { - current++; - Maybe<std::string> c = parseUnicodeCodepoint(¤t, end); - if (!c) { - mError = "invalid unicode escape sequence"; - return *this; - } - mStr += c.value(); - current -= 1; - break; - } - - default: - // Ignore. - break; - } - mLastCharWasEscape = false; - start = current + 1; - } else if (*current == '"') { - if (!mQuote && mTrailingSpace) { - // We found an opening quote, and we have - // trailing space, so we should append that - // space now. - if (mTrailingSpace) { - // We had trailing whitespace, so - // replace with a single space. - if (!mStr.empty()) { - mStr += ' '; - } - mTrailingSpace = false; - } - } - mQuote = !mQuote; - mStr.append(start, current - start); - start = current + 1; - } else if (*current == '\'' && !mQuote) { - // This should be escaped. - mError = "unescaped apostrophe"; +StringBuilder& StringBuilder::Append(const StringPiece& str) { + if (!error_.empty()) { + return *this; + } + + // Where the new data will be appended to. + size_t new_data_index = str_.size(); + + const char* const end = str.end(); + const char* start = str.begin(); + const char* current = start; + while (current != end) { + if (last_char_was_escape_) { + switch (*current) { + case 't': + str_ += '\t'; + break; + case 'n': + str_ += '\n'; + break; + case '#': + str_ += '#'; + break; + case '@': + str_ += '@'; + break; + case '?': + str_ += '?'; + break; + case '"': + str_ += '"'; + break; + case '\'': + str_ += '\''; + break; + case '\\': + str_ += '\\'; + break; + case 'u': { + current++; + Maybe<std::string> c = ParseUnicodeCodepoint(¤t, end); + if (!c) { + error_ = "invalid unicode escape sequence"; return *this; - } else if (*current == '\\') { - // This is an escape sequence, convert to the real value. - if (!mQuote && mTrailingSpace) { - // We had trailing whitespace, so - // replace with a single space. - if (!mStr.empty()) { - mStr += ' '; - } - mTrailingSpace = false; - } - mStr.append(start, current - start); - start = current + 1; - mLastCharWasEscape = true; - } else if (!mQuote) { - // This is not quoted text, so look for whitespace. - if (isspace(*current)) { - // We found whitespace, see if we have seen some - // before. - if (!mTrailingSpace) { - // We didn't see a previous adjacent space, - // so mark that we did. - mTrailingSpace = true; - mStr.append(start, current - start); - } - - // Keep skipping whitespace. - start = current + 1; - } else if (mTrailingSpace) { - // We saw trailing space before, so replace all - // that trailing space with one space. - if (!mStr.empty()) { - mStr += ' '; - } - mTrailingSpace = false; - } + } + str_ += c.value(); + current -= 1; + break; } - current++; - } - mStr.append(start, end - start); - - // Accumulate the added string's UTF-16 length. - ssize_t len = utf8_to_utf16_length( - reinterpret_cast<const uint8_t*>(mStr.data()) + newDataIndex, - mStr.size() - newDataIndex); - if (len < 0) { - mError = "invalid unicode code point"; - return *this; - } - mUtf16Len += len; + + default: + // Ignore. + break; + } + last_char_was_escape_ = false; + start = current + 1; + } else if (*current == '"') { + if (!quote_ && trailing_space_) { + // We found an opening quote, and we have + // trailing space, so we should append that + // space now. + if (trailing_space_) { + // We had trailing whitespace, so + // replace with a single space. + if (!str_.empty()) { + str_ += ' '; + } + trailing_space_ = false; + } + } + quote_ = !quote_; + str_.append(start, current - start); + start = current + 1; + } else if (*current == '\'' && !quote_) { + // This should be escaped. + error_ = "unescaped apostrophe"; + return *this; + } else if (*current == '\\') { + // This is an escape sequence, convert to the real value. + if (!quote_ && trailing_space_) { + // We had trailing whitespace, so + // replace with a single space. + if (!str_.empty()) { + str_ += ' '; + } + trailing_space_ = false; + } + str_.append(start, current - start); + start = current + 1; + last_char_was_escape_ = true; + } else if (!quote_) { + // This is not quoted text, so look for whitespace. + if (isspace(*current)) { + // We found whitespace, see if we have seen some + // before. + if (!trailing_space_) { + // We didn't see a previous adjacent space, + // so mark that we did. + trailing_space_ = true; + str_.append(start, current - start); + } + + // Keep skipping whitespace. + start = current + 1; + } else if (trailing_space_) { + // We saw trailing space before, so replace all + // that trailing space with one space. + if (!str_.empty()) { + str_ += ' '; + } + trailing_space_ = false; + } + } + current++; + } + str_.append(start, end - start); + + // Accumulate the added string's UTF-16 length. + ssize_t len = utf8_to_utf16_length( + reinterpret_cast<const uint8_t*>(str_.data()) + new_data_index, + str_.size() - new_data_index); + if (len < 0) { + error_ = "invalid unicode code point"; return *this; + } + utf16_len_ += len; + return *this; } -std::u16string utf8ToUtf16(const StringPiece& utf8) { - ssize_t utf16Length = utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(utf8.data()), - utf8.length()); - if (utf16Length <= 0) { - return {}; - } - - std::u16string utf16; - utf16.resize(utf16Length); - utf8_to_utf16(reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length(), - &*utf16.begin(), utf16Length + 1); - return utf16; +std::u16string Utf8ToUtf16(const StringPiece& utf8) { + ssize_t utf16_length = utf8_to_utf16_length( + reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length()); + if (utf16_length <= 0) { + return {}; + } + + std::u16string utf16; + utf16.resize(utf16_length); + utf8_to_utf16(reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length(), + &*utf16.begin(), utf16_length + 1); + return utf16; } -std::string utf16ToUtf8(const StringPiece16& utf16) { - ssize_t utf8Length = utf16_to_utf8_length(utf16.data(), utf16.length()); - if (utf8Length <= 0) { - return {}; - } +std::string Utf16ToUtf8(const StringPiece16& utf16) { + ssize_t utf8_length = utf16_to_utf8_length(utf16.data(), utf16.length()); + if (utf8_length <= 0) { + return {}; + } - std::string utf8; - utf8.resize(utf8Length); - utf16_to_utf8(utf16.data(), utf16.length(), &*utf8.begin(), utf8Length + 1); - return utf8; + std::string utf8; + utf8.resize(utf8_length); + utf16_to_utf8(utf16.data(), utf16.length(), &*utf8.begin(), utf8_length + 1); + return utf8; } -bool writeAll(std::ostream& out, const BigBuffer& buffer) { - for (const auto& b : buffer) { - if (!out.write(reinterpret_cast<const char*>(b.buffer.get()), b.size)) { - return false; - } +bool WriteAll(std::ostream& out, const BigBuffer& buffer) { + for (const auto& b : buffer) { + if (!out.write(reinterpret_cast<const char*>(b.buffer.get()), b.size)) { + return false; } - return true; + } + return true; } -std::unique_ptr<uint8_t[]> copy(const BigBuffer& buffer) { - std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[buffer.size()]); - uint8_t* p = data.get(); - for (const auto& block : buffer) { - memcpy(p, block.buffer.get(), block.size); - p += block.size; - } - return data; +std::unique_ptr<uint8_t[]> Copy(const BigBuffer& buffer) { + std::unique_ptr<uint8_t[]> data = + std::unique_ptr<uint8_t[]>(new uint8_t[buffer.size()]); + uint8_t* p = data.get(); + for (const auto& block : buffer) { + memcpy(p, block.buffer.get(), block.size); + p += block.size; + } + return data; } typename Tokenizer::iterator& Tokenizer::iterator::operator++() { - const char* start = mToken.end(); - const char* end = mStr.end(); - if (start == end) { - mEnd = true; - mToken.assign(mToken.end(), 0); - return *this; - } - - start += 1; - const char* current = start; - while (current != end) { - if (*current == mSeparator) { - mToken.assign(start, current - start); - return *this; - } - ++current; - } - mToken.assign(start, end - start); + const char* start = token_.end(); + const char* end = str_.end(); + if (start == end) { + end_ = true; + token_.assign(token_.end(), 0); return *this; + } + + start += 1; + const char* current = start; + while (current != end) { + if (*current == separator_) { + token_.assign(start, current - start); + return *this; + } + ++current; + } + token_.assign(start, end - start); + return *this; } bool Tokenizer::iterator::operator==(const iterator& rhs) const { - // We check equality here a bit differently. - // We need to know that the addresses are the same. - return mToken.begin() == rhs.mToken.begin() && mToken.end() == rhs.mToken.end() && - mEnd == rhs.mEnd; + // We check equality here a bit differently. + // We need to know that the addresses are the same. + return token_.begin() == rhs.token_.begin() && + token_.end() == rhs.token_.end() && end_ == rhs.end_; } bool Tokenizer::iterator::operator!=(const iterator& rhs) const { - return !(*this == rhs); + return !(*this == rhs); } -Tokenizer::iterator::iterator(StringPiece s, char sep, StringPiece tok, bool end) : - mStr(s), mSeparator(sep), mToken(tok), mEnd(end) { +Tokenizer::iterator::iterator(StringPiece s, char sep, StringPiece tok, + bool end) + : str_(s), separator_(sep), token_(tok), end_(end) {} + +Tokenizer::Tokenizer(StringPiece str, char sep) + : begin_(++iterator(str, sep, StringPiece(str.begin() - 1, 0), false)), + end_(str, sep, StringPiece(str.end(), 0), true) {} + +bool ExtractResFilePathParts(const StringPiece& path, StringPiece* out_prefix, + StringPiece* out_entry, StringPiece* out_suffix) { + const StringPiece res_prefix("res/"); + if (!StartsWith(path, res_prefix)) { + return false; + } + + StringPiece::const_iterator last_occurence = path.end(); + for (auto iter = path.begin() + res_prefix.size(); iter != path.end(); + ++iter) { + if (*iter == '/') { + last_occurence = iter; + } + } + + if (last_occurence == path.end()) { + return false; + } + + auto iter = std::find(last_occurence, path.end(), '.'); + *out_suffix = StringPiece(iter, path.end() - iter); + *out_entry = StringPiece(last_occurence + 1, iter - last_occurence - 1); + *out_prefix = StringPiece(path.begin(), last_occurence - path.begin() + 1); + return true; } -Tokenizer::Tokenizer(StringPiece str, char sep) : - mBegin(++iterator(str, sep, StringPiece(str.begin() - 1, 0), false)), - mEnd(str, sep, StringPiece(str.end(), 0), true) { +StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx) { + size_t len; + const char16_t* str = pool.stringAt(idx, &len); + if (str != nullptr) { + return StringPiece16(str, len); + } + return StringPiece16(); } -bool extractResFilePathParts(const StringPiece& path, StringPiece* outPrefix, - StringPiece* outEntry, StringPiece* outSuffix) { - const StringPiece resPrefix("res/"); - if (!stringStartsWith(path, resPrefix)) { - return false; - } - - StringPiece::const_iterator lastOccurence = path.end(); - for (auto iter = path.begin() + resPrefix.size(); iter != path.end(); ++iter) { - if (*iter == '/') { - lastOccurence = iter; - } - } - - if (lastOccurence == path.end()) { - return false; - } - - auto iter = std::find(lastOccurence, path.end(), '.'); - *outSuffix = StringPiece(iter, path.end() - iter); - *outEntry = StringPiece(lastOccurence + 1, iter - lastOccurence - 1); - *outPrefix = StringPiece(path.begin(), lastOccurence - path.begin() + 1); - return true; -} - -StringPiece16 getString16(const android::ResStringPool& pool, size_t idx) { - size_t len; - const char16_t* str = pool.stringAt(idx, &len); - if (str != nullptr) { - return StringPiece16(str, len); - } - return StringPiece16(); -} - -std::string getString(const android::ResStringPool& pool, size_t idx) { - size_t len; - const char* str = pool.string8At(idx, &len); - if (str != nullptr) { - return std::string(str, len); - } - return utf16ToUtf8(getString16(pool, idx)); +std::string GetString(const android::ResStringPool& pool, size_t idx) { + size_t len; + const char* str = pool.string8At(idx, &len); + if (str != nullptr) { + return std::string(str, len); + } + return Utf16ToUtf8(GetString16(pool, idx)); } -} // namespace util -} // namespace aapt +} // namespace util +} // namespace aapt diff --git a/tools/aapt2/util/Util.h b/tools/aapt2/util/Util.h index 077e193e091e..05e9cc5d28ca 100644 --- a/tools/aapt2/util/Util.h +++ b/tools/aapt2/util/Util.h @@ -17,40 +17,53 @@ #ifndef AAPT_UTIL_H #define AAPT_UTIL_H -#include "util/BigBuffer.h" -#include "util/Maybe.h" -#include "util/StringPiece.h" - -#include <androidfw/ResourceTypes.h> #include <functional> #include <memory> #include <ostream> #include <string> #include <vector> +#include "androidfw/ResourceTypes.h" +#include "utils/ByteOrder.h" + +#include "util/BigBuffer.h" +#include "util/Maybe.h" +#include "util/StringPiece.h" + +#ifdef _WIN32 +// TODO(adamlesinski): remove once http://b/32447322 is resolved. +// utils/ByteOrder.h includes winsock2.h on WIN32, +// which will pull in the ERROR definition. This conflicts +// with android-base/logging.h, which takes care of undefining +// ERROR, but it gets included too early (before winsock2.h). +#ifdef ERROR +#undef ERROR +#endif +#endif + namespace aapt { namespace util { -std::vector<std::string> split(const StringPiece& str, char sep); -std::vector<std::string> splitAndLowercase(const StringPiece& str, char sep); +std::vector<std::string> Split(const StringPiece& str, char sep); +std::vector<std::string> SplitAndLowercase(const StringPiece& str, char sep); /** * Returns true if the string starts with prefix. */ -bool stringStartsWith(const StringPiece& str, const StringPiece& prefix); +bool StartsWith(const StringPiece& str, const StringPiece& prefix); /** * Returns true if the string ends with suffix. */ -bool stringEndsWith(const StringPiece& str, const StringPiece& suffix); +bool EndsWith(const StringPiece& str, const StringPiece& suffix); /** * Creates a new StringPiece16 that points to a substring * of the original string without leading or trailing whitespace. */ -StringPiece trimWhitespace(const StringPiece& str); +StringPiece TrimWhitespace(const StringPiece& str); -StringPiece trimWhitespace(const StringPiece& str); +StringPiece TrimWhitespace(const StringPiece& str); /** * UTF-16 isspace(). It basically checks for lower range characters that are @@ -62,18 +75,18 @@ inline bool isspace16(char16_t c) { return c < 0x0080 && isspace(c); } * Returns an iterator to the first character that is not alpha-numeric and that * is not in the allowedChars set. */ -StringPiece::const_iterator findNonAlphaNumericAndNotInSet( - const StringPiece& str, const StringPiece& allowedChars); +StringPiece::const_iterator FindNonAlphaNumericAndNotInSet( + const StringPiece& str, const StringPiece& allowed_chars); /** * Tests that the string is a valid Java class name. */ -bool isJavaClassName(const StringPiece& str); +bool IsJavaClassName(const StringPiece& str); /** * Tests that the string is a valid Java package name. */ -bool isJavaPackageName(const StringPiece& str); +bool IsJavaPackageName(const StringPiece& str); /** * Converts the class name to a fully qualified class name from the given @@ -84,8 +97,8 @@ bool isJavaPackageName(const StringPiece& str); * .a.b --> package.a.b * asdf.adsf --> asdf.adsf */ -Maybe<std::string> getFullyQualifiedClassName(const StringPiece& package, - const StringPiece& className); +Maybe<std::string> GetFullyQualifiedClassName(const StringPiece& package, + const StringPiece& class_name); /** * Makes a std::unique_ptr<> with the template parameter inferred by the @@ -103,15 +116,15 @@ std::unique_ptr<T> make_unique(Args&&... args) { * separator. */ template <typename Container> -::std::function<::std::ostream&(::std::ostream&)> joiner( +::std::function<::std::ostream&(::std::ostream&)> Joiner( const Container& container, const char* sep) { using std::begin; using std::end; - const auto beginIter = begin(container); - const auto endIter = end(container); - return [beginIter, endIter, sep](::std::ostream& out) -> ::std::ostream& { - for (auto iter = beginIter; iter != endIter; ++iter) { - if (iter != beginIter) { + const auto begin_iter = begin(container); + const auto end_iter = end(container); + return [begin_iter, end_iter, sep](::std::ostream& out) -> ::std::ostream& { + for (auto iter = begin_iter; iter != end_iter; ++iter) { + if (iter != begin_iter) { out << sep; } out << *iter; @@ -120,31 +133,12 @@ template <typename Container> }; } -inline ::std::function<::std::ostream&(::std::ostream&)> formatSize( - size_t size) { - return [size](::std::ostream& out) -> ::std::ostream& { - constexpr size_t K = 1024u; - constexpr size_t M = K * K; - constexpr size_t G = M * K; - if (size < K) { - out << size << "B"; - } else if (size < M) { - out << (double(size) / K) << " KiB"; - } else if (size < G) { - out << (double(size) / M) << " MiB"; - } else { - out << (double(size) / G) << " GiB"; - } - return out; - }; -} - /** * Helper method to extract a UTF-16 string from a StringPool. If the string is * stored as UTF-8, * the conversion to UTF-16 happens within ResStringPool. */ -StringPiece16 getString16(const android::ResStringPool& pool, size_t idx); +StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx); /** * Helper method to extract a UTF-8 string from a StringPool. If the string is @@ -154,7 +148,7 @@ StringPiece16 getString16(const android::ResStringPool& pool, size_t idx); * which maintains no state or cache. This means we must return an std::string * copy. */ -std::string getString(const android::ResStringPool& pool, size_t idx); +std::string GetString(const android::ResStringPool& pool, size_t idx); /** * Checks that the Java string format contains no non-positional arguments @@ -165,53 +159,53 @@ std::string getString(const android::ResStringPool& pool, size_t idx); * which will * break the string interpolation. */ -bool verifyJavaStringFormat(const StringPiece& str); +bool VerifyJavaStringFormat(const StringPiece& str); class StringBuilder { public: - StringBuilder& append(const StringPiece& str); - const std::string& str() const; - const std::string& error() const; + StringBuilder& Append(const StringPiece& str); + const std::string& ToString() const; + const std::string& Error() const; // When building StyledStrings, we need UTF-16 indices into the string, // which is what the Java layer expects when dealing with java // String.charAt(). - size_t utf16Len() const; + size_t Utf16Len() const; - operator bool() const; + explicit operator bool() const; private: - std::string mStr; - size_t mUtf16Len = 0; - bool mQuote = false; - bool mTrailingSpace = false; - bool mLastCharWasEscape = false; - std::string mError; + std::string str_; + size_t utf16_len_ = 0; + bool quote_ = false; + bool trailing_space_ = false; + bool last_char_was_escape_ = false; + std::string error_; }; -inline const std::string& StringBuilder::str() const { return mStr; } +inline const std::string& StringBuilder::ToString() const { return str_; } -inline const std::string& StringBuilder::error() const { return mError; } +inline const std::string& StringBuilder::Error() const { return error_; } -inline size_t StringBuilder::utf16Len() const { return mUtf16Len; } +inline size_t StringBuilder::Utf16Len() const { return utf16_len_; } -inline StringBuilder::operator bool() const { return mError.empty(); } +inline StringBuilder::operator bool() const { return error_.empty(); } /** * Converts a UTF8 string to a UTF16 string. */ -std::u16string utf8ToUtf16(const StringPiece& utf8); -std::string utf16ToUtf8(const StringPiece16& utf16); +std::u16string Utf8ToUtf16(const StringPiece& utf8); +std::string Utf16ToUtf8(const StringPiece16& utf16); /** * Writes the entire BigBuffer to the output stream. */ -bool writeAll(std::ostream& out, const BigBuffer& buffer); +bool WriteAll(std::ostream& out, const BigBuffer& buffer); /* * Copies the entire BigBuffer into a single buffer. */ -std::unique_ptr<uint8_t[]> copy(const BigBuffer& buffer); +std::unique_ptr<uint8_t[]> Copy(const BigBuffer& buffer); /** * A Tokenizer implemented as an iterable collection. It does not allocate @@ -226,7 +220,7 @@ class Tokenizer { iterator& operator++(); - StringPiece operator*() { return mToken; } + StringPiece operator*() { return token_; } bool operator==(const iterator& rhs) const; bool operator!=(const iterator& rhs) const; @@ -235,34 +229,34 @@ class Tokenizer { iterator(StringPiece s, char sep, StringPiece tok, bool end); - StringPiece mStr; - char mSeparator; - StringPiece mToken; - bool mEnd; + StringPiece str_; + char separator_; + StringPiece token_; + bool end_; }; Tokenizer(StringPiece str, char sep); - iterator begin() { return mBegin; } + iterator begin() { return begin_; } - iterator end() { return mEnd; } + iterator end() { return end_; } private: - const iterator mBegin; - const iterator mEnd; + const iterator begin_; + const iterator end_; }; -inline Tokenizer tokenize(const StringPiece& str, char sep) { +inline Tokenizer Tokenize(const StringPiece& str, char sep) { return Tokenizer(str, sep); } -inline uint16_t hostToDevice16(uint16_t value) { return htods(value); } +inline uint16_t HostToDevice16(uint16_t value) { return htods(value); } -inline uint32_t hostToDevice32(uint32_t value) { return htodl(value); } +inline uint32_t HostToDevice32(uint32_t value) { return htodl(value); } -inline uint16_t deviceToHost16(uint16_t value) { return dtohs(value); } +inline uint16_t DeviceToHost16(uint16_t value) { return dtohs(value); } -inline uint32_t deviceToHost32(uint32_t value) { return dtohl(value); } +inline uint32_t DeviceToHost32(uint32_t value) { return dtohl(value); } /** * Given a path like: res/xml-sw600dp/foo.xml @@ -273,8 +267,8 @@ inline uint32_t deviceToHost32(uint32_t value) { return dtohl(value); } * * Returns true if successful. */ -bool extractResFilePathParts(const StringPiece& path, StringPiece* outPrefix, - StringPiece* outEntry, StringPiece* outSuffix); +bool ExtractResFilePathParts(const StringPiece& path, StringPiece* out_prefix, + StringPiece* out_entry, StringPiece* out_suffix); } // namespace util diff --git a/tools/aapt2/util/Util_test.cpp b/tools/aapt2/util/Util_test.cpp index 0e27213a8d8a..cac3de4696ab 100644 --- a/tools/aapt2/util/Util_test.cpp +++ b/tools/aapt2/util/Util_test.cpp @@ -14,191 +14,196 @@ * limitations under the License. */ -#include "test/Test.h" -#include "util/StringPiece.h" #include "util/Util.h" #include <string> +#include "test/Test.h" + namespace aapt { TEST(UtilTest, TrimOnlyWhitespace) { - const std::string full = "\n "; + const std::string full = "\n "; - StringPiece trimmed = util::trimWhitespace(full); - EXPECT_TRUE(trimmed.empty()); - EXPECT_EQ(0u, trimmed.size()); + StringPiece trimmed = util::TrimWhitespace(full); + EXPECT_TRUE(trimmed.empty()); + EXPECT_EQ(0u, trimmed.size()); } TEST(UtilTest, StringEndsWith) { - EXPECT_TRUE(util::stringEndsWith("hello.xml", ".xml")); + EXPECT_TRUE(util::EndsWith("hello.xml", ".xml")); } TEST(UtilTest, StringStartsWith) { - EXPECT_TRUE(util::stringStartsWith("hello.xml", "he")); + EXPECT_TRUE(util::StartsWith("hello.xml", "he")); } TEST(UtilTest, StringBuilderSplitEscapeSequence) { - EXPECT_EQ(StringPiece("this is a new\nline."), - util::StringBuilder().append("this is a new\\") - .append("nline.") - .str()); + EXPECT_EQ(StringPiece("this is a new\nline."), util::StringBuilder() + .Append("this is a new\\") + .Append("nline.") + .ToString()); } TEST(UtilTest, StringBuilderWhitespaceRemoval) { - EXPECT_EQ(StringPiece("hey guys this is so cool"), - util::StringBuilder().append(" hey guys ") - .append(" this is so cool ") - .str()); + EXPECT_EQ(StringPiece("hey guys this is so cool"), + util::StringBuilder() + .Append(" hey guys ") + .Append(" this is so cool ") + .ToString()); - EXPECT_EQ(StringPiece(" wow, so many \t spaces. what?"), - util::StringBuilder().append(" \" wow, so many \t ") - .append("spaces. \"what? ") - .str()); + EXPECT_EQ(StringPiece(" wow, so many \t spaces. what?"), + util::StringBuilder() + .Append(" \" wow, so many \t ") + .Append("spaces. \"what? ") + .ToString()); - EXPECT_EQ(StringPiece("where is the pie?"), - util::StringBuilder().append(" where \t ") - .append(" \nis the "" pie?") - .str()); + EXPECT_EQ(StringPiece("where is the pie?"), util::StringBuilder() + .Append(" where \t ") + .Append(" \nis the " + " pie?") + .ToString()); } TEST(UtilTest, StringBuilderEscaping) { - EXPECT_EQ(StringPiece("hey guys\n this \t is so\\ cool"), - util::StringBuilder().append(" hey guys\\n ") - .append(" this \\t is so\\\\ cool ") - .str()); + EXPECT_EQ(StringPiece("hey guys\n this \t is so\\ cool"), + util::StringBuilder() + .Append(" hey guys\\n ") + .Append(" this \\t is so\\\\ cool ") + .ToString()); - EXPECT_EQ(StringPiece("@?#\\\'"), - util::StringBuilder().append("\\@\\?\\#\\\\\\'") - .str()); + EXPECT_EQ(StringPiece("@?#\\\'"), + util::StringBuilder().Append("\\@\\?\\#\\\\\\'").ToString()); } TEST(UtilTest, StringBuilderMisplacedQuote) { - util::StringBuilder builder{}; - EXPECT_FALSE(builder.append("they're coming!")); + util::StringBuilder builder{}; + EXPECT_FALSE(builder.Append("they're coming!")); } TEST(UtilTest, StringBuilderUnicodeCodes) { - EXPECT_EQ(std::string("\u00AF\u0AF0 woah"), - util::StringBuilder().append("\\u00AF\\u0AF0 woah") - .str()); + EXPECT_EQ(std::string("\u00AF\u0AF0 woah"), + util::StringBuilder().Append("\\u00AF\\u0AF0 woah").ToString()); - EXPECT_FALSE(util::StringBuilder().append("\\u00 yo")); + EXPECT_FALSE(util::StringBuilder().Append("\\u00 yo")); } TEST(UtilTest, TokenizeInput) { - auto tokenizer = util::tokenize(StringPiece("this| is|the|end"), '|'); - auto iter = tokenizer.begin(); - ASSERT_EQ(*iter, StringPiece("this")); - ++iter; - ASSERT_EQ(*iter, StringPiece(" is")); - ++iter; - ASSERT_EQ(*iter, StringPiece("the")); - ++iter; - ASSERT_EQ(*iter, StringPiece("end")); - ++iter; - ASSERT_EQ(tokenizer.end(), iter); + auto tokenizer = util::Tokenize(StringPiece("this| is|the|end"), '|'); + auto iter = tokenizer.begin(); + ASSERT_EQ(*iter, StringPiece("this")); + ++iter; + ASSERT_EQ(*iter, StringPiece(" is")); + ++iter; + ASSERT_EQ(*iter, StringPiece("the")); + ++iter; + ASSERT_EQ(*iter, StringPiece("end")); + ++iter; + ASSERT_EQ(tokenizer.end(), iter); } TEST(UtilTest, TokenizeEmptyString) { - auto tokenizer = util::tokenize(StringPiece(""), '|'); - auto iter = tokenizer.begin(); - ASSERT_NE(tokenizer.end(), iter); - ASSERT_EQ(StringPiece(), *iter); - ++iter; - ASSERT_EQ(tokenizer.end(), iter); + auto tokenizer = util::Tokenize(StringPiece(""), '|'); + auto iter = tokenizer.begin(); + ASSERT_NE(tokenizer.end(), iter); + ASSERT_EQ(StringPiece(), *iter); + ++iter; + ASSERT_EQ(tokenizer.end(), iter); } TEST(UtilTest, TokenizeAtEnd) { - auto tokenizer = util::tokenize(StringPiece("one."), '.'); - auto iter = tokenizer.begin(); - ASSERT_EQ(*iter, StringPiece("one")); - ++iter; - ASSERT_NE(iter, tokenizer.end()); - ASSERT_EQ(*iter, StringPiece()); + auto tokenizer = util::Tokenize(StringPiece("one."), '.'); + auto iter = tokenizer.begin(); + ASSERT_EQ(*iter, StringPiece("one")); + ++iter; + ASSERT_NE(iter, tokenizer.end()); + ASSERT_EQ(*iter, StringPiece()); } TEST(UtilTest, IsJavaClassName) { - EXPECT_TRUE(util::isJavaClassName("android.test.Class")); - EXPECT_TRUE(util::isJavaClassName("android.test.Class$Inner")); - EXPECT_TRUE(util::isJavaClassName("android_test.test.Class")); - EXPECT_TRUE(util::isJavaClassName("_android_.test._Class_")); - EXPECT_FALSE(util::isJavaClassName("android.test.$Inner")); - EXPECT_FALSE(util::isJavaClassName("android.test.Inner$")); - EXPECT_FALSE(util::isJavaClassName(".test.Class")); - EXPECT_FALSE(util::isJavaClassName("android")); + EXPECT_TRUE(util::IsJavaClassName("android.test.Class")); + EXPECT_TRUE(util::IsJavaClassName("android.test.Class$Inner")); + EXPECT_TRUE(util::IsJavaClassName("android_test.test.Class")); + EXPECT_TRUE(util::IsJavaClassName("_android_.test._Class_")); + EXPECT_FALSE(util::IsJavaClassName("android.test.$Inner")); + EXPECT_FALSE(util::IsJavaClassName("android.test.Inner$")); + EXPECT_FALSE(util::IsJavaClassName(".test.Class")); + EXPECT_FALSE(util::IsJavaClassName("android")); } TEST(UtilTest, IsJavaPackageName) { - EXPECT_TRUE(util::isJavaPackageName("android")); - EXPECT_TRUE(util::isJavaPackageName("android.test")); - EXPECT_TRUE(util::isJavaPackageName("android.test_thing")); - EXPECT_FALSE(util::isJavaPackageName("_android")); - EXPECT_FALSE(util::isJavaPackageName("android_")); - EXPECT_FALSE(util::isJavaPackageName("android.")); - EXPECT_FALSE(util::isJavaPackageName(".android")); - EXPECT_FALSE(util::isJavaPackageName("android._test")); - EXPECT_FALSE(util::isJavaPackageName("..")); + EXPECT_TRUE(util::IsJavaPackageName("android")); + EXPECT_TRUE(util::IsJavaPackageName("android.test")); + EXPECT_TRUE(util::IsJavaPackageName("android.test_thing")); + EXPECT_FALSE(util::IsJavaPackageName("_android")); + EXPECT_FALSE(util::IsJavaPackageName("android_")); + EXPECT_FALSE(util::IsJavaPackageName("android.")); + EXPECT_FALSE(util::IsJavaPackageName(".android")); + EXPECT_FALSE(util::IsJavaPackageName("android._test")); + EXPECT_FALSE(util::IsJavaPackageName("..")); } TEST(UtilTest, FullyQualifiedClassName) { - Maybe<std::string> res = util::getFullyQualifiedClassName("android", ".asdf"); - AAPT_ASSERT_TRUE(res); - EXPECT_EQ(res.value(), "android.asdf"); + Maybe<std::string> res = util::GetFullyQualifiedClassName("android", ".asdf"); + AAPT_ASSERT_TRUE(res); + EXPECT_EQ(res.value(), "android.asdf"); - res = util::getFullyQualifiedClassName("android", ".a.b"); - AAPT_ASSERT_TRUE(res); - EXPECT_EQ(res.value(), "android.a.b"); + res = util::GetFullyQualifiedClassName("android", ".a.b"); + AAPT_ASSERT_TRUE(res); + EXPECT_EQ(res.value(), "android.a.b"); - res = util::getFullyQualifiedClassName("android", "a.b"); - AAPT_ASSERT_TRUE(res); - EXPECT_EQ(res.value(), "a.b"); + res = util::GetFullyQualifiedClassName("android", "a.b"); + AAPT_ASSERT_TRUE(res); + EXPECT_EQ(res.value(), "a.b"); - res = util::getFullyQualifiedClassName("", "a.b"); - AAPT_ASSERT_TRUE(res); - EXPECT_EQ(res.value(), "a.b"); + res = util::GetFullyQualifiedClassName("", "a.b"); + AAPT_ASSERT_TRUE(res); + EXPECT_EQ(res.value(), "a.b"); - res = util::getFullyQualifiedClassName("android", "Class"); - AAPT_ASSERT_TRUE(res); - EXPECT_EQ(res.value(), "android.Class"); + res = util::GetFullyQualifiedClassName("android", "Class"); + AAPT_ASSERT_TRUE(res); + EXPECT_EQ(res.value(), "android.Class"); - res = util::getFullyQualifiedClassName("", ""); - AAPT_ASSERT_FALSE(res); + res = util::GetFullyQualifiedClassName("", ""); + AAPT_ASSERT_FALSE(res); - res = util::getFullyQualifiedClassName("android", "./Apple"); - AAPT_ASSERT_FALSE(res); + res = util::GetFullyQualifiedClassName("android", "./Apple"); + AAPT_ASSERT_FALSE(res); } TEST(UtilTest, ExtractResourcePathComponents) { - StringPiece prefix, entry, suffix; - ASSERT_TRUE(util::extractResFilePathParts("res/xml-sw600dp/entry.xml", &prefix, &entry, - &suffix)); - EXPECT_EQ(prefix, "res/xml-sw600dp/"); - EXPECT_EQ(entry, "entry"); - EXPECT_EQ(suffix, ".xml"); + StringPiece prefix, entry, suffix; + ASSERT_TRUE(util::ExtractResFilePathParts("res/xml-sw600dp/entry.xml", + &prefix, &entry, &suffix)); + EXPECT_EQ(prefix, "res/xml-sw600dp/"); + EXPECT_EQ(entry, "entry"); + EXPECT_EQ(suffix, ".xml"); - ASSERT_TRUE(util::extractResFilePathParts("res/xml-sw600dp/entry.9.png", &prefix, &entry, - &suffix)); + ASSERT_TRUE(util::ExtractResFilePathParts("res/xml-sw600dp/entry.9.png", + &prefix, &entry, &suffix)); - EXPECT_EQ(prefix, "res/xml-sw600dp/"); - EXPECT_EQ(entry, "entry"); - EXPECT_EQ(suffix, ".9.png"); + EXPECT_EQ(prefix, "res/xml-sw600dp/"); + EXPECT_EQ(entry, "entry"); + EXPECT_EQ(suffix, ".9.png"); - EXPECT_FALSE(util::extractResFilePathParts("AndroidManifest.xml", &prefix, &entry, &suffix)); - EXPECT_FALSE(util::extractResFilePathParts("res/.xml", &prefix, &entry, &suffix)); + EXPECT_FALSE(util::ExtractResFilePathParts("AndroidManifest.xml", &prefix, + &entry, &suffix)); + EXPECT_FALSE( + util::ExtractResFilePathParts("res/.xml", &prefix, &entry, &suffix)); - ASSERT_TRUE(util::extractResFilePathParts("res//.", &prefix, &entry, &suffix)); - EXPECT_EQ(prefix, "res//"); - EXPECT_EQ(entry, ""); - EXPECT_EQ(suffix, "."); + ASSERT_TRUE( + util::ExtractResFilePathParts("res//.", &prefix, &entry, &suffix)); + EXPECT_EQ(prefix, "res//"); + EXPECT_EQ(entry, ""); + EXPECT_EQ(suffix, "."); } TEST(UtilTest, VerifyJavaStringFormat) { - ASSERT_TRUE(util::verifyJavaStringFormat("%09.34f")); - ASSERT_TRUE(util::verifyJavaStringFormat("%9$.34f %8$")); - ASSERT_TRUE(util::verifyJavaStringFormat("%% %%")); - ASSERT_FALSE(util::verifyJavaStringFormat("%09$f %f")); - ASSERT_FALSE(util::verifyJavaStringFormat("%09f %08s")); + ASSERT_TRUE(util::VerifyJavaStringFormat("%09.34f")); + ASSERT_TRUE(util::VerifyJavaStringFormat("%9$.34f %8$")); + ASSERT_TRUE(util::VerifyJavaStringFormat("%% %%")); + ASSERT_FALSE(util::VerifyJavaStringFormat("%09$f %f")); + ASSERT_FALSE(util::VerifyJavaStringFormat("%09f %08s")); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/xml/XmlActionExecutor.cpp b/tools/aapt2/xml/XmlActionExecutor.cpp index 745079c43c7c..7580b469a98e 100644 --- a/tools/aapt2/xml/XmlActionExecutor.cpp +++ b/tools/aapt2/xml/XmlActionExecutor.cpp @@ -19,93 +19,94 @@ namespace aapt { namespace xml { -static bool wrapperOne(XmlNodeAction::ActionFunc& f, Element* el, SourcePathDiagnostics*) { - return f(el); +static bool wrapper_one(XmlNodeAction::ActionFunc& f, Element* el, + SourcePathDiagnostics*) { + return f(el); } -static bool wrapperTwo(XmlNodeAction::ActionFuncWithDiag& f, Element* el, - SourcePathDiagnostics* diag) { - return f(el, diag); +static bool wrapper_two(XmlNodeAction::ActionFuncWithDiag& f, Element* el, + SourcePathDiagnostics* diag) { + return f(el, diag); } -void XmlNodeAction::action(XmlNodeAction::ActionFunc f) { - mActions.emplace_back(std::bind(wrapperOne, std::move(f), - std::placeholders::_1, - std::placeholders::_2)); +void XmlNodeAction::Action(XmlNodeAction::ActionFunc f) { + actions_.emplace_back(std::bind( + wrapper_one, std::move(f), std::placeholders::_1, std::placeholders::_2)); } -void XmlNodeAction::action(XmlNodeAction::ActionFuncWithDiag f) { - mActions.emplace_back(std::bind(wrapperTwo, std::move(f), - std::placeholders::_1, - std::placeholders::_2)); +void XmlNodeAction::Action(XmlNodeAction::ActionFuncWithDiag f) { + actions_.emplace_back(std::bind( + wrapper_two, std::move(f), std::placeholders::_1, std::placeholders::_2)); } -static void printElementToDiagMessage(const Element* el, DiagMessage* msg) { - *msg << "<"; - if (!el->namespaceUri.empty()) { - *msg << el->namespaceUri << ":"; - } - *msg << el->name << ">"; +static void PrintElementToDiagMessage(const Element* el, DiagMessage* msg) { + *msg << "<"; + if (!el->namespace_uri.empty()) { + *msg << el->namespace_uri << ":"; + } + *msg << el->name << ">"; } -bool XmlNodeAction::execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag, - Element* el) const { - bool error = false; - for (const ActionFuncWithDiag& action : mActions) { - error |= !action(el, diag); - } +bool XmlNodeAction::Execute(XmlActionExecutorPolicy policy, + SourcePathDiagnostics* diag, Element* el) const { + bool error = false; + for (const ActionFuncWithDiag& action : actions_) { + error |= !action(el, diag); + } - for (Element* childEl : el->getChildElements()) { - if (childEl->namespaceUri.empty()) { - std::map<std::string, XmlNodeAction>::const_iterator iter = mMap.find(childEl->name); - if (iter != mMap.end()) { - error |= !iter->second.execute(policy, diag, childEl); - continue; - } - } + for (Element* child_el : el->GetChildElements()) { + if (child_el->namespace_uri.empty()) { + std::map<std::string, XmlNodeAction>::const_iterator iter = + map_.find(child_el->name); + if (iter != map_.end()) { + error |= !iter->second.Execute(policy, diag, child_el); + continue; + } + } - if (policy == XmlActionExecutorPolicy::Whitelist) { - DiagMessage errorMsg(childEl->lineNumber); - errorMsg << "unknown element "; - printElementToDiagMessage(childEl, &errorMsg); - errorMsg << " found"; - diag->error(errorMsg); - error = true; - } + if (policy == XmlActionExecutorPolicy::kWhitelist) { + DiagMessage error_msg(child_el->line_number); + error_msg << "unknown element "; + PrintElementToDiagMessage(child_el, &error_msg); + error_msg << " found"; + diag->Error(error_msg); + error = true; } - return !error; + } + return !error; } -bool XmlActionExecutor::execute(XmlActionExecutorPolicy policy, IDiagnostics* diag, - XmlResource* doc) const { - SourcePathDiagnostics sourceDiag(doc->file.source, diag); +bool XmlActionExecutor::Execute(XmlActionExecutorPolicy policy, + IDiagnostics* diag, XmlResource* doc) const { + SourcePathDiagnostics source_diag(doc->file.source, diag); - Element* el = findRootElement(doc); - if (!el) { - if (policy == XmlActionExecutorPolicy::Whitelist) { - sourceDiag.error(DiagMessage() << "no root XML tag found"); - return false; - } - return true; + Element* el = FindRootElement(doc); + if (!el) { + if (policy == XmlActionExecutorPolicy::kWhitelist) { + source_diag.Error(DiagMessage() << "no root XML tag found"); + return false; } + return true; + } - if (el->namespaceUri.empty()) { - std::map<std::string, XmlNodeAction>::const_iterator iter = mMap.find(el->name); - if (iter != mMap.end()) { - return iter->second.execute(policy, &sourceDiag, el); - } + if (el->namespace_uri.empty()) { + std::map<std::string, XmlNodeAction>::const_iterator iter = + map_.find(el->name); + if (iter != map_.end()) { + return iter->second.Execute(policy, &source_diag, el); } + } - if (policy == XmlActionExecutorPolicy::Whitelist) { - DiagMessage errorMsg(el->lineNumber); - errorMsg << "unknown element "; - printElementToDiagMessage(el, &errorMsg); - errorMsg << " found"; - sourceDiag.error(errorMsg); - return false; - } - return true; + if (policy == XmlActionExecutorPolicy::kWhitelist) { + DiagMessage error_msg(el->line_number); + error_msg << "unknown element "; + PrintElementToDiagMessage(el, &error_msg); + error_msg << " found"; + source_diag.Error(error_msg); + return false; + } + return true; } -} // namespace xml -} // namespace aapt +} // namespace xml +} // namespace aapt diff --git a/tools/aapt2/xml/XmlActionExecutor.h b/tools/aapt2/xml/XmlActionExecutor.h index ca21b087f954..68e35631988e 100644 --- a/tools/aapt2/xml/XmlActionExecutor.h +++ b/tools/aapt2/xml/XmlActionExecutor.h @@ -17,15 +17,16 @@ #ifndef AAPT_XML_XMLPATTERN_H #define AAPT_XML_XMLPATTERN_H -#include "Diagnostics.h" -#include "xml/XmlDom.h" - -#include <android-base/macros.h> #include <functional> #include <map> #include <string> #include <vector> +#include "android-base/macros.h" + +#include "Diagnostics.h" +#include "xml/XmlDom.h" + namespace aapt { namespace xml { @@ -34,14 +35,14 @@ enum class XmlActionExecutorPolicy { * Actions on run if elements are matched, errors occur only when actions * return false. */ - None, + kNone, /** * The actions defined must match and run. If an element is found that does * not match * an action, an error occurs. */ - Whitelist, + kWhitelist, }; /** @@ -60,22 +61,22 @@ class XmlNodeAction { * element * with the name `name`. */ - XmlNodeAction& operator[](const std::string& name) { return mMap[name]; } + XmlNodeAction& operator[](const std::string& name) { return map_[name]; } /** * Add an action to be performed at this XmlNodeAction. */ - void action(ActionFunc f); - void action(ActionFuncWithDiag); + void Action(ActionFunc f); + void Action(ActionFuncWithDiag); private: friend class XmlActionExecutor; - bool execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag, + bool Execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag, Element* el) const; - std::map<std::string, XmlNodeAction> mMap; - std::vector<ActionFuncWithDiag> mActions; + std::map<std::string, XmlNodeAction> map_; + std::vector<ActionFuncWithDiag> actions_; }; /** @@ -89,20 +90,19 @@ class XmlActionExecutor { /** * Find or create a root XmlNodeAction that will be performed for the root XML - * element - * with the name `name`. + * element with the name `name`. */ - XmlNodeAction& operator[](const std::string& name) { return mMap[name]; } + XmlNodeAction& operator[](const std::string& name) { return map_[name]; } /** * Execute the defined actions for this XmlResource. * Returns true if all actions return true, otherwise returns false. */ - bool execute(XmlActionExecutorPolicy policy, IDiagnostics* diag, + bool Execute(XmlActionExecutorPolicy policy, IDiagnostics* diag, XmlResource* doc) const; private: - std::map<std::string, XmlNodeAction> mMap; + std::map<std::string, XmlNodeAction> map_; DISALLOW_COPY_AND_ASSIGN(XmlActionExecutor); }; diff --git a/tools/aapt2/xml/XmlActionExecutor_test.cpp b/tools/aapt2/xml/XmlActionExecutor_test.cpp index 106e85601f6e..7110c90fa3a9 100644 --- a/tools/aapt2/xml/XmlActionExecutor_test.cpp +++ b/tools/aapt2/xml/XmlActionExecutor_test.cpp @@ -14,49 +14,53 @@ * limitations under the License. */ -#include "test/Test.h" #include "xml/XmlActionExecutor.h" +#include "test/Test.h" + namespace aapt { namespace xml { TEST(XmlActionExecutorTest, BuildsAccessibleNestedPattern) { - XmlActionExecutor executor; - XmlNodeAction& manifestAction = executor["manifest"]; - XmlNodeAction& applicationAction = manifestAction["application"]; - - Element* manifestEl = nullptr; - manifestAction.action([&](Element* manifest) -> bool { - manifestEl = manifest; - return true; - }); - - Element* applicationEl = nullptr; - applicationAction.action([&](Element* application) -> bool { - applicationEl = application; - return true; - }); - - std::unique_ptr<XmlResource> doc = test::buildXmlDom("<manifest><application /></manifest>"); - - StdErrDiagnostics diag; - ASSERT_TRUE(executor.execute(XmlActionExecutorPolicy::None, &diag, doc.get())); - ASSERT_NE(nullptr, manifestEl); - EXPECT_EQ(std::string("manifest"), manifestEl->name); - - ASSERT_NE(nullptr, applicationEl); - EXPECT_EQ(std::string("application"), applicationEl->name); + XmlActionExecutor executor; + XmlNodeAction& manifest_action = executor["manifest"]; + XmlNodeAction& application_action = manifest_action["application"]; + + Element* manifest_el = nullptr; + manifest_action.Action([&](Element* manifest) -> bool { + manifest_el = manifest; + return true; + }); + + Element* application_el = nullptr; + application_action.Action([&](Element* application) -> bool { + application_el = application; + return true; + }); + + std::unique_ptr<XmlResource> doc = + test::BuildXmlDom("<manifest><application /></manifest>"); + + StdErrDiagnostics diag; + ASSERT_TRUE( + executor.Execute(XmlActionExecutorPolicy::kNone, &diag, doc.get())); + ASSERT_NE(nullptr, manifest_el); + EXPECT_EQ(std::string("manifest"), manifest_el->name); + + ASSERT_NE(nullptr, application_el); + EXPECT_EQ(std::string("application"), application_el->name); } TEST(XmlActionExecutorTest, FailsWhenUndefinedHierarchyExists) { - XmlActionExecutor executor; - executor["manifest"]["application"]; + XmlActionExecutor executor; + executor["manifest"]["application"]; - std::unique_ptr<XmlResource> doc = test::buildXmlDom( - "<manifest><application /><activity /></manifest>"); - StdErrDiagnostics diag; - ASSERT_FALSE(executor.execute(XmlActionExecutorPolicy::Whitelist, &diag, doc.get())); + std::unique_ptr<XmlResource> doc = + test::BuildXmlDom("<manifest><application /><activity /></manifest>"); + StdErrDiagnostics diag; + ASSERT_FALSE( + executor.Execute(XmlActionExecutorPolicy::kWhitelist, &diag, doc.get())); } -} // namespace xml -} // namespace aapt +} // namespace xml +} // namespace aapt diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp index 28de78a400f9..567418edf56b 100644 --- a/tools/aapt2/xml/XmlDom.cpp +++ b/tools/aapt2/xml/XmlDom.cpp @@ -15,475 +15,496 @@ */ #include "XmlDom.h" -#include "XmlPullParser.h" -#include "util/Util.h" -#include <cassert> #include <expat.h> + +#include <cassert> #include <memory> #include <stack> #include <string> #include <tuple> +#include "android-base/logging.h" + +#include "XmlPullParser.h" +#include "util/Util.h" + namespace aapt { namespace xml { constexpr char kXmlNamespaceSep = 1; struct Stack { - std::unique_ptr<xml::Node> root; - std::stack<xml::Node*> nodeStack; - std::string pendingComment; + std::unique_ptr<xml::Node> root; + std::stack<xml::Node*> node_stack; + std::string pending_comment; }; /** * Extracts the namespace and name of an expanded element or attribute name. */ -static void splitName(const char* name, std::string* outNs, std::string* outName) { - const char* p = name; - while (*p != 0 && *p != kXmlNamespaceSep) { - p++; - } - - if (*p == 0) { - outNs->clear(); - *outName = StringPiece(name).toString(); - } else { - *outNs = StringPiece(name, (p - name)).toString(); - *outName = StringPiece(p + 1).toString(); - } +static void SplitName(const char* name, std::string* out_ns, + std::string* out_name) { + const char* p = name; + while (*p != 0 && *p != kXmlNamespaceSep) { + p++; + } + + if (*p == 0) { + out_ns->clear(); + *out_name = StringPiece(name).ToString(); + } else { + *out_ns = StringPiece(name, (p - name)).ToString(); + *out_name = StringPiece(p + 1).ToString(); + } } -static void addToStack(Stack* stack, XML_Parser parser, std::unique_ptr<Node> node) { - node->lineNumber = XML_GetCurrentLineNumber(parser); - node->columnNumber = XML_GetCurrentColumnNumber(parser); - - Node* thisNode = node.get(); - if (!stack->nodeStack.empty()) { - stack->nodeStack.top()->addChild(std::move(node)); - } else { - stack->root = std::move(node); - } - - if (!nodeCast<Text>(thisNode)) { - stack->nodeStack.push(thisNode); - } +static void AddToStack(Stack* stack, XML_Parser parser, + std::unique_ptr<Node> node) { + node->line_number = XML_GetCurrentLineNumber(parser); + node->column_number = XML_GetCurrentColumnNumber(parser); + + Node* this_node = node.get(); + if (!stack->node_stack.empty()) { + stack->node_stack.top()->AddChild(std::move(node)); + } else { + stack->root = std::move(node); + } + + if (!NodeCast<Text>(this_node)) { + stack->node_stack.push(this_node); + } } -static void XMLCALL startNamespaceHandler(void* userData, const char* prefix, const char* uri) { - XML_Parser parser = reinterpret_cast<XML_Parser>(userData); - Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); +static void XMLCALL StartNamespaceHandler(void* user_data, const char* prefix, + const char* uri) { + XML_Parser parser = reinterpret_cast<XML_Parser>(user_data); + Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); - std::unique_ptr<Namespace> ns = util::make_unique<Namespace>(); - if (prefix) { - ns->namespacePrefix = StringPiece(prefix).toString(); - } + std::unique_ptr<Namespace> ns = util::make_unique<Namespace>(); + if (prefix) { + ns->namespace_prefix = StringPiece(prefix).ToString(); + } - if (uri) { - ns->namespaceUri = StringPiece(uri).toString(); - } + if (uri) { + ns->namespace_uri = StringPiece(uri).ToString(); + } - addToStack(stack, parser, std::move(ns)); + AddToStack(stack, parser, std::move(ns)); } -static void XMLCALL endNamespaceHandler(void* userData, const char* prefix) { - XML_Parser parser = reinterpret_cast<XML_Parser>(userData); - Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); +static void XMLCALL EndNamespaceHandler(void* user_data, const char* prefix) { + XML_Parser parser = reinterpret_cast<XML_Parser>(user_data); + Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); - assert(!stack->nodeStack.empty()); - stack->nodeStack.pop(); + CHECK(!stack->node_stack.empty()); + stack->node_stack.pop(); } -static bool lessAttribute(const Attribute& lhs, const Attribute& rhs) { - return std::tie(lhs.namespaceUri, lhs.name, lhs.value) < - std::tie(rhs.namespaceUri, rhs.name, rhs.value); +static bool less_attribute(const Attribute& lhs, const Attribute& rhs) { + return std::tie(lhs.namespace_uri, lhs.name, lhs.value) < + std::tie(rhs.namespace_uri, rhs.name, rhs.value); } -static void XMLCALL startElementHandler(void* userData, const char* name, const char** attrs) { - XML_Parser parser = reinterpret_cast<XML_Parser>(userData); - Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); +static void XMLCALL StartElementHandler(void* user_data, const char* name, + const char** attrs) { + XML_Parser parser = reinterpret_cast<XML_Parser>(user_data); + Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); - std::unique_ptr<Element> el = util::make_unique<Element>(); - splitName(name, &el->namespaceUri, &el->name); + std::unique_ptr<Element> el = util::make_unique<Element>(); + SplitName(name, &el->namespace_uri, &el->name); - while (*attrs) { - Attribute attribute; - splitName(*attrs++, &attribute.namespaceUri, &attribute.name); - attribute.value = StringPiece(*attrs++).toString(); + while (*attrs) { + Attribute attribute; + SplitName(*attrs++, &attribute.namespace_uri, &attribute.name); + attribute.value = StringPiece(*attrs++).ToString(); - // Insert in sorted order. - auto iter = std::lower_bound(el->attributes.begin(), el->attributes.end(), attribute, - lessAttribute); - el->attributes.insert(iter, std::move(attribute)); - } + // Insert in sorted order. + auto iter = std::lower_bound(el->attributes.begin(), el->attributes.end(), + attribute, less_attribute); + el->attributes.insert(iter, std::move(attribute)); + } - el->comment = std::move(stack->pendingComment); - addToStack(stack, parser, std::move(el)); + el->comment = std::move(stack->pending_comment); + AddToStack(stack, parser, std::move(el)); } -static void XMLCALL endElementHandler(void* userData, const char* name) { - XML_Parser parser = reinterpret_cast<XML_Parser>(userData); - Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); +static void XMLCALL EndElementHandler(void* user_data, const char* name) { + XML_Parser parser = reinterpret_cast<XML_Parser>(user_data); + Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); - assert(!stack->nodeStack.empty()); - //stack->nodeStack.top()->comment = std::move(stack->pendingComment); - stack->nodeStack.pop(); + CHECK(!stack->node_stack.empty()); + // stack->nodeStack.top()->comment = std::move(stack->pendingComment); + stack->node_stack.pop(); } -static void XMLCALL characterDataHandler(void* userData, const char* s, int len) { - XML_Parser parser = reinterpret_cast<XML_Parser>(userData); - Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); - - if (!s || len <= 0) { +static void XMLCALL CharacterDataHandler(void* user_data, const char* s, + int len) { + XML_Parser parser = reinterpret_cast<XML_Parser>(user_data); + Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); + + if (!s || len <= 0) { + return; + } + + // See if we can just append the text to a previous text node. + if (!stack->node_stack.empty()) { + Node* currentParent = stack->node_stack.top(); + if (!currentParent->children.empty()) { + Node* last_child = currentParent->children.back().get(); + if (Text* text = NodeCast<Text>(last_child)) { + text->text += StringPiece(s, len).ToString(); return; + } } + } - // See if we can just append the text to a previous text node. - if (!stack->nodeStack.empty()) { - Node* currentParent = stack->nodeStack.top(); - if (!currentParent->children.empty()) { - Node* lastChild = currentParent->children.back().get(); - if (Text* text = nodeCast<Text>(lastChild)) { - text->text += StringPiece(s, len).toString(); - return; - } - } - } - - std::unique_ptr<Text> text = util::make_unique<Text>(); - text->text = StringPiece(s, len).toString(); - addToStack(stack, parser, std::move(text)); + std::unique_ptr<Text> text = util::make_unique<Text>(); + text->text = StringPiece(s, len).ToString(); + AddToStack(stack, parser, std::move(text)); } -static void XMLCALL commentDataHandler(void* userData, const char* comment) { - XML_Parser parser = reinterpret_cast<XML_Parser>(userData); - Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); +static void XMLCALL CommentDataHandler(void* user_data, const char* comment) { + XML_Parser parser = reinterpret_cast<XML_Parser>(user_data); + Stack* stack = reinterpret_cast<Stack*>(XML_GetUserData(parser)); - if (!stack->pendingComment.empty()) { - stack->pendingComment += '\n'; - } - stack->pendingComment += comment; + if (!stack->pending_comment.empty()) { + stack->pending_comment += '\n'; + } + stack->pending_comment += comment; } -std::unique_ptr<XmlResource> inflate(std::istream* in, IDiagnostics* diag, const Source& source) { - Stack stack; - - XML_Parser parser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep); - XML_SetUserData(parser, &stack); - XML_UseParserAsHandlerArg(parser); - XML_SetElementHandler(parser, startElementHandler, endElementHandler); - XML_SetNamespaceDeclHandler(parser, startNamespaceHandler, endNamespaceHandler); - XML_SetCharacterDataHandler(parser, characterDataHandler); - XML_SetCommentHandler(parser, commentDataHandler); - - char buffer[1024]; - while (!in->eof()) { - in->read(buffer, sizeof(buffer) / sizeof(buffer[0])); - if (in->bad() && !in->eof()) { - stack.root = {}; - diag->error(DiagMessage(source) << strerror(errno)); - break; - } - - if (XML_Parse(parser, buffer, in->gcount(), in->eof()) == XML_STATUS_ERROR) { - stack.root = {}; - diag->error(DiagMessage(source.withLine(XML_GetCurrentLineNumber(parser))) - << XML_ErrorString(XML_GetErrorCode(parser))); - break; - } +std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag, + const Source& source) { + Stack stack; + + XML_Parser parser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep); + XML_SetUserData(parser, &stack); + XML_UseParserAsHandlerArg(parser); + XML_SetElementHandler(parser, StartElementHandler, EndElementHandler); + XML_SetNamespaceDeclHandler(parser, StartNamespaceHandler, + EndNamespaceHandler); + XML_SetCharacterDataHandler(parser, CharacterDataHandler); + XML_SetCommentHandler(parser, CommentDataHandler); + + char buffer[1024]; + while (!in->eof()) { + in->read(buffer, sizeof(buffer) / sizeof(buffer[0])); + if (in->bad() && !in->eof()) { + stack.root = {}; + diag->Error(DiagMessage(source) << strerror(errno)); + break; } - XML_ParserFree(parser); - if (stack.root) { - return util::make_unique<XmlResource>(ResourceFile{ {}, {}, source }, std::move(stack.root)); + if (XML_Parse(parser, buffer, in->gcount(), in->eof()) == + XML_STATUS_ERROR) { + stack.root = {}; + diag->Error(DiagMessage(source.WithLine(XML_GetCurrentLineNumber(parser))) + << XML_ErrorString(XML_GetErrorCode(parser))); + break; } - return {}; + } + + XML_ParserFree(parser); + if (stack.root) { + return util::make_unique<XmlResource>(ResourceFile{{}, {}, source}, + std::move(stack.root)); + } + return {}; } -static void copyAttributes(Element* el, android::ResXMLParser* parser) { - const size_t attrCount = parser->getAttributeCount(); - if (attrCount > 0) { - el->attributes.reserve(attrCount); - for (size_t i = 0; i < attrCount; i++) { - Attribute attr; - size_t len; - const char16_t* str16 = parser->getAttributeNamespace(i, &len); - if (str16) { - attr.namespaceUri = util::utf16ToUtf8(StringPiece16(str16, len)); - } - - str16 = parser->getAttributeName(i, &len); - if (str16) { - attr.name = util::utf16ToUtf8(StringPiece16(str16, len)); - } - - str16 = parser->getAttributeStringValue(i, &len); - if (str16) { - attr.value = util::utf16ToUtf8(StringPiece16(str16, len)); - } - el->attributes.push_back(std::move(attr)); - } +static void CopyAttributes(Element* el, android::ResXMLParser* parser) { + const size_t attr_count = parser->getAttributeCount(); + if (attr_count > 0) { + el->attributes.reserve(attr_count); + for (size_t i = 0; i < attr_count; i++) { + Attribute attr; + size_t len; + const char16_t* str16 = parser->getAttributeNamespace(i, &len); + if (str16) { + attr.namespace_uri = util::Utf16ToUtf8(StringPiece16(str16, len)); + } + + str16 = parser->getAttributeName(i, &len); + if (str16) { + attr.name = util::Utf16ToUtf8(StringPiece16(str16, len)); + } + + str16 = parser->getAttributeStringValue(i, &len); + if (str16) { + attr.value = util::Utf16ToUtf8(StringPiece16(str16, len)); + } + el->attributes.push_back(std::move(attr)); } + } } -std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag, - const Source& source) { - // We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which - // causes errors when qualifying it with android:: - using namespace android; +std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len, + IDiagnostics* diag, const Source& source) { + // We import the android namespace because on Windows NO_ERROR is a macro, not + // an enum, which + // causes errors when qualifying it with android:: + using namespace android; - std::unique_ptr<Node> root; - std::stack<Node*> nodeStack; + std::unique_ptr<Node> root; + std::stack<Node*> node_stack; - ResXMLTree tree; - if (tree.setTo(data, dataLen) != NO_ERROR) { - return {}; - } + ResXMLTree tree; + if (tree.setTo(data, data_len) != NO_ERROR) { + return {}; + } + + ResXMLParser::event_code_t code; + while ((code = tree.next()) != ResXMLParser::BAD_DOCUMENT && + code != ResXMLParser::END_DOCUMENT) { + std::unique_ptr<Node> new_node; + switch (code) { + case ResXMLParser::START_NAMESPACE: { + std::unique_ptr<Namespace> node = util::make_unique<Namespace>(); + size_t len; + const char16_t* str16 = tree.getNamespacePrefix(&len); + if (str16) { + node->namespace_prefix = util::Utf16ToUtf8(StringPiece16(str16, len)); + } + + str16 = tree.getNamespaceUri(&len); + if (str16) { + node->namespace_uri = util::Utf16ToUtf8(StringPiece16(str16, len)); + } + new_node = std::move(node); + break; + } + + case ResXMLParser::START_TAG: { + std::unique_ptr<Element> node = util::make_unique<Element>(); + size_t len; + const char16_t* str16 = tree.getElementNamespace(&len); + if (str16) { + node->namespace_uri = util::Utf16ToUtf8(StringPiece16(str16, len)); + } - ResXMLParser::event_code_t code; - while ((code = tree.next()) != ResXMLParser::BAD_DOCUMENT && - code != ResXMLParser::END_DOCUMENT) { - std::unique_ptr<Node> newNode; - switch (code) { - case ResXMLParser::START_NAMESPACE: { - std::unique_ptr<Namespace> node = util::make_unique<Namespace>(); - size_t len; - const char16_t* str16 = tree.getNamespacePrefix(&len); - if (str16) { - node->namespacePrefix = util::utf16ToUtf8(StringPiece16(str16, len)); - } - - str16 = tree.getNamespaceUri(&len); - if (str16) { - node->namespaceUri = util::utf16ToUtf8(StringPiece16(str16, len)); - } - newNode = std::move(node); - break; - } - - case ResXMLParser::START_TAG: { - std::unique_ptr<Element> node = util::make_unique<Element>(); - size_t len; - const char16_t* str16 = tree.getElementNamespace(&len); - if (str16) { - node->namespaceUri = util::utf16ToUtf8(StringPiece16(str16, len)); - } - - str16 = tree.getElementName(&len); - if (str16) { - node->name = util::utf16ToUtf8(StringPiece16(str16, len)); - } - - copyAttributes(node.get(), &tree); - - newNode = std::move(node); - break; - } - - case ResXMLParser::TEXT: { - std::unique_ptr<Text> node = util::make_unique<Text>(); - size_t len; - const char16_t* str16 = tree.getText(&len); - if (str16) { - node->text = util::utf16ToUtf8(StringPiece16(str16, len)); - } - newNode = std::move(node); - break; - } - - case ResXMLParser::END_NAMESPACE: - case ResXMLParser::END_TAG: - assert(!nodeStack.empty()); - nodeStack.pop(); - break; - - default: - assert(false); - break; + str16 = tree.getElementName(&len); + if (str16) { + node->name = util::Utf16ToUtf8(StringPiece16(str16, len)); } - if (newNode) { - newNode->lineNumber = tree.getLineNumber(); - - Node* thisNode = newNode.get(); - if (!root) { - assert(nodeStack.empty()); - root = std::move(newNode); - } else { - assert(!nodeStack.empty()); - nodeStack.top()->addChild(std::move(newNode)); - } - - if (!nodeCast<Text>(thisNode)) { - nodeStack.push(thisNode); - } + CopyAttributes(node.get(), &tree); + + new_node = std::move(node); + break; + } + + case ResXMLParser::TEXT: { + std::unique_ptr<Text> node = util::make_unique<Text>(); + size_t len; + const char16_t* str16 = tree.getText(&len); + if (str16) { + node->text = util::Utf16ToUtf8(StringPiece16(str16, len)); } + new_node = std::move(node); + break; + } + + case ResXMLParser::END_NAMESPACE: + case ResXMLParser::END_TAG: + CHECK(!node_stack.empty()); + node_stack.pop(); + break; + + default: + LOG(FATAL) << "unhandled XML chunk type"; + break; } - return util::make_unique<XmlResource>(ResourceFile{}, std::move(root)); -} -std::unique_ptr<Node> Namespace::clone() { - auto ns = util::make_unique<Namespace>(); - ns->comment = comment; - ns->lineNumber = lineNumber; - ns->columnNumber = columnNumber; - ns->namespacePrefix = namespacePrefix; - ns->namespaceUri = namespaceUri; - - ns->children.reserve(children.size()); - for (const std::unique_ptr<xml::Node>& child : children) { - ns->addChild(child->clone()); + if (new_node) { + new_node->line_number = tree.getLineNumber(); + + Node* this_node = new_node.get(); + if (!root) { + CHECK(node_stack.empty()) << "node stack should be empty"; + root = std::move(new_node); + } else { + CHECK(!node_stack.empty()) << "node stack should not be empty"; + node_stack.top()->AddChild(std::move(new_node)); + } + + if (!NodeCast<Text>(this_node)) { + node_stack.push(this_node); + } } - return std::move(ns); + } + return util::make_unique<XmlResource>(ResourceFile{}, std::move(root)); } -Element* findRootElement(XmlResource* doc) { - return findRootElement(doc->root.get()); +std::unique_ptr<Node> Namespace::Clone() { + auto ns = util::make_unique<Namespace>(); + ns->comment = comment; + ns->line_number = line_number; + ns->column_number = column_number; + ns->namespace_prefix = namespace_prefix; + ns->namespace_uri = namespace_uri; + + ns->children.reserve(children.size()); + for (const std::unique_ptr<xml::Node>& child : children) { + ns->AddChild(child->Clone()); + } + return std::move(ns); } -Element* findRootElement(Node* node) { - if (!node) { - return nullptr; - } +Element* FindRootElement(XmlResource* doc) { + return FindRootElement(doc->root.get()); +} - Element* el = nullptr; - while ((el = nodeCast<Element>(node)) == nullptr) { - if (node->children.empty()) { - return nullptr; - } - // We are looking for the first element, and namespaces can only have one child. - node = node->children.front().get(); +Element* FindRootElement(Node* node) { + if (!node) { + return nullptr; + } + + Element* el = nullptr; + while ((el = NodeCast<Element>(node)) == nullptr) { + if (node->children.empty()) { + return nullptr; } - return el; + // We are looking for the first element, and namespaces can only have one + // child. + node = node->children.front().get(); + } + return el; } -void Node::addChild(std::unique_ptr<Node> child) { - child->parent = this; - children.push_back(std::move(child)); +void Node::AddChild(std::unique_ptr<Node> child) { + child->parent = this; + children.push_back(std::move(child)); } -Attribute* Element::findAttribute(const StringPiece& ns, const StringPiece& name) { - for (auto& attr : attributes) { - if (ns == attr.namespaceUri && name == attr.name) { - return &attr; - } +Attribute* Element::FindAttribute(const StringPiece& ns, + const StringPiece& name) { + for (auto& attr : attributes) { + if (ns == attr.namespace_uri && name == attr.name) { + return &attr; } - return nullptr; + } + return nullptr; } -Element* Element::findChild(const StringPiece& ns, const StringPiece& name) { - return findChildWithAttribute(ns, name, {}, {}, {}); +Element* Element::FindChild(const StringPiece& ns, const StringPiece& name) { + return FindChildWithAttribute(ns, name, {}, {}, {}); } -Element* Element::findChildWithAttribute(const StringPiece& ns, const StringPiece& name, - const StringPiece& attrNs, const StringPiece& attrName, - const StringPiece& attrValue) { - for (auto& childNode : children) { - Node* child = childNode.get(); - while (nodeCast<Namespace>(child)) { - if (child->children.empty()) { - break; - } - child = child->children[0].get(); - } - - if (Element* el = nodeCast<Element>(child)) { - if (ns == el->namespaceUri && name == el->name) { - if (attrNs.empty() && attrName.empty()) { - return el; - } - - Attribute* attr = el->findAttribute(attrNs, attrName); - if (attr && attrValue == attr->value) { - return el; - } - } - } +Element* Element::FindChildWithAttribute(const StringPiece& ns, + const StringPiece& name, + const StringPiece& attr_ns, + const StringPiece& attr_name, + const StringPiece& attr_value) { + for (auto& child_node : children) { + Node* child = child_node.get(); + while (NodeCast<Namespace>(child)) { + if (child->children.empty()) { + break; + } + child = child->children[0].get(); } - return nullptr; -} -std::vector<Element*> Element::getChildElements() { - std::vector<Element*> elements; - for (auto& childNode : children) { - Node* child = childNode.get(); - while (nodeCast<Namespace>(child)) { - if (child->children.empty()) { - break; - } - child = child->children[0].get(); + if (Element* el = NodeCast<Element>(child)) { + if (ns == el->namespace_uri && name == el->name) { + if (attr_ns.empty() && attr_name.empty()) { + return el; } - if (Element* el = nodeCast<Element>(child)) { - elements.push_back(el); + Attribute* attr = el->FindAttribute(attr_ns, attr_name); + if (attr && attr_value == attr->value) { + return el; } + } } - return elements; + } + return nullptr; } -std::unique_ptr<Node> Element::clone() { - auto el = util::make_unique<Element>(); - el->comment = comment; - el->lineNumber = lineNumber; - el->columnNumber = columnNumber; - el->name = name; - el->namespaceUri = namespaceUri; - - el->attributes.reserve(attributes.size()); - for (xml::Attribute& attr : attributes) { - // Don't copy compiled values or attributes. - el->attributes.push_back(xml::Attribute{ attr.namespaceUri, attr.name, attr.value }); +std::vector<Element*> Element::GetChildElements() { + std::vector<Element*> elements; + for (auto& child_node : children) { + Node* child = child_node.get(); + while (NodeCast<Namespace>(child)) { + if (child->children.empty()) { + break; + } + child = child->children[0].get(); } - el->children.reserve(children.size()); - for (const std::unique_ptr<xml::Node>& child : children) { - el->addChild(child->clone()); + if (Element* el = NodeCast<Element>(child)) { + elements.push_back(el); } - return std::move(el); + } + return elements; } -std::unique_ptr<Node> Text::clone() { - auto t = util::make_unique<Text>(); - t->comment = comment; - t->lineNumber = lineNumber; - t->columnNumber = columnNumber; - t->text = text; - return std::move(t); +std::unique_ptr<Node> Element::Clone() { + auto el = util::make_unique<Element>(); + el->comment = comment; + el->line_number = line_number; + el->column_number = column_number; + el->name = name; + el->namespace_uri = namespace_uri; + + el->attributes.reserve(attributes.size()); + for (xml::Attribute& attr : attributes) { + // Don't copy compiled values or attributes. + el->attributes.push_back( + xml::Attribute{attr.namespace_uri, attr.name, attr.value}); + } + + el->children.reserve(children.size()); + for (const std::unique_ptr<xml::Node>& child : children) { + el->AddChild(child->Clone()); + } + return std::move(el); } -void PackageAwareVisitor::visit(Namespace* ns) { - bool added = false; - if (Maybe<ExtractedPackage> maybePackage = extractPackageFromNamespace(ns->namespaceUri)) { - ExtractedPackage& package = maybePackage.value(); - mPackageDecls.push_back(PackageDecl{ ns->namespacePrefix, std::move(package) }); - added = true; - } - - Visitor::visit(ns); +std::unique_ptr<Node> Text::Clone() { + auto t = util::make_unique<Text>(); + t->comment = comment; + t->line_number = line_number; + t->column_number = column_number; + t->text = text; + return std::move(t); +} - if (added) { - mPackageDecls.pop_back(); - } +void PackageAwareVisitor::Visit(Namespace* ns) { + bool added = false; + if (Maybe<ExtractedPackage> maybe_package = + ExtractPackageFromNamespace(ns->namespace_uri)) { + ExtractedPackage& package = maybe_package.value(); + package_decls_.push_back( + PackageDecl{ns->namespace_prefix, std::move(package)}); + added = true; + } + + Visitor::Visit(ns); + + if (added) { + package_decls_.pop_back(); + } } -Maybe<ExtractedPackage> PackageAwareVisitor::transformPackageAlias( - const StringPiece& alias, const StringPiece& localPackage) const { - if (alias.empty()) { - return ExtractedPackage{ localPackage.toString(), false /* private */ }; - } - - const auto rend = mPackageDecls.rend(); - for (auto iter = mPackageDecls.rbegin(); iter != rend; ++iter) { - if (alias == iter->prefix) { - if (iter->package.package.empty()) { - return ExtractedPackage{ localPackage.toString(), - iter->package.privateNamespace }; - } - return iter->package; - } - } - return {}; +Maybe<ExtractedPackage> PackageAwareVisitor::TransformPackageAlias( + const StringPiece& alias, const StringPiece& local_package) const { + if (alias.empty()) { + return ExtractedPackage{local_package.ToString(), false /* private */}; + } + + const auto rend = package_decls_.rend(); + for (auto iter = package_decls_.rbegin(); iter != rend; ++iter) { + if (alias == iter->prefix) { + if (iter->package.package.empty()) { + return ExtractedPackage{local_package.ToString(), + iter->package.private_namespace}; + } + return iter->package; + } + } + return {}; } -} // namespace xml -} // namespace aapt +} // namespace xml +} // namespace aapt diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h index 932303edf41a..e771d8735ac0 100644 --- a/tools/aapt2/xml/XmlDom.h +++ b/tools/aapt2/xml/XmlDom.h @@ -17,6 +17,11 @@ #ifndef AAPT_XML_DOM_H #define AAPT_XML_DOM_H +#include <istream> +#include <memory> +#include <string> +#include <vector> + #include "Diagnostics.h" #include "Resource.h" #include "ResourceValues.h" @@ -24,11 +29,6 @@ #include "util/Util.h" #include "xml/XmlUtil.h" -#include <istream> -#include <memory> -#include <string> -#include <vector> - namespace aapt { namespace xml { @@ -40,16 +40,16 @@ class RawVisitor; class Node { public: Node* parent = nullptr; - size_t lineNumber = 0; - size_t columnNumber = 0; + size_t line_number = 0; + size_t column_number = 0; std::string comment; std::vector<std::unique_ptr<Node>> children; virtual ~Node() = default; - void addChild(std::unique_ptr<Node> child); - virtual void accept(RawVisitor* visitor) = 0; - virtual std::unique_ptr<Node> clone() = 0; + void AddChild(std::unique_ptr<Node> child); + virtual void Accept(RawVisitor* visitor) = 0; + virtual std::unique_ptr<Node> Clone() = 0; }; /** @@ -59,7 +59,7 @@ class Node { template <typename Derived> class BaseNode : public Node { public: - virtual void accept(RawVisitor* visitor) override; + virtual void Accept(RawVisitor* visitor) override; }; /** @@ -67,10 +67,10 @@ class BaseNode : public Node { */ class Namespace : public BaseNode<Namespace> { public: - std::string namespacePrefix; - std::string namespaceUri; + std::string namespace_prefix; + std::string namespace_uri; - std::unique_ptr<Node> clone() override; + std::unique_ptr<Node> Clone() override; }; struct AaptAttribute { @@ -82,12 +82,12 @@ struct AaptAttribute { * An XML attribute. */ struct Attribute { - std::string namespaceUri; + std::string namespace_uri; std::string name; std::string value; - Maybe<AaptAttribute> compiledAttribute; - std::unique_ptr<Item> compiledValue; + Maybe<AaptAttribute> compiled_attribute; + std::unique_ptr<Item> compiled_value; }; /** @@ -95,19 +95,19 @@ struct Attribute { */ class Element : public BaseNode<Element> { public: - std::string namespaceUri; + std::string namespace_uri; std::string name; std::vector<Attribute> attributes; - Attribute* findAttribute(const StringPiece& ns, const StringPiece& name); - xml::Element* findChild(const StringPiece& ns, const StringPiece& name); - xml::Element* findChildWithAttribute(const StringPiece& ns, + Attribute* FindAttribute(const StringPiece& ns, const StringPiece& name); + xml::Element* FindChild(const StringPiece& ns, const StringPiece& name); + xml::Element* FindChildWithAttribute(const StringPiece& ns, const StringPiece& name, - const StringPiece& attrNs, - const StringPiece& attrName, - const StringPiece& attrValue); - std::vector<xml::Element*> getChildElements(); - std::unique_ptr<Node> clone() override; + const StringPiece& attr_ns, + const StringPiece& attr_name, + const StringPiece& attr_value); + std::vector<xml::Element*> GetChildElements(); + std::unique_ptr<Node> Clone() override; }; /** @@ -117,7 +117,7 @@ class Text : public BaseNode<Text> { public: std::string text; - std::unique_ptr<Node> clone() override; + std::unique_ptr<Node> Clone() override; }; /** @@ -133,18 +133,18 @@ class XmlResource { * Inflates an XML DOM from a text stream, logging errors to the logger. * Returns the root node on success, or nullptr on failure. */ -std::unique_ptr<XmlResource> inflate(std::istream* in, IDiagnostics* diag, +std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag, const Source& source); /** * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger. * Returns the root node on success, or nullptr on failure. */ -std::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, +std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len, IDiagnostics* diag, const Source& source); -Element* findRootElement(XmlResource* doc); -Element* findRootElement(Node* node); +Element* FindRootElement(XmlResource* doc); +Element* FindRootElement(Node* node); /** * A visitor interface for the different XML Node subtypes. This will not @@ -155,9 +155,9 @@ class RawVisitor { public: virtual ~RawVisitor() = default; - virtual void visit(Namespace* node) {} - virtual void visit(Element* node) {} - virtual void visit(Text* text) {} + virtual void Visit(Namespace* node) {} + virtual void Visit(Element* node) {} + virtual void Visit(Text* text) {} }; /** @@ -165,17 +165,17 @@ class RawVisitor { */ class Visitor : public RawVisitor { public: - using RawVisitor::visit; + using RawVisitor::Visit; - void visit(Namespace* node) override { visitChildren(node); } + void Visit(Namespace* node) override { VisitChildren(node); } - void visit(Element* node) override { visitChildren(node); } + void Visit(Element* node) override { VisitChildren(node); } - void visit(Text* text) override { visitChildren(text); } + void Visit(Text* text) override { VisitChildren(text); } - void visitChildren(Node* node) { + void VisitChildren(Node* node) { for (auto& child : node->children) { - child->accept(this); + child->Accept(this); } } }; @@ -185,11 +185,12 @@ class Visitor : public RawVisitor { */ class PackageAwareVisitor : public Visitor, public IPackageDeclStack { public: - using Visitor::visit; + using Visitor::Visit; - void visit(Namespace* ns) override; - Maybe<ExtractedPackage> transformPackageAlias( - const StringPiece& alias, const StringPiece& localPackage) const override; + void Visit(Namespace* ns) override; + Maybe<ExtractedPackage> TransformPackageAlias( + const StringPiece& alias, + const StringPiece& local_package) const override; private: struct PackageDecl { @@ -197,30 +198,30 @@ class PackageAwareVisitor : public Visitor, public IPackageDeclStack { ExtractedPackage package; }; - std::vector<PackageDecl> mPackageDecls; + std::vector<PackageDecl> package_decls_; }; // Implementations template <typename Derived> -void BaseNode<Derived>::accept(RawVisitor* visitor) { - visitor->visit(static_cast<Derived*>(this)); +void BaseNode<Derived>::Accept(RawVisitor* visitor) { + visitor->Visit(static_cast<Derived*>(this)); } template <typename T> class NodeCastImpl : public RawVisitor { public: - using RawVisitor::visit; + using RawVisitor::Visit; T* value = nullptr; - void visit(T* v) override { value = v; } + void Visit(T* v) override { value = v; } }; template <typename T> -T* nodeCast(Node* node) { +T* NodeCast(Node* node) { NodeCastImpl<T> visitor; - node->accept(&visitor); + node->Accept(&visitor); return visitor.value; } diff --git a/tools/aapt2/xml/XmlDom_test.cpp b/tools/aapt2/xml/XmlDom_test.cpp index 1909f75ad0c3..a414afe92fc0 100644 --- a/tools/aapt2/xml/XmlDom_test.cpp +++ b/tools/aapt2/xml/XmlDom_test.cpp @@ -16,17 +16,19 @@ #include "xml/XmlDom.h" -#include <gtest/gtest.h> #include <sstream> #include <string> +#include "test/Test.h" + namespace aapt { -constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; +constexpr const char* kXmlPreamble = + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; TEST(XmlDomTest, Inflate) { - std::stringstream in(kXmlPreamble); - in << R"EOF( + std::stringstream in(kXmlPreamble); + in << R"EOF( <Layout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> @@ -36,15 +38,15 @@ TEST(XmlDomTest, Inflate) { </Layout> )EOF"; - const Source source = { "test.xml" }; - StdErrDiagnostics diag; - std::unique_ptr<xml::XmlResource> doc = xml::inflate(&in, &diag, source); - ASSERT_NE(doc, nullptr); + const Source source = {"test.xml"}; + StdErrDiagnostics diag; + std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, &diag, source); + ASSERT_NE(doc, nullptr); - xml::Namespace* ns = xml::nodeCast<xml::Namespace>(doc->root.get()); - ASSERT_NE(ns, nullptr); - EXPECT_EQ(ns->namespaceUri, xml::kSchemaAndroid); - EXPECT_EQ(ns->namespacePrefix, "android"); + xml::Namespace* ns = xml::NodeCast<xml::Namespace>(doc->root.get()); + ASSERT_NE(ns, nullptr); + EXPECT_EQ(ns->namespace_uri, xml::kSchemaAndroid); + EXPECT_EQ(ns->namespace_prefix, "android"); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/xml/XmlPullParser.cpp b/tools/aapt2/xml/XmlPullParser.cpp index 4a944f1b1e48..e59fa86788cd 100644 --- a/tools/aapt2/xml/XmlPullParser.cpp +++ b/tools/aapt2/xml/XmlPullParser.cpp @@ -14,295 +14,295 @@ * limitations under the License. */ +#include <iostream> +#include <string> + #include "util/Maybe.h" #include "util/Util.h" #include "xml/XmlPullParser.h" #include "xml/XmlUtil.h" -#include <iostream> -#include <string> - namespace aapt { namespace xml { constexpr char kXmlNamespaceSep = 1; -XmlPullParser::XmlPullParser(std::istream& in) : mIn(in), mEmpty(), mDepth(0) { - mParser = XML_ParserCreateNS(nullptr, kXmlNamespaceSep); - XML_SetUserData(mParser, this); - XML_SetElementHandler(mParser, startElementHandler, endElementHandler); - XML_SetNamespaceDeclHandler(mParser, startNamespaceHandler, endNamespaceHandler); - XML_SetCharacterDataHandler(mParser, characterDataHandler); - XML_SetCommentHandler(mParser, commentDataHandler); - mEventQueue.push(EventData{ Event::kStartDocument, 0, mDepth++ }); +XmlPullParser::XmlPullParser(std::istream& in) : in_(in), empty_(), depth_(0) { + parser_ = XML_ParserCreateNS(nullptr, kXmlNamespaceSep); + XML_SetUserData(parser_, this); + XML_SetElementHandler(parser_, StartElementHandler, EndElementHandler); + XML_SetNamespaceDeclHandler(parser_, StartNamespaceHandler, + EndNamespaceHandler); + XML_SetCharacterDataHandler(parser_, CharacterDataHandler); + XML_SetCommentHandler(parser_, CommentDataHandler); + event_queue_.push(EventData{Event::kStartDocument, 0, depth_++}); } -XmlPullParser::~XmlPullParser() { - XML_ParserFree(mParser); -} +XmlPullParser::~XmlPullParser() { XML_ParserFree(parser_); } + +XmlPullParser::Event XmlPullParser::Next() { + const Event currentEvent = event(); + if (currentEvent == Event::kBadDocument || + currentEvent == Event::kEndDocument) { + return currentEvent; + } -XmlPullParser::Event XmlPullParser::next() { - const Event currentEvent = getEvent(); - if (currentEvent == Event::kBadDocument || currentEvent == Event::kEndDocument) { - return currentEvent; + event_queue_.pop(); + while (event_queue_.empty()) { + in_.read(buffer_, sizeof(buffer_) / sizeof(*buffer_)); + + const bool done = in_.eof(); + if (in_.bad() && !done) { + error_ = strerror(errno); + event_queue_.push(EventData{Event::kBadDocument}); + continue; } - mEventQueue.pop(); - while (mEventQueue.empty()) { - mIn.read(mBuffer, sizeof(mBuffer) / sizeof(*mBuffer)); - - const bool done = mIn.eof(); - if (mIn.bad() && !done) { - mLastError = strerror(errno); - mEventQueue.push(EventData{ Event::kBadDocument }); - continue; - } - - if (XML_Parse(mParser, mBuffer, mIn.gcount(), done) == XML_STATUS_ERROR) { - mLastError = XML_ErrorString(XML_GetErrorCode(mParser)); - mEventQueue.push(EventData{ Event::kBadDocument }); - continue; - } - - if (done) { - mEventQueue.push(EventData{ Event::kEndDocument, 0, 0 }); - } + if (XML_Parse(parser_, buffer_, in_.gcount(), done) == XML_STATUS_ERROR) { + error_ = XML_ErrorString(XML_GetErrorCode(parser_)); + event_queue_.push(EventData{Event::kBadDocument}); + continue; } - Event event = getEvent(); - - // Record namespace prefixes and package names so that we can do our own - // handling of references that use namespace aliases. - if (event == Event::kStartNamespace || event == Event::kEndNamespace) { - Maybe<ExtractedPackage> result = extractPackageFromNamespace(getNamespaceUri()); - if (event == Event::kStartNamespace) { - if (result) { - mPackageAliases.emplace_back( - PackageDecl{ getNamespacePrefix(), std::move(result.value()) }); - } - } else { - if (result) { - mPackageAliases.pop_back(); - } - } + if (done) { + event_queue_.push(EventData{Event::kEndDocument, 0, 0}); + } + } + + Event next_event = event(); + + // Record namespace prefixes and package names so that we can do our own + // handling of references that use namespace aliases. + if (next_event == Event::kStartNamespace || + next_event == Event::kEndNamespace) { + Maybe<ExtractedPackage> result = + ExtractPackageFromNamespace(namespace_uri()); + if (next_event == Event::kStartNamespace) { + if (result) { + package_aliases_.emplace_back( + PackageDecl{namespace_prefix(), std::move(result.value())}); + } + } else { + if (result) { + package_aliases_.pop_back(); + } } + } - return event; + return next_event; } -XmlPullParser::Event XmlPullParser::getEvent() const { - return mEventQueue.front().event; +XmlPullParser::Event XmlPullParser::event() const { + return event_queue_.front().event; } -const std::string& XmlPullParser::getLastError() const { - return mLastError; -} +const std::string& XmlPullParser::error() const { return error_; } -const std::string& XmlPullParser::getComment() const { - return mEventQueue.front().data1; +const std::string& XmlPullParser::comment() const { + return event_queue_.front().data1; } -size_t XmlPullParser::getLineNumber() const { - return mEventQueue.front().lineNumber; +size_t XmlPullParser::line_number() const { + return event_queue_.front().line_number; } -size_t XmlPullParser::getDepth() const { - return mEventQueue.front().depth; -} +size_t XmlPullParser::depth() const { return event_queue_.front().depth; } -const std::string& XmlPullParser::getText() const { - if (getEvent() != Event::kText) { - return mEmpty; - } - return mEventQueue.front().data1; +const std::string& XmlPullParser::text() const { + if (event() != Event::kText) { + return empty_; + } + return event_queue_.front().data1; } -const std::string& XmlPullParser::getNamespacePrefix() const { - const Event currentEvent = getEvent(); - if (currentEvent != Event::kStartNamespace && currentEvent != Event::kEndNamespace) { - return mEmpty; - } - return mEventQueue.front().data1; +const std::string& XmlPullParser::namespace_prefix() const { + const Event current_event = event(); + if (current_event != Event::kStartNamespace && + current_event != Event::kEndNamespace) { + return empty_; + } + return event_queue_.front().data1; } -const std::string& XmlPullParser::getNamespaceUri() const { - const Event currentEvent = getEvent(); - if (currentEvent != Event::kStartNamespace && currentEvent != Event::kEndNamespace) { - return mEmpty; - } - return mEventQueue.front().data2; +const std::string& XmlPullParser::namespace_uri() const { + const Event current_event = event(); + if (current_event != Event::kStartNamespace && + current_event != Event::kEndNamespace) { + return empty_; + } + return event_queue_.front().data2; } -Maybe<ExtractedPackage> XmlPullParser::transformPackageAlias( - const StringPiece& alias, const StringPiece& localPackage) const { - if (alias.empty()) { - return ExtractedPackage{ localPackage.toString(), false /* private */ }; +Maybe<ExtractedPackage> XmlPullParser::TransformPackageAlias( + const StringPiece& alias, const StringPiece& local_package) const { + if (alias.empty()) { + return ExtractedPackage{local_package.ToString(), false /* private */}; + } + + const auto end_iter = package_aliases_.rend(); + for (auto iter = package_aliases_.rbegin(); iter != end_iter; ++iter) { + if (alias == iter->prefix) { + if (iter->package.package.empty()) { + return ExtractedPackage{local_package.ToString(), + iter->package.private_namespace}; + } + return iter->package; } - - const auto endIter = mPackageAliases.rend(); - for (auto iter = mPackageAliases.rbegin(); iter != endIter; ++iter) { - if (alias == iter->prefix) { - if (iter->package.package.empty()) { - return ExtractedPackage{ localPackage.toString(), - iter->package.privateNamespace }; - } - return iter->package; - } - } - return {}; + } + return {}; } -const std::string& XmlPullParser::getElementNamespace() const { - const Event currentEvent = getEvent(); - if (currentEvent != Event::kStartElement && currentEvent != Event::kEndElement) { - return mEmpty; - } - return mEventQueue.front().data1; +const std::string& XmlPullParser::element_namespace() const { + const Event current_event = event(); + if (current_event != Event::kStartElement && + current_event != Event::kEndElement) { + return empty_; + } + return event_queue_.front().data1; } -const std::string& XmlPullParser::getElementName() const { - const Event currentEvent = getEvent(); - if (currentEvent != Event::kStartElement && currentEvent != Event::kEndElement) { - return mEmpty; - } - return mEventQueue.front().data2; +const std::string& XmlPullParser::element_name() const { + const Event current_event = event(); + if (current_event != Event::kStartElement && + current_event != Event::kEndElement) { + return empty_; + } + return event_queue_.front().data2; } -XmlPullParser::const_iterator XmlPullParser::beginAttributes() const { - return mEventQueue.front().attributes.begin(); +XmlPullParser::const_iterator XmlPullParser::begin_attributes() const { + return event_queue_.front().attributes.begin(); } -XmlPullParser::const_iterator XmlPullParser::endAttributes() const { - return mEventQueue.front().attributes.end(); +XmlPullParser::const_iterator XmlPullParser::end_attributes() const { + return event_queue_.front().attributes.end(); } -size_t XmlPullParser::getAttributeCount() const { - if (getEvent() != Event::kStartElement) { - return 0; - } - return mEventQueue.front().attributes.size(); +size_t XmlPullParser::attribute_count() const { + if (event() != Event::kStartElement) { + return 0; + } + return event_queue_.front().attributes.size(); } /** * Extracts the namespace and name of an expanded element or attribute name. */ -static void splitName(const char* name, std::string& outNs, std::string& outName) { - const char* p = name; - while (*p != 0 && *p != kXmlNamespaceSep) { - p++; - } - - if (*p == 0) { - outNs = std::string(); - outName = name; - } else { - outNs = StringPiece(name, (p - name)).toString(); - outName = p + 1; - } +static void SplitName(const char* name, std::string& out_ns, + std::string& out_name) { + const char* p = name; + while (*p != 0 && *p != kXmlNamespaceSep) { + p++; + } + + if (*p == 0) { + out_ns = std::string(); + out_name = name; + } else { + out_ns = StringPiece(name, (p - name)).ToString(); + out_name = p + 1; + } } -void XMLCALL XmlPullParser::startNamespaceHandler(void* userData, const char* prefix, - const char* uri) { - XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData); - std::string namespaceUri = uri != nullptr ? uri : std::string(); - parser->mNamespaceUris.push(namespaceUri); - parser->mEventQueue.push(EventData{ - Event::kStartNamespace, - XML_GetCurrentLineNumber(parser->mParser), - parser->mDepth++, - prefix != nullptr ? prefix : std::string(), - namespaceUri - }); +void XMLCALL XmlPullParser::StartNamespaceHandler(void* user_data, + const char* prefix, + const char* uri) { + XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); + std::string namespace_uri = uri != nullptr ? uri : std::string(); + parser->namespace_uris_.push(namespace_uri); + parser->event_queue_.push( + EventData{Event::kStartNamespace, + XML_GetCurrentLineNumber(parser->parser_), parser->depth_++, + prefix != nullptr ? prefix : std::string(), namespace_uri}); } -void XMLCALL XmlPullParser::startElementHandler(void* userData, const char* name, - const char** attrs) { - XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData); - - EventData data = { - Event::kStartElement, XML_GetCurrentLineNumber(parser->mParser), parser->mDepth++ - }; - splitName(name, data.data1, data.data2); - - while (*attrs) { - Attribute attribute; - splitName(*attrs++, attribute.namespaceUri, attribute.name); - attribute.value = *attrs++; - - // Insert in sorted order. - auto iter = std::lower_bound(data.attributes.begin(), data.attributes.end(), attribute); - data.attributes.insert(iter, std::move(attribute)); - } - - // Move the structure into the queue (no copy). - parser->mEventQueue.push(std::move(data)); +void XMLCALL XmlPullParser::StartElementHandler(void* user_data, + const char* name, + const char** attrs) { + XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); + + EventData data = {Event::kStartElement, + XML_GetCurrentLineNumber(parser->parser_), + parser->depth_++}; + SplitName(name, data.data1, data.data2); + + while (*attrs) { + Attribute attribute; + SplitName(*attrs++, attribute.namespace_uri, attribute.name); + attribute.value = *attrs++; + + // Insert in sorted order. + auto iter = std::lower_bound(data.attributes.begin(), data.attributes.end(), + attribute); + data.attributes.insert(iter, std::move(attribute)); + } + + // Move the structure into the queue (no copy). + parser->event_queue_.push(std::move(data)); } -void XMLCALL XmlPullParser::characterDataHandler(void* userData, const char* s, int len) { - XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData); +void XMLCALL XmlPullParser::CharacterDataHandler(void* user_data, const char* s, + int len) { + XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); - parser->mEventQueue.push(EventData{ - Event::kText, - XML_GetCurrentLineNumber(parser->mParser), - parser->mDepth, - StringPiece(s, len).toString() - }); + parser->event_queue_.push( + EventData{Event::kText, XML_GetCurrentLineNumber(parser->parser_), + parser->depth_, StringPiece(s, len).ToString()}); } -void XMLCALL XmlPullParser::endElementHandler(void* userData, const char* name) { - XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData); +void XMLCALL XmlPullParser::EndElementHandler(void* user_data, + const char* name) { + XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); - EventData data = { - Event::kEndElement, XML_GetCurrentLineNumber(parser->mParser), --(parser->mDepth) - }; - splitName(name, data.data1, data.data2); + EventData data = {Event::kEndElement, + XML_GetCurrentLineNumber(parser->parser_), + --(parser->depth_)}; + SplitName(name, data.data1, data.data2); - // Move the data into the queue (no copy). - parser->mEventQueue.push(std::move(data)); + // Move the data into the queue (no copy). + parser->event_queue_.push(std::move(data)); } -void XMLCALL XmlPullParser::endNamespaceHandler(void* userData, const char* prefix) { - XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData); - - parser->mEventQueue.push(EventData{ - Event::kEndNamespace, - XML_GetCurrentLineNumber(parser->mParser), - --(parser->mDepth), - prefix != nullptr ? prefix : std::string(), - parser->mNamespaceUris.top() - }); - parser->mNamespaceUris.pop(); +void XMLCALL XmlPullParser::EndNamespaceHandler(void* user_data, + const char* prefix) { + XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); + + parser->event_queue_.push( + EventData{Event::kEndNamespace, XML_GetCurrentLineNumber(parser->parser_), + --(parser->depth_), prefix != nullptr ? prefix : std::string(), + parser->namespace_uris_.top()}); + parser->namespace_uris_.pop(); } -void XMLCALL XmlPullParser::commentDataHandler(void* userData, const char* comment) { - XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(userData); +void XMLCALL XmlPullParser::CommentDataHandler(void* user_data, + const char* comment) { + XmlPullParser* parser = reinterpret_cast<XmlPullParser*>(user_data); - parser->mEventQueue.push(EventData{ - Event::kComment, - XML_GetCurrentLineNumber(parser->mParser), - parser->mDepth, - comment - }); + parser->event_queue_.push(EventData{Event::kComment, + XML_GetCurrentLineNumber(parser->parser_), + parser->depth_, comment}); } -Maybe<StringPiece> findAttribute(const XmlPullParser* parser, const StringPiece& name) { - auto iter = parser->findAttribute("", name); - if (iter != parser->endAttributes()) { - return StringPiece(util::trimWhitespace(iter->value)); - } - return {}; +Maybe<StringPiece> FindAttribute(const XmlPullParser* parser, + const StringPiece& name) { + auto iter = parser->FindAttribute("", name); + if (iter != parser->end_attributes()) { + return StringPiece(util::TrimWhitespace(iter->value)); + } + return {}; } -Maybe<StringPiece> findNonEmptyAttribute(const XmlPullParser* parser, const StringPiece& name) { - auto iter = parser->findAttribute("", name); - if (iter != parser->endAttributes()) { - StringPiece trimmed = util::trimWhitespace(iter->value); - if (!trimmed.empty()) { - return trimmed; - } +Maybe<StringPiece> FindNonEmptyAttribute(const XmlPullParser* parser, + const StringPiece& name) { + auto iter = parser->FindAttribute("", name); + if (iter != parser->end_attributes()) { + StringPiece trimmed = util::TrimWhitespace(iter->value); + if (!trimmed.empty()) { + return trimmed; } - return {}; + } + return {}; } -} // namespace xml -} // namespace aapt +} // namespace xml +} // namespace aapt diff --git a/tools/aapt2/xml/XmlPullParser.h b/tools/aapt2/xml/XmlPullParser.h index ce69df669b0c..ff58d604e35e 100644 --- a/tools/aapt2/xml/XmlPullParser.h +++ b/tools/aapt2/xml/XmlPullParser.h @@ -17,13 +17,8 @@ #ifndef AAPT_XML_PULL_PARSER_H #define AAPT_XML_PULL_PARSER_H -#include "Resource.h" -#include "process/IResourceTableConsumer.h" -#include "util/Maybe.h" -#include "util/StringPiece.h" -#include "xml/XmlUtil.h" - #include <expat.h> + #include <algorithm> #include <istream> #include <ostream> @@ -32,6 +27,14 @@ #include <string> #include <vector> +#include "android-base/macros.h" + +#include "Resource.h" +#include "process/IResourceTableConsumer.h" +#include "util/Maybe.h" +#include "util/StringPiece.h" +#include "xml/XmlUtil.h" + namespace aapt { namespace xml { @@ -51,15 +54,15 @@ class XmlPullParser : public IPackageDeclStack { }; /** - * Skips to the next direct descendant node of the given startDepth, + * Skips to the next direct descendant node of the given start_depth, * skipping namespace nodes. * - * When nextChildNode returns true, you can expect Comments, Text, and + * When NextChildNode() returns true, you can expect Comments, Text, and * StartElement events. */ - static bool nextChildNode(XmlPullParser* parser, size_t startDepth); - static bool skipCurrentElement(XmlPullParser* parser); - static bool isGoodEvent(Event event); + static bool NextChildNode(XmlPullParser* parser, size_t start_depth); + static bool SkipCurrentElement(XmlPullParser* parser); + static bool IsGoodEvent(Event event); explicit XmlPullParser(std::istream& in); ~XmlPullParser(); @@ -67,42 +70,42 @@ class XmlPullParser : public IPackageDeclStack { /** * Returns the current event that is being processed. */ - Event getEvent() const; + Event event() const; - const std::string& getLastError() const; + const std::string& error() const; /** * Note, unlike XmlPullParser, the first call to next() will return * StartElement of the first element. */ - Event next(); + Event Next(); // // These are available for all nodes. // - const std::string& getComment() const; - size_t getLineNumber() const; - size_t getDepth() const; + const std::string& comment() const; + size_t line_number() const; + size_t depth() const; /** * Returns the character data for a Text event. */ - const std::string& getText() const; + const std::string& text() const; // // Namespace prefix and URI are available for StartNamespace and EndNamespace. // - const std::string& getNamespacePrefix() const; - const std::string& getNamespaceUri() const; + const std::string& namespace_prefix() const; + const std::string& namespace_uri() const; // // These are available for StartElement and EndElement. // - const std::string& getElementNamespace() const; - const std::string& getElementName() const; + const std::string& element_namespace() const; + const std::string& element_name() const; /* * Uses the current stack of namespaces to resolve the package. Eg: @@ -115,8 +118,9 @@ class XmlPullParser : public IPackageDeclStack { * If xmlns:app="http://schemas.android.com/apk/res-auto", then * 'package' will be set to 'defaultPackage'. */ - Maybe<ExtractedPackage> transformPackageAlias( - const StringPiece& alias, const StringPiece& localPackage) const override; + Maybe<ExtractedPackage> TransformPackageAlias( + const StringPiece& alias, + const StringPiece& local_package) const override; // // Remaining methods are for retrieving information about attributes @@ -127,7 +131,7 @@ class XmlPullParser : public IPackageDeclStack { // struct Attribute { - std::string namespaceUri; + std::string namespace_uri; std::string name; std::string value; @@ -139,52 +143,54 @@ class XmlPullParser : public IPackageDeclStack { using const_iterator = std::vector<Attribute>::const_iterator; - const_iterator beginAttributes() const; - const_iterator endAttributes() const; - size_t getAttributeCount() const; - const_iterator findAttribute(StringPiece namespaceUri, + const_iterator begin_attributes() const; + const_iterator end_attributes() const; + size_t attribute_count() const; + const_iterator FindAttribute(StringPiece namespace_uri, StringPiece name) const; private: - static void XMLCALL startNamespaceHandler(void* userData, const char* prefix, + DISALLOW_COPY_AND_ASSIGN(XmlPullParser); + + static void XMLCALL StartNamespaceHandler(void* user_data, const char* prefix, const char* uri); - static void XMLCALL startElementHandler(void* userData, const char* name, + static void XMLCALL StartElementHandler(void* user_data, const char* name, const char** attrs); - static void XMLCALL characterDataHandler(void* userData, const char* s, + static void XMLCALL CharacterDataHandler(void* user_data, const char* s, int len); - static void XMLCALL endElementHandler(void* userData, const char* name); - static void XMLCALL endNamespaceHandler(void* userData, const char* prefix); - static void XMLCALL commentDataHandler(void* userData, const char* comment); + static void XMLCALL EndElementHandler(void* user_data, const char* name); + static void XMLCALL EndNamespaceHandler(void* user_data, const char* prefix); + static void XMLCALL CommentDataHandler(void* user_data, const char* comment); struct EventData { Event event; - size_t lineNumber; + size_t line_number; size_t depth; std::string data1; std::string data2; std::vector<Attribute> attributes; }; - std::istream& mIn; - XML_Parser mParser; - char mBuffer[16384]; - std::queue<EventData> mEventQueue; - std::string mLastError; - const std::string mEmpty; - size_t mDepth; - std::stack<std::string> mNamespaceUris; + std::istream& in_; + XML_Parser parser_; + char buffer_[16384]; + std::queue<EventData> event_queue_; + std::string error_; + const std::string empty_; + size_t depth_; + std::stack<std::string> namespace_uris_; struct PackageDecl { std::string prefix; ExtractedPackage package; }; - std::vector<PackageDecl> mPackageAliases; + std::vector<PackageDecl> package_aliases_; }; /** * Finds the attribute in the current element within the global namespace. */ -Maybe<StringPiece> findAttribute(const XmlPullParser* parser, +Maybe<StringPiece> FindAttribute(const XmlPullParser* parser, const StringPiece& name); /** @@ -192,7 +198,7 @@ Maybe<StringPiece> findAttribute(const XmlPullParser* parser, * attribute's value * must not be the empty string. */ -Maybe<StringPiece> findNonEmptyAttribute(const XmlPullParser* parser, +Maybe<StringPiece> FindNonEmptyAttribute(const XmlPullParser* parser, const StringPiece& name); // @@ -224,18 +230,18 @@ inline ::std::ostream& operator<<(::std::ostream& out, return out; } -inline bool XmlPullParser::nextChildNode(XmlPullParser* parser, - size_t startDepth) { +inline bool XmlPullParser::NextChildNode(XmlPullParser* parser, + size_t start_depth) { Event event; // First get back to the start depth. - while (isGoodEvent(event = parser->next()) && - parser->getDepth() > startDepth + 1) { + while (IsGoodEvent(event = parser->Next()) && + parser->depth() > start_depth + 1) { } // Now look for the first good node. - while ((event != Event::kEndElement || parser->getDepth() > startDepth) && - isGoodEvent(event)) { + while ((event != Event::kEndElement || parser->depth() > start_depth) && + IsGoodEvent(event)) { switch (event) { case Event::kText: case Event::kComment: @@ -244,15 +250,15 @@ inline bool XmlPullParser::nextChildNode(XmlPullParser* parser, default: break; } - event = parser->next(); + event = parser->Next(); } return false; } -inline bool XmlPullParser::skipCurrentElement(XmlPullParser* parser) { +inline bool XmlPullParser::SkipCurrentElement(XmlPullParser* parser) { int depth = 1; while (depth > 0) { - switch (parser->next()) { + switch (parser->Next()) { case Event::kEndDocument: return true; case Event::kBadDocument: @@ -270,12 +276,12 @@ inline bool XmlPullParser::skipCurrentElement(XmlPullParser* parser) { return true; } -inline bool XmlPullParser::isGoodEvent(XmlPullParser::Event event) { +inline bool XmlPullParser::IsGoodEvent(XmlPullParser::Event event) { return event != Event::kBadDocument && event != Event::kEndDocument; } inline int XmlPullParser::Attribute::compare(const Attribute& rhs) const { - int cmp = namespaceUri.compare(rhs.namespaceUri); + int cmp = namespace_uri.compare(rhs.namespace_uri); if (cmp != 0) return cmp; return name.compare(rhs.name); } @@ -292,16 +298,16 @@ inline bool XmlPullParser::Attribute::operator!=(const Attribute& rhs) const { return compare(rhs) != 0; } -inline XmlPullParser::const_iterator XmlPullParser::findAttribute( - StringPiece namespaceUri, StringPiece name) const { - const auto endIter = endAttributes(); +inline XmlPullParser::const_iterator XmlPullParser::FindAttribute( + StringPiece namespace_uri, StringPiece name) const { + const auto end_iter = end_attributes(); const auto iter = std::lower_bound( - beginAttributes(), endIter, - std::pair<StringPiece, StringPiece>(namespaceUri, name), + begin_attributes(), end_iter, + std::pair<StringPiece, StringPiece>(namespace_uri, name), [](const Attribute& attr, const std::pair<StringPiece, StringPiece>& rhs) -> bool { - int cmp = attr.namespaceUri.compare(0, attr.namespaceUri.size(), - rhs.first.data(), rhs.first.size()); + int cmp = attr.namespace_uri.compare( + 0, attr.namespace_uri.size(), rhs.first.data(), rhs.first.size()); if (cmp < 0) return true; if (cmp > 0) return false; cmp = attr.name.compare(0, attr.name.size(), rhs.second.data(), @@ -310,11 +316,11 @@ inline XmlPullParser::const_iterator XmlPullParser::findAttribute( return false; }); - if (iter != endIter && namespaceUri == iter->namespaceUri && + if (iter != end_iter && namespace_uri == iter->namespace_uri && name == iter->name) { return iter; } - return endIter; + return end_iter; } } // namespace xml diff --git a/tools/aapt2/xml/XmlPullParser_test.cpp b/tools/aapt2/xml/XmlPullParser_test.cpp index 2c1fdc76e9ad..4f18cd218cd9 100644 --- a/tools/aapt2/xml/XmlPullParser_test.cpp +++ b/tools/aapt2/xml/XmlPullParser_test.cpp @@ -14,42 +14,43 @@ * limitations under the License. */ -#include "test/Test.h" -#include "util/StringPiece.h" #include "xml/XmlPullParser.h" #include <sstream> +#include "test/Test.h" +#include "util/StringPiece.h" + namespace aapt { TEST(XmlPullParserTest, NextChildNodeTraversesCorrectly) { - std::stringstream str; - str << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<a><b><c xmlns:a=\"http://schema.org\"><d/></c><e/></b></a>"; - xml::XmlPullParser parser(str); + std::stringstream str; + str << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<a><b><c xmlns:a=\"http://schema.org\"><d/></c><e/></b></a>"; + xml::XmlPullParser parser(str); - const size_t depthOuter = parser.getDepth(); - ASSERT_TRUE(xml::XmlPullParser::nextChildNode(&parser, depthOuter)); + const size_t depth_outer = parser.depth(); + ASSERT_TRUE(xml::XmlPullParser::NextChildNode(&parser, depth_outer)); - EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.getEvent()); - EXPECT_EQ(StringPiece("a"), StringPiece(parser.getElementName())); + EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.event()); + EXPECT_EQ(StringPiece("a"), StringPiece(parser.element_name())); - const size_t depthA = parser.getDepth(); - ASSERT_TRUE(xml::XmlPullParser::nextChildNode(&parser, depthA)); - EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.getEvent()); - EXPECT_EQ(StringPiece("b"), StringPiece(parser.getElementName())); + const size_t depth_a = parser.depth(); + ASSERT_TRUE(xml::XmlPullParser::NextChildNode(&parser, depth_a)); + EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.event()); + EXPECT_EQ(StringPiece("b"), StringPiece(parser.element_name())); - const size_t depthB = parser.getDepth(); - ASSERT_TRUE(xml::XmlPullParser::nextChildNode(&parser, depthB)); - EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.getEvent()); - EXPECT_EQ(StringPiece("c"), StringPiece(parser.getElementName())); + const size_t depth_b = parser.depth(); + ASSERT_TRUE(xml::XmlPullParser::NextChildNode(&parser, depth_b)); + EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.event()); + EXPECT_EQ(StringPiece("c"), StringPiece(parser.element_name())); - ASSERT_TRUE(xml::XmlPullParser::nextChildNode(&parser, depthB)); - EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.getEvent()); - EXPECT_EQ(StringPiece("e"), StringPiece(parser.getElementName())); + ASSERT_TRUE(xml::XmlPullParser::NextChildNode(&parser, depth_b)); + EXPECT_EQ(xml::XmlPullParser::Event::kStartElement, parser.event()); + EXPECT_EQ(StringPiece("e"), StringPiece(parser.element_name())); - ASSERT_FALSE(xml::XmlPullParser::nextChildNode(&parser, depthOuter)); - EXPECT_EQ(xml::XmlPullParser::Event::kEndDocument, parser.getEvent()); + ASSERT_FALSE(xml::XmlPullParser::NextChildNode(&parser, depth_outer)); + EXPECT_EQ(xml::XmlPullParser::Event::kEndDocument, parser.event()); } -} // namespace aapt +} // namespace aapt diff --git a/tools/aapt2/xml/XmlUtil.cpp b/tools/aapt2/xml/XmlUtil.cpp index b570fd75b44e..d00f7f2fe0aa 100644 --- a/tools/aapt2/xml/XmlUtil.cpp +++ b/tools/aapt2/xml/XmlUtil.cpp @@ -14,60 +14,69 @@ * limitations under the License. */ -#include "util/Maybe.h" -#include "util/Util.h" #include "xml/XmlUtil.h" #include <string> +#include "util/Maybe.h" +#include "util/Util.h" + namespace aapt { namespace xml { -std::string buildPackageNamespace(const StringPiece& package, bool privateReference) { - std::string result = privateReference ? kSchemaPrivatePrefix : kSchemaPublicPrefix; - result.append(package.data(), package.size()); - return result; +std::string BuildPackageNamespace(const StringPiece& package, + bool private_reference) { + std::string result = + private_reference ? kSchemaPrivatePrefix : kSchemaPublicPrefix; + result.append(package.data(), package.size()); + return result; } -Maybe<ExtractedPackage> extractPackageFromNamespace(const std::string& namespaceUri) { - if (util::stringStartsWith(namespaceUri, kSchemaPublicPrefix)) { - StringPiece schemaPrefix = kSchemaPublicPrefix; - StringPiece package = namespaceUri; - package = package.substr(schemaPrefix.size(), package.size() - schemaPrefix.size()); - if (package.empty()) { - return {}; - } - return ExtractedPackage{ package.toString(), false /* isPrivate */ }; - - } else if (util::stringStartsWith(namespaceUri, kSchemaPrivatePrefix)) { - StringPiece schemaPrefix = kSchemaPrivatePrefix; - StringPiece package = namespaceUri; - package = package.substr(schemaPrefix.size(), package.size() - schemaPrefix.size()); - if (package.empty()) { - return {}; - } - return ExtractedPackage{ package.toString(), true /* isPrivate */ }; +Maybe<ExtractedPackage> ExtractPackageFromNamespace( + const std::string& namespace_uri) { + if (util::StartsWith(namespace_uri, kSchemaPublicPrefix)) { + StringPiece schema_prefix = kSchemaPublicPrefix; + StringPiece package = namespace_uri; + package = package.substr(schema_prefix.size(), + package.size() - schema_prefix.size()); + if (package.empty()) { + return {}; + } + return ExtractedPackage{package.ToString(), false /* is_private */}; - } else if (namespaceUri == kSchemaAuto) { - return ExtractedPackage{ std::string(), true /* isPrivate */ }; + } else if (util::StartsWith(namespace_uri, kSchemaPrivatePrefix)) { + StringPiece schema_prefix = kSchemaPrivatePrefix; + StringPiece package = namespace_uri; + package = package.substr(schema_prefix.size(), + package.size() - schema_prefix.size()); + if (package.empty()) { + return {}; } - return {}; + return ExtractedPackage{package.ToString(), true /* is_private */}; + + } else if (namespace_uri == kSchemaAuto) { + return ExtractedPackage{std::string(), true /* is_private */}; + } + return {}; } -void transformReferenceFromNamespace(IPackageDeclStack* declStack, - const StringPiece& localPackage, Reference* inRef) { - if (inRef->name) { - if (Maybe<ExtractedPackage> transformedPackage = - declStack->transformPackageAlias(inRef->name.value().package, localPackage)) { - ExtractedPackage& extractedPackage = transformedPackage.value(); - inRef->name.value().package = std::move(extractedPackage.package); +void TransformReferenceFromNamespace(IPackageDeclStack* decl_stack, + const StringPiece& local_package, + Reference* in_ref) { + if (in_ref->name) { + if (Maybe<ExtractedPackage> transformed_package = + decl_stack->TransformPackageAlias(in_ref->name.value().package, + local_package)) { + ExtractedPackage& extracted_package = transformed_package.value(); + in_ref->name.value().package = std::move(extracted_package.package); - // If the reference was already private (with a * prefix) and the namespace is public, - // we keep the reference private. - inRef->privateReference |= extractedPackage.privateNamespace; - } + // If the reference was already private (with a * prefix) and the + // namespace is public, + // we keep the reference private. + in_ref->private_reference |= extracted_package.private_namespace; } + } } -} // namespace xml -} // namespace aapt +} // namespace xml +} // namespace aapt diff --git a/tools/aapt2/xml/XmlUtil.h b/tools/aapt2/xml/XmlUtil.h index 96de654c9877..536540162d07 100644 --- a/tools/aapt2/xml/XmlUtil.h +++ b/tools/aapt2/xml/XmlUtil.h @@ -17,11 +17,11 @@ #ifndef AAPT_XML_XMLUTIL_H #define AAPT_XML_XMLUTIL_H +#include <string> + #include "ResourceValues.h" #include "util/Maybe.h" -#include <string> - namespace aapt { namespace xml { @@ -51,7 +51,7 @@ struct ExtractedPackage { * private resources * are made visible. */ - bool privateNamespace; + bool private_namespace; }; /** @@ -62,8 +62,8 @@ struct ExtractedPackage { * Special case: if namespaceUri is http://schemas.android.com/apk/res-auto, * returns an empty package name. */ -Maybe<ExtractedPackage> extractPackageFromNamespace( - const std::string& namespaceUri); +Maybe<ExtractedPackage> ExtractPackageFromNamespace( + const std::string& namespace_uri); /** * Returns an XML Android namespace for the given package of the form: @@ -74,8 +74,8 @@ Maybe<ExtractedPackage> extractPackageFromNamespace( * * http://schemas.android.com/apk/prv/res/<package> */ -std::string buildPackageNamespace(const StringPiece& package, - bool privateReference = false); +std::string BuildPackageNamespace(const StringPiece& package, + bool private_reference = false); /** * Interface representing a stack of XML namespace declarations. When looking up @@ -89,20 +89,19 @@ struct IPackageDeclStack { * Returns an ExtractedPackage struct if the alias given corresponds with a * package declaration. */ - virtual Maybe<ExtractedPackage> transformPackageAlias( - const StringPiece& alias, const StringPiece& localPackage) const = 0; + virtual Maybe<ExtractedPackage> TransformPackageAlias( + const StringPiece& alias, const StringPiece& local_package) const = 0; }; /** * Helper function for transforming the original Reference inRef to a fully * qualified reference * via the IPackageDeclStack. This will also mark the Reference as private if - * the namespace of - * the package declaration was private. + * the namespace of the package declaration was private. */ -void transformReferenceFromNamespace(IPackageDeclStack* declStack, - const StringPiece& localPackage, - Reference* inRef); +void TransformReferenceFromNamespace(IPackageDeclStack* decl_stack, + const StringPiece& local_package, + Reference* in_ref); } // namespace xml } // namespace aapt diff --git a/tools/aapt2/xml/XmlUtil_test.cpp b/tools/aapt2/xml/XmlUtil_test.cpp index cbeb8bcda9e0..5eecc8f5fb20 100644 --- a/tools/aapt2/xml/XmlUtil_test.cpp +++ b/tools/aapt2/xml/XmlUtil_test.cpp @@ -14,38 +14,46 @@ * limitations under the License. */ -#include "test/Test.h" #include "xml/XmlUtil.h" +#include "test/Test.h" + namespace aapt { TEST(XmlUtilTest, ExtractPackageFromNamespace) { - AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("com.android")); - AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("http://schemas.android.com/apk")); - AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("http://schemas.android.com/apk/res")); - AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("http://schemas.android.com/apk/res/")); - AAPT_ASSERT_FALSE(xml::extractPackageFromNamespace("http://schemas.android.com/apk/prv/res/")); - - Maybe<xml::ExtractedPackage> p = - xml::extractPackageFromNamespace("http://schemas.android.com/apk/res/a"); - AAPT_ASSERT_TRUE(p); - EXPECT_EQ(std::string("a"), p.value().package); - EXPECT_FALSE(p.value().privateNamespace); - - p = xml::extractPackageFromNamespace("http://schemas.android.com/apk/prv/res/android"); - AAPT_ASSERT_TRUE(p); - EXPECT_EQ(std::string("android"), p.value().package); - EXPECT_TRUE(p.value().privateNamespace); - - p = xml::extractPackageFromNamespace("http://schemas.android.com/apk/prv/res/com.test"); - AAPT_ASSERT_TRUE(p); - EXPECT_EQ(std::string("com.test"), p.value().package); - EXPECT_TRUE(p.value().privateNamespace); - - p = xml::extractPackageFromNamespace("http://schemas.android.com/apk/res-auto"); - AAPT_ASSERT_TRUE(p); - EXPECT_EQ(std::string(), p.value().package); - EXPECT_TRUE(p.value().privateNamespace); + AAPT_ASSERT_FALSE(xml::ExtractPackageFromNamespace("com.android")); + AAPT_ASSERT_FALSE( + xml::ExtractPackageFromNamespace("http://schemas.android.com/apk")); + AAPT_ASSERT_FALSE( + xml::ExtractPackageFromNamespace("http://schemas.android.com/apk/res")); + AAPT_ASSERT_FALSE( + xml::ExtractPackageFromNamespace("http://schemas.android.com/apk/res/")); + AAPT_ASSERT_FALSE(xml::ExtractPackageFromNamespace( + "http://schemas.android.com/apk/prv/res/")); + + Maybe<xml::ExtractedPackage> p = + xml::ExtractPackageFromNamespace("http://schemas.android.com/apk/res/a"); + AAPT_ASSERT_TRUE(p); + EXPECT_EQ(std::string("a"), p.value().package); + EXPECT_FALSE(p.value().private_namespace); + + p = xml::ExtractPackageFromNamespace( + "http://schemas.android.com/apk/prv/res/android"); + AAPT_ASSERT_TRUE(p); + EXPECT_EQ(std::string("android"), p.value().package); + EXPECT_TRUE(p.value().private_namespace); + + p = xml::ExtractPackageFromNamespace( + "http://schemas.android.com/apk/prv/res/com.test"); + AAPT_ASSERT_TRUE(p); + EXPECT_EQ(std::string("com.test"), p.value().package); + EXPECT_TRUE(p.value().private_namespace); + + p = xml::ExtractPackageFromNamespace( + "http://schemas.android.com/apk/res-auto"); + AAPT_ASSERT_TRUE(p); + EXPECT_EQ(std::string(), p.value().package); + EXPECT_TRUE(p.value().private_namespace); } -} // namespace aapt +} // namespace aapt |