mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-06 22:15:31 +00:00
ICU-6441 make ucnv_countAvailable() not fully load converters
X-SVN-Rev: 25584
This commit is contained in:
parent
67f42c995f
commit
abb7ac7522
12 changed files with 386 additions and 218 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 2000-2008, International Business Machines
|
||||
* Copyright (C) 2000-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* file name: ucnv2022.c
|
||||
|
@ -165,7 +165,8 @@ typedef enum {
|
|||
* all versions, not just JIS7 and JIS8.
|
||||
* - ICU does not distinguish between different versions of JIS X 0208.
|
||||
*/
|
||||
static const uint16_t jpCharsetMasks[5]={
|
||||
enum { MAX_JA_VERSION=4 };
|
||||
static const uint16_t jpCharsetMasks[MAX_JA_VERSION+1]={
|
||||
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT),
|
||||
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212),
|
||||
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212)|CSM(GB2312)|CSM(KSC5601)|CSM(ISO8859_1)|CSM(ISO8859_7),
|
||||
|
@ -370,7 +371,7 @@ typedef enum{
|
|||
|
||||
/*********** ISO 2022 Converter Protos ***********/
|
||||
static void
|
||||
_ISO2022Open(UConverter *cnv, const char *name, const char *locale,uint32_t options, UErrorCode *errorCode);
|
||||
_ISO2022Open(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode);
|
||||
|
||||
static void
|
||||
_ISO2022Close(UConverter *converter);
|
||||
|
@ -448,40 +449,53 @@ setInitialStateFromUnicodeKR(UConverter* converter,UConverterDataISO2022 *myConv
|
|||
}
|
||||
|
||||
static void
|
||||
_ISO2022Open(UConverter *cnv, const char *name, const char *locale,uint32_t options, UErrorCode *errorCode){
|
||||
_ISO2022Open(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode){
|
||||
|
||||
char myLocale[6]={' ',' ',' ',' ',' ',' '};
|
||||
|
||||
cnv->extraInfo = uprv_malloc (sizeof (UConverterDataISO2022));
|
||||
if(cnv->extraInfo != NULL) {
|
||||
UConverterNamePieces stackPieces;
|
||||
UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
|
||||
UConverterDataISO2022 *myConverterData=(UConverterDataISO2022 *) cnv->extraInfo;
|
||||
uint32_t version;
|
||||
|
||||
stackArgs.onlyTestIsLoadable = pArgs->onlyTestIsLoadable;
|
||||
|
||||
uprv_memset(myConverterData, 0, sizeof(UConverterDataISO2022));
|
||||
myConverterData->currentType = ASCII1;
|
||||
cnv->fromUnicodeStatus =FALSE;
|
||||
if(locale){
|
||||
uprv_strncpy(myLocale, locale, sizeof(myLocale));
|
||||
if(pArgs->locale){
|
||||
uprv_strncpy(myLocale, pArgs->locale, sizeof(myLocale));
|
||||
}
|
||||
version = options & UCNV_OPTIONS_VERSION_MASK;
|
||||
version = pArgs->options & UCNV_OPTIONS_VERSION_MASK;
|
||||
myConverterData->version = version;
|
||||
if(myLocale[0]=='j' && (myLocale[1]=='a'|| myLocale[1]=='p') &&
|
||||
(myLocale[2]=='_' || myLocale[2]=='\0'))
|
||||
{
|
||||
size_t len=0;
|
||||
/* open the required converters and cache them */
|
||||
if(jpCharsetMasks[version]&CSM(ISO8859_7)) {
|
||||
myConverterData->myConverterArray[ISO8859_7]= ucnv_loadSharedData("ISO8859_7", NULL, errorCode);
|
||||
if(version>MAX_JA_VERSION) {
|
||||
/* prevent indexing beyond jpCharsetMasks[] */
|
||||
myConverterData->version = version = 0;
|
||||
}
|
||||
myConverterData->myConverterArray[JISX208] = ucnv_loadSharedData("Shift-JIS", NULL, errorCode);
|
||||
if(jpCharsetMasks[version]&CSM(ISO8859_7)) {
|
||||
myConverterData->myConverterArray[ISO8859_7] =
|
||||
ucnv_loadSharedData("ISO8859_7", &stackPieces, &stackArgs, errorCode);
|
||||
}
|
||||
myConverterData->myConverterArray[JISX208] =
|
||||
ucnv_loadSharedData("Shift-JIS", &stackPieces, &stackArgs, errorCode);
|
||||
if(jpCharsetMasks[version]&CSM(JISX212)) {
|
||||
myConverterData->myConverterArray[JISX212] = ucnv_loadSharedData("jisx-212", NULL, errorCode);
|
||||
myConverterData->myConverterArray[JISX212] =
|
||||
ucnv_loadSharedData("jisx-212", &stackPieces, &stackArgs, errorCode);
|
||||
}
|
||||
if(jpCharsetMasks[version]&CSM(GB2312)) {
|
||||
myConverterData->myConverterArray[GB2312] = ucnv_loadSharedData("ibm-5478", NULL, errorCode); /* gb_2312_80-1 */
|
||||
myConverterData->myConverterArray[GB2312] =
|
||||
ucnv_loadSharedData("ibm-5478", &stackPieces, &stackArgs, errorCode); /* gb_2312_80-1 */
|
||||
}
|
||||
if(jpCharsetMasks[version]&CSM(KSC5601)) {
|
||||
myConverterData->myConverterArray[KSC5601] = ucnv_loadSharedData("ksc_5601", NULL, errorCode);
|
||||
myConverterData->myConverterArray[KSC5601] =
|
||||
ucnv_loadSharedData("ksc_5601", &stackPieces, &stackArgs, errorCode);
|
||||
}
|
||||
|
||||
/* set the function pointers to appropriate funtions */
|
||||
|
@ -496,48 +510,56 @@ _ISO2022Open(UConverter *cnv, const char *name, const char *locale,uint32_t opti
|
|||
else if(myLocale[0]=='k' && (myLocale[1]=='o'|| myLocale[1]=='r') &&
|
||||
(myLocale[2]=='_' || myLocale[2]=='\0'))
|
||||
{
|
||||
if (version==1){
|
||||
myConverterData->currentConverter=
|
||||
ucnv_open("icu-internal-25546",errorCode);
|
||||
|
||||
if (U_FAILURE(*errorCode)) {
|
||||
_ISO2022Close(cnv);
|
||||
return;
|
||||
}
|
||||
|
||||
(void)uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=1");
|
||||
uprv_memcpy(cnv->subChars, myConverterData->currentConverter->subChars, 4);
|
||||
cnv->subCharLen = myConverterData->currentConverter->subCharLen;
|
||||
}else{
|
||||
myConverterData->currentConverter=ucnv_open("ibm-949",errorCode);
|
||||
|
||||
if (U_FAILURE(*errorCode)) {
|
||||
_ISO2022Close(cnv);
|
||||
return;
|
||||
}
|
||||
|
||||
myConverterData->version = 0;
|
||||
(void)uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=0");
|
||||
const char *cnvName;
|
||||
if(version==1) {
|
||||
cnvName="icu-internal-25546";
|
||||
} else {
|
||||
cnvName="ibm-949";
|
||||
myConverterData->version=version=0;
|
||||
}
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
UErrorCode localStatus=U_ZERO_ERROR;
|
||||
pArgs->isLoadable=ucnv_canCreateConverter(cnvName, &localStatus);
|
||||
uprv_free(cnv->extraInfo);
|
||||
cnv->extraInfo=NULL;
|
||||
return;
|
||||
} else {
|
||||
myConverterData->currentConverter=ucnv_open(cnvName, errorCode);
|
||||
if (U_FAILURE(*errorCode)) {
|
||||
_ISO2022Close(cnv);
|
||||
return;
|
||||
}
|
||||
|
||||
/* initialize the state variables */
|
||||
setInitialStateToUnicodeKR(cnv, myConverterData);
|
||||
setInitialStateFromUnicodeKR(cnv, myConverterData);
|
||||
if(version==1) {
|
||||
(void)uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=1");
|
||||
uprv_memcpy(cnv->subChars, myConverterData->currentConverter->subChars, 4);
|
||||
cnv->subCharLen = myConverterData->currentConverter->subCharLen;
|
||||
}else{
|
||||
(void)uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=0");
|
||||
}
|
||||
|
||||
/* set the function pointers to appropriate funtions */
|
||||
cnv->sharedData=(UConverterSharedData*)&_ISO2022KRData;
|
||||
uprv_strcpy(myConverterData->locale,"ko");
|
||||
/* initialize the state variables */
|
||||
setInitialStateToUnicodeKR(cnv, myConverterData);
|
||||
setInitialStateFromUnicodeKR(cnv, myConverterData);
|
||||
|
||||
/* set the function pointers to appropriate funtions */
|
||||
cnv->sharedData=(UConverterSharedData*)&_ISO2022KRData;
|
||||
uprv_strcpy(myConverterData->locale,"ko");
|
||||
}
|
||||
}
|
||||
else if(((myLocale[0]=='z' && myLocale[1]=='h') || (myLocale[0]=='c'&& myLocale[1]=='n'))&&
|
||||
(myLocale[2]=='_' || myLocale[2]=='\0'))
|
||||
{
|
||||
|
||||
/* open the required converters and cache them */
|
||||
myConverterData->myConverterArray[GB2312_1] = ucnv_loadSharedData("ibm-5478", NULL, errorCode);
|
||||
myConverterData->myConverterArray[GB2312_1] =
|
||||
ucnv_loadSharedData("ibm-5478", &stackPieces, &stackArgs, errorCode);
|
||||
if(version==1) {
|
||||
myConverterData->myConverterArray[ISO_IR_165] = ucnv_loadSharedData("iso-ir-165", NULL, errorCode);
|
||||
myConverterData->myConverterArray[ISO_IR_165] =
|
||||
ucnv_loadSharedData("iso-ir-165", &stackPieces, &stackArgs, errorCode);
|
||||
}
|
||||
myConverterData->myConverterArray[CNS_11643] = ucnv_loadSharedData("cns-11643-1992", NULL, errorCode);
|
||||
myConverterData->myConverterArray[CNS_11643] =
|
||||
ucnv_loadSharedData("cns-11643-1992", &stackPieces, &stackArgs, errorCode);
|
||||
|
||||
|
||||
/* set the function pointers to appropriate funtions */
|
||||
|
@ -575,6 +597,10 @@ _ISO2022Open(UConverter *cnv, const char *name, const char *locale,uint32_t opti
|
|||
if(U_FAILURE(*errorCode)) {
|
||||
_ISO2022Close(cnv);
|
||||
}
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
_ISO2022Close(cnv);
|
||||
pArgs->isLoadable=TRUE;
|
||||
}
|
||||
} else {
|
||||
*errorCode = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
|
|
@ -219,8 +219,8 @@ static UBool U_CALLCONV ucnv_cleanup(void) {
|
|||
|
||||
static UBool U_CALLCONV
|
||||
isCnvAcceptable(void *context,
|
||||
const char *type, const char *name,
|
||||
const UDataInfo *pInfo) {
|
||||
const char *type, const char *name,
|
||||
const UDataInfo *pInfo) {
|
||||
return (UBool)(
|
||||
pInfo->size>=20 &&
|
||||
pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
|
||||
|
@ -551,7 +551,7 @@ ucnv_load(UConverterLoadArgs *pArgs, UErrorCode *err) {
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
else if (!pArgs->onlyTestIsLoadable)
|
||||
{
|
||||
/* share it with other library clients */
|
||||
ucnv_shareConverterData(mySharedConverterData);
|
||||
|
@ -603,6 +603,11 @@ ucnv_unloadSharedDataIfReady(UConverterSharedData *sharedData)
|
|||
void
|
||||
ucnv_incrementRefCount(UConverterSharedData *sharedData)
|
||||
{
|
||||
/*
|
||||
Checking whether it's an algorithic converter is okay
|
||||
in multithreaded applications because the value never changes.
|
||||
Don't check referenceCounter for any other value.
|
||||
*/
|
||||
if(sharedData != NULL && sharedData->referenceCounter != ~0) {
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
sharedData->referenceCounter++;
|
||||
|
@ -610,27 +615,39 @@ ucnv_incrementRefCount(UConverterSharedData *sharedData)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* *pPieces must be initialized.
|
||||
* The name without options will be copied to pPieces->cnvName.
|
||||
* The locale and options will be copied to pPieces only if present in inName,
|
||||
* otherwise the existing values in pPieces remain.
|
||||
* *pArgs will be set to the pPieces values.
|
||||
*/
|
||||
static void
|
||||
parseConverterOptions(const char *inName,
|
||||
char *cnvName,
|
||||
char *locale,
|
||||
uint32_t *pFlags,
|
||||
UConverterNamePieces *pPieces,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode *err)
|
||||
{
|
||||
char *cnvName = pPieces->cnvName;
|
||||
char c;
|
||||
int32_t len = 0;
|
||||
|
||||
pArgs->name=inName;
|
||||
pArgs->locale=pPieces->locale;
|
||||
pArgs->options=pPieces->options;
|
||||
|
||||
/* copy the converter name itself to cnvName */
|
||||
while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) {
|
||||
if (++len>=UCNV_MAX_CONVERTER_NAME_LENGTH) {
|
||||
*err = U_ILLEGAL_ARGUMENT_ERROR; /* bad name */
|
||||
*cnvName=0;
|
||||
pPieces->cnvName[0]=0;
|
||||
return;
|
||||
}
|
||||
*cnvName++=c;
|
||||
inName++;
|
||||
}
|
||||
*cnvName=0;
|
||||
pArgs->name=pPieces->cnvName;
|
||||
|
||||
/* parse options. No more name copying should occur. */
|
||||
while((c=*inName)!=0) {
|
||||
|
@ -641,7 +658,7 @@ parseConverterOptions(const char *inName,
|
|||
/* inName is behind an option separator */
|
||||
if(uprv_strncmp(inName, "locale=", 7)==0) {
|
||||
/* do not modify locale itself in case we have multiple locale options */
|
||||
char *dest=locale;
|
||||
char *dest=pPieces->locale;
|
||||
|
||||
/* copy the locale option value */
|
||||
inName+=7;
|
||||
|
@ -651,7 +668,7 @@ parseConverterOptions(const char *inName,
|
|||
|
||||
if(++len>=ULOC_FULLNAME_CAPACITY) {
|
||||
*err=U_ILLEGAL_ARGUMENT_ERROR; /* bad name */
|
||||
*locale=0;
|
||||
pPieces->locale[0]=0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -659,19 +676,19 @@ parseConverterOptions(const char *inName,
|
|||
}
|
||||
*dest=0;
|
||||
} else if(uprv_strncmp(inName, "version=", 8)==0) {
|
||||
/* copy the version option value into bits 3..0 of *pFlags */
|
||||
/* copy the version option value into bits 3..0 of pPieces->options */
|
||||
inName+=8;
|
||||
c=*inName;
|
||||
if(c==0) {
|
||||
*pFlags&=~UCNV_OPTION_VERSION;
|
||||
pArgs->options=(pPieces->options&=~UCNV_OPTION_VERSION);
|
||||
return;
|
||||
} else if((uint8_t)(c-'0')<10) {
|
||||
*pFlags=(*pFlags&~UCNV_OPTION_VERSION)|(uint32_t)(c-'0');
|
||||
pArgs->options=pPieces->options=(pPieces->options&~UCNV_OPTION_VERSION)|(uint32_t)(c-'0');
|
||||
++inName;
|
||||
}
|
||||
} else if(uprv_strncmp(inName, "swaplfnl", 8)==0) {
|
||||
inName+=8;
|
||||
*pFlags|=UCNV_OPTION_SWAP_LFNL;
|
||||
pArgs->options=(pPieces->options|=UCNV_OPTION_SWAP_LFNL);
|
||||
/* add processing for new options here with another } else if(uprv_strncmp(inName, "option-name=", XX)==0) { */
|
||||
} else {
|
||||
/* ignore any other options until we define some */
|
||||
|
@ -692,8 +709,12 @@ parseConverterOptions(const char *inName,
|
|||
* -Call AlgorithmicConverter initializer (Data=FALSE, Cached=TRUE)
|
||||
*/
|
||||
UConverterSharedData *
|
||||
ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UErrorCode * err) {
|
||||
UConverterLookupData stackLookup;
|
||||
ucnv_loadSharedData(const char *converterName,
|
||||
UConverterNamePieces *pPieces,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode * err) {
|
||||
UConverterNamePieces stackPieces;
|
||||
UConverterLoadArgs stackArgs;
|
||||
UConverterSharedData *mySharedConverterData = NULL;
|
||||
UErrorCode internalErrorCode = U_ZERO_ERROR;
|
||||
UBool mayContainOption = TRUE;
|
||||
|
@ -703,21 +724,40 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if(lookup == NULL) {
|
||||
lookup = &stackLookup;
|
||||
if(pPieces == NULL) {
|
||||
if(pArgs != NULL) {
|
||||
/*
|
||||
* Bad: We may set pArgs pointers to stackPieces fields
|
||||
* which will be invalid after this function returns.
|
||||
*/
|
||||
*err = U_INTERNAL_PROGRAM_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
pPieces = &stackPieces;
|
||||
}
|
||||
if(pArgs == NULL) {
|
||||
uprv_memset(&stackArgs, 0, sizeof(stackArgs));
|
||||
stackArgs.size = (int32_t)sizeof(stackArgs);
|
||||
pArgs = &stackArgs;
|
||||
}
|
||||
|
||||
lookup->locale[0] = 0;
|
||||
lookup->options = 0;
|
||||
pPieces->cnvName[0] = 0;
|
||||
pPieces->locale[0] = 0;
|
||||
pPieces->options = 0;
|
||||
|
||||
pArgs->name = converterName;
|
||||
pArgs->locale = pPieces->locale;
|
||||
pArgs->options = pPieces->options;
|
||||
|
||||
/* In case "name" is NULL we want to open the default converter. */
|
||||
if (converterName == NULL) {
|
||||
#if U_CHARSET_IS_UTF8
|
||||
pArgs->name = "UTF-8";
|
||||
return (UConverterSharedData *)converterData[UCNV_UTF8];
|
||||
#else
|
||||
/* Call ucnv_getDefaultName first to query the name from the OS. */
|
||||
lookup->realName = ucnv_getDefaultName();
|
||||
if (lookup->realName == NULL) {
|
||||
pArgs->name = ucnv_getDefaultName();
|
||||
if (pArgs->name == NULL) {
|
||||
*err = U_MISSING_RESOURCE_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -729,36 +769,36 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
|
|||
}
|
||||
else if(UCNV_FAST_IS_UTF8(converterName)) {
|
||||
/* fastpath for UTF-8 */
|
||||
pArgs->name = "UTF-8";
|
||||
return (UConverterSharedData *)converterData[UCNV_UTF8];
|
||||
}
|
||||
else {
|
||||
/* separate the converter name from the options */
|
||||
parseConverterOptions(converterName, lookup->cnvName, lookup->locale, &lookup->options, err);
|
||||
parseConverterOptions(converterName, pPieces, pArgs, err);
|
||||
if (U_FAILURE(*err)) {
|
||||
/* Very bad name used. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the canonical converter name */
|
||||
lookup->realName = ucnv_io_getConverterName(lookup->cnvName, &mayContainOption, &internalErrorCode);
|
||||
if (U_FAILURE(internalErrorCode) || lookup->realName == NULL) {
|
||||
pArgs->name = ucnv_io_getConverterName(pArgs->name, &mayContainOption, &internalErrorCode);
|
||||
if (U_FAILURE(internalErrorCode) || pArgs->name == NULL) {
|
||||
/*
|
||||
* set the input name in case the converter was added
|
||||
* without updating the alias table, or when there is no alias table
|
||||
*/
|
||||
lookup->realName = lookup->cnvName;
|
||||
pArgs->name = pPieces->cnvName;
|
||||
}
|
||||
}
|
||||
|
||||
/* separate the converter name from the options */
|
||||
if(mayContainOption && lookup->realName != lookup->cnvName) {
|
||||
parseConverterOptions(lookup->realName, lookup->cnvName, lookup->locale, &lookup->options, err);
|
||||
lookup->realName = lookup->cnvName;
|
||||
if(mayContainOption && pArgs->name != pPieces->cnvName) {
|
||||
parseConverterOptions(pArgs->name, pPieces, pArgs, err);
|
||||
}
|
||||
|
||||
/* get the shared data for an algorithmic converter, if it is one */
|
||||
if (checkForAlgorithmic) {
|
||||
mySharedConverterData = (UConverterSharedData *)getAlgorithmicTypeFromName(lookup->realName);
|
||||
mySharedConverterData = (UConverterSharedData *)getAlgorithmicTypeFromName(pArgs->name);
|
||||
}
|
||||
if (mySharedConverterData == NULL)
|
||||
{
|
||||
|
@ -767,16 +807,11 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
|
|||
/* converter data cache, and adding new entries to the cache */
|
||||
/* to prevent other threads from modifying the cache during the */
|
||||
/* process. */
|
||||
UConverterLoadArgs args={ 0 };
|
||||
|
||||
args.size=sizeof(UConverterLoadArgs);
|
||||
args.nestedLoads=1;
|
||||
args.options=lookup->options;
|
||||
args.pkg=NULL;
|
||||
args.name=lookup->realName;
|
||||
pArgs->nestedLoads=1;
|
||||
pArgs->pkg=NULL;
|
||||
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
mySharedConverterData = ucnv_load(&args, err);
|
||||
mySharedConverterData = ucnv_load(pArgs, err);
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
if (U_FAILURE (*err) || (mySharedConverterData == NULL))
|
||||
{
|
||||
|
@ -790,7 +825,8 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
|
|||
UConverter *
|
||||
ucnv_createConverter(UConverter *myUConverter, const char *converterName, UErrorCode * err)
|
||||
{
|
||||
UConverterLookupData stackLookup;
|
||||
UConverterNamePieces stackPieces;
|
||||
UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
|
||||
UConverterSharedData *mySharedConverterData;
|
||||
|
||||
UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN);
|
||||
|
@ -798,25 +834,16 @@ ucnv_createConverter(UConverter *myUConverter, const char *converterName, UError
|
|||
if(U_SUCCESS(*err)) {
|
||||
UTRACE_DATA1(UTRACE_OPEN_CLOSE, "open converter %s", converterName);
|
||||
|
||||
mySharedConverterData = ucnv_loadSharedData(converterName, &stackLookup, err);
|
||||
mySharedConverterData = ucnv_loadSharedData(converterName, &stackPieces, &stackArgs, err);
|
||||
|
||||
myUConverter = ucnv_createConverterFromSharedData(
|
||||
myUConverter, mySharedConverterData,
|
||||
&stackArgs,
|
||||
err);
|
||||
|
||||
if(U_SUCCESS(*err)) {
|
||||
myUConverter = ucnv_createConverterFromSharedData(
|
||||
myUConverter, mySharedConverterData,
|
||||
stackLookup.realName, stackLookup.locale, stackLookup.options,
|
||||
err);
|
||||
|
||||
if(U_SUCCESS(*err)) {
|
||||
UTRACE_EXIT_PTR_STATUS(myUConverter, *err);
|
||||
return myUConverter;
|
||||
}
|
||||
/*
|
||||
else mySharedConverterData was already cleaned up by
|
||||
ucnv_createConverterFromSharedData.
|
||||
*/
|
||||
/*else {
|
||||
ucnv_unloadSharedDataIfReady(mySharedConverterData);
|
||||
}*/
|
||||
UTRACE_EXIT_PTR_STATUS(myUConverter, *err);
|
||||
return myUConverter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -825,6 +852,31 @@ ucnv_createConverter(UConverter *myUConverter, const char *converterName, UError
|
|||
return NULL;
|
||||
}
|
||||
|
||||
U_CFUNC UBool
|
||||
ucnv_canCreateConverter(const char *converterName, UErrorCode *err) {
|
||||
UConverter myUConverter;
|
||||
UConverterNamePieces stackPieces;
|
||||
UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
|
||||
UConverterSharedData *mySharedConverterData;
|
||||
|
||||
UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN);
|
||||
|
||||
if(U_SUCCESS(*err)) {
|
||||
UTRACE_DATA1(UTRACE_OPEN_CLOSE, "test if can open converter %s", converterName);
|
||||
|
||||
stackArgs.onlyTestIsLoadable=TRUE;
|
||||
mySharedConverterData = ucnv_loadSharedData(converterName, &stackPieces, &stackArgs, err);
|
||||
ucnv_createConverterFromSharedData(
|
||||
&myUConverter, mySharedConverterData,
|
||||
&stackArgs,
|
||||
err);
|
||||
ucnv_unloadSharedDataIfReady(mySharedConverterData);
|
||||
}
|
||||
|
||||
UTRACE_EXIT_STATUS(*err);
|
||||
return U_SUCCESS(*err) && stackArgs.isLoadable;
|
||||
}
|
||||
|
||||
UConverter *
|
||||
ucnv_createAlgorithmicConverter(UConverter *myUConverter,
|
||||
UConverterType type,
|
||||
|
@ -832,7 +884,7 @@ ucnv_createAlgorithmicConverter(UConverter *myUConverter,
|
|||
UErrorCode *err) {
|
||||
UConverter *cnv;
|
||||
const UConverterSharedData *sharedData;
|
||||
UBool isAlgorithmicConverter;
|
||||
UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
|
||||
|
||||
UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN_ALGORITHMIC);
|
||||
UTRACE_DATA1(UTRACE_OPEN_CLOSE, "open algorithmic converter type %d", (int32_t)type);
|
||||
|
@ -844,18 +896,24 @@ ucnv_createAlgorithmicConverter(UConverter *myUConverter,
|
|||
}
|
||||
|
||||
sharedData = converterData[type];
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
isAlgorithmicConverter = (UBool)(sharedData == NULL || sharedData->referenceCounter != ~0);
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
if (isAlgorithmicConverter) {
|
||||
/*
|
||||
Checking whether it's an algorithic converter is okay
|
||||
in multithreaded applications because the value never changes.
|
||||
Don't check referenceCounter for any other value.
|
||||
*/
|
||||
if(sharedData == NULL || sharedData->referenceCounter != ~0) {
|
||||
/* not a valid type, or not an algorithmic converter */
|
||||
*err = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
UTRACE_EXIT_STATUS(U_ILLEGAL_ARGUMENT_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cnv = ucnv_createConverterFromSharedData(myUConverter, (UConverterSharedData *)sharedData, "",
|
||||
locale != NULL ? locale : "", options, err);
|
||||
stackArgs.name = "";
|
||||
stackArgs.options = options;
|
||||
stackArgs.locale=locale;
|
||||
cnv = ucnv_createConverterFromSharedData(
|
||||
myUConverter, (UConverterSharedData *)sharedData,
|
||||
&stackArgs, err);
|
||||
|
||||
UTRACE_EXIT_PTR_STATUS(cnv, *err);
|
||||
return cnv;
|
||||
|
@ -864,11 +922,10 @@ ucnv_createAlgorithmicConverter(UConverter *myUConverter,
|
|||
UConverter*
|
||||
ucnv_createConverterFromPackage(const char *packageName, const char *converterName, UErrorCode * err)
|
||||
{
|
||||
char cnvName[UCNV_MAX_CONVERTER_NAME_LENGTH], locale[ULOC_FULLNAME_CAPACITY];
|
||||
UConverter *myUConverter;
|
||||
UConverterSharedData *mySharedConverterData;
|
||||
|
||||
UConverterLoadArgs args={ 0 };
|
||||
UConverterNamePieces stackPieces;
|
||||
UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
|
||||
|
||||
UTRACE_ENTRY_OC(UTRACE_UCNV_OPEN_PACKAGE);
|
||||
|
||||
|
@ -879,21 +936,21 @@ ucnv_createConverterFromPackage(const char *packageName, const char *converterNa
|
|||
|
||||
UTRACE_DATA2(UTRACE_OPEN_CLOSE, "open converter %s from package %s", converterName, packageName);
|
||||
|
||||
args.size=sizeof(UConverterLoadArgs);
|
||||
args.nestedLoads=1;
|
||||
args.pkg=packageName;
|
||||
|
||||
/* first, get the options out of the converterName string */
|
||||
parseConverterOptions(converterName, cnvName, locale, &args.options, err);
|
||||
stackPieces.cnvName[0] = 0;
|
||||
stackPieces.locale[0] = 0;
|
||||
stackPieces.options = 0;
|
||||
parseConverterOptions(converterName, &stackPieces, &stackArgs, err);
|
||||
if (U_FAILURE(*err)) {
|
||||
/* Very bad name used. */
|
||||
UTRACE_EXIT_STATUS(*err);
|
||||
return NULL;
|
||||
}
|
||||
args.name=cnvName;
|
||||
stackArgs.nestedLoads=1;
|
||||
stackArgs.pkg=packageName;
|
||||
|
||||
/* open the data, unflatten the shared structure */
|
||||
mySharedConverterData = createConverterFromFile(&args, err);
|
||||
mySharedConverterData = createConverterFromFile(&stackArgs, err);
|
||||
|
||||
if (U_FAILURE(*err)) {
|
||||
UTRACE_EXIT_STATUS(*err);
|
||||
|
@ -901,7 +958,7 @@ ucnv_createConverterFromPackage(const char *packageName, const char *converterNa
|
|||
}
|
||||
|
||||
/* create the actual converter */
|
||||
myUConverter = ucnv_createConverterFromSharedData(NULL, mySharedConverterData, cnvName, locale, args.options, err);
|
||||
myUConverter = ucnv_createConverterFromSharedData(NULL, mySharedConverterData, &stackArgs, err);
|
||||
|
||||
if (U_FAILURE(*err)) {
|
||||
ucnv_close(myUConverter);
|
||||
|
@ -917,17 +974,22 @@ ucnv_createConverterFromPackage(const char *packageName, const char *converterNa
|
|||
UConverter*
|
||||
ucnv_createConverterFromSharedData(UConverter *myUConverter,
|
||||
UConverterSharedData *mySharedConverterData,
|
||||
const char *realName, const char *locale, uint32_t options,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode *err)
|
||||
{
|
||||
UBool isCopyLocal;
|
||||
|
||||
if(U_FAILURE(*err)) {
|
||||
ucnv_unloadSharedDataIfReady(mySharedConverterData);
|
||||
return myUConverter;
|
||||
}
|
||||
if(myUConverter == NULL)
|
||||
{
|
||||
myUConverter = (UConverter *) uprv_malloc (sizeof (UConverter));
|
||||
if(myUConverter == NULL)
|
||||
{
|
||||
*err = U_MEMORY_ALLOCATION_ERROR;
|
||||
ucnv_unloadSharedDataIfReady(mySharedConverterData);
|
||||
return NULL;
|
||||
}
|
||||
isCopyLocal = FALSE;
|
||||
|
@ -940,20 +1002,24 @@ ucnv_createConverterFromSharedData(UConverter *myUConverter,
|
|||
myUConverter->isCopyLocal = isCopyLocal;
|
||||
/*myUConverter->isExtraLocal = FALSE;*/ /* Set by the memset call */
|
||||
myUConverter->sharedData = mySharedConverterData;
|
||||
myUConverter->options = options;
|
||||
myUConverter->preFromUFirstCP = U_SENTINEL;
|
||||
myUConverter->fromCharErrorBehaviour = UCNV_TO_U_DEFAULT_CALLBACK;
|
||||
myUConverter->fromUCharErrorBehaviour = UCNV_FROM_U_DEFAULT_CALLBACK;
|
||||
myUConverter->toUnicodeStatus = mySharedConverterData->toUnicodeStatus;
|
||||
myUConverter->maxBytesPerUChar = mySharedConverterData->staticData->maxBytesPerChar;
|
||||
myUConverter->subChar1 = mySharedConverterData->staticData->subChar1;
|
||||
myUConverter->subCharLen = mySharedConverterData->staticData->subCharLen;
|
||||
myUConverter->subChars = (uint8_t *)myUConverter->subUChars;
|
||||
uprv_memcpy(myUConverter->subChars, mySharedConverterData->staticData->subChar, myUConverter->subCharLen);
|
||||
myUConverter->toUCallbackReason = UCNV_ILLEGAL; /* default reason to invoke (*fromCharErrorBehaviour) */
|
||||
myUConverter->options = pArgs->options;
|
||||
if(!pArgs->onlyTestIsLoadable) {
|
||||
myUConverter->preFromUFirstCP = U_SENTINEL;
|
||||
myUConverter->fromCharErrorBehaviour = UCNV_TO_U_DEFAULT_CALLBACK;
|
||||
myUConverter->fromUCharErrorBehaviour = UCNV_FROM_U_DEFAULT_CALLBACK;
|
||||
myUConverter->toUnicodeStatus = mySharedConverterData->toUnicodeStatus;
|
||||
myUConverter->maxBytesPerUChar = mySharedConverterData->staticData->maxBytesPerChar;
|
||||
myUConverter->subChar1 = mySharedConverterData->staticData->subChar1;
|
||||
myUConverter->subCharLen = mySharedConverterData->staticData->subCharLen;
|
||||
myUConverter->subChars = (uint8_t *)myUConverter->subUChars;
|
||||
uprv_memcpy(myUConverter->subChars, mySharedConverterData->staticData->subChar, myUConverter->subCharLen);
|
||||
myUConverter->toUCallbackReason = UCNV_ILLEGAL; /* default reason to invoke (*fromCharErrorBehaviour) */
|
||||
}
|
||||
|
||||
if(mySharedConverterData->impl->open != NULL) {
|
||||
mySharedConverterData->impl->open(myUConverter, realName, locale, options, err);
|
||||
if(mySharedConverterData->impl->open == NULL) {
|
||||
pArgs->isLoadable = pArgs->onlyTestIsLoadable;
|
||||
} else {
|
||||
mySharedConverterData->impl->open(myUConverter, pArgs, err);
|
||||
if(U_FAILURE(*err)) {
|
||||
ucnv_close(myUConverter);
|
||||
return NULL;
|
||||
|
@ -1073,8 +1139,7 @@ static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
|
|||
for (idx = 0; idx < allConverterCount; idx++) {
|
||||
localStatus = U_ZERO_ERROR;
|
||||
converterName = uenum_next(allConvEnum, NULL, &localStatus);
|
||||
ucnv_close(ucnv_createConverter(&tempConverter, converterName, &localStatus));
|
||||
if (U_SUCCESS(localStatus)) {
|
||||
if (ucnv_canCreateConverter(converterName, &localStatus)) {
|
||||
localConverterList[localConverterCount++] = converterName;
|
||||
}
|
||||
}
|
||||
|
@ -1130,19 +1195,23 @@ you shouldn't be modifying or deleting the string from a separate thread.
|
|||
*/
|
||||
static U_INLINE void
|
||||
internalSetName(const char *name, UErrorCode *status) {
|
||||
UConverterLookupData lookup;
|
||||
UConverterNamePieces stackPieces;
|
||||
UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
|
||||
int32_t length=(int32_t)(uprv_strlen(name));
|
||||
UBool containsOption = (UBool)(uprv_strchr(name, UCNV_OPTION_SEP_CHAR) != NULL);
|
||||
const UConverterSharedData *algorithmicSharedData;
|
||||
|
||||
lookup.locale[0] = 0;
|
||||
lookup.options = 0;
|
||||
lookup.realName = name;
|
||||
stackArgs.name = name;
|
||||
if(containsOption) {
|
||||
parseConverterOptions(lookup.realName, lookup.cnvName, lookup.locale, &lookup.options, status);
|
||||
lookup.realName = lookup.cnvName;
|
||||
stackPieces.cnvName[0] = 0;
|
||||
stackPieces.locale[0] = 0;
|
||||
stackPieces.options = 0;
|
||||
parseConverterOptions(name, &stackPieces, &stackArgs, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
algorithmicSharedData = getAlgorithmicTypeFromName(lookup.realName);
|
||||
algorithmicSharedData = getAlgorithmicTypeFromName(stackArgs.name);
|
||||
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Copyright (C) 1999-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*
|
||||
|
@ -49,9 +49,11 @@ typedef struct UConverterSharedData UConverterSharedData;
|
|||
typedef struct {
|
||||
int32_t size; /* sizeof(UConverterLoadArgs) */
|
||||
int32_t nestedLoads; /* count nested ucnv_load() calls */
|
||||
int32_t reserved; /* reserved - for good alignment of the pointers */
|
||||
UBool onlyTestIsLoadable; /* input: don't actually load */
|
||||
UBool isLoadable; /* output, if onlyTestIsLoadable is set */
|
||||
int16_t reserved; /* reserved - for good alignment of the pointers */
|
||||
uint32_t options;
|
||||
const char *pkg, *name;
|
||||
const char *pkg, *name, *locale;
|
||||
} UConverterLoadArgs;
|
||||
|
||||
typedef void (*UConverterLoad) (UConverterSharedData *sharedData,
|
||||
|
@ -59,7 +61,7 @@ typedef void (*UConverterLoad) (UConverterSharedData *sharedData,
|
|||
const uint8_t *raw, UErrorCode *pErrorCode);
|
||||
typedef void (*UConverterUnload) (UConverterSharedData *sharedData);
|
||||
|
||||
typedef void (*UConverterOpen) (UConverter *cnv, const char *name, const char *locale,uint32_t options, UErrorCode *pErrorCode);
|
||||
typedef void (*UConverterOpen) (UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *pErrorCode);
|
||||
typedef void (*UConverterClose) (UConverter *cnv);
|
||||
|
||||
typedef enum UConverterResetChoice {
|
||||
|
|
|
@ -42,6 +42,15 @@
|
|||
(name[4]=='8' && name[5]==0) : \
|
||||
(name[3]=='8' && name[4]==0)))
|
||||
|
||||
typedef struct {
|
||||
char cnvName[UCNV_MAX_CONVERTER_NAME_LENGTH];
|
||||
char locale[ULOC_FULLNAME_CAPACITY];
|
||||
uint32_t options;
|
||||
} UConverterNamePieces;
|
||||
|
||||
U_CFUNC UBool
|
||||
ucnv_canCreateConverter(const char *converterName, UErrorCode *err);
|
||||
|
||||
/* figures out if we need to go to file to read in the data tables.
|
||||
* @param converterName The name of the converter
|
||||
* @param err The error code
|
||||
|
@ -66,28 +75,41 @@ ucnv_createAlgorithmicConverter(UConverter *myUConverter,
|
|||
const char *locale, uint32_t options,
|
||||
UErrorCode *err);
|
||||
|
||||
/* Creates a converter from shared data
|
||||
/*
|
||||
* Creates a converter from shared data.
|
||||
* Adopts mySharedConverterData: No matter what happens, the caller must not
|
||||
* unload mySharedConverterData, except via ucnv_close(return value)
|
||||
* if this function is successful.
|
||||
*/
|
||||
UConverter*
|
||||
ucnv_createConverterFromSharedData(UConverter *myUConverter, UConverterSharedData *mySharedConverterData, const char *realName, const char *locale, uint32_t options, UErrorCode *err);
|
||||
ucnv_createConverterFromSharedData(UConverter *myUConverter,
|
||||
UConverterSharedData *mySharedConverterData,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode *err);
|
||||
|
||||
UConverter* ucnv_createConverterFromPackage(const char *packageName, const char *converterName,
|
||||
UErrorCode *err);
|
||||
|
||||
typedef struct {
|
||||
char cnvName[UCNV_MAX_CONVERTER_NAME_LENGTH], locale[ULOC_FULLNAME_CAPACITY];
|
||||
const char *realName;
|
||||
uint32_t options;
|
||||
} UConverterLookupData;
|
||||
|
||||
/**
|
||||
* Load a converter but do not create a UConverter object.
|
||||
* Simply return the UConverterSharedData.
|
||||
* Performs alias lookup etc.
|
||||
* The UConverterNamePieces need not be initialized
|
||||
* before calling this function.
|
||||
* The UConverterLoadArgs must be initialized
|
||||
* before calling this function.
|
||||
* If the args are passed in, then the pieces must be passed in too.
|
||||
* In other words, the following combinations are allowed:
|
||||
* - pieces==NULL && args==NULL
|
||||
* - pieces!=NULL && args==NULL
|
||||
* - pieces!=NULL && args!=NULL
|
||||
* @internal
|
||||
*/
|
||||
UConverterSharedData *
|
||||
ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UErrorCode * err);
|
||||
ucnv_loadSharedData(const char *converterName,
|
||||
UConverterNamePieces *pieces,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode * err);
|
||||
|
||||
/**
|
||||
* This may unload the shared data in a thread safe manner.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 2000-2007, International Business Machines
|
||||
* Copyright (C) 2000-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* file name: ucnv_lmb.cpp
|
||||
|
@ -519,6 +519,7 @@ typedef struct
|
|||
}
|
||||
UConverterDataLMBCS;
|
||||
|
||||
static void _LMBCSClose(UConverter * _this);
|
||||
|
||||
#define DECLARE_LMBCS_DATA(n) \
|
||||
static const UConverterImpl _LMBCSImpl##n={\
|
||||
|
@ -556,53 +557,53 @@ optimization group. So, we put the common stuff into a worker function,
|
|||
and set up another macro to stamp out the 12 open functions:*/
|
||||
#define DEFINE_LMBCS_OPEN(n) \
|
||||
static void \
|
||||
_LMBCSOpen##n(UConverter* _this,const char* name,const char* locale,uint32_t options,UErrorCode* err) \
|
||||
{ _LMBCSOpenWorker(_this, name,locale,options, err, n);}
|
||||
_LMBCSOpen##n(UConverter* _this, UConverterLoadArgs* pArgs, UErrorCode* err) \
|
||||
{ _LMBCSOpenWorker(_this, pArgs, err, n); }
|
||||
|
||||
|
||||
|
||||
/* Here's the open worker & the common close function */
|
||||
static void
|
||||
_LMBCSOpenWorker(UConverter* _this,
|
||||
const char* name,
|
||||
const char* locale,
|
||||
uint32_t options,
|
||||
UErrorCode* err,
|
||||
ulmbcs_byte_t OptGroup
|
||||
)
|
||||
_LMBCSOpenWorker(UConverter* _this,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode* err,
|
||||
ulmbcs_byte_t OptGroup)
|
||||
{
|
||||
UConverterDataLMBCS * extraInfo = (UConverterDataLMBCS*)uprv_malloc (sizeof (UConverterDataLMBCS));
|
||||
UConverterDataLMBCS * extraInfo = _this->extraInfo =
|
||||
(UConverterDataLMBCS*)uprv_malloc (sizeof (UConverterDataLMBCS));
|
||||
if(extraInfo != NULL)
|
||||
{
|
||||
UConverterNamePieces stackPieces;
|
||||
UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
|
||||
ulmbcs_byte_t i;
|
||||
|
||||
uprv_memset(extraInfo, 0, sizeof(UConverterDataLMBCS));
|
||||
|
||||
stackArgs.onlyTestIsLoadable = pArgs->onlyTestIsLoadable;
|
||||
|
||||
for (i=0; i <= ULMBCS_GRP_LAST && U_SUCCESS(*err); i++)
|
||||
{
|
||||
if(OptGroupByteToCPName[i] != NULL) {
|
||||
extraInfo->OptGrpConverter[i] = ucnv_loadSharedData(OptGroupByteToCPName[i], NULL, err);
|
||||
extraInfo->OptGrpConverter[i] = ucnv_loadSharedData(OptGroupByteToCPName[i], &stackPieces, &stackArgs, err);
|
||||
}
|
||||
}
|
||||
|
||||
if(U_SUCCESS(*err)) {
|
||||
extraInfo->OptGroup = OptGroup;
|
||||
extraInfo->localeConverterIndex = FindLMBCSLocale(locale);
|
||||
} else {
|
||||
/* one of the subconverters could not be loaded, unload the previous ones */
|
||||
while(i > 0) {
|
||||
if(extraInfo->OptGrpConverter[--i] != NULL) {
|
||||
ucnv_unloadSharedDataIfReady(extraInfo->OptGrpConverter[i]);
|
||||
extraInfo->OptGrpConverter[i] = NULL;
|
||||
}
|
||||
}
|
||||
if(U_FAILURE(*err)) {
|
||||
_LMBCSClose(_this);
|
||||
return;
|
||||
}
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
_LMBCSClose(_this);
|
||||
pArgs->isLoadable=TRUE;
|
||||
return;
|
||||
}
|
||||
extraInfo->OptGroup = OptGroup;
|
||||
extraInfo->localeConverterIndex = FindLMBCSLocale(pArgs->locale);
|
||||
}
|
||||
else
|
||||
{
|
||||
*err = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
_this->extraInfo = extraInfo;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -620,6 +621,7 @@ _LMBCSClose(UConverter * _this)
|
|||
}
|
||||
if (!_this->isExtraLocal) {
|
||||
uprv_free (_this->extraInfo);
|
||||
_this->extraInfo = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 2002-2008, International Business Machines
|
||||
* Copyright (C) 2002-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* file name: ucnv_u16.c
|
||||
|
@ -1179,11 +1179,13 @@ _UTF16Reset(UConverter *cnv, UConverterResetChoice choice) {
|
|||
|
||||
static void
|
||||
_UTF16Open(UConverter *cnv,
|
||||
const char *name,
|
||||
const char *locale,
|
||||
uint32_t options,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode *pErrorCode) {
|
||||
_UTF16Reset(cnv, UCNV_RESET_BOTH);
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
pArgs->isLoadable=TRUE;
|
||||
} else {
|
||||
_UTF16Reset(cnv, UCNV_RESET_BOTH);
|
||||
}
|
||||
}
|
||||
|
||||
static const char utf16BOM[8]={ (char)0xfe, (char)0xff, 0, 0, (char)0xff, (char)0xfe, 0, 0 };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 2002-2006, International Business Machines
|
||||
* Copyright (C) 2002-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* file name: ucnv_u32.c
|
||||
|
@ -1033,11 +1033,13 @@ _UTF32Reset(UConverter *cnv, UConverterResetChoice choice) {
|
|||
|
||||
static void
|
||||
_UTF32Open(UConverter *cnv,
|
||||
const char *name,
|
||||
const char *locale,
|
||||
uint32_t options,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode *pErrorCode) {
|
||||
_UTF32Reset(cnv, UCNV_RESET_BOTH);
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
pArgs->isLoadable=TRUE;
|
||||
} else {
|
||||
_UTF32Reset(cnv, UCNV_RESET_BOTH);
|
||||
}
|
||||
}
|
||||
|
||||
static const char utf32BOM[8]={ 0, 0, (char)0xfe, (char)0xff, (char)0xff, (char)0xfe, 0, 0 };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 2002-2004, International Business Machines
|
||||
* Copyright (C) 2002-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* file name: ucnv_u7.c
|
||||
|
@ -190,12 +190,12 @@ _UTF7Reset(UConverter *cnv, UConverterResetChoice choice) {
|
|||
|
||||
static void
|
||||
_UTF7Open(UConverter *cnv,
|
||||
const char *name,
|
||||
const char *locale,
|
||||
uint32_t options,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode *pErrorCode) {
|
||||
if((options&0xf)<=1) {
|
||||
cnv->fromUnicodeStatus=(options&0xf)<<28;
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
pArgs->isLoadable=TRUE;
|
||||
} else if((pArgs->options&0xf)<=1) {
|
||||
cnv->fromUnicodeStatus=(pArgs->options&0xf)<<28;
|
||||
_UTF7Reset(cnv, UCNV_RESET_BOTH);
|
||||
} else {
|
||||
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 2000-2008, International Business Machines
|
||||
* Copyright (C) 2000-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* file name: ucnvhz.c
|
||||
|
@ -24,6 +24,7 @@
|
|||
#include "unicode/uset.h"
|
||||
#include "ucnv_bld.h"
|
||||
#include "ucnv_cnv.h"
|
||||
#include "ucnv_imp.h"
|
||||
|
||||
#define UCNV_TILDE 0x7E /* ~ */
|
||||
#define UCNV_OPEN_BRACE 0x7B /* { */
|
||||
|
@ -65,7 +66,17 @@ typedef struct{
|
|||
|
||||
|
||||
static void
|
||||
_HZOpen(UConverter *cnv, const char *name,const char *locale,uint32_t options, UErrorCode *errorCode){
|
||||
_HZOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode){
|
||||
UConverter *gbConverter;
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
UErrorCode localStatus = U_ZERO_ERROR;
|
||||
pArgs->isLoadable = ucnv_canCreateConverter("GBK", &localStatus);
|
||||
return;
|
||||
}
|
||||
gbConverter = ucnv_open("GBK", errorCode);
|
||||
if(U_FAILURE(*errorCode)) {
|
||||
return;
|
||||
}
|
||||
cnv->toUnicodeStatus = 0;
|
||||
cnv->fromUnicodeStatus= 0;
|
||||
cnv->mode=0;
|
||||
|
@ -73,9 +84,10 @@ _HZOpen(UConverter *cnv, const char *name,const char *locale,uint32_t options, U
|
|||
cnv->extraInfo = uprv_malloc(sizeof(UConverterDataHZ));
|
||||
if(cnv->extraInfo != NULL){
|
||||
uprv_memset(cnv->extraInfo, 0, sizeof(UConverterDataHZ));
|
||||
((UConverterDataHZ*)cnv->extraInfo)->gbConverter = ucnv_open("GBK",errorCode);
|
||||
((UConverterDataHZ*)cnv->extraInfo)->gbConverter = gbConverter;
|
||||
}
|
||||
else {
|
||||
ucnv_close(gbConverter);
|
||||
*errorCode = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 2000-2008, International Business Machines
|
||||
* Copyright (C) 2000-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* file name: ucnvisci.c
|
||||
|
@ -152,9 +152,10 @@ static const LookupDataStruct lookupInitialData[]={
|
|||
};
|
||||
|
||||
static void initializeSets() {
|
||||
/* TODO: Replace the following two lines with PNJ_CONSONANT_SET = uset_openEmpty(); */
|
||||
PNJ_CONSONANT_SET = uset_open(0,0);
|
||||
uset_clear(PNJ_CONSONANT_SET);
|
||||
|
||||
|
||||
uset_addRange(PNJ_CONSONANT_SET, 0x0A15, 0x0A28);
|
||||
uset_addRange(PNJ_CONSONANT_SET, 0x0A2A, 0x0A30);
|
||||
uset_addRange(PNJ_CONSONANT_SET, 0x0A35, 0x0A36);
|
||||
|
@ -170,8 +171,12 @@ static void initializeSets() {
|
|||
uset_compact(PNJ_BINDI_TIPPI_SET);
|
||||
}
|
||||
|
||||
static void _ISCIIOpen(UConverter *cnv, const char *name, const char *locale,
|
||||
uint32_t options, UErrorCode *errorCode) {
|
||||
static void _ISCIIOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode) {
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
pArgs->isLoadable=TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ensure that the sets used in special handling of certain Gurmukhi characters are initialized. */
|
||||
initializeSets();
|
||||
|
||||
|
@ -186,20 +191,20 @@ static void _ISCIIOpen(UConverter *cnv, const char *name, const char *locale,
|
|||
converterData->contextCharFromUnicode=0x0000;
|
||||
converterData->resetToDefaultToUnicode=FALSE;
|
||||
/* check if the version requested is supported */
|
||||
if ((options & UCNV_OPTIONS_VERSION_MASK) < 9) {
|
||||
if ((pArgs->options & UCNV_OPTIONS_VERSION_MASK) < 9) {
|
||||
/* initialize state variables */
|
||||
converterData->currentDeltaFromUnicode
|
||||
= converterData->currentDeltaToUnicode
|
||||
= converterData->defDeltaToUnicode = (uint16_t)(lookupInitialData[options & UCNV_OPTIONS_VERSION_MASK].uniLang * DELTA);
|
||||
= converterData->defDeltaToUnicode = (uint16_t)(lookupInitialData[pArgs->options & UCNV_OPTIONS_VERSION_MASK].uniLang * DELTA);
|
||||
|
||||
converterData->currentMaskFromUnicode
|
||||
= converterData->currentMaskToUnicode
|
||||
= converterData->defMaskToUnicode = lookupInitialData[options & UCNV_OPTIONS_VERSION_MASK].maskEnum;
|
||||
= converterData->defMaskToUnicode = lookupInitialData[pArgs->options & UCNV_OPTIONS_VERSION_MASK].maskEnum;
|
||||
|
||||
converterData->isFirstBuffer=TRUE;
|
||||
(void)uprv_strcpy(converterData->name, ISCII_CNV_PREFIX);
|
||||
len = (int32_t)uprv_strlen(converterData->name);
|
||||
converterData->name[len]= (char)((options & UCNV_OPTIONS_VERSION_MASK) + '0');
|
||||
converterData->name[len]= (char)((pArgs->options & UCNV_OPTIONS_VERSION_MASK) + '0');
|
||||
converterData->name[len+1]=0;
|
||||
|
||||
converterData->prevToUnicodeStatus = 0x0000;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2000-2008, International Business Machines
|
||||
* Copyright (C) 2000-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -1400,6 +1400,8 @@ ucnv_MBCSLoad(UConverterSharedData *sharedData,
|
|||
/* TODO parse package name out of the prefix of the base name in the extension .cnv file? */
|
||||
args.size=sizeof(UConverterLoadArgs);
|
||||
args.nestedLoads=2;
|
||||
args.onlyTestIsLoadable=pArgs->onlyTestIsLoadable;
|
||||
args.isLoadable=pArgs->isLoadable;
|
||||
args.reserved=pArgs->reserved;
|
||||
args.options=pArgs->options;
|
||||
args.pkg=pArgs->pkg;
|
||||
|
@ -1415,6 +1417,15 @@ ucnv_MBCSLoad(UConverterSharedData *sharedData,
|
|||
*pErrorCode=U_INVALID_TABLE_FORMAT;
|
||||
return;
|
||||
}
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
/*
|
||||
* Exit as soon as we know that we can load the converter
|
||||
* and the format is valid and supported.
|
||||
* The worst that can happen in the following code is a memory
|
||||
* allocation error.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy the base table data */
|
||||
uprv_memcpy(mbcsTable, &baseSharedData->mbcs, sizeof(UConverterMBCSTable));
|
||||
|
@ -1529,6 +1540,15 @@ ucnv_MBCSLoad(UConverterSharedData *sharedData,
|
|||
*pErrorCode=U_INVALID_TABLE_FORMAT;
|
||||
return;
|
||||
}
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
/*
|
||||
* Exit as soon as we know that we can load the converter
|
||||
* and the format is valid and supported.
|
||||
* The worst that can happen in the following code is a memory
|
||||
* allocation error.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
mbcsTable->countStates=(uint8_t)header->countStates;
|
||||
mbcsTable->countToUFallbacks=header->countToUFallbacks;
|
||||
|
@ -1660,24 +1680,27 @@ ucnv_MBCSUnload(UConverterSharedData *sharedData) {
|
|||
|
||||
static void
|
||||
ucnv_MBCSOpen(UConverter *cnv,
|
||||
const char *name,
|
||||
const char *locale,
|
||||
uint32_t options,
|
||||
UErrorCode *pErrorCode) {
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode *pErrorCode) {
|
||||
UConverterMBCSTable *mbcsTable;
|
||||
const int32_t *extIndexes;
|
||||
uint8_t outputType;
|
||||
int8_t maxBytesPerUChar;
|
||||
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
pArgs->isLoadable=TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
mbcsTable=&cnv->sharedData->mbcs;
|
||||
outputType=mbcsTable->outputType;
|
||||
|
||||
if(outputType==MBCS_OUTPUT_DBCS_ONLY) {
|
||||
/* the swaplfnl option does not apply, remove it */
|
||||
cnv->options=options&=~UCNV_OPTION_SWAP_LFNL;
|
||||
cnv->options=pArgs->options&=~UCNV_OPTION_SWAP_LFNL;
|
||||
}
|
||||
|
||||
if((options&UCNV_OPTION_SWAP_LFNL)!=0) {
|
||||
if((pArgs->options&UCNV_OPTION_SWAP_LFNL)!=0) {
|
||||
/* do this because double-checked locking is broken */
|
||||
UBool isCached;
|
||||
|
||||
|
@ -1692,13 +1715,13 @@ ucnv_MBCSOpen(UConverter *cnv,
|
|||
}
|
||||
|
||||
/* the option does not apply, remove it */
|
||||
cnv->options=options&=~UCNV_OPTION_SWAP_LFNL;
|
||||
cnv->options=pArgs->options&=~UCNV_OPTION_SWAP_LFNL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(uprv_strstr(name, "18030")!=NULL) {
|
||||
if(uprv_strstr(name, "gb18030")!=NULL || uprv_strstr(name, "GB18030")!=NULL) {
|
||||
if(uprv_strstr(pArgs->name, "18030")!=NULL) {
|
||||
if(uprv_strstr(pArgs->name, "gb18030")!=NULL || uprv_strstr(pArgs->name, "GB18030")!=NULL) {
|
||||
/* set a flag for GB 18030 mode, which changes the callback behavior */
|
||||
cnv->options|=_MBCS_OPTION_GB18030;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2000-2006, International Business Machines
|
||||
* Copyright (C) 2000-2009, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -190,10 +190,13 @@ _SCSUReset(UConverter *cnv, UConverterResetChoice choice) {
|
|||
|
||||
static void
|
||||
_SCSUOpen(UConverter *cnv,
|
||||
const char *name,
|
||||
const char *locale,
|
||||
uint32_t options,
|
||||
UConverterLoadArgs *pArgs,
|
||||
UErrorCode *pErrorCode) {
|
||||
const char *locale=pArgs->locale;
|
||||
if(pArgs->onlyTestIsLoadable) {
|
||||
pArgs->isLoadable=TRUE;
|
||||
return;
|
||||
}
|
||||
cnv->extraInfo=uprv_malloc(sizeof(SCSUData));
|
||||
if(cnv->extraInfo!=NULL) {
|
||||
if(locale!=NULL && locale[0]=='j' && locale[1]=='a' && (locale[2]==0 || locale[2]=='_')) {
|
||||
|
|
Loading…
Add table
Reference in a new issue