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
|
eMAX_LOCALES
|
||||||
} ELocalePos;
|
} 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 Locale *gLocaleCache = NULL;
|
||||||
static const Locale *gDefaultLocale = NULL;
|
static const Locale *gDefaultLocale = NULL;
|
||||||
@ -256,7 +262,8 @@ Locale::Locale(Locale::ELocaleType t)
|
|||||||
|
|
||||||
Locale::Locale( const char * newLanguage,
|
Locale::Locale( const char * newLanguage,
|
||||||
const char * newCountry,
|
const char * newCountry,
|
||||||
const char * newVariant)
|
const char * newVariant,
|
||||||
|
const char * newKeywords)
|
||||||
: UObject(), fullName(fullNameBuffer)
|
: UObject(), fullName(fullNameBuffer)
|
||||||
{
|
{
|
||||||
if( (newLanguage==NULL) && (newCountry == NULL) && (newVariant == NULL) )
|
if( (newLanguage==NULL) && (newCountry == NULL) && (newVariant == NULL) )
|
||||||
@ -482,7 +489,11 @@ Locale& Locale::init(const char* localeID)
|
|||||||
fieldLen[fieldIdx-1] = separator - field[fieldIdx-1];
|
fieldLen[fieldIdx-1] = separator - field[fieldIdx-1];
|
||||||
fieldIdx++;
|
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))
|
if (fieldLen[0] >= (int32_t)(sizeof(language))
|
||||||
|| (fieldLen[1] == 4 && fieldLen[2] >= (int32_t)(sizeof(country)))
|
|| (fieldLen[1] == 4 && fieldLen[2] >= (int32_t)(sizeof(country)))
|
||||||
@ -1090,5 +1101,109 @@ Locale::getLocaleCache(void)
|
|||||||
return gLocaleCache;
|
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
|
//eof
|
||||||
U_NAMESPACE_END
|
U_NAMESPACE_END
|
||||||
|
@ -756,10 +756,11 @@ compareKeywordStructs(const void *context, const void *left, const void *right)
|
|||||||
return uprv_strcmp(leftString, rightString);
|
return uprv_strcmp(leftString, rightString);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t
|
U_CFUNC int32_t
|
||||||
_getKeywords(const char *localeID,
|
locale_getKeywords(const char *localeID,
|
||||||
char prev,
|
char prev,
|
||||||
char *keywords, int32_t keywordCapacity,
|
char *keywords, int32_t keywordCapacity,
|
||||||
|
char *values, int32_t valuesCapacity, int32_t *valLen,
|
||||||
UBool valuesToo,
|
UBool valuesToo,
|
||||||
UErrorCode *status) {
|
UErrorCode *status) {
|
||||||
|
|
||||||
@ -771,6 +772,7 @@ _getKeywords(const char *localeID,
|
|||||||
const char* nextSeparator = NULL;
|
const char* nextSeparator = NULL;
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
int32_t keywordsLen = 0;
|
int32_t keywordsLen = 0;
|
||||||
|
int32_t valuesLen = 0;
|
||||||
|
|
||||||
if(prev == '@') { /* start of keyword definition */
|
if(prev == '@') { /* start of keyword definition */
|
||||||
/* we will grab pairs, trim spaces, lowercase keywords, sort and return */
|
/* we will grab pairs, trim spaces, lowercase keywords, sort and return */
|
||||||
@ -856,8 +858,20 @@ _getKeywords(const char *localeID,
|
|||||||
keywordsLen++;
|
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);
|
return u_terminateChars(keywords, keywordCapacity, keywordsLen, status);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@ -1004,7 +1018,7 @@ uloc_getKeywords(const char* localeID,
|
|||||||
|
|
||||||
/* keywords are located after '@' */
|
/* keywords are located after '@' */
|
||||||
if((localeID = uprv_strchr(localeID, '@')) != NULL) {
|
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) {
|
if(i) {
|
||||||
@ -1095,7 +1109,7 @@ uloc_getName(const char* localeID,
|
|||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
++fieldCount;
|
++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) {
|
} else if(fieldCount < 2) {
|
||||||
do {
|
do {
|
||||||
if(i<nameCapacity) {
|
if(i<nameCapacity) {
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "unicode/unistr.h"
|
#include "unicode/unistr.h"
|
||||||
#include "unicode/putil.h"
|
#include "unicode/putil.h"
|
||||||
#include "unicode/uloc.h"
|
#include "unicode/uloc.h"
|
||||||
|
#include "unicode/strenum.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
@ -250,6 +251,8 @@ public:
|
|||||||
* @param country Uppercase two-letter ISO-3166 code. (optional)
|
* @param country Uppercase two-letter ISO-3166 code. (optional)
|
||||||
* @param variant Uppercase vendor and browser specific code. See class
|
* @param variant Uppercase vendor and browser specific code. See class
|
||||||
* description. (optional)
|
* description. (optional)
|
||||||
|
* @param keywordsAndValues A string consisting of keyword/values pairs, such as
|
||||||
|
* "collation=phonebook;currency=euro"
|
||||||
*
|
*
|
||||||
* @see getDefault
|
* @see getDefault
|
||||||
* @see uloc_getDefault
|
* @see uloc_getDefault
|
||||||
@ -257,7 +260,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
Locale( const char * language,
|
Locale( const char * language,
|
||||||
const char * country = 0,
|
const char * country = 0,
|
||||||
const char * variant = 0);
|
const char * variant = 0,
|
||||||
|
const char * keywordsAndValues = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a Locale object from another Locale object.
|
* Initializes a Locale object from another Locale object.
|
||||||
@ -387,6 +391,25 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline const char * getName() const;
|
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
|
* returns the locale's three-letter language code, as specified
|
||||||
* in ISO draft standard ISO-639-2..
|
* in ISO draft standard ISO-639-2..
|
||||||
|
Loading…
Reference in New Issue
Block a user