summaryrefslogtreecommitdiff
path: root/libs/androidfw/LocaleData.cpp
diff options
context:
space:
mode:
author Victor Chang <vichang@google.com> 2024-12-27 14:04:08 +0000
committer Victor Chang <vichang@google.com> 2024-12-31 14:16:09 +0000
commita490e2cf1ef7257b40bcb45df6bde5972df2ac13 (patch)
tree73b8fe2890777badb1c9b69b4ad8d3324b00f030 /libs/androidfw/LocaleData.cpp
parent7b64171769bd4c75518bff8d9e01158f3d467cec (diff)
Extract implementation of script and locale matching into LocaleDataLookup.h
It helps adding new unit tests, and fixing correctness and performance bugs later. Bug: 386340812 Test: atest libandroidfw_tests Change-Id: I4d3ee1333637d2cd22d5fdfad730935951feeccb
Diffstat (limited to 'libs/androidfw/LocaleData.cpp')
-rw-r--r--libs/androidfw/LocaleData.cpp58
1 files changed, 13 insertions, 45 deletions
diff --git a/libs/androidfw/LocaleData.cpp b/libs/androidfw/LocaleData.cpp
index 020cef6012e9..1b23d90c5ab3 100644
--- a/libs/androidfw/LocaleData.cpp
+++ b/libs/androidfw/LocaleData.cpp
@@ -23,39 +23,18 @@
#include <unordered_set>
#include <androidfw/LocaleData.h>
+#include <androidfw/LocaleDataLookup.h>
namespace android {
-#include "LocaleDataTables.cpp"
-
-inline uint32_t packLocale(const char* language, const char* region) {
- return (((uint8_t) language[0]) << 24u) | (((uint8_t) language[1]) << 16u) |
- (((uint8_t) region[0]) << 8u) | ((uint8_t) region[1]);
-}
-
-inline uint32_t dropRegion(uint32_t packed_locale) {
- return packed_locale & 0xFFFF0000LU;
-}
-
-inline bool hasRegion(uint32_t packed_locale) {
- return (packed_locale & 0x0000FFFFLU) != 0;
-}
-
-const size_t SCRIPT_LENGTH = 4;
-const size_t SCRIPT_PARENTS_COUNT = sizeof(SCRIPT_PARENTS)/sizeof(SCRIPT_PARENTS[0]);
const uint32_t PACKED_ROOT = 0; // to represent the root locale
+const uint32_t MAX_PARENT_DEPTH = getMaxAncestorTreeDepth();
uint32_t findParent(uint32_t packed_locale, const char* script) {
if (hasRegion(packed_locale)) {
- for (size_t i = 0; i < SCRIPT_PARENTS_COUNT; i++) {
- if (memcmp(script, SCRIPT_PARENTS[i].script, SCRIPT_LENGTH) == 0) {
- auto map = SCRIPT_PARENTS[i].map;
- auto lookup_result = map->find(packed_locale);
- if (lookup_result != map->end()) {
- return lookup_result->second;
- }
- break;
- }
+ auto parent_key = findParentLocalePackedKey(script, packed_locale);
+ if (parent_key != 0) {
+ return parent_key;
}
return dropRegion(packed_locale);
}
@@ -111,17 +90,6 @@ size_t findDistance(uint32_t supported,
return supported_ancestor_count + request_ancestors_index - 1;
}
-inline bool isRepresentative(uint32_t language_and_region, const char* script) {
- const uint64_t packed_locale = (
- (((uint64_t) language_and_region) << 32u) |
- (((uint64_t) script[0]) << 24u) |
- (((uint64_t) script[1]) << 16u) |
- (((uint64_t) script[2]) << 8u) |
- ((uint64_t) script[3]));
-
- return (REPRESENTATIVE_LOCALES.count(packed_locale) != 0);
-}
-
const uint32_t US_SPANISH = 0x65735553LU; // es-US
const uint32_t MEXICAN_SPANISH = 0x65734D58LU; // es-MX
const uint32_t LATIN_AMERICAN_SPANISH = 0x6573A424LU; // es-419
@@ -185,8 +153,8 @@ int localeDataCompareRegions(
// If we are here, left and right are equidistant from the request. We will
// try and see if any of them is a representative locale.
- const bool left_is_representative = isRepresentative(left, requested_script);
- const bool right_is_representative = isRepresentative(right, requested_script);
+ const bool left_is_representative = isLocaleRepresentative(left, requested_script);
+ const bool right_is_representative = isLocaleRepresentative(right, requested_script);
if (left_is_representative != right_is_representative) {
return (int) left_is_representative - (int) right_is_representative;
}
@@ -204,14 +172,14 @@ void localeDataComputeScript(char out[4], const char* language, const char* regi
return;
}
uint32_t lookup_key = packLocale(language, region);
- auto lookup_result = LIKELY_SCRIPTS.find(lookup_key);
- if (lookup_result == LIKELY_SCRIPTS.end()) {
+ auto lookup_result = lookupLikelyScript(lookup_key);
+ if (lookup_result == nullptr) {
// We couldn't find the locale. Let's try without the region
if (region[0] != '\0') {
lookup_key = dropRegion(lookup_key);
- lookup_result = LIKELY_SCRIPTS.find(lookup_key);
- if (lookup_result != LIKELY_SCRIPTS.end()) {
- memcpy(out, SCRIPT_CODES[lookup_result->second], SCRIPT_LENGTH);
+ lookup_result = lookupLikelyScript(lookup_key);
+ if (lookup_result != nullptr) {
+ memcpy(out, lookup_result, SCRIPT_LENGTH);
return;
}
}
@@ -220,7 +188,7 @@ void localeDataComputeScript(char out[4], const char* language, const char* regi
return;
} else {
// We found the locale.
- memcpy(out, SCRIPT_CODES[lookup_result->second], SCRIPT_LENGTH);
+ memcpy(out, lookup_result, SCRIPT_LENGTH);
}
}