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; }
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; }
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 UCollator* ucol_open(const char *loc, UErrorCode *status) { U_NAMESPACE_USE UTRACE_ENTRY_OC(UTRACE_UCOL_OPEN); UTRACE_DATA1(UTRACE_INFO, "locale = \"%s\"", loc); UCollator *result = NULL; u_init(status); #if !UCONFIG_NO_SERVICE result = Collator::createUCollator(loc, status); if (result == NULL) #endif { result = ucol_open_internal(loc, status); } UTRACE_EXIT_PTR_STATUS(result, *status); return result; }
/*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_CAPI UCollator* U_EXPORT2 ucol_openFromShortString( const char *definition, UBool forceDefaults, UParseError *parseError, UErrorCode *status) { UTRACE_ENTRY_OC(UTRACE_UCOL_OPEN_FROM_SHORT_STRING); UTRACE_DATA1(UTRACE_INFO, "short string = \"%s\"", definition); if(U_FAILURE(*status)) return 0; UParseError internalParseError; if(!parseError) { parseError = &internalParseError; } parseError->line = 0; parseError->offset = 0; parseError->preContext[0] = 0; parseError->postContext[0] = 0; // first we want to pick stuff out of short string. // we'll end up with an UCA version, locale and a bunch of // settings // analyse the string in order to get everything we need. const char *string = definition; CollatorSpec s; ucol_sit_initCollatorSpecs(&s); string = ucol_sit_readSpecs(&s, definition, parseError, status); ucol_sit_calculateWholeLocale(&s); char buffer[internalBufferSize]; uprv_memset(buffer, 0, internalBufferSize); uloc_canonicalize(s.locale, buffer, internalBufferSize, status); UCollator *result = ucol_open(buffer, status); int32_t i = 0; for(i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) { if(s.options[i] != UCOL_DEFAULT) { if(forceDefaults || ucol_getAttribute(result, (UColAttribute)i, status) != s.options[i]) { ucol_setAttribute(result, (UColAttribute)i, s.options[i], status); } if(U_FAILURE(*status)) { parseError->offset = (int32_t)(string - definition); ucol_close(result); return NULL; } } } if(s.variableTopSet) { if(s.variableTopString[0]) { ucol_setVariableTop(result, s.variableTopString, s.variableTopStringLen, status); } else { // we set by value, using 'B' ucol_restoreVariableTop(result, s.variableTopValue, status); } } if(U_FAILURE(*status)) { // here it can only be a bogus value ucol_close(result); result = NULL; } UTRACE_EXIT_PTR_STATUS(result, *status); return result; }