ICU-2438 C++ implementation for getKeywords and getKeywordValue
X-SVN-Rev: 13423
This commit is contained in:
parent
c93ae8408a
commit
f6a15b10ba
@ -67,6 +67,12 @@ typedef enum ELocalePos {
|
||||
eMAX_LOCALES
|
||||
} ELocalePos;
|
||||
|
||||
U_CFUNC int32_t locale_getKeywords(const char *localeID,
|
||||
char prev,
|
||||
char *keywords, int32_t keywordCapacity,
|
||||
char *values, int32_t valuesCapacity, int32_t *valLen,
|
||||
UBool valuesToo,
|
||||
UErrorCode *status);
|
||||
|
||||
static Locale *gLocaleCache = NULL;
|
||||
static const Locale *gDefaultLocale = NULL;
|
||||
@ -256,7 +262,8 @@ Locale::Locale(Locale::ELocaleType t)
|
||||
|
||||
Locale::Locale( const char * newLanguage,
|
||||
const char * newCountry,
|
||||
const char * newVariant)
|
||||
const char * newVariant,
|
||||
const char * newKeywords)
|
||||
: UObject(), fullName(fullNameBuffer)
|
||||
{
|
||||
if( (newLanguage==NULL) && (newCountry == NULL) && (newVariant == NULL) )
|
||||
@ -482,7 +489,11 @@ Locale& Locale::init(const char* localeID)
|
||||
fieldLen[fieldIdx-1] = separator - field[fieldIdx-1];
|
||||
fieldIdx++;
|
||||
}
|
||||
fieldLen[fieldIdx-1] = length - (int32_t)(field[fieldIdx-1] - fullName);
|
||||
if(separator = uprv_strchr(field[fieldIdx-1], '@')) {
|
||||
fieldLen[fieldIdx-1] = separator - field[fieldIdx-1];
|
||||
} else {
|
||||
fieldLen[fieldIdx-1] = length - (int32_t)(field[fieldIdx-1] - fullName);
|
||||
}
|
||||
|
||||
if (fieldLen[0] >= (int32_t)(sizeof(language))
|
||||
|| (fieldLen[1] == 4 && fieldLen[2] >= (int32_t)(sizeof(country)))
|
||||
@ -1090,5 +1101,109 @@ Locale::getLocaleCache(void)
|
||||
return gLocaleCache;
|
||||
}
|
||||
|
||||
class KeywordEnumeration : public StringEnumeration {
|
||||
private:
|
||||
char *keywords;
|
||||
char *current;
|
||||
UChar currUKey[256];
|
||||
UnicodeString currUSKey;
|
||||
static const char fgClassID;
|
||||
|
||||
public:
|
||||
static inline UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
|
||||
virtual UClassID getDynamicClassID(void) const { return getStaticClassID(); }
|
||||
public:
|
||||
KeywordEnumeration(const char *keys, int32_t keywordLen, UErrorCode &status) {
|
||||
keywords = (char *)uprv_malloc(keywordLen+1);
|
||||
uprv_memcpy(keywords, keys, keywordLen);
|
||||
keywords[keywordLen] = 0;
|
||||
current = keywords;
|
||||
}
|
||||
|
||||
~KeywordEnumeration() {
|
||||
uprv_free(keywords);
|
||||
}
|
||||
|
||||
int32_t count(UErrorCode &status) const {
|
||||
char *kw = keywords;
|
||||
int32_t result = 0;
|
||||
while(*kw) {
|
||||
result++;
|
||||
kw += uprv_strlen(kw)+1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* next(int32_t* resultLength, UErrorCode& status) {
|
||||
const char* result = current;
|
||||
if(*result) {
|
||||
*resultLength = uprv_strlen(current);
|
||||
current += *resultLength+1;
|
||||
} else {
|
||||
*resultLength = 0;
|
||||
result = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const UChar* unext(int32_t* resultLength, UErrorCode& status) {
|
||||
const char* starter = next(resultLength, status);
|
||||
if(starter) {
|
||||
u_charsToUChars(starter, currUKey, *resultLength);
|
||||
currUKey[*resultLength] = 0;
|
||||
return currUKey;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const UnicodeString* snext(UErrorCode& status) {
|
||||
int32_t resultLength = 0;
|
||||
const UChar* starter = unext(&resultLength, status);
|
||||
if(starter) {
|
||||
currUSKey.setTo(TRUE, starter, resultLength);
|
||||
return &currUSKey;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void reset(UErrorCode& /*status*/) {
|
||||
current = keywords;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
const char KeywordEnumeration::fgClassID = '\0';
|
||||
|
||||
StringEnumeration *
|
||||
Locale::getKeywords(UErrorCode &status) const
|
||||
{
|
||||
char keywords[256];
|
||||
int32_t keywordCapacity = 256;
|
||||
StringEnumeration *result = NULL;
|
||||
|
||||
const char* variantStart = uprv_strchr(fullName, '@');
|
||||
const char* assignment = uprv_strchr(fullName, '=');
|
||||
if(variantStart) {
|
||||
if(assignment) {
|
||||
int32_t keyLen = locale_getKeywords(variantStart+1, '@', keywords, keywordCapacity, NULL, 0, NULL, FALSE, &status);
|
||||
if(keyLen) {
|
||||
result = new KeywordEnumeration(keywords, keyLen, status);
|
||||
}
|
||||
} else {
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t
|
||||
Locale::getKeywordValue(const char* keywordName, char *buffer, int32_t bufLen, UErrorCode &status) const
|
||||
{
|
||||
return uloc_getKeywordValue(fullName, keywordName, buffer, bufLen, &status);
|
||||
}
|
||||
|
||||
//eof
|
||||
U_NAMESPACE_END
|
||||
|
@ -756,10 +756,11 @@ compareKeywordStructs(const void *context, const void *left, const void *right)
|
||||
return uprv_strcmp(leftString, rightString);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
_getKeywords(const char *localeID,
|
||||
U_CFUNC int32_t
|
||||
locale_getKeywords(const char *localeID,
|
||||
char prev,
|
||||
char *keywords, int32_t keywordCapacity,
|
||||
char *values, int32_t valuesCapacity, int32_t *valLen,
|
||||
UBool valuesToo,
|
||||
UErrorCode *status) {
|
||||
|
||||
@ -771,6 +772,7 @@ _getKeywords(const char *localeID,
|
||||
const char* nextSeparator = NULL;
|
||||
int32_t i = 0;
|
||||
int32_t keywordsLen = 0;
|
||||
int32_t valuesLen = 0;
|
||||
|
||||
if(prev == '@') { /* start of keyword definition */
|
||||
/* we will grab pairs, trim spaces, lowercase keywords, sort and return */
|
||||
@ -856,8 +858,20 @@ _getKeywords(const char *localeID,
|
||||
keywordsLen++;
|
||||
}
|
||||
}
|
||||
if(values) {
|
||||
if(valuesLen + keywordList[i].valueLen + 1< valuesCapacity) {
|
||||
uprv_strcpy(values+valuesLen, keywordList[i].valueStart);
|
||||
values[valuesLen + keywordList[i].valueLen] = 0;
|
||||
}
|
||||
valuesLen += keywordList[i].valueLen + 1;
|
||||
}
|
||||
}
|
||||
if(values) {
|
||||
values[valuesLen] = 0;
|
||||
if(valLen) {
|
||||
*valLen = valuesLen;
|
||||
}
|
||||
}
|
||||
|
||||
return u_terminateChars(keywords, keywordCapacity, keywordsLen, status);
|
||||
} else {
|
||||
return 0;
|
||||
@ -1004,7 +1018,7 @@ uloc_getKeywords(const char* localeID,
|
||||
|
||||
/* keywords are located after '@' */
|
||||
if((localeID = uprv_strchr(localeID, '@')) != NULL) {
|
||||
i=_getKeywords(localeID+1, '@', keywords, keywordsCapacity, FALSE, status);
|
||||
i=locale_getKeywords(localeID+1, '@', keywords, keywordsCapacity, NULL, 0, NULL, FALSE, status);
|
||||
}
|
||||
|
||||
if(i) {
|
||||
@ -1095,7 +1109,7 @@ uloc_getName(const char* localeID,
|
||||
}
|
||||
++i;
|
||||
++fieldCount;
|
||||
i += _getKeywords(localeID+1, '@', name+i, nameCapacity-i, TRUE, err);
|
||||
i += locale_getKeywords(localeID+1, '@', name+i, nameCapacity-i, NULL, 0, NULL, TRUE, err);
|
||||
} else if(fieldCount < 2) {
|
||||
do {
|
||||
if(i<nameCapacity) {
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "unicode/unistr.h"
|
||||
#include "unicode/putil.h"
|
||||
#include "unicode/uloc.h"
|
||||
#include "unicode/strenum.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
@ -250,6 +251,8 @@ public:
|
||||
* @param country Uppercase two-letter ISO-3166 code. (optional)
|
||||
* @param variant Uppercase vendor and browser specific code. See class
|
||||
* description. (optional)
|
||||
* @param keywordsAndValues A string consisting of keyword/values pairs, such as
|
||||
* "collation=phonebook;currency=euro"
|
||||
*
|
||||
* @see getDefault
|
||||
* @see uloc_getDefault
|
||||
@ -257,7 +260,8 @@ public:
|
||||
*/
|
||||
Locale( const char * language,
|
||||
const char * country = 0,
|
||||
const char * variant = 0);
|
||||
const char * variant = 0,
|
||||
const char * keywordsAndValues = 0);
|
||||
|
||||
/**
|
||||
* Initializes a Locale object from another Locale object.
|
||||
@ -387,6 +391,25 @@ public:
|
||||
*/
|
||||
inline const char * getName() 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;
|
||||
|
||||
/**
|
||||
* Get the value for a keyword.
|
||||
*
|
||||
* @param keywordName name of the keyword for which we want the value. Case insensitive.
|
||||
* @return pointer to the keyword value owned by the Locale object or NULL if there is
|
||||
* no such a keyword.
|
||||
*
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
int32_t getKeywordValue(const char* keywordName, char *buffer, int32_t bufLen, UErrorCode &status) const;
|
||||
|
||||
/**
|
||||
* returns the locale's three-letter language code, as specified
|
||||
* in ISO draft standard ISO-639-2..
|
||||
|
Loading…
Reference in New Issue
Block a user