U_CDECL_END /** * Load the property names data. Caller should check that data is * not loaded BEFORE calling this function. Returns TRUE if the load * succeeds. */ static UBool _load() { UErrorCode ec = U_ZERO_ERROR; UDataMemory* data = udata_openChoice(0, PNAME_DATA_TYPE, PNAME_DATA_NAME, isPNameAcceptable, 0, &ec); if (U_SUCCESS(ec)) { umtx_lock(NULL); if (UDATA == NULL) { UDATA = data; PNAME = (const PropertyAliases*) udata_getMemory(UDATA); ucln_common_registerCleanup(UCLN_COMMON_PNAME, pname_cleanup); data = NULL; } umtx_unlock(NULL); } if (data) { udata_close(data); } return PNAME!=NULL; }
U_CFUNC void res_unload(ResourceData *pResData) { if(pResData->data!=NULL) { udata_close(pResData->data); pResData->data=NULL; } }
UBool timeZone_cleanup() { // Aliases into UDATA_MEMORY; do NOT delete DATA = NULL; INDEX_BY_ID = NULL; INDEX_BY_OFFSET = NULL; INDEX_BY_COUNTRY = NULL; delete []ZONE_IDS; ZONE_IDS = NULL; delete DEFAULT_ZONE; DEFAULT_ZONE = NULL; delete _GMT; _GMT = NULL; if (UDATA_MEMORY) { udata_close(UDATA_MEMORY); UDATA_MEMORY = NULL; } if (LOCK) { umtx_destroy(&LOCK); LOCK = NULL; } return TRUE; }
static UDataMemory *doLoadFromIndividualFiles(const char *pkgName, const char *dataPath, const char *tocEntryPathSuffix, /* following arguments are the same as doOpenChoice itself */ const char *path, const char *type, const char *name, UDataMemoryIsAcceptable *isAcceptable, void *context, UErrorCode *subErrorCode, UErrorCode *pErrorCode) { UDataMemory *retVal = NULL; const char *pathBuffer; UDataMemory dataMemory; UDataMemory *pEntryData; UDataPathIterator iter; /* look in ind. files: package\nam.typ ========================= */ /* init path iterator for individual files */ udata_pathiter_init(&iter, dataPath, pkgName, path, tocEntryPathSuffix, FALSE); while((pathBuffer = udata_pathiter_next(&iter))) { #ifdef UDATA_DEBUG fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer); #endif if(uprv_mapFile(&dataMemory, pathBuffer)) { pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, subErrorCode, pErrorCode); if (pEntryData != NULL) { /* Data is good. * Hand off ownership of the backing memory to the user's UDataMemory. * and return it. */ pEntryData->mapAddr = dataMemory.mapAddr; pEntryData->map = dataMemory.map; #ifdef UDATA_DEBUG fprintf(stderr, "** Mapped file: %s\n", pathBuffer); #endif retVal = pEntryData; goto commonReturn; } /* the data is not acceptable, or some error occured. Either way, unmap the memory */ udata_close(&dataMemory); /* If we had a nasty error, bail out completely. */ if (U_FAILURE(*pErrorCode)) { retVal = NULL; goto commonReturn; } /* Otherwise remember that we found data but didn't like it for some reason */ *subErrorCode=U_INVALID_FORMAT_ERROR; } #ifdef UDATA_DEBUG fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded"); #endif } commonReturn: udata_pathiter_dt(&iter); return retVal; }
static void TestUDataOpenChoiceDemo1() { UDataMemory *result; UErrorCode status=U_ZERO_ERROR; const char* name[]={ "cnvalias", "unames", "test" }; const char* type="icu"; const char* testPath="testdata"; result=udata_openChoice(NULL, "icu", name[0], isAcceptable1, NULL, &status); if(U_FAILURE(status)){ log_err("FAIL: udata_openChoice() failed name=%s, type=%s, \n errorcode=%s\n", name[0], type, myErrorName(status)); } else { log_verbose("PASS: udata_openChoice worked\n"); udata_close(result); } result=udata_openChoice(NULL, type, name[1], isAcceptable1, NULL, &status); if(U_FAILURE(status)){ status=U_ZERO_ERROR; result=udata_openChoice(NULL, type, name[1], isAcceptable2, NULL, &status); if(U_FAILURE(status)){ log_err("FAIL: udata_openChoice() failed name=%s, type=%s, \n errorcode=%s\n", name[1], type, myErrorName(status)); } } if(U_SUCCESS(status)){ udata_close(result); } result=udata_openChoice(testPath, type, name[2], isAcceptable1, NULL, &status); if(U_FAILURE(status)){ status=U_ZERO_ERROR; result=udata_openChoice(testPath, type, name[2], isAcceptable3, NULL, &status); if(U_FAILURE(status)){ log_err("FAIL: udata_openChoice() failed path=%s name=%s, type=%s, \n errorcode=%s\n", testPath, name[2], type, myErrorName(status)); } } if(U_SUCCESS(status)){ udata_close(result); } }
//----------------------------------------------------------------------------- // // Destructor. Don't call this - use removeReference() instead. // //----------------------------------------------------------------------------- RBBIDataWrapper::~RBBIDataWrapper() { U_ASSERT(fRefCount == 0); if (fUDataMem) { udata_close(fUDataMem); } else if (!fDontFreeData) { uprv_free((void *)fHeader); } }
static UBool U_CALLCONV pname_cleanup(void) { if (UDATA) { udata_close(UDATA); UDATA = NULL; } PNAME = NULL; return TRUE; }
U_CDECL_END /* do not close UCA returned by ucol_initUCA! */ UCollator * ucol_initUCA(UErrorCode *status) { if(U_FAILURE(*status)) { return NULL; } UBool needsInit; UMTX_CHECK(NULL, (_staticUCA == NULL), needsInit); if(needsInit) { UDataMemory *result = udata_openChoice(U_ICUDATA_COLL, UCA_DATA_TYPE, UCA_DATA_NAME, isAcceptableUCA, NULL, status); if(U_SUCCESS(*status)){ UCollator *newUCA = ucol_initCollator((const UCATableHeader *)udata_getMemory(result), NULL, NULL, status); if(U_SUCCESS(*status)){ // Initalize variables for implicit generation uprv_uca_initImplicitConstants(status); umtx_lock(NULL); if(_staticUCA == NULL) { UCA_DATA_MEM = result; _staticUCA = newUCA; newUCA = NULL; result = NULL; } umtx_unlock(NULL); ucln_i18n_registerCleanup(UCLN_I18N_UCOL_RES, ucol_res_cleanup); if(newUCA != NULL) { ucol_close(newUCA); udata_close(result); } }else{ ucol_close(newUCA); udata_close(result); } } else { udata_close(result); } } return _staticUCA; }
U_CAPI void U_EXPORT2 ucase_close(UCaseProps *csp) { if(csp!=NULL) { #if !UCASE_HARDCODE_DATA udata_close(csp->mem); #endif uprv_free(csp); } }
U_CAPI void U_EXPORT2 ubidi_closeProps(UBiDiProps *bdp) { if(bdp!=NULL) { #if !UBIDI_HARDCODE_DATA udata_close(bdp->mem); #endif uprv_free(bdp); } }
static void TestUDataGetMemory() { UDataMemory *result; const int32_t *table=NULL; uint16_t* intValue=0; UErrorCode status=U_ZERO_ERROR; const char* name="cnvalias"; const char* type; const char* name2="test"; const char* testPath = loadTestData(&status); type="icu"; log_verbose("Testing udata_getMemory() for \"cnvalias.icu\"\n"); result=udata_openChoice(NULL, type, name, isAcceptable1, NULL, &status); if(U_FAILURE(status)){ log_err("FAIL: udata_openChoice() failed for name=%s, type=%s, \n errorcode=%s\n", name, type, myErrorName(status)); return; } table=(const int32_t *)udata_getMemory(result); /* The alias table may list more converters than what's actually available now. [grhoten] */ if(ucnv_countAvailable() > table[1]) /*???*/ log_err("FAIL: udata_getMemory() failed ucnv_countAvailable returned = %d, expected = %d\n", ucnv_countAvailable(), table[1+2*(*table)]); udata_close(result); type="icu"; log_verbose("Testing udata_getMemory for \"test.icu\"()\n"); result=udata_openChoice(testPath, type, name2, isAcceptable3, NULL, &status); if(U_FAILURE(status)){ log_err("FAIL: udata_openChoice() failed for path=%s name=%s, type=%s, \n errorcode=%s\n", testPath, name2, type, myErrorName(status)); return; } intValue=(uint16_t *)udata_getMemory(result); /*printf("%d ..... %s", *(intValue), intValue+1));*/ if( *intValue != 2000 || strcmp((char*)(intValue+1), "YEAR") != 0 ) log_err("FAIL: udata_getMemory() failed: intValue :- Expected:2000 Got:%d \n\tstringValue:- Expected:YEAR Got:%s\n", *intValue, (intValue+1)); udata_close(result); }
static UBool U_CALLCONV ucnv_io_cleanup(void) { if (gAliasData) { udata_close(gAliasData); gAliasData = NULL; } uprv_memset(&gMainTable, 0, sizeof(gMainTable)); return TRUE; /* Everything was cleaned up */ }
SpoofData::~SpoofData() { if (fDataOwned) { uprv_free(fRawData); } fRawData = NULL; if (fUDM != NULL) { udata_close(fUDM); } fUDM = NULL; }
static int8_t uprv_loadPropsData(UErrorCode *pErrorCode) { /* load Unicode character properties data from file if necessary */ /* * This lazy intialization with double-checked locking (without mutex protection for * haveNormData==0) is transiently unsafe under certain circumstances. * Check the readme and use u_init() if necessary. */ if(havePropsData==0) { UCharProps ucp={ NULL }; if(U_FAILURE(*pErrorCode)) { return havePropsData; } /* open the data outside the mutex block */ _openProps(&ucp, pErrorCode); if(U_SUCCESS(*pErrorCode)) { /* in the mutex block, set the data for this process */ umtx_lock(NULL); if(propsData==NULL) { propsData=ucp.propsData; ucp.propsData=NULL; pData32=ucp.pData32; ucp.pData32=NULL; uprv_memcpy(&propsTrie, &ucp.propsTrie, sizeof(propsTrie)); uprv_memcpy(&propsVectorsTrie, &ucp.propsVectorsTrie, sizeof(propsVectorsTrie)); } /* initialize some variables */ uprv_memcpy(indexes, pData32, sizeof(indexes)); /* additional properties */ if(indexes[UPROPS_ADDITIONAL_VECTORS_INDEX]!=0) { propsVectors=pData32+indexes[UPROPS_ADDITIONAL_VECTORS_INDEX]; countPropsVectors=indexes[UPROPS_RESERVED_INDEX]-indexes[UPROPS_ADDITIONAL_VECTORS_INDEX]; propsVectorsColumns=indexes[UPROPS_ADDITIONAL_VECTORS_COLUMNS_INDEX]; } havePropsData=1; umtx_unlock(NULL); } else { dataErrorCode=*pErrorCode; havePropsData=-1; } ucln_common_registerCleanup(UCLN_COMMON_UCHAR, uchar_cleanup); /* if a different thread set it first, then close the extra data */ udata_close(ucp.propsData); /* NULL if it was set correctly */ } return havePropsData; }
DictionaryMatcher * ICULanguageBreakFactory::loadDictionaryMatcherFor(UScriptCode script, int32_t /* brkType */) { UErrorCode status = U_ZERO_ERROR; // open root from brkitr tree. UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, "", &status); b = ures_getByKeyWithFallback(b, "dictionaries", b, &status); int32_t dictnlength = 0; const UChar *dictfname = ures_getStringByKeyWithFallback(b, uscript_getShortName(script), &dictnlength, &status); if (U_FAILURE(status)) { ures_close(b); return NULL; } CharString dictnbuf; CharString ext; const UChar *extStart = u_memrchr(dictfname, 0x002e, dictnlength); // last dot if (extStart != NULL) { int32_t len = (int32_t)(extStart - dictfname); ext.appendInvariantChars(UnicodeString(FALSE, extStart + 1, dictnlength - len - 1), status); dictnlength = len; } dictnbuf.appendInvariantChars(UnicodeString(FALSE, dictfname, dictnlength), status); ures_close(b); UDataMemory *file = udata_open(U_ICUDATA_BRKITR, ext.data(), dictnbuf.data(), &status); if (U_SUCCESS(status)) { // build trie const uint8_t *data = (const uint8_t *)udata_getMemory(file); const int32_t *indexes = (const int32_t *)data; const int32_t offset = indexes[DictionaryData::IX_STRING_TRIE_OFFSET]; const int32_t trieType = indexes[DictionaryData::IX_TRIE_TYPE] & DictionaryData::TRIE_TYPE_MASK; DictionaryMatcher *m = NULL; if (trieType == DictionaryData::TRIE_TYPE_BYTES) { const int32_t transform = indexes[DictionaryData::IX_TRANSFORM]; const char *characters = (const char *)(data + offset); m = new BytesDictionaryMatcher(characters, transform, file); } else if (trieType == DictionaryData::TRIE_TYPE_UCHARS) { const UChar *characters = (const UChar *)(data + offset); m = new UCharsDictionaryMatcher(characters, file); } if (m == NULL) { // no matcher exists to take ownership - either we are an invalid // type or memory allocation failed udata_close(file); } return m; } else if (dictfname != NULL) { // we don't have a dictionary matcher. // returning NULL here will cause us to fail to find a dictionary break engine, as expected status = U_ZERO_ERROR; return NULL; } return NULL; }
static void TestUDataOpenChoiceDemo2() { UDataMemory *result; UErrorCode status=U_ZERO_ERROR; int i; int p=2; const char* name="test"; const char* type="icu"; const char* path = loadTestData(&status); result=udata_openChoice(path, type, name, isAcceptable, &p, &status); if(U_FAILURE(status)){ log_err("failed to load data at p=%s t=%s n=%s, isAcceptable", path, type, name); } if(U_SUCCESS(status) ) { udata_close(result); } p=0; for(i=0;i<2; i++){ result=udata_openChoice(path, type, name, isAcceptable, &p, &status); if(p<2) { if(U_FAILURE(status) && status==U_INVALID_FORMAT_ERROR){ log_verbose("Loads the data but rejects it as expected %s\n", myErrorName(status)); status=U_ZERO_ERROR; p++; } else { log_err("FAIL: failed to either load the data or to reject the loaded data. ERROR=%s\n", myErrorName(status) ); } } else if(p == 2) { if(U_FAILURE(status)) { log_err("FAIL: failed to load the data and accept it. ERROR=%s\n", myErrorName(status) ); } else { log_verbose("Loads the data and accepts it for p==2 as expected\n"); udata_close(result); } } } }
static UBool U_CALLCONV udata_cleanup(void) { if (gCommonDataCache) { /* Delete the cache of user data mappings. */ uhash_close(gCommonDataCache); /* Table owns the contents, and will delete them. */ gCommonDataCache = NULL; /* Cleanup is not thread safe. */ } if (gCommonICUData != NULL) { udata_close(gCommonICUData); /* Clean up common ICU Data */ gCommonICUData = NULL; } if (gStubICUData != NULL) { udata_close(gStubICUData); /* Clean up the stub ICU Data */ gStubICUData = NULL; } return TRUE; /* Everything was cleaned up */ }
SpoofData::~SpoofData() { utrie2_close(fAnyCaseTrie); fAnyCaseTrie = NULL; utrie2_close(fLowerCaseTrie); fLowerCaseTrie = NULL; if (fDataOwned) { uprv_free(fRawData); } fRawData = NULL; if (fUDM != NULL) { udata_close(fUDM); } fUDM = NULL; }
U_CDECL_BEGIN static UBool U_CALLCONV ucol_res_cleanup(void) { if (UCA_DATA_MEM) { udata_close(UCA_DATA_MEM); UCA_DATA_MEM = NULL; } if (_staticUCA) { ucol_close(_staticUCA); _staticUCA = NULL; } return TRUE; }
extern int main(int argc, const char *argv[]) { UDataMemory *result = NULL; UErrorCode status=U_ZERO_ERROR; uint16_t intValue = 0; char *string = NULL; uint16_t *intPointer = NULL; const void *dataMemory = NULL; char curPathBuffer[1024]; #ifdef WIN32 char *currdir = _getcwd(NULL, 0); #else char *currdir = getcwd(NULL, 0); #endif /* need to put "current/dir" as path */ strcpy(curPathBuffer, currdir); result=udata_openChoice(curPathBuffer, DATA_TYPE, DATA_NAME, isAcceptable, NULL, &status); if(currdir != NULL) { free(currdir); } if(U_FAILURE(status)){ printf("Failed to open data file example.dat in %s with error number %d\n", curPathBuffer, status); return -1; } dataMemory = udata_getMemory(result); intPointer = (uint16_t *)dataMemory; printf("Read value %d from data file\n", *intPointer); string = (char *) (intPointer+1); printf("Read string %s from data file\n", string); if(U_SUCCESS(status)){ udata_close(result); } return 0; }
static UBool U_CALLCONV uchar_cleanup(void) { if (propsData) { udata_close(propsData); propsData=NULL; } pData32=NULL; propsVectors=NULL; countPropsVectors=0; uprv_memset(dataVersion, 0, U_MAX_VERSION_LENGTH); dataErrorCode=U_ZERO_ERROR; havePropsData=0; return TRUE; }
U_CDECL_BEGIN static UBool U_CALLCONV unorm_cleanup(void) { #if !UNORM_HARDCODE_DATA if(normData!=NULL) { udata_close(normData); normData=NULL; } dataErrorCode=U_ZERO_ERROR; haveNormData=0; #endif return TRUE; }
/*----------------------------------------------------------------------* * * * checkCommonData Validate the format of a common data file. * * Fill in the virtual function ptr based on TOC type * * If the data is invalid, close the UDataMemory * * and set the appropriate error code. * * * *----------------------------------------------------------------------*/ U_CFUNC void udata_checkCommonData(UDataMemory *udm, UErrorCode *err) { if (U_FAILURE(*err)) { return; } if(udm==NULL || udm->pHeader==NULL) { *err=U_INVALID_FORMAT_ERROR; } else if(!(udm->pHeader->dataHeader.magic1==0xda && udm->pHeader->dataHeader.magic2==0x27 && udm->pHeader->info.isBigEndian==U_IS_BIG_ENDIAN && udm->pHeader->info.charsetFamily==U_CHARSET_FAMILY) ) { /* header not valid */ *err=U_INVALID_FORMAT_ERROR; } else if (udm->pHeader->info.dataFormat[0]==0x43 && udm->pHeader->info.dataFormat[1]==0x6d && udm->pHeader->info.dataFormat[2]==0x6e && udm->pHeader->info.dataFormat[3]==0x44 && udm->pHeader->info.formatVersion[0]==1 ) { /* dataFormat="CmnD" */ udm->vFuncs = &CmnDFuncs; udm->toc=(const char *)udm->pHeader+udata_getHeaderSize(udm->pHeader); } else if(udm->pHeader->info.dataFormat[0]==0x54 && udm->pHeader->info.dataFormat[1]==0x6f && udm->pHeader->info.dataFormat[2]==0x43 && udm->pHeader->info.dataFormat[3]==0x50 && udm->pHeader->info.formatVersion[0]==1 ) { /* dataFormat="ToCP" */ udm->vFuncs = &ToCPFuncs; udm->toc=(const char *)udm->pHeader+udata_getHeaderSize(udm->pHeader); } else { /* dataFormat not recognized */ *err=U_INVALID_FORMAT_ERROR; } if (U_FAILURE(*err)) { /* If the data is no good and we memory-mapped it ourselves, * close the memory mapping so it doesn't leak. Note that this has * no effect on non-memory mapped data, other than clearing fields in udm. */ udata_close(udm); } }
/* Deletes (frees) the Shared data it's passed. first it checks the referenceCounter to * see if anyone is using it, if not it frees all the memory stemming from sharedConverterData and * returns TRUE, * otherwise returns FALSE * @param sharedConverterData The shared data * @return if not it frees all the memory stemming from sharedConverterData and * returns TRUE, otherwise returns FALSE */ static UBool ucnv_deleteSharedConverterData(UConverterSharedData * deadSharedData) { UTRACE_ENTRY_OC(UTRACE_UCNV_UNLOAD); UTRACE_DATA2(UTRACE_OPEN_CLOSE, "unload converter %s shared data %p", deadSharedData->staticData->name, deadSharedData); if (deadSharedData->referenceCounter > 0) { UTRACE_EXIT_VALUE((int32_t)FALSE); return FALSE; } if (deadSharedData->impl->unload != NULL) { deadSharedData->impl->unload(deadSharedData); } if(deadSharedData->dataMemory != NULL) { UDataMemory *data = (UDataMemory*)deadSharedData->dataMemory; udata_close(data); } if(deadSharedData->table != NULL) { uprv_free(deadSharedData->table); } #if 0 /* if the static data is actually owned by the shared data */ /* enable if we ever have this situation. */ if(deadSharedData->staticDataOwned == TRUE) /* see ucnv_bld.h */ { uprv_free((void*)deadSharedData->staticData); } #endif #if 0 /* Zap it ! */ uprv_memset(deadSharedData->0, sizeof(*deadSharedData)); #endif uprv_free(deadSharedData); UTRACE_EXIT_VALUE((int32_t)TRUE); return TRUE; }
static void TestSwapData() { char name[100]; UDataMemory *pData; uint8_t *buffer; const char *pkg, *nm; UErrorCode errorCode; int32_t i; buffer=(uint8_t *)uprv_malloc(2*SWAP_BUFFER_SIZE); if(buffer==NULL) { log_err("unable to allocate %d bytes\n", 2*SWAP_BUFFER_SIZE); return; } for(i=0; i<LENGTHOF(swapCases); ++i) { /* build the name for logging */ errorCode=U_ZERO_ERROR; if(swapCases[i].name[0]=='*') { pkg=loadTestData(&errorCode); nm=swapCases[i].name+1; uprv_strcpy(name, "testdata"); } else { pkg=NULL; nm=swapCases[i].name; uprv_strcpy(name, "NULL"); } uprv_strcat(name, "/"); uprv_strcat(name, nm); uprv_strcat(name, "."); uprv_strcat(name, swapCases[i].type); pData=udata_open(pkg, swapCases[i].type, nm, &errorCode); if(U_SUCCESS(errorCode)) { TestSwapCase(pData, name, swapCases[i].swapFn, buffer, buffer+SWAP_BUFFER_SIZE); udata_close(pData); } else { log_data_err("udata_open(%s) failed - %s\n", name, u_errorName(errorCode)); } } uprv_free(buffer); }
U_CAPI UCaseProps * U_EXPORT2 ucase_open(UErrorCode *pErrorCode) { UCaseProps cspProto={ NULL }, *csp; cspProto.mem=udata_openChoice(NULL, UCASE_DATA_TYPE, UCASE_DATA_NAME, isAcceptable, &cspProto, pErrorCode); if(U_FAILURE(*pErrorCode)) { return NULL; } csp=ucase_openData( &cspProto, udata_getMemory(cspProto.mem), udata_getLength(cspProto.mem), pErrorCode); if(U_FAILURE(*pErrorCode)) { udata_close(cspProto.mem); return NULL; } else { return csp; } }
U_CAPI UBiDiProps * U_EXPORT2 ubidi_openProps(UErrorCode *pErrorCode) { UBiDiProps bdpProto={ NULL }, *bdp; bdpProto.mem=udata_openChoice(NULL, UBIDI_DATA_TYPE, UBIDI_DATA_NAME, isAcceptable, &bdpProto, pErrorCode); if(U_FAILURE(*pErrorCode)) { return NULL; } bdp=ubidi_openData( &bdpProto, udata_getMemory(bdpProto.mem), udata_getLength(bdpProto.mem), pErrorCode); if(U_FAILURE(*pErrorCode)) { udata_close(bdpProto.mem); return NULL; } else { return bdp; } }
/*Takes an alias name gets an actual converter file name *goes to disk and opens it. *allocates the memory and returns a new UConverter object */ static UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs, UErrorCode * err) { UDataMemory *data; UConverterSharedData *sharedData; UTRACE_ENTRY_OC(UTRACE_UCNV_LOAD); if (err == NULL || U_FAILURE (*err)) { UTRACE_EXIT_STATUS(*err); return NULL; } UTRACE_DATA2(UTRACE_OPEN_CLOSE, "load converter %s from package %s", pArgs->name, pArgs->pkg); data = udata_openChoice(pArgs->pkg, DATA_TYPE, pArgs->name, isCnvAcceptable, NULL, err); if(U_FAILURE(*err)) { UTRACE_EXIT_STATUS(*err); return NULL; } sharedData = ucnv_data_unFlattenClone(pArgs, data, err); if(U_FAILURE(*err)) { udata_close(data); UTRACE_EXIT_STATUS(*err); return NULL; } /* * TODO Store pkg in a field in the shared data so that delta-only converters * can load base converters from the same package. * If the pkg name is longer than the field, then either do not load the converter * in the first place, or just set the pkg field to "". */ UTRACE_EXIT_PTR_STATUS(sharedData, *err); return sharedData; }
U_NAMESPACE_BEGIN // ------------------------------------- BreakIterator* BreakIterator::buildInstance(const Locale& loc, const char *type, int32_t kind, UErrorCode &status) { char fnbuff[256]; char ext[4]={'\0'}; char actualLocale[ULOC_FULLNAME_CAPACITY]; int32_t size; const UChar* brkfname = NULL; UResourceBundle brkRulesStack; UResourceBundle brkNameStack; UResourceBundle *brkRules = &brkRulesStack; UResourceBundle *brkName = &brkNameStack; RuleBasedBreakIterator *result = NULL; if (U_FAILURE(status)) return NULL; ures_initStackObject(brkRules); ures_initStackObject(brkName); // Get the locale UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, loc.getName(), &status); /* this is a hack for now. Should be fixed when the data is fetched from brk_index.txt */ if(status==U_USING_DEFAULT_WARNING){ status=U_ZERO_ERROR; ures_openFillIn(b, U_ICUDATA_BRKITR, "", &status); } // Get the "boundaries" array. if (U_SUCCESS(status)) { brkRules = ures_getByKeyWithFallback(b, "boundaries", brkRules, &status); // Get the string object naming the rules file brkName = ures_getByKeyWithFallback(brkRules, type, brkName, &status); // Get the actual string brkfname = ures_getString(brkName, &size, &status); U_ASSERT((size_t)size<sizeof(fnbuff)); if ((size_t)size>=sizeof(fnbuff)) { size=0; if (U_SUCCESS(status)) { status = U_BUFFER_OVERFLOW_ERROR; } } // Use the string if we found it if (U_SUCCESS(status) && brkfname) { uprv_strncpy(actualLocale, ures_getLocale(brkName, &status), sizeof(actualLocale)/sizeof(actualLocale[0])); UChar* extStart=u_strchr(brkfname, 0x002e); int len = 0; if(extStart!=NULL){ len = (int)(extStart-brkfname); u_UCharsToChars(extStart+1, ext, sizeof(ext)); // nul terminates the buff u_UCharsToChars(brkfname, fnbuff, len); } fnbuff[len]=0; // nul terminate } } ures_close(brkRules); ures_close(brkName); UDataMemory* file = udata_open(U_ICUDATA_BRKITR, ext, fnbuff, &status); if (U_FAILURE(status)) { ures_close(b); return NULL; } // Create a RuleBasedBreakIterator result = new RuleBasedBreakIterator(file, status); // If there is a result, set the valid locale and actual locale, and the kind if (U_SUCCESS(status) && result != NULL) { U_LOCALE_BASED(locBased, *(BreakIterator*)result); locBased.setLocaleIDs(ures_getLocaleByType(b, ULOC_VALID_LOCALE, &status), actualLocale); result->setBreakType(kind); } ures_close(b); if (U_FAILURE(status) && result != NULL) { // Sometimes redundant check, but simple delete result; return NULL; } if (result == NULL) { udata_close(file); if (U_SUCCESS(status)) { status = U_MEMORY_ALLOCATION_ERROR; } } return result; }
static UBool haveAliasData(UErrorCode *pErrorCode) { int needInit; if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return FALSE; } UMTX_CHECK(NULL, (gAliasData==NULL), needInit); /* load converter alias data from file if necessary */ if (needInit) { UDataMemory *data; const uint16_t *table; const uint32_t *sectionSizes; uint32_t tableStart; uint32_t currOffset; data = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, pErrorCode); if(U_FAILURE(*pErrorCode)) { return FALSE; } sectionSizes = (const uint32_t *)udata_getMemory(data); table = (const uint16_t *)sectionSizes; tableStart = sectionSizes[0]; if (tableStart < minTocLength) { *pErrorCode = U_INVALID_FORMAT_ERROR; udata_close(data); return FALSE; } umtx_lock(NULL); if(gAliasData==NULL) { gMainTable.converterListSize = sectionSizes[1]; gMainTable.tagListSize = sectionSizes[2]; gMainTable.aliasListSize = sectionSizes[3]; gMainTable.untaggedConvArraySize = sectionSizes[4]; gMainTable.taggedAliasArraySize = sectionSizes[5]; gMainTable.taggedAliasListsSize = sectionSizes[6]; gMainTable.optionTableSize = sectionSizes[7]; gMainTable.stringTableSize = sectionSizes[8]; if (tableStart > 8) { gMainTable.normalizedStringTableSize = sectionSizes[9]; } currOffset = tableStart * (sizeof(uint32_t)/sizeof(uint16_t)) + (sizeof(uint32_t)/sizeof(uint16_t)); gMainTable.converterList = table + currOffset; currOffset += gMainTable.converterListSize; gMainTable.tagList = table + currOffset; currOffset += gMainTable.tagListSize; gMainTable.aliasList = table + currOffset; currOffset += gMainTable.aliasListSize; gMainTable.untaggedConvArray = table + currOffset; currOffset += gMainTable.untaggedConvArraySize; gMainTable.taggedAliasArray = table + currOffset; /* aliasLists is a 1's based array, but it has a padding character */ currOffset += gMainTable.taggedAliasArraySize; gMainTable.taggedAliasLists = table + currOffset; currOffset += gMainTable.taggedAliasListsSize; if (gMainTable.optionTableSize > 0 && ((const UConverterAliasOptions *)(table + currOffset))->stringNormalizationType < UCNV_IO_NORM_TYPE_COUNT) { /* Faster table */ gMainTable.optionTable = (const UConverterAliasOptions *)(table + currOffset); } else { /* Smaller table, or I can't handle this normalization mode! Use the original slower table lookup. */ gMainTable.optionTable = &defaultTableOptions; } currOffset += gMainTable.optionTableSize; gMainTable.stringTable = table + currOffset; currOffset += gMainTable.stringTableSize; gMainTable.normalizedStringTable = ((gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED) ? gMainTable.stringTable : (table + currOffset)); ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup); gAliasData = data; data=NULL; } umtx_unlock(NULL); /* if a different thread set it first, then close the extra data */ if(data!=NULL) { udata_close(data); /* NULL if it was set correctly */ } } return TRUE; }