From 3a49ed86f91f3e5b40eb6581c472c0f2ea1c4862 Mon Sep 17 00:00:00 2001 From: Vladimir Weinstein Date: Wed, 12 Nov 2003 23:50:21 +0000 Subject: [PATCH] ICU-2438 getKeywords ->createKeywords, added Locale::getBaseName X-SVN-Rev: 13702 --- icu4c/source/common/locid.cpp | 52 +++++++++++++++++++++++--- icu4c/source/common/unicode/locid.h | 17 ++++++++- icu4c/source/test/intltest/loctest.cpp | 2 +- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp index b3edd4a8c21..1179c719091 100644 --- a/icu4c/source/common/locid.cpp +++ b/icu4c/source/common/locid.cpp @@ -247,16 +247,20 @@ Locale::~Locale() uprv_free(fullName); fullName = NULL; } + if (baseName && baseName != baseNameBuffer) { + uprv_free(baseName); + baseName = NULL; + } } Locale::Locale() - : UObject(), fullName(fullNameBuffer) + : UObject(), fullName(fullNameBuffer), baseName(NULL) { init(NULL); } Locale::Locale(Locale::ELocaleType t) - : UObject(), fullName(fullNameBuffer) + : UObject(), fullName(fullNameBuffer), baseName(NULL) { setToBogus(); } @@ -266,7 +270,7 @@ Locale::Locale( const char * newLanguage, const char * newCountry, const char * newVariant, const char * newKeywords) - : UObject(), fullName(fullNameBuffer) + : UObject(), fullName(fullNameBuffer), baseName(NULL) { if( (newLanguage==NULL) && (newCountry == NULL) && (newVariant == NULL) ) { @@ -386,7 +390,7 @@ Locale::Locale( const char * newLanguage, } Locale::Locale(const Locale &other) - : UObject(other), fullName(fullNameBuffer) + : UObject(other), fullName(fullNameBuffer), baseName(NULL) { *this = other; } @@ -408,14 +412,26 @@ Locale &Locale::operator=(const Locale &other) fullName = fullNameBuffer; } + if(baseName && baseName != baseNameBuffer) { + uprv_free(baseName); + baseName = NULL; + } + /* Allocate the full name if necessary */ if(other.fullName != other.fullNameBuffer) { fullName = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(other.fullName)+1)); } - /* Copy the full name */ uprv_strcpy(fullName, other.fullName); + if(other.baseName) { + if(other.baseName != other.baseNameBuffer) { + baseName = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(other.fullName)+1)); + } + uprv_strcpy(baseName, other.baseName); + } + + /* Copy the language and country fields */ uprv_strcpy(language, other.language); uprv_strcpy(script, other.script); @@ -448,6 +464,11 @@ Locale& Locale::init(const char* localeID) fullName = fullNameBuffer; } + if(baseName && baseName != baseNameBuffer) { + uprv_free(baseName); + baseName = NULL; + } + // not a loop: // just an easy way to have a common error-exit // without goto and without another function @@ -1188,7 +1209,7 @@ public: const char KeywordEnumeration::fgClassID = '\0'; StringEnumeration * -Locale::getKeywords(UErrorCode &status) const +Locale::createKeywords(UErrorCode &status) const { char keywords[256]; int32_t keywordCapacity = 256; @@ -1215,5 +1236,24 @@ Locale::getKeywordValue(const char* keywordName, char *buffer, int32_t bufLen, U return uloc_getKeywordValue(fullName, keywordName, buffer, bufLen, &status); } +const char * +Locale::getBaseName() const +{ + // lazy init + UErrorCode status = U_ZERO_ERROR; + // semantically const + if(baseName == 0) { + ((Locale *)this)->baseName = ((Locale *)this)->baseNameBuffer; + int32_t baseNameSize = uloc_getBaseName(fullName, baseName, ULOC_FULLNAME_CAPACITY, &status); + if(baseNameSize >= ULOC_FULLNAME_CAPACITY) { + ((Locale *)this)->baseName = (char *)malloc(sizeof(char) * baseNameSize + 1); + uloc_getBaseName(fullName, baseName, baseNameSize+1, &status); + } + baseName[baseNameSize] = 0; + } + return baseName; +} + + //eof U_NAMESPACE_END diff --git a/icu4c/source/common/unicode/locid.h b/icu4c/source/common/unicode/locid.h index 566ea79df76..473808b6864 100644 --- a/icu4c/source/common/unicode/locid.h +++ b/icu4c/source/common/unicode/locid.h @@ -404,13 +404,25 @@ public: */ inline const char * getName() const; + /** + * Returns the programmatic name of the entire locale, with the language, + * country and variant separated by underbars and without keywords. + * If a field is missing, up + * to two leading underbars will occur. Example: "en", "de_DE", "en_US_WIN", + * "de__POSIX", "fr__MAC", "__MAC", "_MT", "_FR_EURO" + * @return A pointer to "name". + * @draft ICU 2.8 + */ + const char * getBaseName() const; + + /** * Gets the list of keywords for the specified locale. * * @return pointer to StringEnumeration class. Client must dispose of it by calling delete. * @draft ICU 2.8 */ - StringEnumeration * getKeywords(UErrorCode &status) const; + StringEnumeration * createKeywords(UErrorCode &status) const; /** * Get the value for a keyword. @@ -682,6 +694,9 @@ private: int32_t variantBegin; char* fullName; char fullNameBuffer[ULOC_FULLNAME_CAPACITY]; + // name without keywords + char* baseName; + char baseNameBuffer[ULOC_FULLNAME_CAPACITY]; UBool fIsBogus; diff --git a/icu4c/source/test/intltest/loctest.cpp b/icu4c/source/test/intltest/loctest.cpp index 89df414a042..a3e29a662e0 100644 --- a/icu4c/source/test/intltest/loctest.cpp +++ b/icu4c/source/test/intltest/loctest.cpp @@ -1516,7 +1516,7 @@ LocaleTest::TestKeywordVariants(void) { for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) { status = U_ZERO_ERROR; Locale l(testCases[i].localeID); - keywords = l.getKeywords(status); + keywords = l.createKeywords(status); if(status != testCases[i].expectedStatus) { err("Expected to get status %s. Got %s instead\n",