#include "unicode/ures.h"
#include "unicode/ustring.h"
#include "unicode/ucnv.h"
#include "bytesinkutil.h"
#include "charstr.h"
#include "uresimp.h"
#include "ustr_imp.h"
#include "cwchar.h"
#include "ucln_cmn.h"
#include "cmemory.h"
#include "cstring.h"
#include "mutex.h"
#include "uhash.h"
#include "unicode/uenum.h"
#include "uenumimp.h"
#include "ulocimp.h"
#include "umutex.h"
#include "putilimp.h"
#include "uassert.h"
#include "uresdata.h"
usingnamespaceicu;
static UHashtable *cache = …;
static icu::UInitOnce gCacheInitOnce { … };
static UMutex resbMutex;
static int32_t U_CALLCONV hashEntry(const UHashTok parm) { … }
static UBool U_CALLCONV compareEntries(const UHashTok p1, const UHashTok p2) { … }
static UBool chopLocale(char *name) { … }
static UBool hasVariant(const char* localeID) { … }
#define INCLUDED_FROM_URESBUND_CPP
#include "localefallback_data.h"
static const char* performFallbackLookup(const char* key,
const char* keyStrs,
const char* valueStrs,
const int32_t* lookupTable,
int32_t lookupTableLength) { … }
static CharString getDefaultScript(const CharString& language, const CharString& region) { … }
enum UResOpenType { … };
UResOpenType;
static bool getParentLocaleID(char *name, const char *origName, UResOpenType openType) { … }
static UBool mayHaveParent(char *name) { … }
static void entryIncrease(UResourceDataEntry *entry) { … }
static UResourceDataEntry *getFallbackData(
const UResourceBundle *resBundle,
const char **resTag, Resource *res, UErrorCode *status) { … }
static void
free_entry(UResourceDataEntry *entry) { … }
static int32_t ures_flushCache()
{ … }
#ifdef URES_DEBUG
#include <stdio.h>
U_CAPI UBool U_EXPORT2 ures_dumpCacheContents() {
UBool cacheNotEmpty = false;
int32_t pos = UHASH_FIRST;
const UHashElement *e;
UResourceDataEntry *resB;
Mutex lock(&resbMutex);
if (cache == nullptr) {
fprintf(stderr,"%s:%d: RB Cache is nullptr.\n", __FILE__, __LINE__);
return false;
}
while ((e = uhash_nextElement(cache, &pos)) != nullptr) {
cacheNotEmpty=true;
resB = (UResourceDataEntry *) e->value.pointer;
fprintf(stderr,"%s:%d: RB Cache: Entry @0x%p, refcount %d, name %s:%s. Pool 0x%p, alias 0x%p, parent 0x%p\n",
__FILE__, __LINE__,
(void*)resB, resB->fCountExisting,
resB->fName?resB->fName:"nullptr",
resB->fPath?resB->fPath:"nullptr",
(void*)resB->fPool,
(void*)resB->fAlias,
(void*)resB->fParent);
}
fprintf(stderr,"%s:%d: RB Cache still contains %d items.\n", __FILE__, __LINE__, uhash_count(cache));
return cacheNotEmpty;
}
#endif
static UBool U_CALLCONV ures_cleanup()
{ … }
static void U_CALLCONV createCache(UErrorCode &status) { … }
static void initCache(UErrorCode *status) { … }
static void setEntryName(UResourceDataEntry *res, const char *name, UErrorCode *status) { … }
static UResourceDataEntry *
getPoolEntry(const char *path, UErrorCode *status);
static UResourceDataEntry *init_entry(const char *localeID, const char *path, UErrorCode *status) { … }
static UResourceDataEntry *
getPoolEntry(const char *path, UErrorCode *status) { … }
static UResourceDataEntry *
findFirstExisting(const char* path, char* name, const char* defaultLocale, UResOpenType openType,
UBool *isRoot, UBool *foundParent, UBool *isDefault, UErrorCode* status) { … }
static void ures_setIsStackObject( UResourceBundle* resB, UBool state) { … }
static UBool ures_isStackObject(const UResourceBundle* resB) { … }
U_CFUNC void ures_initStackObject(UResourceBundle* resB) { … }
U_NAMESPACE_BEGIN
StackUResourceBundle::StackUResourceBundle() { … }
StackUResourceBundle::~StackUResourceBundle() { … }
U_NAMESPACE_END
static UBool
loadParentsExceptRoot(UResourceDataEntry *&t1,
char name[], int32_t nameCapacity,
UBool usingUSRData, char usrDataPath[], UErrorCode *status) { … }
static UBool
insertRootBundle(UResourceDataEntry *&t1, UErrorCode *status) { … }
static UResourceDataEntry *entryOpen(const char* path, const char* localeID,
UResOpenType openType, UErrorCode* status) { … }
static UResourceDataEntry *
entryOpenDirect(const char* path, const char* localeID, UErrorCode* status) { … }
static void entryCloseInt(UResourceDataEntry *resB) { … }
static void entryClose(UResourceDataEntry *resB) { … }
static void ures_appendResPath(UResourceBundle *resB, const char* toAdd, int32_t lenToAdd, UErrorCode *status) { … }
static void ures_freeResPath(UResourceBundle *resB) { … }
static void
ures_closeBundle(UResourceBundle* resB, UBool freeBundleObj)
{ … }
U_CAPI void U_EXPORT2
ures_close(UResourceBundle* resB)
{ … }
namespace {
UResourceBundle *init_resb_result(
UResourceDataEntry *dataEntry, Resource r, const char *key, int32_t idx,
UResourceDataEntry *validLocaleDataEntry, const char *containerResPath,
int32_t recursionDepth,
UResourceBundle *resB, UErrorCode *status);
UResourceBundle *getAliasTargetAsResourceBundle(
const ResourceData &resData, Resource r, const char *key, int32_t idx,
UResourceDataEntry *validLocaleDataEntry, const char *containerResPath,
int32_t recursionDepth,
UResourceBundle *resB, UErrorCode *status) { … }
UResourceBundle *init_resb_result(
UResourceDataEntry *dataEntry, Resource r, const char *key, int32_t idx,
UResourceDataEntry *validLocaleDataEntry, const char *containerResPath,
int32_t recursionDepth,
UResourceBundle *resB, UErrorCode *status) { … }
UResourceBundle *init_resb_result(
UResourceDataEntry *dataEntry, Resource r, const char *key, int32_t idx,
const UResourceBundle *container,
UResourceBundle *resB, UErrorCode *status) { … }
}
UResourceBundle *ures_copyResb(UResourceBundle *r, const UResourceBundle *original, UErrorCode *status) { … }
U_CAPI const char16_t* U_EXPORT2 ures_getString(const UResourceBundle* resB, int32_t* len, UErrorCode* status) { … }
static const char *
ures_toUTF8String(const char16_t *s16, int32_t length16,
char *dest, int32_t *pLength,
UBool forceCopy,
UErrorCode *status) { … }
U_CAPI const char * U_EXPORT2
ures_getUTF8String(const UResourceBundle *resB,
char *dest, int32_t *pLength,
UBool forceCopy,
UErrorCode *status) { … }
U_CAPI const uint8_t* U_EXPORT2 ures_getBinary(const UResourceBundle* resB, int32_t* len,
UErrorCode* status) { … }
U_CAPI const int32_t* U_EXPORT2 ures_getIntVector(const UResourceBundle* resB, int32_t* len,
UErrorCode* status) { … }
U_CAPI int32_t U_EXPORT2 ures_getInt(const UResourceBundle* resB, UErrorCode *status) { … }
U_CAPI uint32_t U_EXPORT2 ures_getUInt(const UResourceBundle* resB, UErrorCode *status) { … }
U_CAPI UResType U_EXPORT2 ures_getType(const UResourceBundle *resB) { … }
U_CAPI const char * U_EXPORT2 ures_getKey(const UResourceBundle *resB) { … }
U_CAPI int32_t U_EXPORT2 ures_getSize(const UResourceBundle *resB) { … }
static const char16_t* ures_getStringWithAlias(const UResourceBundle *resB, Resource r, int32_t sIndex, int32_t *len, UErrorCode *status) { … }
U_CAPI void U_EXPORT2 ures_resetIterator(UResourceBundle *resB){ … }
U_CAPI UBool U_EXPORT2 ures_hasNext(const UResourceBundle *resB) { … }
U_CAPI const char16_t* U_EXPORT2 ures_getNextString(UResourceBundle *resB, int32_t* len, const char ** key, UErrorCode *status) { … }
U_CAPI UResourceBundle* U_EXPORT2 ures_getNextResource(UResourceBundle *resB, UResourceBundle *fillIn, UErrorCode *status) { … }
U_CAPI UResourceBundle* U_EXPORT2 ures_getByIndex(const UResourceBundle *resB, int32_t indexR, UResourceBundle *fillIn, UErrorCode *status) { … }
U_CAPI const char16_t* U_EXPORT2 ures_getStringByIndex(const UResourceBundle *resB, int32_t indexS, int32_t* len, UErrorCode *status) { … }
U_CAPI const char * U_EXPORT2
ures_getUTF8StringByIndex(const UResourceBundle *resB,
int32_t idx,
char *dest, int32_t *pLength,
UBool forceCopy,
UErrorCode *status) { … }
U_CAPI UResourceBundle* U_EXPORT2
ures_findResource(const char* path, UResourceBundle *fillIn, UErrorCode *status)
{ … }
U_CAPI UResourceBundle* U_EXPORT2
ures_findSubResource(const UResourceBundle *resB, char* path, UResourceBundle *fillIn, UErrorCode *status)
{ … }
U_CAPI const char16_t* U_EXPORT2
ures_getStringByKeyWithFallback(const UResourceBundle *resB,
const char* inKey,
int32_t* len,
UErrorCode *status) { … }
static Resource getTableItemByKeyPath(const ResourceData *pResData, Resource table, const char *key) { … }
static void createPath(const char* origResPath,
int32_t origResPathLen,
const char* resPath,
int32_t resPathLen,
const char* inKey,
CharString& path,
UErrorCode* status) { … }
U_CAPI UResourceBundle* U_EXPORT2
ures_getByKeyWithFallback(const UResourceBundle *resB,
const char* inKey,
UResourceBundle *fillIn,
UErrorCode *status) { … }
namespace {
void getAllItemsWithFallback(
const UResourceBundle *bundle, ResourceDataValue &value,
ResourceSink &sink, UErrorCode &errorCode) { … }
struct GetAllChildrenSink : public ResourceSink { … };
GetAllChildrenSink::~GetAllChildrenSink() { … }
U_CAPI void U_EXPORT2
ures_getAllChildrenWithFallback(const UResourceBundle *bundle, const char *path,
icu::ResourceSink &sink, UErrorCode &errorCode) { … }
}
U_CAPI void U_EXPORT2
ures_getValueWithFallback(const UResourceBundle *bundle, const char *path,
UResourceBundle *tempFillIn,
ResourceDataValue &value, UErrorCode &errorCode) { … }
U_CAPI void U_EXPORT2
ures_getAllItemsWithFallback(const UResourceBundle *bundle, const char *path,
icu::ResourceSink &sink, UErrorCode &errorCode) { … }
U_CAPI UResourceBundle* U_EXPORT2 ures_getByKey(const UResourceBundle *resB, const char* inKey, UResourceBundle *fillIn, UErrorCode *status) { … }
U_CAPI const char16_t* U_EXPORT2 ures_getStringByKey(const UResourceBundle *resB, const char* inKey, int32_t* len, UErrorCode *status) { … }
U_CAPI const char * U_EXPORT2
ures_getUTF8StringByKey(const UResourceBundle *resB,
const char *key,
char *dest, int32_t *pLength,
UBool forceCopy,
UErrorCode *status) { … }
U_CAPI const char* U_EXPORT2
ures_getLocaleInternal(const UResourceBundle* resourceBundle, UErrorCode* status)
{ … }
U_CAPI const char* U_EXPORT2
ures_getLocale(const UResourceBundle* resourceBundle,
UErrorCode* status)
{ … }
U_CAPI const char* U_EXPORT2
ures_getLocaleByType(const UResourceBundle* resourceBundle,
ULocDataLocaleType type,
UErrorCode* status) { … }
U_CFUNC const char* ures_getName(const UResourceBundle* resB) { … }
#ifdef URES_DEBUG
U_CFUNC const char* ures_getPath(const UResourceBundle* resB) {
if(resB == nullptr) {
return nullptr;
}
return resB->fData->fPath;
}
#endif
static UResourceBundle*
ures_openWithType(UResourceBundle *r, const char* path, const char* localeID,
UResOpenType openType, UErrorCode* status) { … }
U_CAPI UResourceBundle* U_EXPORT2
ures_open(const char* path, const char* localeID, UErrorCode* status) { … }
U_CAPI UResourceBundle* U_EXPORT2
ures_openNoDefault(const char* path, const char* localeID, UErrorCode* status) { … }
U_CAPI UResourceBundle* U_EXPORT2
ures_openDirect(const char* path, const char* localeID, UErrorCode* status) { … }
U_CAPI void U_EXPORT2
ures_openFillIn(UResourceBundle *r, const char* path,
const char* localeID, UErrorCode* status) { … }
U_CAPI void U_EXPORT2
ures_openDirectFillIn(UResourceBundle *r, const char* path, const char* localeID, UErrorCode* status) { … }
U_CAPI int32_t U_EXPORT2
ures_countArrayItems(const UResourceBundle* resourceBundle,
const char* resourceKey,
UErrorCode* status)
{ … }
U_CAPI const char* U_EXPORT2
ures_getVersionNumberInternal(const UResourceBundle *resourceBundle)
{ … }
U_CAPI const char* U_EXPORT2
ures_getVersionNumber(const UResourceBundle* resourceBundle)
{ … }
U_CAPI void U_EXPORT2 ures_getVersion(const UResourceBundle* resB, UVersionInfo versionInfo) { … }
#define INDEX_LOCALE_NAME …
#define INDEX_TAG …
#define DEFAULT_TAG …
#if defined(URES_TREE_DEBUG)
#include <stdio.h>
#endif
ULocalesContext;
static void U_CALLCONV
ures_loc_closeLocales(UEnumeration *enumerator) { … }
static int32_t U_CALLCONV
ures_loc_countLocales(UEnumeration *en, UErrorCode * ) { … }
U_CDECL_BEGIN
static const char * U_CALLCONV
ures_loc_nextLocale(UEnumeration* en,
int32_t* resultLength,
UErrorCode* status) { … }
static void U_CALLCONV
ures_loc_resetLocales(UEnumeration* en,
UErrorCode* ) { … }
U_CDECL_END
static const UEnumeration gLocalesEnum = …;
U_CAPI UEnumeration* U_EXPORT2
ures_openAvailableLocales(const char *path, UErrorCode *status)
{ … }
static UBool isLocaleInList(UEnumeration *locEnum, const char *locToSearch, UErrorCode *status) { … }
static void getParentForFunctionalEquivalent(const char* localeID,
UResourceBundle* res,
UResourceBundle* bund1,
CharString& parent) { … }
U_CAPI int32_t U_EXPORT2
ures_getFunctionalEquivalent(char *result, int32_t resultCapacity,
const char *path, const char *resName, const char *keyword, const char *locid,
UBool *isAvailable, UBool omitDefault, UErrorCode *status)
{ … }
U_CAPI UEnumeration* U_EXPORT2
ures_getKeywordValues(const char *path, const char *keyword, UErrorCode *status)
{ … }
#if 0
U_CAPI UBool U_EXPORT2
ures_equal(const UResourceBundle* res1, const UResourceBundle* res2){
if(res1==nullptr || res2==nullptr){
return res1==res2;
}
if(res1->fKey==nullptr|| res2->fKey==nullptr){
return (res1->fKey==res2->fKey);
}else{
if(uprv_strcmp(res1->fKey, res2->fKey)!=0){
return false;
}
}
if(uprv_strcmp(res1->fData->fName, res2->fData->fName)!=0){
return false;
}
if(res1->fData->fPath == nullptr|| res2->fData->fPath==nullptr){
return (res1->fData->fPath == res2->fData->fPath);
}else{
if(uprv_strcmp(res1->fData->fPath, res2->fData->fPath)!=0){
return false;
}
}
if(uprv_strcmp(res1->fData->fParent->fName, res2->fData->fParent->fName)!=0){
return false;
}
if(uprv_strcmp(res1->fData->fParent->fPath, res2->fData->fParent->fPath)!=0){
return false;
}
if(uprv_strncmp(res1->fResPath, res2->fResPath, res1->fResPathLen)!=0){
return false;
}
if(res1->fRes != res2->fRes){
return false;
}
return true;
}
U_CAPI UResourceBundle* U_EXPORT2
ures_clone(const UResourceBundle* res, UErrorCode* status){
UResourceBundle* bundle = nullptr;
UResourceBundle* ret = nullptr;
if(U_FAILURE(*status) || res == nullptr){
return nullptr;
}
bundle = ures_open(res->fData->fPath, res->fData->fName, status);
if(res->fResPath!=nullptr){
ret = ures_findSubResource(bundle, res->fResPath, nullptr, status);
ures_close(bundle);
}else{
ret = bundle;
}
return ret;
}
U_CAPI const UResourceBundle* U_EXPORT2
ures_getParentBundle(const UResourceBundle* res){
if(res==nullptr){
return nullptr;
}
return res->fParentRes;
}
#endif
U_CAPI void U_EXPORT2
ures_getVersionByKey(const UResourceBundle* res, const char *key, UVersionInfo ver, UErrorCode *status) { … }