AAPT2: Convert binary ResTable_config to proto
Test: make aapt2_tests
Change-Id: I8641f13ce41cd58ac8bc3da31c4e15a7b3f06092
diff --git a/tools/aapt2/Locale.cpp b/tools/aapt2/Locale.cpp
index 7664fac..d81921f 100644
--- a/tools/aapt2/Locale.cpp
+++ b/tools/aapt2/Locale.cpp
@@ -24,9 +24,10 @@
#include "util/Util.h"
-namespace aapt {
+using ::android::ResTable_config;
+using ::android::StringPiece;
-using android::ResTable_config;
+namespace aapt {
void LocaleValue::set_language(const char* language_chars) {
size_t i = 0;
@@ -72,7 +73,7 @@
return std::all_of(std::begin(str), std::end(str), ::isdigit);
}
-bool LocaleValue::InitFromFilterString(const android::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, '_');
@@ -138,6 +139,71 @@
return true;
}
+bool LocaleValue::InitFromBcp47Tag(const StringPiece& bcp47tag) {
+ return InitFromBcp47TagImpl(bcp47tag, '-');
+}
+
+bool LocaleValue::InitFromBcp47TagImpl(const StringPiece& bcp47tag, const char separator) {
+ std::vector<std::string> subtags = util::SplitAndLowercase(bcp47tag, separator);
+ if (subtags.size() == 1) {
+ set_language(subtags[0].c_str());
+ } else if (subtags.size() == 2) {
+ 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:
+ 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 {
+ set_script(subtags[1].c_str());
+ break;
+ }
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ set_variant(subtags[1].c_str());
+ break;
+ default:
+ return false;
+ }
+ } else if (subtags.size() == 3) {
+ // The language is always the first subtag.
+ 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) {
+ set_script(subtags[1].c_str());
+ } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
+ set_region(subtags[1].c_str());
+ } else {
+ return false;
+ }
+
+ // 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) {
+ set_variant(subtags[2].c_str());
+ } else {
+ set_region(subtags[2].c_str());
+ }
+ } else if (subtags.size() == 4) {
+ 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 false;
+ }
+ return true;
+}
+
ssize_t LocaleValue::InitFromParts(std::vector<std::string>::iterator iter,
std::vector<std::string>::iterator end) {
const std::vector<std::string>::iterator start_iter = iter;
@@ -145,71 +211,13 @@
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, '+');
- subtags.erase(subtags.begin());
- if (subtags.size() == 1) {
- set_language(subtags[0].c_str());
- } else if (subtags.size() == 2) {
- 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:
- 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 {
- set_script(subtags[1].c_str());
- break;
- }
- case 5:
- case 6:
- case 7:
- case 8:
- set_variant(subtags[1].c_str());
- break;
- default:
- return -1;
- }
- } else if (subtags.size() == 3) {
- // The language is always the first subtag.
- 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) {
- set_script(subtags[1].c_str());
- } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
- set_region(subtags[1].c_str());
- } else {
- return -1;
- }
-
- // 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) {
- set_variant(subtags[2].c_str());
- } else {
- set_region(subtags[2].c_str());
- }
- } else if (subtags.size() == 4) {
- 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 {
+ // except that the separator is "+" and not "-". Skip the prefix 'b+'.
+ if (!InitFromBcp47TagImpl(StringPiece(part).substr(2), '+')) {
return -1;
}
-
++iter;
-
} else {
- if ((part.length() == 2 || part.length() == 3) && is_alpha(part) &&
- part != "car") {
+ if ((part.length() == 2 || part.length() == 3) && is_alpha(part) && part != "car") {
set_language(part.c_str());
++iter;
@@ -222,7 +230,6 @@
}
}
}
-
return static_cast<ssize_t>(iter - start_iter);
}