Index: icu46/source/common/locdispnames.cpp |
=================================================================== |
--- icu46/source/common/locdispnames.cpp (revision 0) |
+++ icu46/source/common/locdispnames.cpp (revision 0) |
@@ -0,0 +1,824 @@ |
+/* |
+******************************************************************************* |
+* |
+* Copyright (C) 1997-2010, International Business Machines |
+* Corporation and others. All Rights Reserved. |
+* |
+******************************************************************************* |
+* file name: locdispnames.cpp |
+* encoding: US-ASCII |
+* tab size: 8 (not used) |
+* indentation:4 |
+* |
+* created on: 2010feb25 |
+* created by: Markus W. Scherer |
+* |
+* Code for locale display names, separated out from other .cpp files |
+* that then do not depend on resource bundle code and display name data. |
+*/ |
+ |
+#include "unicode/utypes.h" |
+#include "unicode/brkiter.h" |
+#include "unicode/locid.h" |
+#include "unicode/uloc.h" |
+#include "unicode/ures.h" |
+#include "unicode/ustring.h" |
+#include "cmemory.h" |
+#include "cstring.h" |
+#include "putilimp.h" |
+#include "ulocimp.h" |
+#include "uresimp.h" |
+#include "ureslocs.h" |
+#include "ustr_imp.h" |
+ |
+// C++ API ----------------------------------------------------------------- *** |
+ |
+U_NAMESPACE_BEGIN |
+ |
+UnicodeString& |
+Locale::getDisplayLanguage(UnicodeString& dispLang) const |
+{ |
+ return this->getDisplayLanguage(getDefault(), dispLang); |
+} |
+ |
+/*We cannot make any assumptions on the size of the output display strings |
+* Yet, since we are calling through to a C API, we need to set limits on |
+* buffer size. For all the following getDisplay functions we first attempt |
+* to fill up a stack allocated buffer. If it is to small we heap allocated |
+* the exact buffer we need copy it to the UnicodeString and delete it*/ |
+ |
+UnicodeString& |
+Locale::getDisplayLanguage(const Locale &displayLocale, |
+ UnicodeString &result) const { |
+ UChar *buffer; |
+ UErrorCode errorCode=U_ZERO_ERROR; |
+ int32_t length; |
+ |
+ buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ |
+ length=uloc_getDisplayLanguage(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ |
+ if(errorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ buffer=result.getBuffer(length); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ errorCode=U_ZERO_ERROR; |
+ length=uloc_getDisplayLanguage(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ } |
+ |
+ return result; |
+} |
+ |
+UnicodeString& |
+Locale::getDisplayScript(UnicodeString& dispScript) const |
+{ |
+ return this->getDisplayScript(getDefault(), dispScript); |
+} |
+ |
+UnicodeString& |
+Locale::getDisplayScript(const Locale &displayLocale, |
+ UnicodeString &result) const { |
+ UChar *buffer; |
+ UErrorCode errorCode=U_ZERO_ERROR; |
+ int32_t length; |
+ |
+ buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ |
+ length=uloc_getDisplayScript(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ |
+ if(errorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ buffer=result.getBuffer(length); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ errorCode=U_ZERO_ERROR; |
+ length=uloc_getDisplayScript(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ } |
+ |
+ return result; |
+} |
+ |
+UnicodeString& |
+Locale::getDisplayCountry(UnicodeString& dispCntry) const |
+{ |
+ return this->getDisplayCountry(getDefault(), dispCntry); |
+} |
+ |
+UnicodeString& |
+Locale::getDisplayCountry(const Locale &displayLocale, |
+ UnicodeString &result) const { |
+ UChar *buffer; |
+ UErrorCode errorCode=U_ZERO_ERROR; |
+ int32_t length; |
+ |
+ buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ |
+ length=uloc_getDisplayCountry(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ |
+ if(errorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ buffer=result.getBuffer(length); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ errorCode=U_ZERO_ERROR; |
+ length=uloc_getDisplayCountry(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ } |
+ |
+ return result; |
+} |
+ |
+UnicodeString& |
+Locale::getDisplayVariant(UnicodeString& dispVar) const |
+{ |
+ return this->getDisplayVariant(getDefault(), dispVar); |
+} |
+ |
+UnicodeString& |
+Locale::getDisplayVariant(const Locale &displayLocale, |
+ UnicodeString &result) const { |
+ UChar *buffer; |
+ UErrorCode errorCode=U_ZERO_ERROR; |
+ int32_t length; |
+ |
+ buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ |
+ length=uloc_getDisplayVariant(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ |
+ if(errorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ buffer=result.getBuffer(length); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ errorCode=U_ZERO_ERROR; |
+ length=uloc_getDisplayVariant(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ } |
+ |
+ return result; |
+} |
+ |
+UnicodeString& |
+Locale::getDisplayName( UnicodeString& name ) const |
+{ |
+ return this->getDisplayName(getDefault(), name); |
+} |
+ |
+UnicodeString& |
+Locale::getDisplayName(const Locale &displayLocale, |
+ UnicodeString &result) const { |
+ UChar *buffer; |
+ UErrorCode errorCode=U_ZERO_ERROR; |
+ int32_t length; |
+ |
+ buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ |
+ length=uloc_getDisplayName(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ |
+ if(errorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ buffer=result.getBuffer(length); |
+ if(buffer==0) { |
+ result.truncate(0); |
+ return result; |
+ } |
+ errorCode=U_ZERO_ERROR; |
+ length=uloc_getDisplayName(fullName, displayLocale.fullName, |
+ buffer, result.getCapacity(), |
+ &errorCode); |
+ result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0); |
+ } |
+ |
+ return result; |
+} |
+ |
+#if ! UCONFIG_NO_BREAK_ITERATION |
+ |
+// ------------------------------------- |
+// Gets the objectLocale display name in the default locale language. |
+UnicodeString& U_EXPORT2 |
+BreakIterator::getDisplayName(const Locale& objectLocale, |
+ UnicodeString& name) |
+{ |
+ return objectLocale.getDisplayName(name); |
+} |
+ |
+// ------------------------------------- |
+// Gets the objectLocale display name in the displayLocale language. |
+UnicodeString& U_EXPORT2 |
+BreakIterator::getDisplayName(const Locale& objectLocale, |
+ const Locale& displayLocale, |
+ UnicodeString& name) |
+{ |
+ return objectLocale.getDisplayName(displayLocale, name); |
+} |
+ |
+#endif |
+ |
+ |
+U_NAMESPACE_END |
+ |
+// C API ------------------------------------------------------------------- *** |
+ |
+U_NAMESPACE_USE |
+ |
+/* ### Constants **************************************************/ |
+ |
+/* These strings describe the resources we attempt to load from |
+ the locale ResourceBundle data file.*/ |
+static const char _kLanguages[] = "Languages"; |
+static const char _kScripts[] = "Scripts"; |
+static const char _kCountries[] = "Countries"; |
+static const char _kVariants[] = "Variants"; |
+static const char _kKeys[] = "Keys"; |
+static const char _kTypes[] = "Types"; |
+static const char _kRootName[] = "root"; |
+static const char _kCurrency[] = "currency"; |
+static const char _kCurrencies[] = "Currencies"; |
+static const char _kLocaleDisplayPattern[] = "localeDisplayPattern"; |
+static const char _kPattern[] = "pattern"; |
+static const char _kSeparator[] = "separator"; |
+ |
+/* ### Display name **************************************************/ |
+ |
+static int32_t |
+_getStringOrCopyKey(const char *path, const char *locale, |
+ const char *tableKey, |
+ const char* subTableKey, |
+ const char *itemKey, |
+ const char *substitute, |
+ UChar *dest, int32_t destCapacity, |
+ UErrorCode *pErrorCode) { |
+ const UChar *s = NULL; |
+ int32_t length = 0; |
+ |
+ if(itemKey==NULL) { |
+ /* top-level item: normal resource bundle access */ |
+ UResourceBundle *rb; |
+ |
+ rb=ures_open(path, locale, pErrorCode); |
+ |
+ if(U_SUCCESS(*pErrorCode)) { |
+ s=ures_getStringByKey(rb, tableKey, &length, pErrorCode); |
+ /* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */ |
+ ures_close(rb); |
+ } |
+ } else { |
+ /* Language code should not be a number. If it is, set the error code. */ |
+ if (!uprv_strncmp(tableKey, "Languages", 9) && uprv_strtol(itemKey, NULL, 10)) { |
+ *pErrorCode = U_MISSING_RESOURCE_ERROR; |
+ } else { |
+ /* second-level item, use special fallback */ |
+ s=uloc_getTableStringWithFallback(path, locale, |
+ tableKey, |
+ subTableKey, |
+ itemKey, |
+ &length, |
+ pErrorCode); |
+ } |
+ } |
+ |
+ if(U_SUCCESS(*pErrorCode)) { |
+ int32_t copyLength=uprv_min(length, destCapacity); |
+ if(copyLength>0 && s != NULL) { |
+ u_memcpy(dest, s, copyLength); |
+ } |
+ } else { |
+ /* no string from a resource bundle: convert the substitute */ |
+ length=(int32_t)uprv_strlen(substitute); |
+ u_charsToUChars(substitute, dest, uprv_min(length, destCapacity)); |
+ *pErrorCode=U_USING_DEFAULT_WARNING; |
+ } |
+ |
+ return u_terminateUChars(dest, destCapacity, length, pErrorCode); |
+} |
+ |
+typedef int32_t U_CALLCONV UDisplayNameGetter(const char *, char *, int32_t, UErrorCode *); |
+ |
+static int32_t |
+_getDisplayNameForComponent(const char *locale, |
+ const char *displayLocale, |
+ UChar *dest, int32_t destCapacity, |
+ UDisplayNameGetter *getter, |
+ const char *tag, |
+ UErrorCode *pErrorCode) { |
+ char localeBuffer[ULOC_FULLNAME_CAPACITY*4]; |
+ int32_t length; |
+ UErrorCode localStatus; |
+ const char* root = NULL; |
+ |
+ /* argument checking */ |
+ if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { |
+ return 0; |
+ } |
+ |
+ if(destCapacity<0 || (destCapacity>0 && dest==NULL)) { |
+ *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; |
+ return 0; |
+ } |
+ |
+ localStatus = U_ZERO_ERROR; |
+ length=(*getter)(locale, localeBuffer, sizeof(localeBuffer), &localStatus); |
+ if(U_FAILURE(localStatus) || localStatus==U_STRING_NOT_TERMINATED_WARNING) { |
+ *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; |
+ return 0; |
+ } |
+ if(length==0) { |
+ return u_terminateUChars(dest, destCapacity, 0, pErrorCode); |
+ } |
+ |
+ root = tag == _kCountries ? U_ICUDATA_REGION : U_ICUDATA_LANG; |
+ |
+ return _getStringOrCopyKey(root, displayLocale, |
+ tag, NULL, localeBuffer, |
+ localeBuffer, |
+ dest, destCapacity, |
+ pErrorCode); |
+} |
+ |
+U_CAPI int32_t U_EXPORT2 |
+uloc_getDisplayLanguage(const char *locale, |
+ const char *displayLocale, |
+ UChar *dest, int32_t destCapacity, |
+ UErrorCode *pErrorCode) { |
+ return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity, |
+ uloc_getLanguage, _kLanguages, pErrorCode); |
+} |
+ |
+U_CAPI int32_t U_EXPORT2 |
+uloc_getDisplayScript(const char* locale, |
+ const char* displayLocale, |
+ UChar *dest, int32_t destCapacity, |
+ UErrorCode *pErrorCode) |
+{ |
+ return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity, |
+ uloc_getScript, _kScripts, pErrorCode); |
+} |
+ |
+U_CAPI int32_t U_EXPORT2 |
+uloc_getDisplayCountry(const char *locale, |
+ const char *displayLocale, |
+ UChar *dest, int32_t destCapacity, |
+ UErrorCode *pErrorCode) { |
+ return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity, |
+ uloc_getCountry, _kCountries, pErrorCode); |
+} |
+ |
+/* |
+ * TODO separate variant1_variant2_variant3... |
+ * by getting each tag's display string and concatenating them with ", " |
+ * in between - similar to uloc_getDisplayName() |
+ */ |
+U_CAPI int32_t U_EXPORT2 |
+uloc_getDisplayVariant(const char *locale, |
+ const char *displayLocale, |
+ UChar *dest, int32_t destCapacity, |
+ UErrorCode *pErrorCode) { |
+ return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity, |
+ uloc_getVariant, _kVariants, pErrorCode); |
+} |
+ |
+U_CAPI int32_t U_EXPORT2 |
+uloc_getDisplayName(const char *locale, |
+ const char *displayLocale, |
+ UChar *dest, int32_t destCapacity, |
+ UErrorCode *pErrorCode) |
+{ |
+ int32_t length, length2, length3 = 0; |
+ UBool hasLanguage, hasScript, hasCountry, hasVariant, hasKeywords; |
+ UEnumeration* keywordEnum = NULL; |
+ int32_t keywordCount = 0; |
+ const char *keyword = NULL; |
+ int32_t keywordLen = 0; |
+ char keywordValue[256]; |
+ int32_t keywordValueLen = 0; |
+ |
+ int32_t locSepLen = 0; |
+ int32_t locPatLen = 0; |
+ int32_t p0Len = 0; |
+ int32_t defaultPatternLen = 9; |
+ const UChar *dispLocSeparator; |
+ const UChar *dispLocPattern; |
+ static const UChar defaultSeparator[3] = { 0x002c, 0x0020 , 0x0000 }; /* comma + space */ |
+ static const UChar defaultPattern[10] = { 0x007b, 0x0030, 0x007d, 0x0020, 0x0028, 0x007b, 0x0031, 0x007d, 0x0029, 0x0000 }; /* {0} ({1}) */ |
+ static const UChar pat0[4] = { 0x007b, 0x0030, 0x007d , 0x0000 } ; /* {0} */ |
+ static const UChar pat1[4] = { 0x007b, 0x0031, 0x007d , 0x0000 } ; /* {1} */ |
+ |
+ UResourceBundle *bundle = NULL; |
+ UResourceBundle *locdsppat = NULL; |
+ |
+ UErrorCode status = U_ZERO_ERROR; |
+ |
+ /* argument checking */ |
+ if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { |
+ return 0; |
+ } |
+ |
+ if(destCapacity<0 || (destCapacity>0 && dest==NULL)) { |
+ *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; |
+ return 0; |
+ } |
+ |
+ bundle = ures_open(U_ICUDATA_LANG, displayLocale, &status); |
+ |
+ locdsppat = ures_getByKeyWithFallback(bundle, _kLocaleDisplayPattern, NULL, &status); |
+ dispLocSeparator = ures_getStringByKeyWithFallback(locdsppat, _kSeparator, &locSepLen, &status); |
+ dispLocPattern = ures_getStringByKeyWithFallback(locdsppat, _kPattern, &locPatLen, &status); |
+ |
+ /*close the bundles */ |
+ ures_close(locdsppat); |
+ ures_close(bundle); |
+ |
+ /* If we couldn't find any data, then use the defaults */ |
+ if ( locSepLen == 0) { |
+ dispLocSeparator = defaultSeparator; |
+ locSepLen = 2; |
+ } |
+ |
+ if ( locPatLen == 0) { |
+ dispLocPattern = defaultPattern; |
+ locPatLen = 9; |
+ } |
+ |
+ /* |
+ * if there is a language, then write "language (country, variant)" |
+ * otherwise write "country, variant" |
+ */ |
+ |
+ /* write the language */ |
+ length=uloc_getDisplayLanguage(locale, displayLocale, |
+ dest, destCapacity, |
+ pErrorCode); |
+ hasLanguage= length>0; |
+ |
+ if(hasLanguage) { |
+ p0Len = length; |
+ |
+ /* append " (" */ |
+ if(length<destCapacity) { |
+ dest[length]=0x20; |
+ } |
+ ++length; |
+ if(length<destCapacity) { |
+ dest[length]=0x28; |
+ } |
+ ++length; |
+ } |
+ |
+ if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ /* keep preflighting */ |
+ *pErrorCode=U_ZERO_ERROR; |
+ } |
+ |
+ /* append the script */ |
+ if(length<destCapacity) { |
+ length2=uloc_getDisplayScript(locale, displayLocale, |
+ dest+length, destCapacity-length, |
+ pErrorCode); |
+ } else { |
+ length2=uloc_getDisplayScript(locale, displayLocale, |
+ NULL, 0, |
+ pErrorCode); |
+ } |
+ hasScript= length2>0; |
+ length+=length2; |
+ |
+ if(hasScript) { |
+ /* append separator */ |
+ if(length+locSepLen<=destCapacity) { |
+ u_memcpy(dest+length,dispLocSeparator,locSepLen); |
+ } |
+ length+=locSepLen; |
+ } |
+ |
+ if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ /* keep preflighting */ |
+ *pErrorCode=U_ZERO_ERROR; |
+ } |
+ |
+ /* append the country */ |
+ if(length<destCapacity) { |
+ length2=uloc_getDisplayCountry(locale, displayLocale, |
+ dest+length, destCapacity-length, |
+ pErrorCode); |
+ } else { |
+ length2=uloc_getDisplayCountry(locale, displayLocale, |
+ NULL, 0, |
+ pErrorCode); |
+ } |
+ hasCountry= length2>0; |
+ length+=length2; |
+ |
+ if(hasCountry) { |
+ /* append separator */ |
+ if(length+locSepLen<=destCapacity) { |
+ u_memcpy(dest+length,dispLocSeparator,locSepLen); |
+ } |
+ length+=locSepLen; |
+ } |
+ |
+ if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ /* keep preflighting */ |
+ *pErrorCode=U_ZERO_ERROR; |
+ } |
+ |
+ /* append the variant */ |
+ if(length<destCapacity) { |
+ length2=uloc_getDisplayVariant(locale, displayLocale, |
+ dest+length, destCapacity-length, |
+ pErrorCode); |
+ } else { |
+ length2=uloc_getDisplayVariant(locale, displayLocale, |
+ NULL, 0, |
+ pErrorCode); |
+ } |
+ hasVariant= length2>0; |
+ length+=length2; |
+ |
+ if(hasVariant) { |
+ /* append separator */ |
+ if(length+locSepLen<=destCapacity) { |
+ u_memcpy(dest+length,dispLocSeparator,locSepLen); |
+ } |
+ length+=locSepLen; |
+ } |
+ |
+ keywordEnum = uloc_openKeywords(locale, pErrorCode); |
+ |
+ for(keywordCount = uenum_count(keywordEnum, pErrorCode); keywordCount > 0 ; keywordCount--){ |
+ if(U_FAILURE(*pErrorCode)){ |
+ break; |
+ } |
+ /* the uenum_next returns NUL terminated string */ |
+ keyword = uenum_next(keywordEnum, &keywordLen, pErrorCode); |
+ if(length + length3 < destCapacity) { |
+ length3 += uloc_getDisplayKeyword(keyword, displayLocale, dest+length+length3, destCapacity-length-length3, pErrorCode); |
+ } else { |
+ length3 += uloc_getDisplayKeyword(keyword, displayLocale, NULL, 0, pErrorCode); |
+ } |
+ if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ /* keep preflighting */ |
+ *pErrorCode=U_ZERO_ERROR; |
+ } |
+ keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, 256, pErrorCode); |
+ if(keywordValueLen) { |
+ if(length + length3 < destCapacity) { |
+ dest[length + length3] = 0x3D; |
+ } |
+ length3++; |
+ if(length + length3 < destCapacity) { |
+ length3 += uloc_getDisplayKeywordValue(locale, keyword, displayLocale, dest+length+length3, destCapacity-length-length3, pErrorCode); |
+ } else { |
+ length3 += uloc_getDisplayKeywordValue(locale, keyword, displayLocale, NULL, 0, pErrorCode); |
+ } |
+ if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ /* keep preflighting */ |
+ *pErrorCode=U_ZERO_ERROR; |
+ } |
+ } |
+ if(keywordCount > 1) { |
+ if(length + length3 + locSepLen <= destCapacity && keywordCount) { |
+ u_memcpy(dest+length+length3,dispLocSeparator,locSepLen); |
+ length3+=locSepLen; |
+ } |
+ } |
+ } |
+ uenum_close(keywordEnum); |
+ |
+ hasKeywords = length3 > 0; |
+ length += length3; |
+ |
+ |
+ if ((hasScript && !hasCountry) |
+ || ((hasScript || hasCountry) && !hasVariant && !hasKeywords) |
+ || ((hasScript || hasCountry || hasVariant) && !hasKeywords)) { |
+ /* Remove separator */ |
+ length -= locSepLen; |
+ } else if (hasLanguage && !hasScript && !hasCountry && !hasVariant && !hasKeywords) { |
+ /* Remove " (" */ |
+ length-=2; |
+ } |
+ |
+ if (hasLanguage && (hasScript || hasCountry || hasVariant || hasKeywords)) { |
+ /* append ")" */ |
+ if(length<destCapacity) { |
+ dest[length]=0x29; |
+ } |
+ ++length; |
+ |
+ /* If the localized display pattern is something other than the default pattern of "{0} ({1})", then |
+ * then we need to do the formatting here. It would be easier to use a messageFormat to do this, but we |
+ * can't since we don't have the APIs in the i18n library available to us at this point. |
+ */ |
+ if (locPatLen != defaultPatternLen || u_strcmp(dispLocPattern,defaultPattern)) { /* Something other than the default pattern */ |
+ UChar *p0 = u_strstr(dispLocPattern,pat0); |
+ UChar *p1 = u_strstr(dispLocPattern,pat1); |
+ u_terminateUChars(dest, destCapacity, length, pErrorCode); |
+ |
+ if ( p0 != NULL && p1 != NULL ) { /* The pattern is well formed */ |
+ if ( dest ) { |
+ int32_t destLen = 0; |
+ UChar *result = (UChar *)uprv_malloc((length+1)*sizeof(UChar)); |
+ UChar *upos = (UChar *)dispLocPattern; |
+ u_strcpy(result,dest); |
+ dest[0] = 0; |
+ while ( *upos ) { |
+ if ( upos == p0 ) { /* Handle {0} substitution */ |
+ u_strncat(dest,result,p0Len); |
+ destLen += p0Len; |
+ dest[destLen] = 0; /* Null terminate */ |
+ upos += 3; |
+ } else if ( upos == p1 ) { /* Handle {1} substitution */ |
+ UChar *p1Start = &result[p0Len+2]; |
+ u_strncat(dest,p1Start,length-p0Len-3); |
+ destLen += (length-p0Len-3); |
+ dest[destLen] = 0; /* Null terminate */ |
+ upos += 3; |
+ } else { /* Something from the pattern not {0} or {1} */ |
+ u_strncat(dest,upos,1); |
+ upos++; |
+ destLen++; |
+ dest[destLen] = 0; /* Null terminate */ |
+ } |
+ } |
+ length = destLen; |
+ uprv_free(result); |
+ } |
+ } |
+ } |
+ } |
+ if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) { |
+ /* keep preflighting */ |
+ *pErrorCode=U_ZERO_ERROR; |
+ } |
+ |
+ return u_terminateUChars(dest, destCapacity, length, pErrorCode); |
+} |
+ |
+U_CAPI int32_t U_EXPORT2 |
+uloc_getDisplayKeyword(const char* keyword, |
+ const char* displayLocale, |
+ UChar* dest, |
+ int32_t destCapacity, |
+ UErrorCode* status){ |
+ |
+ /* argument checking */ |
+ if(status==NULL || U_FAILURE(*status)) { |
+ return 0; |
+ } |
+ |
+ if(destCapacity<0 || (destCapacity>0 && dest==NULL)) { |
+ *status=U_ILLEGAL_ARGUMENT_ERROR; |
+ return 0; |
+ } |
+ |
+ |
+ /* pass itemKey=NULL to look for a top-level item */ |
+ return _getStringOrCopyKey(U_ICUDATA_LANG, displayLocale, |
+ _kKeys, NULL, |
+ keyword, |
+ keyword, |
+ dest, destCapacity, |
+ status); |
+ |
+} |
+ |
+ |
+#define UCURRENCY_DISPLAY_NAME_INDEX 1 |
+ |
+U_CAPI int32_t U_EXPORT2 |
+uloc_getDisplayKeywordValue( const char* locale, |
+ const char* keyword, |
+ const char* displayLocale, |
+ UChar* dest, |
+ int32_t destCapacity, |
+ UErrorCode* status){ |
+ |
+ |
+ char keywordValue[ULOC_FULLNAME_CAPACITY*4]; |
+ int32_t capacity = ULOC_FULLNAME_CAPACITY*4; |
+ int32_t keywordValueLen =0; |
+ |
+ /* argument checking */ |
+ if(status==NULL || U_FAILURE(*status)) { |
+ return 0; |
+ } |
+ |
+ if(destCapacity<0 || (destCapacity>0 && dest==NULL)) { |
+ *status=U_ILLEGAL_ARGUMENT_ERROR; |
+ return 0; |
+ } |
+ |
+ /* get the keyword value */ |
+ keywordValue[0]=0; |
+ keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, capacity, status); |
+ |
+ /* |
+ * if the keyword is equal to currency .. then to get the display name |
+ * we need to do the fallback ourselves |
+ */ |
+ if(uprv_stricmp(keyword, _kCurrency)==0){ |
+ |
+ int32_t dispNameLen = 0; |
+ const UChar *dispName = NULL; |
+ |
+ UResourceBundle *bundle = ures_open(U_ICUDATA_CURR, displayLocale, status); |
+ UResourceBundle *currencies = ures_getByKey(bundle, _kCurrencies, NULL, status); |
+ UResourceBundle *currency = ures_getByKeyWithFallback(currencies, keywordValue, NULL, status); |
+ |
+ dispName = ures_getStringByIndex(currency, UCURRENCY_DISPLAY_NAME_INDEX, &dispNameLen, status); |
+ |
+ /*close the bundles */ |
+ ures_close(currency); |
+ ures_close(currencies); |
+ ures_close(bundle); |
+ |
+ if(U_FAILURE(*status)){ |
+ if(*status == U_MISSING_RESOURCE_ERROR){ |
+ /* we just want to write the value over if nothing is available */ |
+ *status = U_USING_DEFAULT_WARNING; |
+ }else{ |
+ return 0; |
+ } |
+ } |
+ |
+ /* now copy the dispName over if not NULL */ |
+ if(dispName != NULL){ |
+ if(dispNameLen <= destCapacity){ |
+ uprv_memcpy(dest, dispName, dispNameLen * U_SIZEOF_UCHAR); |
+ return u_terminateUChars(dest, destCapacity, dispNameLen, status); |
+ }else{ |
+ *status = U_BUFFER_OVERFLOW_ERROR; |
+ return dispNameLen; |
+ } |
+ }else{ |
+ /* we have not found the display name for the value .. just copy over */ |
+ if(keywordValueLen <= destCapacity){ |
+ u_charsToUChars(keywordValue, dest, keywordValueLen); |
+ return u_terminateUChars(dest, destCapacity, keywordValueLen, status); |
+ }else{ |
+ *status = U_BUFFER_OVERFLOW_ERROR; |
+ return keywordValueLen; |
+ } |
+ } |
+ |
+ |
+ }else{ |
+ |
+ return _getStringOrCopyKey(U_ICUDATA_LANG, displayLocale, |
+ _kTypes, keyword, |
+ keywordValue, |
+ keywordValue, |
+ dest, destCapacity, |
+ status); |
+ } |
+} |
Property changes on: icu46/source/common/locdispnames.cpp |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |