ICU-5225 Minor speed improvement for opening and closing converters
by storing information about whether converter options are on the canonical converter name. X-SVN-Rev: 19707
This commit is contained in:
parent
f7ad33b0b7
commit
78f8b26a73
@ -160,6 +160,7 @@ static uint16_t gAvailableConverterCount = 0;
|
||||
|
||||
static char gDefaultConverterNameBuffer[UCNV_MAX_CONVERTER_NAME_LENGTH + 1]; /* +1 for NULL */
|
||||
static const char *gDefaultConverterName = NULL;
|
||||
static UBool gDefaultConverterContainsOption;
|
||||
|
||||
|
||||
static const char DATA_TYPE[] = "cnv";
|
||||
@ -182,6 +183,7 @@ static UBool U_CALLCONV ucnv_cleanup(void) {
|
||||
|
||||
gDefaultConverterName = NULL;
|
||||
gDefaultConverterNameBuffer[0] = 0;
|
||||
gDefaultConverterContainsOption = FALSE;
|
||||
|
||||
umtx_destroy(&cnvCacheMutex); /* Don't worry about destroying the mutex even */
|
||||
/* if the hash table still exists. The mutex */
|
||||
@ -658,6 +660,7 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
|
||||
UConverterLookupData stackLookup;
|
||||
UConverterSharedData *mySharedConverterData = NULL;
|
||||
UErrorCode internalErrorCode = U_ZERO_ERROR;
|
||||
UBool mayContainOption = TRUE;
|
||||
|
||||
if (U_FAILURE (*err)) {
|
||||
return NULL;
|
||||
@ -673,6 +676,7 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
|
||||
/* In case "name" is NULL we want to open the default converter. */
|
||||
if (converterName == NULL) {
|
||||
lookup->realName = ucnv_getDefaultName();
|
||||
mayContainOption = gDefaultConverterContainsOption;
|
||||
if (lookup->realName == NULL) {
|
||||
*err = U_MISSING_RESOURCE_ERROR;
|
||||
return NULL;
|
||||
@ -687,7 +691,7 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
|
||||
}
|
||||
|
||||
/* get the canonical converter name */
|
||||
lookup->realName = ucnv_io_getConverterName(lookup->cnvName, &internalErrorCode);
|
||||
lookup->realName = ucnv_io_getConverterName(lookup->cnvName, &mayContainOption, &internalErrorCode);
|
||||
if (U_FAILURE(internalErrorCode) || lookup->realName == NULL) {
|
||||
/*
|
||||
* set the input name in case the converter was added
|
||||
@ -698,7 +702,7 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
|
||||
}
|
||||
|
||||
/* separate the converter name from the options */
|
||||
if(lookup->realName != lookup->cnvName) {
|
||||
if(mayContainOption && lookup->realName != lookup->cnvName) {
|
||||
parseConverterOptions(lookup->realName, lookup->cnvName, lookup->locale, &lookup->options, err);
|
||||
lookup->realName = lookup->cnvName;
|
||||
}
|
||||
@ -1113,6 +1117,7 @@ ucnv_getDefaultName() {
|
||||
uprv_memcpy(gDefaultConverterNameBuffer, name, length);
|
||||
gDefaultConverterNameBuffer[length]=0;
|
||||
gDefaultConverterName = gDefaultConverterNameBuffer;
|
||||
gDefaultConverterContainsOption = (UBool)(uprv_strchr(gDefaultConverterName, UCNV_OPTION_SEP_CHAR) != NULL);
|
||||
name = gDefaultConverterName;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
@ -1133,7 +1138,7 @@ ucnv_setDefaultName(const char *converterName) {
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
} else {
|
||||
UErrorCode errorCode=U_ZERO_ERROR;
|
||||
const char *name=ucnv_io_getConverterName(converterName, &errorCode);
|
||||
const char *name=ucnv_io_getConverterName(converterName, NULL, &errorCode);
|
||||
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
|
||||
@ -1147,6 +1152,7 @@ ucnv_setDefaultName(const char *converterName) {
|
||||
uprv_memcpy(gDefaultConverterNameBuffer, converterName, length);
|
||||
gDefaultConverterNameBuffer[length]=0;
|
||||
gDefaultConverterName=gDefaultConverterNameBuffer;
|
||||
gDefaultConverterContainsOption = (UBool)(uprv_strchr(gDefaultConverterName, UCNV_OPTION_SEP_CHAR) != NULL);
|
||||
}
|
||||
}
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
|
@ -73,6 +73,8 @@
|
||||
* index of this list is also used by other sections, like the 4th section.
|
||||
* The index for the 3rd and 4th section is used to get the
|
||||
* alias -> converter name mapping. Section 3 and 4 form a two column table.
|
||||
* Some of the most significant bits of each index may contain other
|
||||
* information (see findConverter for details).
|
||||
*
|
||||
* 4) This section contains a list of mapped converter names. Consider this
|
||||
* as a table that maps the 3rd section to the 1st section. This list contains
|
||||
@ -187,7 +189,8 @@ enum {
|
||||
};
|
||||
|
||||
static const UConverterAliasOptions defaultTableOptions = {
|
||||
UCNV_IO_UNNORMALIZED
|
||||
UCNV_IO_UNNORMALIZED,
|
||||
0 /* containsCnvOptionInfo */
|
||||
};
|
||||
static UConverterAlias gMainTable;
|
||||
|
||||
@ -435,7 +438,7 @@ ucnv_compareNames(const char *name1, const char *name2) {
|
||||
* return the converter number index for gConverterList
|
||||
*/
|
||||
static U_INLINE uint32_t
|
||||
findConverter(const char *alias, UErrorCode *pErrorCode) {
|
||||
findConverter(const char *alias, UBool *containsOption, UErrorCode *pErrorCode) {
|
||||
uint32_t mid, start, limit;
|
||||
uint32_t lastMid;
|
||||
int result;
|
||||
@ -484,6 +487,14 @@ findConverter(const char *alias, UErrorCode *pErrorCode) {
|
||||
if (gMainTable.untaggedConvArray[mid] & UCNV_AMBIGUOUS_ALIAS_MAP_BIT) {
|
||||
*pErrorCode = U_AMBIGUOUS_ALIAS_WARNING;
|
||||
}
|
||||
/* State whether the canonical converter name contains an option.
|
||||
This information is contained in this list in order to maintain backward & forward compatibility. */
|
||||
if (containsOption) {
|
||||
UBool containsCnvOptionInfo = (UBool)gMainTable.optionTable->containsCnvOptionInfo;
|
||||
*containsOption = (UBool)((containsCnvOptionInfo
|
||||
&& ((gMainTable.untaggedConvArray[mid] & UCNV_CONTAINS_OPTION_BIT) != 0))
|
||||
|| !containsCnvOptionInfo);
|
||||
}
|
||||
return gMainTable.untaggedConvArray[mid] & UCNV_CONVERTER_INDEX_MASK;
|
||||
}
|
||||
}
|
||||
@ -528,7 +539,7 @@ findTaggedAliasListsOffset(const char *alias, const char *standard, UErrorCode *
|
||||
uint32_t tagNum = getTagNumber(standard);
|
||||
|
||||
/* Make a quick guess. Hopefully they used a TR22 canonical alias. */
|
||||
convNum = findConverter(alias, &myErr);
|
||||
convNum = findConverter(alias, NULL, &myErr);
|
||||
if (myErr != U_ZERO_ERROR) {
|
||||
*pErrorCode = myErr;
|
||||
}
|
||||
@ -579,7 +590,7 @@ findTaggedConverterNum(const char *alias, const char *standard, UErrorCode *pErr
|
||||
uint32_t tagNum = getTagNumber(standard);
|
||||
|
||||
/* Make a quick guess. Hopefully they used a TR22 canonical alias. */
|
||||
convNum = findConverter(alias, &myErr);
|
||||
convNum = findConverter(alias, NULL, &myErr);
|
||||
if (myErr != U_ZERO_ERROR) {
|
||||
*pErrorCode = myErr;
|
||||
}
|
||||
@ -615,9 +626,9 @@ findTaggedConverterNum(const char *alias, const char *standard, UErrorCode *pErr
|
||||
|
||||
|
||||
U_CFUNC const char *
|
||||
ucnv_io_getConverterName(const char *alias, UErrorCode *pErrorCode) {
|
||||
ucnv_io_getConverterName(const char *alias, UBool *containsOption, UErrorCode *pErrorCode) {
|
||||
if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) {
|
||||
uint32_t convNum = findConverter(alias, pErrorCode);
|
||||
uint32_t convNum = findConverter(alias, containsOption, pErrorCode);
|
||||
if (convNum < gMainTable.converterListSize) {
|
||||
return GET_STRING(gMainTable.converterList[convNum]);
|
||||
}
|
||||
@ -724,7 +735,7 @@ ucnv_openStandardNames(const char *convName,
|
||||
static uint16_t
|
||||
ucnv_io_countAliases(const char *alias, UErrorCode *pErrorCode) {
|
||||
if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) {
|
||||
uint32_t convNum = findConverter(alias, pErrorCode);
|
||||
uint32_t convNum = findConverter(alias, NULL, pErrorCode);
|
||||
if (convNum < gMainTable.converterListSize) {
|
||||
/* tagListNum - 1 is the ALL tag */
|
||||
int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum];
|
||||
@ -743,7 +754,7 @@ static uint16_t
|
||||
ucnv_io_getAliases(const char *alias, uint16_t start, const char **aliases, UErrorCode *pErrorCode) {
|
||||
if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) {
|
||||
uint32_t currAlias;
|
||||
uint32_t convNum = findConverter(alias, pErrorCode);
|
||||
uint32_t convNum = findConverter(alias, NULL, pErrorCode);
|
||||
if (convNum < gMainTable.converterListSize) {
|
||||
/* tagListNum - 1 is the ALL tag */
|
||||
int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum];
|
||||
@ -767,7 +778,7 @@ ucnv_io_getAliases(const char *alias, uint16_t start, const char **aliases, UErr
|
||||
static const char *
|
||||
ucnv_io_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode) {
|
||||
if(haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) {
|
||||
uint32_t convNum = findConverter(alias, pErrorCode);
|
||||
uint32_t convNum = findConverter(alias, NULL, pErrorCode);
|
||||
if (convNum < gMainTable.converterListSize) {
|
||||
/* tagListNum - 1 is the ALL tag */
|
||||
int32_t listOffset = gMainTable.taggedAliasArray[(gMainTable.tagListSize - 1)*gMainTable.converterListSize + convNum];
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "udataswp.h"
|
||||
|
||||
#define UCNV_AMBIGUOUS_ALIAS_MAP_BIT 0x8000
|
||||
#define UCNV_CONTAINS_OPTION_BIT 0x4000
|
||||
#define UCNV_CONVERTER_INDEX_MASK 0xFFF
|
||||
#define UCNV_NUM_RESERVED_TAGS 2
|
||||
#define UCNV_NUM_HIDDEN_TAGS 1
|
||||
@ -32,6 +33,7 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
uint16_t stringNormalizationType;
|
||||
uint16_t containsCnvOptionInfo;
|
||||
} UConverterAliasOptions;
|
||||
|
||||
typedef struct UConverterAlias {
|
||||
@ -85,11 +87,12 @@ ucnv_io_stripEBCDICForCompare(char *dst, const char *name);
|
||||
* is returned in mixed-case.
|
||||
* Returns NULL if the alias is not found.
|
||||
* @param alias The alias name to be searched.
|
||||
* @param containsOption A return value stating whether the returned converter name contains an option (a comma)
|
||||
* @param pErrorCode The error code
|
||||
* @return the converter name in mixed-case, return NULL if the alias is not found.
|
||||
*/
|
||||
U_CFUNC const char *
|
||||
ucnv_io_getConverterName(const char *alias, UErrorCode *pErrorCode);
|
||||
ucnv_io_getConverterName(const char *alias, UBool *containsOption, UErrorCode *pErrorCode);
|
||||
|
||||
/**
|
||||
* Return the number of all aliases and converter names.
|
||||
|
@ -138,7 +138,8 @@ static UBool verbose = FALSE;
|
||||
static int lineNum = 1;
|
||||
|
||||
static UConverterAliasOptions tableOptions = {
|
||||
UCNV_IO_UNNORMALIZED
|
||||
UCNV_IO_UNNORMALIZED,
|
||||
1 /* containsCnvOptionInfo */
|
||||
};
|
||||
|
||||
/* prototypes --------------------------------------------------------------- */
|
||||
@ -880,6 +881,9 @@ resolveAliases(uint16_t *uniqueAliasArr, uint16_t *uniqueAliasToConverterArr, ui
|
||||
oldTagNum = currTagNum;
|
||||
/*printf("%s -> %s\n", GET_ALIAS_STR(knownAliases[idx]), GET_ALIAS_STR(converters[currConvNum].converter));*/
|
||||
}
|
||||
if (uprv_strchr(GET_ALIAS_STR(converters[currConvNum].converter), UCNV_OPTION_SEP_CHAR) != NULL) {
|
||||
uniqueAliasToConverterArr[uniqueAliasIdx-1] |= UCNV_CONTAINS_OPTION_BIT;
|
||||
}
|
||||
}
|
||||
return uniqueAliasIdx;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user