From a490e2cf1ef7257b40bcb45df6bde5972df2ac13 Mon Sep 17 00:00:00 2001 From: Victor Chang Date: Fri, 27 Dec 2024 14:04:08 +0000 Subject: 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 --- .../androidfw/include/androidfw/LocaleDataLookup.h | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 libs/androidfw/include/androidfw/LocaleDataLookup.h (limited to 'libs/androidfw/include') diff --git a/libs/androidfw/include/androidfw/LocaleDataLookup.h b/libs/androidfw/include/androidfw/LocaleDataLookup.h new file mode 100644 index 000000000000..7fde7123ed0b --- /dev/null +++ b/libs/androidfw/include/androidfw/LocaleDataLookup.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2024 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. + */ + +#pragma once + +#include +#include + + +namespace android { + +namespace hidden { + bool isRepresentative(uint64_t packed_locale); +} + +constexpr size_t SCRIPT_LENGTH = 4; + +constexpr inline uint32_t packLocale(const char* language, const char* region) { + const unsigned char* lang = reinterpret_cast(language); + const unsigned char* reg = reinterpret_cast(region); + return (static_cast(lang[0]) << 24u) | + (static_cast(lang[1]) << 16u) | + (static_cast(reg[0]) << 8u) | + static_cast(reg[1]); +} + +constexpr inline uint32_t dropRegion(uint32_t packed_locale) { + return packed_locale & 0xFFFF0000LU; +} + +constexpr inline bool hasRegion(uint32_t packed_locale) { + return (packed_locale & 0x0000FFFFLU) != 0; +} + +/** + * Return nullptr if the key isn't found. The input packed_lang_region can be computed + * by android::packLocale. + * Note that the returned char* is either nullptr or 4-byte char seqeuence, but isn't + * a null-terminated string. + */ +const char* lookupLikelyScript(uint32_t packed_lang_region); +/** + * Return false if the key isn't representative. The input lookup key can be computed + * by android::packLocale. + */ +bool inline isLocaleRepresentative(uint32_t language_and_region, const char* script) { + const unsigned char* s = reinterpret_cast(script); + const uint64_t packed_locale = ( + ((static_cast(language_and_region)) << 32u) | + (static_cast(s[0]) << 24u) | + (static_cast(s[1]) << 16u) | + (static_cast(s[2]) << 8u) | + static_cast(s[3])); + + return hidden::isRepresentative(packed_locale); +} + +/** + * Return a parent packed key for a given script and child packed key. Return 0 if + * no parent is found. + */ +uint32_t findParentLocalePackedKey(const char* script, uint32_t packed_lang_region); + +uint32_t getMaxAncestorTreeDepth(); + +} // namespace android -- cgit v1.2.3-59-g8ed1b