diff options
author | Narayan Kamath <narayan@google.com> | 2014-03-07 19:39:13 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-03-07 19:39:13 +0000 |
commit | d5b9bcb60d7d20e3e32edcef7d9b235e0ccccf82 (patch) | |
tree | 8943af3865523559f65eeb676eb57d80aecc92d8 /libs | |
parent | f214b4cccba33d66cf52e1896a09e57704c4dae1 (diff) | |
parent | 28879bbfe89dc4bf2067a7183975ecffb82f68e6 (diff) | |
download | frameworks_base-d5b9bcb60d7d20e3e32edcef7d9b235e0ccccf82.zip frameworks_base-d5b9bcb60d7d20e3e32edcef7d9b235e0ccccf82.tar.gz frameworks_base-d5b9bcb60d7d20e3e32edcef7d9b235e0ccccf82.tar.bz2 |
am 28879bbf: am be57fca4: Merge "Extended locales in AAPT / AssetManager."
* commit '28879bbfe89dc4bf2067a7183975ecffb82f68e6':
Extended locales in AAPT / AssetManager.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/androidfw/AssetManager.cpp | 30 | ||||
-rw-r--r-- | libs/androidfw/ResourceTypes.cpp | 95 | ||||
-rw-r--r-- | libs/androidfw/tests/ResourceTypes_test.cpp | 35 |
3 files changed, 114 insertions, 46 deletions
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 5069958..b4d482a 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -386,17 +386,8 @@ void AssetManager::setConfiguration(const ResTable_config& config, const char* l if (locale) { setLocaleLocked(locale); } else if (config.language[0] != 0) { - char spec[9]; - spec[0] = config.language[0]; - spec[1] = config.language[1]; - if (config.country[0] != 0) { - spec[2] = '_'; - spec[3] = config.country[0]; - spec[4] = config.country[1]; - spec[5] = 0; - } else { - spec[3] = 0; - } + char spec[RESTABLE_MAX_LOCALE_LEN]; + config.getBcp47Locale(spec); setLocaleLocked(spec); } else { updateResourceParamsLocked(); @@ -668,20 +659,11 @@ void AssetManager::updateResourceParamsLocked() const return; } - size_t llen = mLocale ? strlen(mLocale) : 0; - mConfig->language[0] = 0; - mConfig->language[1] = 0; - mConfig->country[0] = 0; - mConfig->country[1] = 0; - if (llen >= 2) { - mConfig->language[0] = mLocale[0]; - mConfig->language[1] = mLocale[1]; - } - if (llen >= 5) { - mConfig->country[0] = mLocale[3]; - mConfig->country[1] = mLocale[4]; + if (mLocale) { + mConfig->setBcp47Locale(mLocale); + } else { + mConfig->clearLocale(); } - mConfig->size = sizeof(*mConfig); res->setParameters(mConfig); } diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 0c356b6..efb589a 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -1592,9 +1592,9 @@ void ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) { return 0; } -/* static */ void packLanguageOrRegion(const char in[3], const char base, +/* static */ void packLanguageOrRegion(const char* in, const char base, char out[2]) { - if (in[2] == 0) { + if (in[2] == 0 || in[2] == '-') { out[0] = in[0]; out[1] = in[1]; } else { @@ -1608,11 +1608,11 @@ void ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) { } -void ResTable_config::packLanguage(const char language[3]) { +void ResTable_config::packLanguage(const char* language) { packLanguageOrRegion(language, 'a', this->language); } -void ResTable_config::packRegion(const char region[3]) { +void ResTable_config::packRegion(const char* region) { packLanguageOrRegion(region, '0', this->country); } @@ -2320,7 +2320,7 @@ bool ResTable_config::match(const ResTable_config& settings) const { return true; } -void ResTable_config::getLocale(char str[RESTABLE_MAX_LOCALE_LEN]) const { +void ResTable_config::getBcp47Locale(char str[RESTABLE_MAX_LOCALE_LEN]) const { memset(str, 0, RESTABLE_MAX_LOCALE_LEN); // This represents the "any" locale value, which has traditionally been @@ -2331,34 +2331,83 @@ void ResTable_config::getLocale(char str[RESTABLE_MAX_LOCALE_LEN]) const { size_t charsWritten = 0; if (language[0]) { - unpackLanguage(str); + charsWritten += unpackLanguage(str); } - if (country[0]) { + if (localeScript[0]) { if (charsWritten) { - str[charsWritten++] = '_'; - str[charsWritten++] = 'r'; + str[charsWritten++] = '-'; } - charsWritten += unpackRegion(str + charsWritten); + memcpy(str + charsWritten, localeScript, sizeof(localeScript)); + charsWritten += sizeof(localeScript); } - if (localeScript[0]) { + if (country[0]) { if (charsWritten) { - str[charsWritten++] = '_'; - str[charsWritten++] = '_s'; + str[charsWritten++] = '-'; } - memcpy(str + charsWritten, localeScript, sizeof(localeScript)); + charsWritten += unpackRegion(str + charsWritten); } if (localeVariant[0]) { if (charsWritten) { - str[charsWritten++] = '_'; - str[charsWritten++] = 'v'; + str[charsWritten++] = '-'; } memcpy(str + charsWritten, localeVariant, sizeof(localeVariant)); } } +/* static */ inline bool assignLocaleComponent(ResTable_config* config, + const char* start, size_t size) { + + switch (size) { + case 0: + return false; + case 2: + case 3: + config->language[0] ? config->packRegion(start) : config->packLanguage(start); + break; + case 4: + config->localeScript[0] = toupper(start[0]); + for (size_t i = 1; i < 4; ++i) { + config->localeScript[i] = tolower(start[i]); + } + break; + case 5: + case 6: + case 7: + case 8: + for (size_t i = 0; i < size; ++i) { + config->localeVariant[i] = tolower(start[i]); + } + break; + default: + return false; + } + + return true; +} + +void ResTable_config::setBcp47Locale(const char* in) { + locale = 0; + memset(localeScript, 0, sizeof(localeScript)); + memset(localeVariant, 0, sizeof(localeVariant)); + + const char* separator = in; + const char* start = in; + while ((separator = strchr(start, '-')) != NULL) { + const size_t size = separator - start; + if (!assignLocaleComponent(this, start, size)) { + fprintf(stderr, "Invalid BCP-47 locale string: %s", in); + } + + start = (separator + 1); + } + + const size_t size = in + strlen(in) - start; + assignLocaleComponent(this, start, size); +} + String8 ResTable_config::toString() const { String8 res; @@ -2371,7 +2420,7 @@ String8 ResTable_config::toString() const { res.appendFormat("%dmnc", dtohs(mnc)); } char localeStr[RESTABLE_MAX_LOCALE_LEN]; - getLocale(localeStr); + getBcp47Locale(localeStr); res.append(localeStr); if ((screenLayout&MASK_LAYOUTDIR) != 0) { @@ -5126,18 +5175,20 @@ void ResTable::getConfigurations(Vector<ResTable_config>* configs) const const size_t L = type->configs.size(); for (size_t l=0; l<L; l++) { const ResTable_type* config = type->configs[l]; - const ResTable_config* cfg = &config->config; + ResTable_config cfg; + memset(&cfg, 0, sizeof(ResTable_config)); + cfg.copyFromDtoH(config->config); // only insert unique const size_t M = configs->size(); size_t m; for (m=0; m<M; m++) { - if (0 == (*configs)[m].compare(*cfg)) { + if (0 == (*configs)[m].compare(cfg)) { break; } } // if we didn't find it if (m == M) { - configs->add(*cfg); + configs->add(cfg); } } } @@ -5155,7 +5206,7 @@ void ResTable::getLocales(Vector<String8>* locales) const char locale[RESTABLE_MAX_LOCALE_LEN]; for (size_t i=0; i<I; i++) { - configs[i].getLocale(locale); + configs[i].getBcp47Locale(locale); const size_t J = locales->size(); size_t j; for (j=0; j<J; j++) { @@ -5815,7 +5866,7 @@ void ResTable::print(bool inclValues) const } #if 0 char localeStr[RESTABLE_MAX_LOCALE_LEN]; - mParams.getLocale(localeStr); + mParams.getBcp47Locale(localeStr); printf("mParams=%s,\n" localeStr); #endif size_t pgCount = mPackageGroups.size(); diff --git a/libs/androidfw/tests/ResourceTypes_test.cpp b/libs/androidfw/tests/ResourceTypes_test.cpp index eadfe00..4888b4a 100644 --- a/libs/androidfw/tests/ResourceTypes_test.cpp +++ b/libs/androidfw/tests/ResourceTypes_test.cpp @@ -146,5 +146,40 @@ TEST(ResourceTypesTest, IsMoreSpecificThan) { EXPECT_TRUE(r.isMoreSpecificThan(l)); } +TEST(ResourceTypesTest, setLocale) { + ResTable_config test; + test.setBcp47Locale("en-US"); + EXPECT_EQ('e', test.language[0]); + EXPECT_EQ('n', test.language[1]); + EXPECT_EQ('U', test.country[0]); + EXPECT_EQ('S', test.country[1]); + EXPECT_EQ(0, test.localeScript[0]); + EXPECT_EQ(0, test.localeVariant[0]); + + test.setBcp47Locale("eng-419"); + char out[4] = { 1, 1, 1, 1}; + test.unpackLanguage(out); + EXPECT_EQ('e', out[0]); + EXPECT_EQ('n', out[1]); + EXPECT_EQ('g', out[2]); + EXPECT_EQ(0, out[3]); + memset(out, 1, 4); + test.unpackRegion(out); + EXPECT_EQ('4', out[0]); + EXPECT_EQ('1', out[1]); + EXPECT_EQ('9', out[2]); + + + test.setBcp47Locale("en-Latn-419"); + memset(out, 1, 4); + EXPECT_EQ('e', test.language[0]); + EXPECT_EQ('n', test.language[1]); + + EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4)); + test.unpackRegion(out); + EXPECT_EQ('4', out[0]); + EXPECT_EQ('1', out[1]); + EXPECT_EQ('9', out[2]); +} } // namespace android. |