diff --git a/.gitignore b/.gitignore index 8244b963207..480af807826 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ icu4c/source/common/*.plg icu4c/source/common/*.vcxproj.user icu4c/source/common/Debug icu4c/source/common/Makefile +icu4c/source/common/Makefile.local icu4c/source/common/Release icu4c/source/common/common.res icu4c/source/common/common.vcproj.*.*.user diff --git a/icu4c/source/common/putil.cpp b/icu4c/source/common/putil.cpp index f65eb1b3660..7c9536b5b6e 100644 --- a/icu4c/source/common/putil.cpp +++ b/icu4c/source/common/putil.cpp @@ -1,7 +1,7 @@ /* ****************************************************************************** * -* Copyright (C) 1997-2011, International Business Machines +* Copyright (C) 1997-2012, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** @@ -2118,8 +2118,8 @@ uprv_dl_open(const char *libName, UErrorCode *status) { if(U_FAILURE(*status)) return ret; ret = dlopen(libName, RTLD_NOW|RTLD_GLOBAL); if(ret==NULL) { -#ifndef U_TRACE_DYLOAD - perror("dlopen"); +#ifdef U_TRACE_DYLOAD + printf("dlerror on dlopen(%s): %s\n", libName, dlerror()); #endif *status = U_MISSING_RESOURCE_ERROR; } @@ -2142,6 +2142,9 @@ uprv_dlsym_func(void *lib, const char* sym, UErrorCode *status) { if(U_FAILURE(*status)) return uret.fp; uret.vp = dlsym(lib, sym); if(uret.vp == NULL) { +#ifdef U_TRACE_DYLOAD + printf("dlerror on dlsym(%p,%s): %s\n", lib,sym, dlerror()); +#endif *status = U_MISSING_RESOURCE_ERROR; } return uret.fp; diff --git a/icu4c/source/common/udata.cpp b/icu4c/source/common/udata.cpp index bdf910a4cde..c4f8752a4eb 100644 --- a/icu4c/source/common/udata.cpp +++ b/icu4c/source/common/udata.cpp @@ -1,7 +1,7 @@ /* ****************************************************************************** * -* Copyright (C) 1999-2011, International Business Machines +* Copyright (C) 1999-2012, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** diff --git a/icu4c/source/i18n/coll.cpp b/icu4c/source/i18n/coll.cpp index 3f05f696e45..a3564016b03 100644 --- a/icu4c/source/i18n/coll.cpp +++ b/icu4c/source/i18n/coll.cpp @@ -1,6 +1,6 @@ /* ****************************************************************************** - * Copyright (C) 1996-2011, International Business Machines Corporation and + * Copyright (C) 1996-2012, International Business Machines Corporation and * others. All Rights Reserved. ****************************************************************************** */ @@ -250,6 +250,17 @@ Collator::createUCollator(const char *loc, result = rbc->ucollator; rbc->ucollator = NULL; // to prevent free on delete } + } else { + // should go in a function- ucol_initDelegate(delegate) + result = (UCollator *)uprv_malloc(sizeof(UCollator)); + if(result == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + } else { + uprv_memset(result, 0, sizeof(UCollator)); + result->delegate = col; + result->freeOnClose = TRUE; // do free on close. + col = NULL; // to prevent free on delete. + } } delete col; } @@ -326,6 +337,7 @@ Collator* U_EXPORT2 Collator::createInstance(const Locale& desiredLocale, Locale actualLoc; Collator *result = (Collator*)gService->get(desiredLocale, &actualLoc, status); + // Ugly Hack Alert! If the returned locale is empty (not root, // but empty -- getName() == "") then that means the service // returned a default object, not a "real" service object. In @@ -876,6 +888,16 @@ Collator::getEquivalentReorderCodes(int32_t /* reorderCode */, return 0; } +int32_t U_EXPORT2 Collator::internalGetShortDefinitionString(const char */*locale*/, + char */*buffer*/, + int32_t /*capacity*/, + UErrorCode &status) { + if(U_SUCCESS(status)) { + status = U_UNSUPPORTED_ERROR; /* Shouldn't happen, internal function */ + } + return 0; +} + // UCollator private data members ---------------------------------------- /* This is useless information */ diff --git a/icu4c/source/i18n/tblcoll.cpp b/icu4c/source/i18n/tblcoll.cpp index 04344e07019..7b14f89f1e6 100644 --- a/icu4c/source/i18n/tblcoll.cpp +++ b/icu4c/source/i18n/tblcoll.cpp @@ -1,6 +1,6 @@ /* ****************************************************************************** - * Copyright (C) 1996-2011, International Business Machines Corporation and + * Copyright (C) 1996-2012, International Business Machines Corporation and * others. All Rights Reserved. ****************************************************************************** */ @@ -761,6 +761,16 @@ RuleBasedCollator::checkOwned() { } } + +int32_t U_EXPORT2 RuleBasedCollator::internalGetShortDefinitionString(const char *locale, + char *buffer, + int32_t capacity, + UErrorCode &status) { + /* simply delegate */ + return ucol_getShortDefinitionString(ucollator, locale, buffer, capacity, &status); +} + + UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedCollator) U_NAMESPACE_END diff --git a/icu4c/source/i18n/ucol.cpp b/icu4c/source/i18n/ucol.cpp index ddd406caee5..74940a7b153 100644 --- a/icu4c/source/i18n/ucol.cpp +++ b/icu4c/source/i18n/ucol.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 1996-2011, International Business Machines +* Copyright (C) 1996-2012, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: ucol.cpp @@ -38,6 +38,7 @@ #include "utracimp.h" #include "putilimp.h" #include "uassert.h" +#include "unicode/coll.h" #ifdef UCOL_DEBUG #include @@ -727,6 +728,10 @@ ucol_close(UCollator *coll) uprv_free(coll->reorderCodes); } + if(coll->delegate != NULL) { + delete (Collator*)coll->delegate; + } + /* Here, it would be advisable to close: */ /* - UData for UCA (unless we stuff it in the root resb */ /* Again, do we need additional housekeeping... HMMM! */ @@ -894,6 +899,8 @@ UCollator* ucol_initCollator(const UCATableHeader *image, UCollator *fillIn, con result->freeOnClose = FALSE; } + result->delegate = NULL; + result->image = image; result->mapping.getFoldingOffset = _getFoldingOffset; const uint8_t *mapping = (uint8_t*)result->image+result->image->mappingPosition; @@ -4483,6 +4490,10 @@ ucol_getSortKey(const UCollator *coll, ((sourceLength==-1 && source!=NULL) ? u_strlen(source) : sourceLength)); } + if(coll->delegate != NULL) { + return ((const Collator*)coll->delegate)->getSortKey(source, sourceLength, result, resultLength); + } + UErrorCode status = U_ZERO_ERROR; int32_t keySize = 0; @@ -6465,6 +6476,11 @@ ucol_setVariableTop(UCollator *coll, const UChar *varTop, int32_t len, UErrorCod return 0; } + if(coll->delegate!=NULL) { + return ((Collator*)coll->delegate)->setVariableTop(varTop, len, *status); + } + + collIterate s; IInit_collIterate(coll, varTop, len, &s, status); if(U_FAILURE(*status)) { @@ -6502,6 +6518,9 @@ U_CAPI uint32_t U_EXPORT2 ucol_getVariableTop(const UCollator *coll, UErrorCode if(U_FAILURE(*status) || coll == NULL) { return 0; } + if(coll->delegate!=NULL) { + return ((const Collator*)coll->delegate)->getVariableTop(*status); + } return coll->variableTopValue<<16; } @@ -6523,6 +6542,11 @@ ucol_setAttribute(UCollator *coll, UColAttribute attr, UColAttributeValue value, return; } + if(coll->delegate != NULL) { + ((Collator*)coll->delegate)->setAttribute(attr,value,*status); + return; + } + UColAttributeValue oldFrench = coll->frenchCollation; UColAttributeValue oldCaseFirst = coll->caseFirst; switch(attr) { @@ -6660,6 +6684,11 @@ ucol_getAttribute(const UCollator *coll, UColAttribute attr, UErrorCode *status) if(U_FAILURE(*status) || coll == NULL) { return UCOL_DEFAULT; } + + if(coll->delegate != NULL) { + return ((Collator*)coll->delegate)->getAttribute(attr,*status); + } + switch(attr) { case UCOL_NUMERIC_COLLATION: return coll->numericCollation; @@ -6709,6 +6738,10 @@ ucol_getReorderCodes(const UCollator *coll, return 0; } + if(coll->delegate!=NULL) { + return ((const Collator*)coll->delegate)->getReorderCodes(dest, destCapacity, *status); + } + if (destCapacity < 0 || (destCapacity > 0 && dest == NULL)) { *status = U_ILLEGAL_ARGUMENT_ERROR; return 0; @@ -6742,6 +6775,11 @@ ucol_setReorderCodes(UCollator* coll, *status = U_ILLEGAL_ARGUMENT_ERROR; return; } + + if(coll->delegate!=NULL) { + ((Collator*)coll->delegate)->setReorderCodes(reorderCodes, reorderCodesLength, *status); + return; + } if (coll->reorderCodes != NULL && coll->freeReorderCodesOnClose == TRUE) { uprv_free(coll->reorderCodes); @@ -6840,6 +6878,10 @@ U_CAPI void U_EXPORT2 ucol_getVersion(const UCollator* coll, UVersionInfo versionInfo) { + if(coll->delegate!=NULL) { + ((const Collator*)coll->delegate)->getVersion(versionInfo); + return; + } /* RunTime version */ uint8_t rtVersion = UCOL_RUNTIME_VERSION; /* Builder version*/ @@ -8100,6 +8142,11 @@ ucol_strcoll( const UCollator *coll, return UCOL_EQUAL; } + if(coll->delegate != NULL) { + UErrorCode status = U_ZERO_ERROR; + return ((const Collator*)coll->delegate)->compare(source,sourceLength,target,targetLength, status); + } + /* Scan the strings. Find: */ /* The length of any leading portion that is equal */ /* Whether they are exactly equal. (in which case we just return) */ diff --git a/icu4c/source/i18n/ucol_imp.h b/icu4c/source/i18n/ucol_imp.h index e82badfbf50..b54ed04be41 100644 --- a/icu4c/source/i18n/ucol_imp.h +++ b/icu4c/source/i18n/ucol_imp.h @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 1998-2011, International Business Machines +* Copyright (C) 1998-2012, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -1016,6 +1016,7 @@ struct UCollator { int32_t* reorderCodes; int32_t reorderCodesLength; uint8_t* leadBytePermutationTable; + void *delegate; /* if non-null: C++ object to delegate all API calls to. */ }; U_CDECL_END diff --git a/icu4c/source/i18n/ucol_res.cpp b/icu4c/source/i18n/ucol_res.cpp index 0a3d8dbbdda..2f730469561 100644 --- a/icu4c/source/i18n/ucol_res.cpp +++ b/icu4c/source/i18n/ucol_res.cpp @@ -756,7 +756,7 @@ ucol_openAvailableLocales(UErrorCode *status) { if (U_FAILURE(*status)) { return NULL; } - StringEnumeration *s = Collator::getAvailableLocales(); + StringEnumeration *s = icu::Collator::getAvailableLocales(); if (s == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; @@ -949,6 +949,9 @@ ucol_getLocaleByType(const UCollator *coll, ULocDataLocaleType type, UErrorCode UTRACE_ENTRY(UTRACE_UCOL_GETLOCALE); UTRACE_DATA1(UTRACE_INFO, "coll=%p", coll); + if(coll->delegate!=NULL) { + return ((const Collator*)coll->delegate)->getLocale(type, *status).getName(); + } switch(type) { case ULOC_ACTUAL_LOCALE: result = coll->actualLocale; diff --git a/icu4c/source/i18n/ucol_sit.cpp b/icu4c/source/i18n/ucol_sit.cpp index d5a61c5d37e..728f6319e4e 100644 --- a/icu4c/source/i18n/ucol_sit.cpp +++ b/icu4c/source/i18n/ucol_sit.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 2004-2011, International Business Machines +* Copyright (C) 2004-2012, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * file name: ucol_sit.cpp @@ -22,15 +22,23 @@ #include "cmemory.h" #include "cstring.h" #include "uresimp.h" +#include "unicode/coll.h" + +#ifdef UCOL_TRACE_SIT +# include +#endif #if !UCONFIG_NO_COLLATION enum OptionsList { UCOL_SIT_LANGUAGE = 0, - UCOL_SIT_SCRIPT, - UCOL_SIT_REGION, - UCOL_SIT_VARIANT, - UCOL_SIT_KEYWORD, + UCOL_SIT_SCRIPT = 1, + UCOL_SIT_REGION = 2, + UCOL_SIT_VARIANT = 3, + UCOL_SIT_KEYWORD = 4, + UCOL_SIT_PROVIDER = 5, + UCOL_SIT_LOCELEMENT_MAX = UCOL_SIT_PROVIDER, /* the last element that's part of LocElements */ + UCOL_SIT_BCP47, UCOL_SIT_STRENGTH, UCOL_SIT_CASE_LEVEL, @@ -56,6 +64,7 @@ static const char hiraganaQArg = 'H'; static const char keywordArg = 'K'; static const char languageArg = 'L'; static const char normArg = 'N'; +static const char providerArg = 'P'; static const char regionArg = 'R'; static const char strengthArg = 'S'; static const char variableTopArg = 'T'; @@ -64,10 +73,13 @@ static const char RFC3066Arg = 'X'; static const char scriptArg = 'Z'; static const char collationKeyword[] = "@collation="; +static const char providerKeyword[] = "@sp="; -static const int32_t locElementCount = 5; + +static const int32_t locElementCount = UCOL_SIT_LOCELEMENT_MAX+1; static const int32_t locElementCapacity = 32; static const int32_t loc3066Capacity = 256; +static const int32_t locProviderCapacity = 10; static const int32_t internalBufferSize = 512; /* structure containing specification of a collator. Initialized @@ -77,6 +89,7 @@ static const int32_t internalBufferSize = 512; struct CollatorSpec { char locElements[locElementCount][locElementCapacity]; char locale[loc3066Capacity]; + char provider[locProviderCapacity]; UColAttributeValue options[UCOL_ATTRIBUTE_COUNT]; uint32_t variableTopValue; UChar variableTopString[locElementCapacity]; @@ -122,6 +135,9 @@ ucol_sit_attributeValueToLetter(UColAttributeValue value, UErrorCode *status) { } } *status = U_ILLEGAL_ARGUMENT_ERROR; +#ifdef UCOL_TRACE_SIT + fprintf(stderr, "%s:%d: unknown UColAttributeValue %d: %s\n", __FILE__, __LINE__, value, u_errorName(*status)); +#endif return 0; } @@ -134,6 +150,9 @@ ucol_sit_letterToAttributeValue(char letter, UErrorCode *status) { } } *status = U_ILLEGAL_ARGUMENT_ERROR; +#ifdef UCOL_TRACE_SIT + fprintf(stderr, "%s:%d: unknown letter %c: %s\n", __FILE__, __LINE__, letter, u_errorName(*status)); +#endif return UCOL_DEFAULT; } @@ -151,7 +170,7 @@ _processLocaleElement(CollatorSpec *spec, uint32_t value, const char* string, { int32_t len = 0; do { - if(value == 0 || value == 4) { + if(value == UCOL_SIT_LANGUAGE || value == UCOL_SIT_KEYWORD || value == UCOL_SIT_PROVIDER) { spec->locElements[value][len++] = uprv_tolower(*string); } else { spec->locElements[value][len++] = *string; @@ -192,6 +211,9 @@ _processCollatorOption(CollatorSpec *spec, uint32_t option, const char* string, { spec->options[option] = ucol_sit_letterToAttributeValue(*string, status); if((*(++string) != '_' && *string) || U_FAILURE(*status)) { +#ifdef UCOL_TRACE_SIT + fprintf(stderr, "%s:%d: unknown collator option at '%s': %s\n", __FILE__, __LINE__, string, u_errorName(*status)); +#endif *status = U_ILLEGAL_ARGUMENT_ERROR; } return string; @@ -215,6 +237,9 @@ readHexCodeUnit(const char **string, UErrorCode *status) value = c - 'A' + 10; } else { *status = U_ILLEGAL_ARGUMENT_ERROR; +#ifdef UCOL_TRACE_SIT + fprintf(stderr, "%s:%d: Bad hex char at '%s': %s\n", __FILE__, __LINE__, *string, u_errorName(*status)); +#endif return 0; } result = (result << 4) | (UChar)value; @@ -224,6 +249,9 @@ readHexCodeUnit(const char **string, UErrorCode *status) // if the string was terminated before we read 4 digits, set an error if(noDigits < 4) { *status = U_ILLEGAL_ARGUMENT_ERROR; +#ifdef UCOL_TRACE_SIT + fprintf(stderr, "%s:%d: Short (only %d digits, wanted 4) at '%s': %s\n", __FILE__, __LINE__, noDigits,*string, u_errorName(*status)); +#endif } return result; } @@ -269,15 +297,16 @@ static const ShortStringOptions options[UCOL_SIT_ITEMS_COUNT] = /* 07 CASE_LEVEL */ {caseLevelArg, _processCollatorOption, UCOL_CASE_LEVEL }, // case level O, X, D /* 12 FRENCH_COLLATION */ {frenchCollArg, _processCollatorOption, UCOL_FRENCH_COLLATION }, // french O, X, D /* 13 HIRAGANA_QUATERNARY] */ {hiraganaQArg, _processCollatorOption, UCOL_HIRAGANA_QUATERNARY_MODE }, // hiragana O, X, D -/* 04 KEYWORD */ {keywordArg, _processLocaleElement, 4 }, // keyword -/* 00 LANGUAGE */ {languageArg, _processLocaleElement, 0 }, // language +/* 04 KEYWORD */ {keywordArg, _processLocaleElement, UCOL_SIT_KEYWORD }, // keyword +/* 00 LANGUAGE */ {languageArg, _processLocaleElement, UCOL_SIT_LANGUAGE }, // language /* 11 NORMALIZATION_MODE */ {normArg, _processCollatorOption, UCOL_NORMALIZATION_MODE }, // norm O, X, D -/* 02 REGION */ {regionArg, _processLocaleElement, 2 }, // region +/* 02 REGION */ {regionArg, _processLocaleElement, UCOL_SIT_REGION }, // region /* 06 STRENGTH */ {strengthArg, _processCollatorOption, UCOL_STRENGTH }, // strength 1, 2, 3, 4, I, D /* 14 VARIABLE_TOP */ {variableTopArg, _processVariableTop, 0 }, -/* 03 VARIANT */ {variantArg, _processLocaleElement, 3 }, // variant +/* 03 VARIANT */ {variantArg, _processLocaleElement, UCOL_SIT_VARIANT }, // variant /* 05 RFC3066BIS */ {RFC3066Arg, _processRFC3066Locale, 0 }, // rfc3066bis locale name -/* 01 SCRIPT */ {scriptArg, _processLocaleElement, 1 } // script +/* 01 SCRIPT */ {scriptArg, _processLocaleElement, UCOL_SIT_SCRIPT }, // script +/* PROVIDER */ {providerArg, _processLocaleElement, UCOL_SIT_PROVIDER } }; @@ -296,6 +325,9 @@ const char* ucol_sit_readOption(const char *start, CollatorSpec *spec, } } *status = U_ILLEGAL_ARGUMENT_ERROR; +#ifdef UCOL_TRACE_SIT + fprintf(stderr, "%s:%d: Unknown option at '%s': %s\n", __FILE__, __LINE__, start, u_errorName(*status)); +#endif return start; } @@ -372,29 +404,35 @@ ucol_sit_calculateWholeLocale(CollatorSpec *s) { // locale if(s->locale[0] == 0) { // first the language - uprv_strcat(s->locale, s->locElements[0]); + uprv_strcat(s->locale, s->locElements[UCOL_SIT_LANGUAGE]); // then the script, if present - if(*(s->locElements[1])) { + if(*(s->locElements[UCOL_SIT_SCRIPT])) { uprv_strcat(s->locale, "_"); - uprv_strcat(s->locale, s->locElements[1]); + uprv_strcat(s->locale, s->locElements[UCOL_SIT_SCRIPT]); } // then the region, if present - if(*(s->locElements[2])) { + if(*(s->locElements[UCOL_SIT_REGION])) { uprv_strcat(s->locale, "_"); - uprv_strcat(s->locale, s->locElements[2]); - } else if(*(s->locElements[3])) { // if there is a variant, we need an underscore + uprv_strcat(s->locale, s->locElements[UCOL_SIT_REGION]); + } else if(*(s->locElements[UCOL_SIT_VARIANT])) { // if there is a variant, we need an underscore uprv_strcat(s->locale, "_"); } // add variant, if there - if(*(s->locElements[3])) { + if(*(s->locElements[UCOL_SIT_VARIANT])) { uprv_strcat(s->locale, "_"); - uprv_strcat(s->locale, s->locElements[3]); + uprv_strcat(s->locale, s->locElements[UCOL_SIT_VARIANT]); } // if there is a collation keyword, add that too - if(*(s->locElements[4])) { + if(*(s->locElements[UCOL_SIT_KEYWORD])) { uprv_strcat(s->locale, collationKeyword); - uprv_strcat(s->locale, s->locElements[4]); + uprv_strcat(s->locale, s->locElements[UCOL_SIT_KEYWORD]); + } + + // if there is a provider keyword, add that too + if(*(s->locElements[UCOL_SIT_PROVIDER])) { + uprv_strcat(s->locale, providerKeyword); + uprv_strcat(s->locale, s->locElements[UCOL_SIT_PROVIDER]); } } } @@ -558,6 +596,9 @@ ucol_getShortDefinitionString(const UCollator *coll, UErrorCode *status) { if(U_FAILURE(*status)) return 0; + if(coll->delegate != NULL) { + return ((Collator*)coll->delegate)->internalGetShortDefinitionString(locale,dst,capacity,*status); + } char buffer[internalBufferSize]; uprv_memset(buffer, 0, internalBufferSize*sizeof(char)); int32_t resultSize = 0; @@ -664,6 +705,9 @@ ucol_getAttributeOrDefault(const UCollator *coll, UColAttribute attr, UErrorCode case UCOL_ATTRIBUTE_COUNT: default: *status = U_ILLEGAL_ARGUMENT_ERROR; +#ifdef UCOL_TRACE_SIT + fprintf(stderr, "%s:%d: Unknown attr value '%d': %s\n", __FILE__, __LINE__, (int)attr, u_errorName(*status)); +#endif break; } return UCOL_DEFAULT; diff --git a/icu4c/source/i18n/udat.cpp b/icu4c/source/i18n/udat.cpp index b3ce51dc71d..96bf6a5dd3e 100644 --- a/icu4c/source/i18n/udat.cpp +++ b/icu4c/source/i18n/udat.cpp @@ -23,6 +23,7 @@ #include "unicode/ustring.h" #include "cpputils.h" #include "reldtfmt.h" +#include "umutex.h" U_NAMESPACE_USE @@ -83,6 +84,40 @@ udat_toCalendarDateField(UDateFormatField field) { return gDateFieldMapping[field]; } +/* For now- one opener. */ +static UDateFormatOpener gOpener = NULL; + +U_INTERNAL void U_EXPORT2 +udat_registerOpener(UDateFormatOpener opener, UErrorCode *status) +{ + if(U_FAILURE(*status)) return; + umtx_lock(NULL); + if(gOpener==NULL) { + gOpener = opener; + } else { + *status = U_ILLEGAL_ARGUMENT_ERROR; + } + umtx_unlock(NULL); +} + +U_INTERNAL UDateFormatOpener U_EXPORT2 +udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status) +{ + if(U_FAILURE(*status)) return NULL; + UDateFormatOpener oldOpener = NULL; + umtx_lock(NULL); + if(gOpener==NULL || gOpener!=opener) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + } else { + oldOpener=gOpener; + gOpener=NULL; + } + umtx_unlock(NULL); + return oldOpener; +} + + + U_CAPI UDateFormat* U_EXPORT2 udat_open(UDateFormatStyle timeStyle, UDateFormatStyle dateStyle, @@ -97,6 +132,12 @@ udat_open(UDateFormatStyle timeStyle, if(U_FAILURE(*status)) { return 0; } + if(gOpener!=NULL) { // if it's registered + fmt = (DateFormat*) (*gOpener)(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status); + if(fmt!=NULL) { + return (UDateFormat*)fmt; + } // else fall through. + } if(timeStyle != UDAT_IGNORE) { if(locale == 0) { fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle, diff --git a/icu4c/source/i18n/unicode/coll.h b/icu4c/source/i18n/unicode/coll.h index 3192c0fd170..bae4c25aa21 100644 --- a/icu4c/source/i18n/unicode/coll.h +++ b/icu4c/source/i18n/unicode/coll.h @@ -1,6 +1,6 @@ /* ****************************************************************************** -* Copyright (C) 1996-2011, International Business Machines * +* Copyright (C) 1996-2012, International Business Machines * * Corporation and others. All Rights Reserved. * ****************************************************************************** */ @@ -1048,6 +1048,35 @@ public: static UCollator* createUCollator(const char* loc, UErrorCode* status); #endif /* U_HIDE_INTERNAL_API */ #endif + + /** Get the short definition string for a collator. This internal API harvests the collator's + * locale and the attribute set and produces a string that can be used for opening + * a collator with the same properties using the ucol_openFromShortString API. + * This string will be normalized. + * The structure and the syntax of the string is defined in the "Naming collators" + * section of the users guide: + * http://icu-project.org/userguide/Collate_Concepts.html#Naming_Collators + * This function supports preflighting. + * + * This is internal, and intended to be used with delegate converters. + * + * @param locale a locale that will appear as a collators locale in the resulting + * short string definition. If NULL, the locale will be harvested + * from the collator. + * @param buffer space to hold the resulting string + * @param capacity capacity of the buffer + * @param status for returning errors. All the preflighting errors are featured + * @return length of the resulting string + * @see ucol_openFromShortString + * @see ucol_normalizeShortDefinitionString + * @see ucol_getShortDefinitionString + * @internal + */ + virtual int32_t internalGetShortDefinitionString(const char *locale, + char *buffer, + int32_t capacity, + UErrorCode &status); + private: /** * Assignment operator. Private for now. diff --git a/icu4c/source/i18n/unicode/tblcoll.h b/icu4c/source/i18n/unicode/tblcoll.h index 83e59998987..ad0d108005a 100644 --- a/icu4c/source/i18n/unicode/tblcoll.h +++ b/icu4c/source/i18n/unicode/tblcoll.h @@ -1,6 +1,6 @@ /* ****************************************************************************** -* Copyright (C) 1996-2011, International Business Machines Corporation and +* Copyright (C) 1996-2012, International Business Machines Corporation and * others. All Rights Reserved. ****************************************************************************** */ @@ -911,6 +911,35 @@ private: */ UCollationStrength getUCollationStrength( const Collator::ECollationStrength &strength) const; + public: + /** Get the short definition string for a collator. This internal API harvests the collator's + * locale and the attribute set and produces a string that can be used for opening + * a collator with the same properties using the ucol_openFromShortString API. + * This string will be normalized. + * The structure and the syntax of the string is defined in the "Naming collators" + * section of the users guide: + * http://icu-project.org/userguide/Collate_Concepts.html#Naming_Collators + * This function supports preflighting. + * + * This is internal, and intended to be used with delegate converters. + * + * @param locale a locale that will appear as a collators locale in the resulting + * short string definition. If NULL, the locale will be harvested + * from the collator. + * @param buffer space to hold the resulting string + * @param capacity capacity of the buffer + * @param status for returning errors. All the preflighting errors are featured + * @return length of the resulting string + * @see ucol_openFromShortString + * @see ucol_normalizeShortDefinitionString + * @see ucol_getShortDefinitionString + * @internal + */ + virtual int32_t internalGetShortDefinitionString(const char *locale, + char *buffer, + int32_t capacity, + UErrorCode &status); + }; // inline method implementation --------------------------------------------- diff --git a/icu4c/source/i18n/unicode/udat.h b/icu4c/source/i18n/unicode/udat.h index 5906adcc4ad..07b2c1a4cbd 100644 --- a/icu4c/source/i18n/unicode/udat.h +++ b/icu4c/source/i18n/unicode/udat.h @@ -1022,6 +1022,34 @@ udat_applyPatternRelative(UDateFormat *format, UErrorCode *status); #endif /* U_HIDE_INTERNAL_API */ +/** + * @internal + * @see udat_open + */ +typedef UDateFormat* (U_EXPORT2 *UDateFormatOpener) (UDateFormatStyle timeStyle, + UDateFormatStyle dateStyle, + const char *locale, + const UChar *tzID, + int32_t tzIDLength, + const UChar *pattern, + int32_t patternLength, + UErrorCode *status); + +/** + * Register a provider factory + * @internal ICU 49 + */ +U_INTERNAL void U_EXPORT2 +udat_registerOpener(UDateFormatOpener opener, UErrorCode *status); + +/** + * Un-Register a provider factory + * @internal ICU 49 + */ +U_INTERNAL UDateFormatOpener U_EXPORT2 +udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status); + + #endif /* #if !UCONFIG_NO_FORMATTING */ #endif