160916893Sopenharmony_ci/* 260916893Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 360916893Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 460916893Sopenharmony_ci * you may not use this file except in compliance with the License. 560916893Sopenharmony_ci * You may obtain a copy of the License at 660916893Sopenharmony_ci * 760916893Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 860916893Sopenharmony_ci * 960916893Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1060916893Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1160916893Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1260916893Sopenharmony_ci * See the License for the specific language governing permissions and 1360916893Sopenharmony_ci * limitations under the License. 1460916893Sopenharmony_ci */ 1560916893Sopenharmony_ci 1660916893Sopenharmony_ci#include "data_resource.h" 1760916893Sopenharmony_ci#include <cstring> 1860916893Sopenharmony_ci#include "i18n_memory_adapter.h" 1960916893Sopenharmony_ci#include "securec.h" 2060916893Sopenharmony_ci#include "str_util.h" 2160916893Sopenharmony_ci 2260916893Sopenharmony_ciusing namespace OHOS::I18N; 2360916893Sopenharmony_ciusing namespace std; 2460916893Sopenharmony_ci 2560916893Sopenharmony_ci#ifdef I18N_PRODUCT 2660916893Sopenharmony_cistatic const char *DATA_RESOURCE_PATH = "system/i18n/i18n.dat"; 2760916893Sopenharmony_ci#else 2860916893Sopenharmony_cistatic const char *DATA_RESOURCE_PATH = "/storage/data/i18n.dat"; 2960916893Sopenharmony_ci#endif 3060916893Sopenharmony_ci 3160916893Sopenharmony_ciDataResource::DataResource(const LocaleInfo *localeInfo) 3260916893Sopenharmony_ci{ 3360916893Sopenharmony_ci uint32_t enMask = LocaleInfo("en", "US").GetMask(); 3460916893Sopenharmony_ci if (localeInfo == nullptr) { 3560916893Sopenharmony_ci localeMask = enMask; 3660916893Sopenharmony_ci } else { 3760916893Sopenharmony_ci localeMask = localeInfo->GetMask(); 3860916893Sopenharmony_ci if (localeInfo->IsDefaultLocale()) { 3960916893Sopenharmony_ci fallbackMask = 0; 4060916893Sopenharmony_ci } else { 4160916893Sopenharmony_ci fallbackMask = GetFallbackMask(*localeInfo); 4260916893Sopenharmony_ci } 4360916893Sopenharmony_ci if ((fallbackMask != 0) && (fallbackMask != enMask)) { 4460916893Sopenharmony_ci defaultMask = enMask; 4560916893Sopenharmony_ci } 4660916893Sopenharmony_ci } 4760916893Sopenharmony_ci for (int i = 0; i < DataResourceType::RESOURCE_TYPE_END; ++i) { 4860916893Sopenharmony_ci loaded[i] = DataResourceType::RESOURCE_TYPE_END; 4960916893Sopenharmony_ci } 5060916893Sopenharmony_ci} 5160916893Sopenharmony_ci 5260916893Sopenharmony_ciDataResource::~DataResource() 5360916893Sopenharmony_ci{ 5460916893Sopenharmony_ci if (resourceIndex != nullptr) { 5560916893Sopenharmony_ci I18nFree(static_cast<void *>(resourceIndex)); 5660916893Sopenharmony_ci } 5760916893Sopenharmony_ci if (fallbackResourceIndex) { 5860916893Sopenharmony_ci I18nFree(static_cast<void *>(fallbackResourceIndex)); 5960916893Sopenharmony_ci } 6060916893Sopenharmony_ci if (defaultResourceIndex) { 6160916893Sopenharmony_ci I18nFree(static_cast<void *>(defaultResourceIndex)); 6260916893Sopenharmony_ci } 6360916893Sopenharmony_ci FreeResource(); 6460916893Sopenharmony_ci} 6560916893Sopenharmony_ci 6660916893Sopenharmony_civoid DataResource::FreeResource() 6760916893Sopenharmony_ci{ 6860916893Sopenharmony_ci if (resource != nullptr) { 6960916893Sopenharmony_ci while (resourceCount > 0) { 7060916893Sopenharmony_ci I18nFree(static_cast<void *>(resource[resourceCount - 1])); 7160916893Sopenharmony_ci --resourceCount; 7260916893Sopenharmony_ci } 7360916893Sopenharmony_ci } 7460916893Sopenharmony_ci I18nFree(static_cast<void *>(resource)); 7560916893Sopenharmony_ci if (fallbackResource != nullptr) { 7660916893Sopenharmony_ci while (fallbackResourceCount > 0) { 7760916893Sopenharmony_ci I18nFree(static_cast<void *>(fallbackResource[fallbackResourceCount - 1])); 7860916893Sopenharmony_ci --fallbackResourceCount; 7960916893Sopenharmony_ci } 8060916893Sopenharmony_ci } 8160916893Sopenharmony_ci I18nFree(static_cast<void *>(fallbackResource)); 8260916893Sopenharmony_ci if (defaultResource != nullptr) { 8360916893Sopenharmony_ci while (defaultResourceCount > 0) { 8460916893Sopenharmony_ci I18nFree(static_cast<void *>(defaultResource[defaultResourceCount - 1])); 8560916893Sopenharmony_ci --defaultResourceCount; 8660916893Sopenharmony_ci } 8760916893Sopenharmony_ci } 8860916893Sopenharmony_ci I18nFree(static_cast<void *>(defaultResource)); 8960916893Sopenharmony_ci} 9060916893Sopenharmony_ci 9160916893Sopenharmony_cichar *DataResource::GetString(DataResourceType type) const 9260916893Sopenharmony_ci{ 9360916893Sopenharmony_ci uint32_t index = static_cast<uint32_t>(type); 9460916893Sopenharmony_ci return GetString(index); 9560916893Sopenharmony_ci} 9660916893Sopenharmony_ci 9760916893Sopenharmony_cichar *DataResource::GetString(uint32_t index) const 9860916893Sopenharmony_ci{ 9960916893Sopenharmony_ci if (index >= DataResourceType::RESOURCE_TYPE_END) { 10060916893Sopenharmony_ci return nullptr; 10160916893Sopenharmony_ci } 10260916893Sopenharmony_ci uint32_t targetType = loaded[index]; 10360916893Sopenharmony_ci if (targetType == DataResourceType::RESOURCE_TYPE_END) { 10460916893Sopenharmony_ci return nullptr; 10560916893Sopenharmony_ci } 10660916893Sopenharmony_ci switch (targetType) { 10760916893Sopenharmony_ci case LocaleDataType::RESOURCE: { 10860916893Sopenharmony_ci return BinarySearchString(resourceIndex, resourceCount, index, resource, resourceCount); 10960916893Sopenharmony_ci } 11060916893Sopenharmony_ci case LocaleDataType::FALLBACK_RESOURCE: { 11160916893Sopenharmony_ci return BinarySearchString(fallbackResourceIndex, fallbackResourceCount, index, 11260916893Sopenharmony_ci fallbackResource, fallbackResourceCount); 11360916893Sopenharmony_ci } 11460916893Sopenharmony_ci default: { 11560916893Sopenharmony_ci return BinarySearchString(defaultResourceIndex, defaultResourceCount, index, 11660916893Sopenharmony_ci defaultResource, defaultResourceCount); 11760916893Sopenharmony_ci } 11860916893Sopenharmony_ci } 11960916893Sopenharmony_ci} 12060916893Sopenharmony_ci 12160916893Sopenharmony_cichar *DataResource::BinarySearchString(uint32_t *indexArray, uint32_t length, uint32_t target, 12260916893Sopenharmony_ci char **stringArray, uint32_t stringLength) const 12360916893Sopenharmony_ci{ 12460916893Sopenharmony_ci if ((indexArray == nullptr) || (stringArray == nullptr) || (stringLength == 0) || (length == 0)) { 12560916893Sopenharmony_ci return nullptr; 12660916893Sopenharmony_ci } 12760916893Sopenharmony_ci int32_t low = 0; 12860916893Sopenharmony_ci int32_t high = static_cast<int32_t>(length - 1); 12960916893Sopenharmony_ci while (low <= high) { 13060916893Sopenharmony_ci int32_t mid = low + (high - low) / 2; 13160916893Sopenharmony_ci if (mid > static_cast<int32_t>(stringLength)) { 13260916893Sopenharmony_ci return nullptr; 13360916893Sopenharmony_ci } 13460916893Sopenharmony_ci uint32_t temp = indexArray[mid]; 13560916893Sopenharmony_ci if (temp == target) { 13660916893Sopenharmony_ci return stringArray[mid]; 13760916893Sopenharmony_ci } else if (temp < target) { 13860916893Sopenharmony_ci low = mid + 1; 13960916893Sopenharmony_ci } else { 14060916893Sopenharmony_ci high = mid - 1; 14160916893Sopenharmony_ci } 14260916893Sopenharmony_ci } 14360916893Sopenharmony_ci return nullptr; 14460916893Sopenharmony_ci} 14560916893Sopenharmony_ci 14660916893Sopenharmony_cibool DataResource::Init(void) 14760916893Sopenharmony_ci{ 14860916893Sopenharmony_ci int32_t infile = open(DATA_RESOURCE_PATH, O_RDONLY); 14960916893Sopenharmony_ci if (infile < 0) { 15060916893Sopenharmony_ci return false; 15160916893Sopenharmony_ci } 15260916893Sopenharmony_ci bool ret = ReadHeader(infile); 15360916893Sopenharmony_ci if (!ret) { 15460916893Sopenharmony_ci close(infile); 15560916893Sopenharmony_ci return false; 15660916893Sopenharmony_ci } 15760916893Sopenharmony_ci if ((localesCount < 1) || (localesCount > MAX_LOCALE_ITEM_SIZE)) { 15860916893Sopenharmony_ci close(infile); 15960916893Sopenharmony_ci return false; 16060916893Sopenharmony_ci } 16160916893Sopenharmony_ci ret = PrepareData(infile); 16260916893Sopenharmony_ci close(infile); 16360916893Sopenharmony_ci return ret; 16460916893Sopenharmony_ci} 16560916893Sopenharmony_ci 16660916893Sopenharmony_cibool DataResource::ReadHeader(int32_t infile) 16760916893Sopenharmony_ci{ 16860916893Sopenharmony_ci int32_t seekSize = lseek(infile, GLOBAL_RESOURCE_HEADER_SKIP, SEEK_SET); 16960916893Sopenharmony_ci if (seekSize < 0) { 17060916893Sopenharmony_ci return false; 17160916893Sopenharmony_ci } 17260916893Sopenharmony_ci char cache[GLOBAL_RESOURCE_HEADER_LEFT] = {0}; 17360916893Sopenharmony_ci int32_t readSize = read(infile, cache, GLOBAL_RESOURCE_HEADER_LEFT); 17460916893Sopenharmony_ci if (readSize != GLOBAL_RESOURCE_HEADER_LEFT) { 17560916893Sopenharmony_ci return false; 17660916893Sopenharmony_ci } 17760916893Sopenharmony_ci localesCount = ((static_cast<unsigned char>(cache[0]) << SHIFT_ONE_BYTE) | (static_cast<unsigned char>(cache[1]))); 17860916893Sopenharmony_ci stringPoolOffset = ((static_cast<unsigned char>(cache[GLOBAL_RESOURCE_INDEX_OFFSET]) << SHIFT_ONE_BYTE) | 17960916893Sopenharmony_ci (static_cast<unsigned char>(cache[GLOBAL_RESOURCE_INDEX_OFFSET + 1]))); 18060916893Sopenharmony_ci return true; 18160916893Sopenharmony_ci} 18260916893Sopenharmony_ci 18360916893Sopenharmony_cibool DataResource::PrepareData(int32_t infile) 18460916893Sopenharmony_ci{ 18560916893Sopenharmony_ci uint32_t localeSize = localesCount * GLOBAL_LOCALE_MASK_ITEM_SIZE; 18660916893Sopenharmony_ci char *locales = reinterpret_cast<char *>(I18nMalloc(localeSize)); 18760916893Sopenharmony_ci if (locales == nullptr) { 18860916893Sopenharmony_ci return false; 18960916893Sopenharmony_ci } 19060916893Sopenharmony_ci int32_t readSize = read(infile, locales, localeSize); 19160916893Sopenharmony_ci if (readSize < 0 || localeSize != static_cast<uint32_t>(readSize)) { 19260916893Sopenharmony_ci I18nFree(static_cast<void *>(locales)); 19360916893Sopenharmony_ci return false; 19460916893Sopenharmony_ci } 19560916893Sopenharmony_ci int32_t localeIndex = BinarySearchLocale(localeMask, reinterpret_cast<unsigned char*>(locales)); 19660916893Sopenharmony_ci int32_t fallbackLocaleIndex = -1; 19760916893Sopenharmony_ci int32_t defaultLocaleIndex = -1; 19860916893Sopenharmony_ci GetFallbackAndDefaultLocaleIndex(fallbackLocaleIndex, defaultLocaleIndex, locales); 19960916893Sopenharmony_ci uint32_t configOffset = 0; 20060916893Sopenharmony_ci if (localeIndex >= 0) { 20160916893Sopenharmony_ci configOffset = ConvertUChar(reinterpret_cast<unsigned char*>(locales + GLOBAL_LOCALE_MASK_ITEM_SIZE * 20260916893Sopenharmony_ci localeIndex + GLOBAL_RESOURCE_MASK_OFFSET)); 20360916893Sopenharmony_ci resourceCount = ConvertUChar(reinterpret_cast<unsigned char*>(locales + GLOBAL_LOCALE_MASK_ITEM_SIZE * 20460916893Sopenharmony_ci localeIndex + GLOBAL_RESOURCE_MASK_OFFSET + GLOBAL_RESOURCE_INDEX_OFFSET)); 20560916893Sopenharmony_ci } 20660916893Sopenharmony_ci uint32_t fallbackConfigOffset = 0; 20760916893Sopenharmony_ci uint32_t defaultConfigOffset = 0; 20860916893Sopenharmony_ci GetFallbackAndDefaultInfo(fallbackLocaleIndex, defaultLocaleIndex, fallbackConfigOffset, defaultConfigOffset, 20960916893Sopenharmony_ci locales); 21060916893Sopenharmony_ci I18nFree(static_cast<void *>(locales)); 21160916893Sopenharmony_ci bool ret = true; 21260916893Sopenharmony_ci if (IsTypeNeeded(localeIndex, resourceCount)) { 21360916893Sopenharmony_ci ret = PrepareLocaleData(infile, configOffset, resourceCount, LocaleDataType::RESOURCE); 21460916893Sopenharmony_ci } 21560916893Sopenharmony_ci if (IsTypeNeeded(fallbackLocaleIndex, fallbackResourceCount)) { 21660916893Sopenharmony_ci ret = PrepareLocaleData(infile, fallbackConfigOffset, fallbackResourceCount, 21760916893Sopenharmony_ci LocaleDataType::FALLBACK_RESOURCE); 21860916893Sopenharmony_ci } 21960916893Sopenharmony_ci if (IsTypeNeeded(defaultLocaleIndex, defaultResourceCount)) { 22060916893Sopenharmony_ci ret = PrepareLocaleData(infile, defaultConfigOffset, defaultResourceCount, LocaleDataType::DEFAULT_RESOURCE); 22160916893Sopenharmony_ci } 22260916893Sopenharmony_ci return ret; 22360916893Sopenharmony_ci} 22460916893Sopenharmony_ci 22560916893Sopenharmony_cibool DataResource::IsTypeNeeded(int32_t index, uint32_t count) 22660916893Sopenharmony_ci{ 22760916893Sopenharmony_ci if ((index < 0) || FullLoaded()) { 22860916893Sopenharmony_ci return false; 22960916893Sopenharmony_ci } 23060916893Sopenharmony_ci return (count > 0) && (count <= DataResourceType::RESOURCE_TYPE_END); 23160916893Sopenharmony_ci} 23260916893Sopenharmony_ci 23360916893Sopenharmony_civoid DataResource::GetFallbackAndDefaultLocaleIndex(int32_t &fallbackLocaleIndex, int32_t &defaultLocaleIndex, 23460916893Sopenharmony_ci char *locales) 23560916893Sopenharmony_ci{ 23660916893Sopenharmony_ci if (fallbackMask != 0) { 23760916893Sopenharmony_ci fallbackLocaleIndex = BinarySearchLocale(fallbackMask, reinterpret_cast<unsigned char*>(locales)); 23860916893Sopenharmony_ci } 23960916893Sopenharmony_ci if (defaultMask != 0) { 24060916893Sopenharmony_ci defaultLocaleIndex = BinarySearchLocale(defaultMask, reinterpret_cast<unsigned char*>(locales)); 24160916893Sopenharmony_ci } 24260916893Sopenharmony_ci} 24360916893Sopenharmony_ci 24460916893Sopenharmony_civoid DataResource::GetFallbackAndDefaultInfo(const int32_t &fallbackLocaleIndex, const int32_t &defaultLocaleIndex, 24560916893Sopenharmony_ci uint32_t &fallbackConfigOffset, uint32_t &defaultConfigOffset, char* locales) 24660916893Sopenharmony_ci{ 24760916893Sopenharmony_ci if (fallbackLocaleIndex != -1) { 24860916893Sopenharmony_ci fallbackConfigOffset = ConvertUChar(reinterpret_cast<unsigned char*>(locales + GLOBAL_LOCALE_MASK_ITEM_SIZE * 24960916893Sopenharmony_ci fallbackLocaleIndex + GLOBAL_RESOURCE_MASK_OFFSET)); 25060916893Sopenharmony_ci fallbackResourceCount = ConvertUChar(reinterpret_cast<unsigned char*>(locales + GLOBAL_LOCALE_MASK_ITEM_SIZE * 25160916893Sopenharmony_ci fallbackLocaleIndex + GLOBAL_RESOURCE_MASK_OFFSET + GLOBAL_RESOURCE_INDEX_OFFSET)); 25260916893Sopenharmony_ci } 25360916893Sopenharmony_ci if (defaultLocaleIndex != -1) { 25460916893Sopenharmony_ci defaultConfigOffset = ConvertUChar(reinterpret_cast<unsigned char*>(locales + GLOBAL_LOCALE_MASK_ITEM_SIZE * 25560916893Sopenharmony_ci defaultLocaleIndex + GLOBAL_RESOURCE_MASK_OFFSET)); 25660916893Sopenharmony_ci defaultResourceCount = ConvertUChar(reinterpret_cast<unsigned char*>(locales + GLOBAL_LOCALE_MASK_ITEM_SIZE * 25760916893Sopenharmony_ci defaultLocaleIndex + GLOBAL_RESOURCE_MASK_OFFSET + GLOBAL_RESOURCE_INDEX_OFFSET)); 25860916893Sopenharmony_ci } 25960916893Sopenharmony_ci} 26060916893Sopenharmony_ci 26160916893Sopenharmony_cibool DataResource::PrepareLocaleData(int32_t infile, uint32_t configOffset, uint32_t count, LocaleDataType type) 26260916893Sopenharmony_ci{ 26360916893Sopenharmony_ci currentType = type; 26460916893Sopenharmony_ci if (count < 1 || count > DataResourceType::RESOURCE_TYPE_END) { 26560916893Sopenharmony_ci return false; 26660916893Sopenharmony_ci } 26760916893Sopenharmony_ci uint32_t resourceSize = count * GLOBAL_RESOURCE_CONFIG_SIZE; 26860916893Sopenharmony_ci char *configs = reinterpret_cast<char *>(I18nMalloc(resourceSize)); 26960916893Sopenharmony_ci if (configs == nullptr) { 27060916893Sopenharmony_ci return false; 27160916893Sopenharmony_ci } 27260916893Sopenharmony_ci int32_t seekSize = lseek(infile, configOffset, SEEK_SET); 27360916893Sopenharmony_ci if (configOffset != static_cast<uint32_t>(seekSize)) { 27460916893Sopenharmony_ci I18nFree(static_cast<void *>(configs)); 27560916893Sopenharmony_ci return false; 27660916893Sopenharmony_ci } 27760916893Sopenharmony_ci int32_t readSize = read(infile, configs, resourceSize); 27860916893Sopenharmony_ci if (readSize != resourceSize) { 27960916893Sopenharmony_ci I18nFree(static_cast<void *>(configs)); 28060916893Sopenharmony_ci return false; 28160916893Sopenharmony_ci } 28260916893Sopenharmony_ci bool ret = GetStringFromStringPool(configs, resourceSize, infile, type); 28360916893Sopenharmony_ci I18nFree(static_cast<void *>(configs)); 28460916893Sopenharmony_ci return ret; 28560916893Sopenharmony_ci} 28660916893Sopenharmony_ci 28760916893Sopenharmony_ciuint32_t DataResource::GetFinalCount(char *configs, uint32_t configSize, LocaleDataType type) 28860916893Sopenharmony_ci{ 28960916893Sopenharmony_ci uint32_t count = 0; 29060916893Sopenharmony_ci switch (type) { 29160916893Sopenharmony_ci case LocaleDataType::RESOURCE: { 29260916893Sopenharmony_ci count = resourceCount; 29360916893Sopenharmony_ci break; 29460916893Sopenharmony_ci } 29560916893Sopenharmony_ci case LocaleDataType::FALLBACK_RESOURCE: { 29660916893Sopenharmony_ci count = fallbackResourceCount; 29760916893Sopenharmony_ci break; 29860916893Sopenharmony_ci } 29960916893Sopenharmony_ci default: { 30060916893Sopenharmony_ci count = defaultResourceCount; 30160916893Sopenharmony_ci } 30260916893Sopenharmony_ci } 30360916893Sopenharmony_ci uint32_t finalCount = 0; 30460916893Sopenharmony_ci for (uint32_t i = 0; i < count; ++i) { 30560916893Sopenharmony_ci uint32_t index = ConvertUChar(reinterpret_cast<unsigned char*>(configs + i * GLOBAL_RESOURCE_CONFIG_SIZE)); 30660916893Sopenharmony_ci if (index >= DataResourceType::RESOURCE_TYPE_END) { 30760916893Sopenharmony_ci return 0; 30860916893Sopenharmony_ci } 30960916893Sopenharmony_ci if (loaded[index] != DataResourceType::RESOURCE_TYPE_END) { 31060916893Sopenharmony_ci continue; 31160916893Sopenharmony_ci } else { 31260916893Sopenharmony_ci loaded[index] = type; 31360916893Sopenharmony_ci } 31460916893Sopenharmony_ci ++finalCount; 31560916893Sopenharmony_ci } 31660916893Sopenharmony_ci return finalCount; 31760916893Sopenharmony_ci} 31860916893Sopenharmony_ci 31960916893Sopenharmony_cibool DataResource::GetStringFromStringPool(char *configs, const uint32_t configsSize, int32_t infile, 32060916893Sopenharmony_ci LocaleDataType type) 32160916893Sopenharmony_ci{ 32260916893Sopenharmony_ci uint32_t finalCount = GetFinalCount(configs, configsSize, type); 32360916893Sopenharmony_ci if (finalCount == 0) { 32460916893Sopenharmony_ci return true; 32560916893Sopenharmony_ci } 32660916893Sopenharmony_ci uint32_t **index = nullptr; 32760916893Sopenharmony_ci char ***wanted = nullptr; 32860916893Sopenharmony_ci uint32_t originalCount = 0; 32960916893Sopenharmony_ci switch (type) { 33060916893Sopenharmony_ci case LocaleDataType::RESOURCE: { 33160916893Sopenharmony_ci originalCount = resourceCount; 33260916893Sopenharmony_ci resourceCount = finalCount; 33360916893Sopenharmony_ci index = &resourceIndex; 33460916893Sopenharmony_ci wanted = &resource; 33560916893Sopenharmony_ci break; 33660916893Sopenharmony_ci } 33760916893Sopenharmony_ci case LocaleDataType::FALLBACK_RESOURCE: { 33860916893Sopenharmony_ci originalCount = fallbackResourceCount; 33960916893Sopenharmony_ci fallbackResourceCount = finalCount; 34060916893Sopenharmony_ci index = &fallbackResourceIndex; 34160916893Sopenharmony_ci wanted = &fallbackResource; 34260916893Sopenharmony_ci break; 34360916893Sopenharmony_ci } 34460916893Sopenharmony_ci default: { 34560916893Sopenharmony_ci originalCount = defaultResourceCount; 34660916893Sopenharmony_ci defaultResourceCount = finalCount; 34760916893Sopenharmony_ci index = &defaultResourceIndex; 34860916893Sopenharmony_ci wanted = &defaultResource; 34960916893Sopenharmony_ci break; 35060916893Sopenharmony_ci } 35160916893Sopenharmony_ci } 35260916893Sopenharmony_ci if (!ApplyForResource(index, wanted, finalCount)) { 35360916893Sopenharmony_ci return false; 35460916893Sopenharmony_ci } 35560916893Sopenharmony_ci return Retrieve(configs, configsSize, infile, originalCount, type); 35660916893Sopenharmony_ci} 35760916893Sopenharmony_ci 35860916893Sopenharmony_civoid DataResource::GetType(char** &adjustResource, uint32_t* &adjustResourceIndex, uint32_t &count, 35960916893Sopenharmony_ci LocaleDataType type) 36060916893Sopenharmony_ci{ 36160916893Sopenharmony_ci switch (type) { 36260916893Sopenharmony_ci case LocaleDataType::RESOURCE: { 36360916893Sopenharmony_ci adjustResource = resource; 36460916893Sopenharmony_ci adjustResourceIndex = resourceIndex; 36560916893Sopenharmony_ci count = resourceCount; 36660916893Sopenharmony_ci break; 36760916893Sopenharmony_ci } 36860916893Sopenharmony_ci case LocaleDataType::FALLBACK_RESOURCE: { 36960916893Sopenharmony_ci adjustResource = fallbackResource; 37060916893Sopenharmony_ci adjustResourceIndex = fallbackResourceIndex; 37160916893Sopenharmony_ci count = fallbackResourceCount; 37260916893Sopenharmony_ci break; 37360916893Sopenharmony_ci } 37460916893Sopenharmony_ci default: { 37560916893Sopenharmony_ci adjustResource = defaultResource; 37660916893Sopenharmony_ci adjustResourceIndex = defaultResourceIndex; 37760916893Sopenharmony_ci count = defaultResourceCount; 37860916893Sopenharmony_ci break; 37960916893Sopenharmony_ci } 38060916893Sopenharmony_ci } 38160916893Sopenharmony_ci} 38260916893Sopenharmony_ci 38360916893Sopenharmony_cibool DataResource::Retrieve(char *configs, uint32_t configsSize, int32_t infile, const uint32_t orginalCount, 38460916893Sopenharmony_ci LocaleDataType type) 38560916893Sopenharmony_ci{ 38660916893Sopenharmony_ci uint32_t count = 0; 38760916893Sopenharmony_ci char **adjustResource = nullptr; 38860916893Sopenharmony_ci uint32_t *adjustResourceIndex = nullptr; 38960916893Sopenharmony_ci GetType(adjustResource, adjustResourceIndex, count, type); 39060916893Sopenharmony_ci uint32_t currentIndex = 0; 39160916893Sopenharmony_ci for (uint32_t i = 0; i < orginalCount; ++i) { 39260916893Sopenharmony_ci uint32_t index = ConvertUChar(reinterpret_cast<unsigned char*>(configs + i * GLOBAL_RESOURCE_CONFIG_SIZE)); 39360916893Sopenharmony_ci if (loaded[index] != type) { 39460916893Sopenharmony_ci continue; 39560916893Sopenharmony_ci } 39660916893Sopenharmony_ci uint32_t offset = ConvertUChar(reinterpret_cast<unsigned char*>(configs + i * 39760916893Sopenharmony_ci GLOBAL_RESOURCE_CONFIG_SIZE + GLOBAL_RESOURCE_INDEX_OFFSET)); 39860916893Sopenharmony_ci uint32_t length = ConvertUChar(reinterpret_cast<unsigned char*>(configs + i * 39960916893Sopenharmony_ci GLOBAL_RESOURCE_CONFIG_SIZE + GLOBAL_RESOURCE_MASK_OFFSET)); 40060916893Sopenharmony_ci int32_t seekSize = lseek(infile, stringPoolOffset + offset, SEEK_SET); 40160916893Sopenharmony_ci if ((length == 0) || (seekSize != static_cast<uint32_t>(stringPoolOffset + offset))) { 40260916893Sopenharmony_ci adjustResource[currentIndex] = nullptr; 40360916893Sopenharmony_ci adjustResourceIndex[currentIndex] = index; 40460916893Sopenharmony_ci } else { 40560916893Sopenharmony_ci char *temp = reinterpret_cast<char *>(I18nMalloc(length + 1)); 40660916893Sopenharmony_ci if (temp == nullptr) { 40760916893Sopenharmony_ci loaded[index] = DataResourceType::RESOURCE_TYPE_END; 40860916893Sopenharmony_ci return false; 40960916893Sopenharmony_ci } 41060916893Sopenharmony_ci int32_t readSize = read(infile, temp, length); 41160916893Sopenharmony_ci temp[length] = 0; 41260916893Sopenharmony_ci if ((readSize < 0) || (static_cast<uint32_t>(readSize) != length)) { 41360916893Sopenharmony_ci I18nFree(static_cast<void *>(temp)); 41460916893Sopenharmony_ci return false; 41560916893Sopenharmony_ci } 41660916893Sopenharmony_ci adjustResource[currentIndex] = temp; 41760916893Sopenharmony_ci adjustResourceIndex[currentIndex] = index; 41860916893Sopenharmony_ci } 41960916893Sopenharmony_ci ++currentIndex; 42060916893Sopenharmony_ci } 42160916893Sopenharmony_ci return true; 42260916893Sopenharmony_ci} 42360916893Sopenharmony_ci 42460916893Sopenharmony_cibool DataResource::ApplyForResource(uint32_t **index, char ***wanted, uint32_t totalCount) 42560916893Sopenharmony_ci{ 42660916893Sopenharmony_ci if ((index == nullptr) || (wanted == nullptr) || (totalCount == 0)) { 42760916893Sopenharmony_ci return false; 42860916893Sopenharmony_ci } 42960916893Sopenharmony_ci *index = reinterpret_cast<uint32_t *>(I18nMalloc(sizeof(uint32_t) * totalCount)); 43060916893Sopenharmony_ci if (*index == nullptr) { 43160916893Sopenharmony_ci return false; 43260916893Sopenharmony_ci } 43360916893Sopenharmony_ci *wanted = reinterpret_cast<char **>(I18nMalloc(sizeof(char *) * totalCount)); 43460916893Sopenharmony_ci if (*wanted == nullptr) { 43560916893Sopenharmony_ci return false; // free *index in FreeResource 43660916893Sopenharmony_ci } 43760916893Sopenharmony_ci for (uint32_t i = 0; i < totalCount; ++i) { 43860916893Sopenharmony_ci (*wanted)[i] = nullptr; 43960916893Sopenharmony_ci } 44060916893Sopenharmony_ci return true; 44160916893Sopenharmony_ci} 44260916893Sopenharmony_ci 44360916893Sopenharmony_ciint32_t DataResource::BinarySearchLocale(const uint32_t mask, unsigned char *locales) 44460916893Sopenharmony_ci{ 44560916893Sopenharmony_ci if ((locales == nullptr) || (localesCount == 0)) { 44660916893Sopenharmony_ci return -1; 44760916893Sopenharmony_ci } 44860916893Sopenharmony_ci int32_t low = 0; 44960916893Sopenharmony_ci int32_t high = static_cast<int32_t>(localesCount - 1); 45060916893Sopenharmony_ci while (low <= high) { 45160916893Sopenharmony_ci int32_t mid = low + (high - low) / 2; 45260916893Sopenharmony_ci if (mid > 1024) { // locales count < 1024 45360916893Sopenharmony_ci return -1; 45460916893Sopenharmony_ci } 45560916893Sopenharmony_ci uint32_t midMask = ConvertUint(locales + mid * GLOBAL_LOCALE_MASK_ITEM_SIZE); 45660916893Sopenharmony_ci if (midMask == mask) { 45760916893Sopenharmony_ci return mid; 45860916893Sopenharmony_ci } else if (midMask < mask) { 45960916893Sopenharmony_ci low = mid + 1; 46060916893Sopenharmony_ci } else { 46160916893Sopenharmony_ci high = mid - 1; 46260916893Sopenharmony_ci } 46360916893Sopenharmony_ci } 46460916893Sopenharmony_ci return -1; 46560916893Sopenharmony_ci} 46660916893Sopenharmony_ci 46760916893Sopenharmony_ciuint32_t DataResource::ConvertUint(unsigned char *src) 46860916893Sopenharmony_ci{ 46960916893Sopenharmony_ci if (src == nullptr) { 47060916893Sopenharmony_ci return 0; 47160916893Sopenharmony_ci } 47260916893Sopenharmony_ci uint32_t ret = 0; 47360916893Sopenharmony_ci ret |= (src[0] << SHIFT_THREE_BYTE); // 0 indicates first byte 47460916893Sopenharmony_ci ret |= (src[1] << SHIFT_TWO_BYTE); // 1 indicates second byte 47560916893Sopenharmony_ci ret |= (src[2] << SHIFT_ONE_BYTE); // 2 indicates third byte 47660916893Sopenharmony_ci ret |= src[3]; // 3 indicates forth byte 47760916893Sopenharmony_ci return ret; 47860916893Sopenharmony_ci} 47960916893Sopenharmony_ci 48060916893Sopenharmony_ciuint32_t DataResource::ConvertUChar(unsigned char *src) 48160916893Sopenharmony_ci{ 48260916893Sopenharmony_ci if (src == nullptr) { 48360916893Sopenharmony_ci return 0; 48460916893Sopenharmony_ci } 48560916893Sopenharmony_ci uint32_t ret = 0; 48660916893Sopenharmony_ci ret |= (src[0] << SHIFT_ONE_BYTE); 48760916893Sopenharmony_ci ret |= src[1]; 48860916893Sopenharmony_ci return ret; 48960916893Sopenharmony_ci} 49060916893Sopenharmony_ci 49160916893Sopenharmony_cibool DataResource::FullLoaded() 49260916893Sopenharmony_ci{ 49360916893Sopenharmony_ci for (uint32_t i = 0; i < DataResourceType::RESOURCE_TYPE_END; ++i) { 49460916893Sopenharmony_ci if (loaded[i] == DataResourceType::RESOURCE_TYPE_END) { 49560916893Sopenharmony_ci return false; 49660916893Sopenharmony_ci } 49760916893Sopenharmony_ci } 49860916893Sopenharmony_ci return true; 49960916893Sopenharmony_ci} 50060916893Sopenharmony_ci 50160916893Sopenharmony_ciuint32_t DataResource::GetFallbackMask(const LocaleInfo &src) 50260916893Sopenharmony_ci{ 50360916893Sopenharmony_ci const char *language = src.GetLanguage(); 50460916893Sopenharmony_ci const char *script = src.GetScript(); 50560916893Sopenharmony_ci const char *region = src.GetRegion(); 50660916893Sopenharmony_ci if ((language != nullptr) && (strcmp("en", language) == 0) && (script == nullptr)) { 50760916893Sopenharmony_ci return LocaleInfo("en", "", "US").GetMask(); 50860916893Sopenharmony_ci } 50960916893Sopenharmony_ci if (region == nullptr) { 51060916893Sopenharmony_ci return LocaleInfo("en", "US").GetMask(); 51160916893Sopenharmony_ci } 51260916893Sopenharmony_ci if (script == nullptr) { 51360916893Sopenharmony_ci return LocaleInfo(language, "", "").GetMask(); 51460916893Sopenharmony_ci } 51560916893Sopenharmony_ci return LocaleInfo(language, script, "").GetMask(); 51660916893Sopenharmony_ci} 51760916893Sopenharmony_ci 51860916893Sopenharmony_civoid DataResource::GetString(DataResourceType type, std::string &ret) const 51960916893Sopenharmony_ci{ 52060916893Sopenharmony_ci uint32_t index = static_cast<uint32_t>(type); 52160916893Sopenharmony_ci char *temp = GetString(index); 52260916893Sopenharmony_ci if (temp == nullptr) { 52360916893Sopenharmony_ci ret = ""; 52460916893Sopenharmony_ci } else { 52560916893Sopenharmony_ci ret = temp; 52660916893Sopenharmony_ci } 52760916893Sopenharmony_ci} 528