U_CAPI void U_EXPORT2 u_init(UErrorCode *status) { UTRACE_ENTRY_OC(UTRACE_U_INIT); /* Make sure the global mutexes are initialized. */ umtx_init(NULL); umtx_lock(&gICUInitMutex); if (gICUInitialized || U_FAILURE(*status)) { umtx_unlock(&gICUInitMutex); UTRACE_EXIT_STATUS(*status); return; } /* Do any required init for services that don't have open operations * and use "only" the double-check initialization method for performance * reasons (avoiding a mutex lock even for _checking_ whether the * initialization had occurred). */ /* Char Properties */ uprv_loadPropsData(status); #if !UCONFIG_NO_NORMALIZATION /* Normalization */ unorm_haveData(status); #endif gICUInitialized = TRUE; /* TODO: don't set if U_FAILURE? */ umtx_unlock(&gICUInitMutex); UTRACE_EXIT_STATUS(*status); }
UConverter * ucnv_createAlgorithmicConverter(UConverter *myUConverter, UConverterType type, const char *locale, uint32_t options, UErrorCode *err) { UConverter *cnv; const UConverterSharedData *sharedData; UBool isAlgorithmicConverter; UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN_ALGORITHMIC); UTRACE_DATA1(UTRACE_OPEN_CLOSE, "open algorithmic converter type %d", (int32_t)type); if(type<0 || UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES<=type) { *err = U_ILLEGAL_ARGUMENT_ERROR; UTRACE_EXIT_STATUS(U_ILLEGAL_ARGUMENT_ERROR); return NULL; } sharedData = converterData[type]; umtx_lock(&cnvCacheMutex); isAlgorithmicConverter = (UBool)(sharedData == NULL || sharedData->referenceCounter != ~0); umtx_unlock(&cnvCacheMutex); if (isAlgorithmicConverter) { /* not a valid type, or not an algorithmic converter */ *err = U_ILLEGAL_ARGUMENT_ERROR; UTRACE_EXIT_STATUS(U_ILLEGAL_ARGUMENT_ERROR); return NULL; } cnv = ucnv_createConverterFromSharedData(myUConverter, (UConverterSharedData *)sharedData, "", locale != NULL ? locale : "", options, err); UTRACE_EXIT_PTR_STATUS(cnv, *err); return cnv; }
/* * ICU Initialization Function. Need not be called. */ U_CAPI void U_EXPORT2 u_init(UErrorCode *status) { UTRACE_ENTRY_OC(UTRACE_U_INIT); /* initialize plugins */ uplug_init(status); umtx_lock(&gICUInitMutex); if (gICUInitialized || U_FAILURE(*status)) { umtx_unlock(&gICUInitMutex); UTRACE_EXIT_STATUS(*status); return; } /* * 2005-may-02 * * ICU4C 3.4 (jitterbug 4497) hardcodes the data for Unicode character * properties for APIs that want to be fast. * Therefore, we need not load them here nor check for errors. * Instead, we load the converter alias table to see if any ICU data * is available. * Users should really open the service objects they need and check * for errors there, to make sure that the actual items they need are * available. */ #if !UCONFIG_NO_CONVERSION ucnv_io_countKnownConverters(status); #endif gICUInitialized = TRUE; /* TODO: don't set if U_FAILURE? */ umtx_unlock(&gICUInitMutex); UTRACE_EXIT_STATUS(*status); }
UConverter* ucnv_createConverterFromPackage(const char *packageName, const char *converterName, UErrorCode * err) { char cnvName[UCNV_MAX_CONVERTER_NAME_LENGTH], locale[ULOC_FULLNAME_CAPACITY]; UConverter *myUConverter; UConverterSharedData *mySharedConverterData; UConverterLoadArgs args={ 0 }; UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN_PACKAGE); if(U_FAILURE(*err)) { UTRACE_EXIT_STATUS(*err); return NULL; } UTRACE_DATA2(UTRACE_OPEN_CLOSE, "open converter %s from package %s", converterName, packageName); args.size=sizeof(UConverterLoadArgs); args.nestedLoads=1; args.pkg=packageName; /* first, get the options out of the converterName string */ parseConverterOptions(converterName, cnvName, locale, &args.options, err); if (U_FAILURE(*err)) { /* Very bad name used. */ UTRACE_EXIT_STATUS(*err); return NULL; } args.name=cnvName; /* open the data, unflatten the shared structure */ mySharedConverterData = createConverterFromFile(&args, err); if (U_FAILURE(*err)) { UTRACE_EXIT_STATUS(*err); return NULL; } /* create the actual converter */ myUConverter = ucnv_createConverterFromSharedData(NULL, mySharedConverterData, cnvName, locale, args.options, err); if (U_FAILURE(*err)) { ucnv_close(myUConverter); UTRACE_EXIT_STATUS(*err); return NULL; } UTRACE_EXIT_PTR_STATUS(myUConverter, *err); return myUConverter; }
U_CAPI void U_EXPORT2 u_init(UErrorCode *status) { UTRACE_ENTRY_OC(UTRACE_U_INIT); /* Make sure the global mutexes are initialized. */ umtx_init(NULL); umtx_lock(&gICUInitMutex); if (gICUInitialized || U_FAILURE(*status)) { umtx_unlock(&gICUInitMutex); UTRACE_EXIT_STATUS(*status); return; } #if 1 /* * 2005-may-02 * * ICU4C 3.4 (jitterbug 4497) hardcodes the data for Unicode character * properties for APIs that want to be fast. * Therefore, we need not load them here nor check for errors. * Instead, we load the converter alias table to see if any ICU data * is available. * Users should really open the service objects they need and check * for errors there, to make sure that the actual items they need are * available. */ #if !UCONFIG_NO_CONVERSION ucnv_io_countKnownConverters(status); #endif #else /* Do any required init for services that don't have open operations * and use "only" the double-check initialization method for performance * reasons (avoiding a mutex lock even for _checking_ whether the * initialization had occurred). */ /* Char Properties */ uprv_haveProperties(status); /* load the case and bidi properties but don't fail if they are not available */ u_isULowercase(0x61); u_getIntPropertyValue(0x200D, UCHAR_JOINING_TYPE); /* ZERO WIDTH JOINER: Join_Causing */ #if !UCONFIG_NO_NORMALIZATION /* Normalization */ unorm_haveData(status); #endif #endif gICUInitialized = TRUE; /* TODO: don't set if U_FAILURE? */ umtx_unlock(&gICUInitMutex); UTRACE_EXIT_STATUS(*status); }
UConverter * ucnv_createConverter(UConverter *myUConverter, const char *converterName, UErrorCode * err) { UConverterLookupData stackLookup; UConverterSharedData *mySharedConverterData; UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN); if(U_SUCCESS(*err)) { UTRACE_DATA1(UTRACE_OPEN_CLOSE, "open converter %s", converterName); mySharedConverterData = ucnv_loadSharedData(converterName, &stackLookup, err); if(U_SUCCESS(*err)) { myUConverter = ucnv_createConverterFromSharedData( myUConverter, mySharedConverterData, stackLookup.realName, stackLookup.locale, stackLookup.options, err); if(U_SUCCESS(*err)) { UTRACE_EXIT_PTR_STATUS(myUConverter, *err); return myUConverter; } else { ucnv_unloadSharedDataIfReady(mySharedConverterData); } } } /* exit with error */ UTRACE_EXIT_STATUS(*err); return NULL; }
/*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_END U_NAMESPACE_USE /* * ICU Initialization Function. Need not be called. */ U_CAPI void U_EXPORT2 u_init(UErrorCode *status) { UTRACE_ENTRY_OC(UTRACE_U_INIT); umtx_initOnce(gICUInitOnce, &initData, *status); UTRACE_EXIT_STATUS(*status); }