diff --git a/icu4c/source/common/ucnv.c b/icu4c/source/common/ucnv.c index 29e6f127e27..ef4ce20f2d3 100644 --- a/icu4c/source/common/ucnv.c +++ b/icu4c/source/common/ucnv.c @@ -384,8 +384,7 @@ int32_t ucnv_getDisplayName (const UConverter * converter, /*resets the internal states of a converter *goal : have the same behaviour than a freshly created converter */ -void ucnv_reset (UConverter * converter) -{ +static void _reset(UConverter *converter, UConverterResetChoice choice) { /* first, notify the callback functions that the converter is reset */ UConverterToUnicodeArgs toUArgs = { sizeof(UConverterToUnicodeArgs), @@ -412,87 +411,45 @@ void ucnv_reset (UConverter * converter) if(converter == NULL) { return; } + toUArgs.converter = fromUArgs.converter = converter; - errorCode = U_ZERO_ERROR; - converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_RESET, &errorCode); - errorCode = U_ZERO_ERROR; - converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_RESET, &errorCode); + if(choice<=UCNV_RESET_TO_UNICODE) { + errorCode = U_ZERO_ERROR; + converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_RESET, &errorCode); + } + if(choice!=UCNV_RESET_TO_UNICODE) { + errorCode = U_ZERO_ERROR; + converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_RESET, &errorCode); + } /* now reset the converter itself */ - converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus; - converter->fromUnicodeStatus = 0; - converter->UCharErrorBufferLength = 0; - converter->charErrorBufferLength = 0; + if(choice<=UCNV_RESET_TO_UNICODE) { + converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus; + converter->UCharErrorBufferLength = 0; + } + if(choice!=UCNV_RESET_TO_UNICODE) { + converter->fromUnicodeStatus = 0; + converter->charErrorBufferLength = 0; + } + if (converter->sharedData->impl->reset != NULL) { /* call the custom reset function */ - converter->sharedData->impl->reset(converter); - } else { + converter->sharedData->impl->reset(converter, choice); + } else if(choice<=UCNV_RESET_TO_UNICODE) { converter->mode = UCNV_SI; } } -void ucnv_resetToUnicode(UConverter *converter) -{ -#if 0 - UConverterToUnicodeArgs toUArgs = { - sizeof(UConverterToUnicodeArgs), - TRUE, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - }; - UErrorCode errorCode = U_ZERO_ERROR; - - if(converter == NULL) { - return; - } - - toUArgs.converter = converter; - converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_RESET, &errorCode); - - /* now reset the converter itself */ - converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus; - converter->fromUnicodeStatus = 0; - converter->UCharErrorBufferLength = 0; - converter->charErrorBufferLength = 0; - - /* Todo: Needs rest of implementation */ -#endif +void ucnv_reset(UConverter *converter) { + _reset(converter, UCNV_RESET_BOTH); } -void ucnv_resetFromUnicode(UConverter *converter) -{ -#if 0 - UConverterFromUnicodeArgs fromUArgs = { - sizeof(UConverterFromUnicodeArgs), - TRUE, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - }; - UErrorCode errorCode = U_ZERO_ERROR; +void ucnv_resetToUnicode(UConverter *converter) { + _reset(converter, UCNV_RESET_TO_UNICODE); +} - if(converter == NULL) { - return; - } - - fromUArgs.converter = converter; - converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_RESET, &errorCode); - - /* now reset the converter itself */ - converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus; - converter->fromUnicodeStatus = 0; - converter->UCharErrorBufferLength = 0; - converter->charErrorBufferLength = 0; - - /* Todo: Needs rest of implementation */ -#endif +void ucnv_resetFromUnicode(UConverter *converter) { + _reset(converter, UCNV_RESET_FROM_UNICODE); } int8_t ucnv_getMaxCharSize (const UConverter * converter) diff --git a/icu4c/source/common/ucnv2022.c b/icu4c/source/common/ucnv2022.c index 38bd2b7cafc..1794c8e5841 100644 --- a/icu4c/source/common/ucnv2022.c +++ b/icu4c/source/common/ucnv2022.c @@ -334,7 +334,7 @@ UCNV_TableStates_2022 getKey_2022(char source, /*********** ISO 2022 Converter Protos ***********/ static void _ISO2022Open(UConverter *cnv, const char *name, const char *locale,uint32_t options, UErrorCode *errorCode); static void _ISO2022Close(UConverter *converter); -static void _ISO2022Reset(UConverter *converter); +static void _ISO2022Reset(UConverter *converter, UConverterResetChoice choice); static const char* _ISO2022getName(const UConverter* cnv); /************ protos of functions for setting the initial state *********************/ @@ -650,34 +650,44 @@ _ISO2022Close(UConverter *converter) { } static void -_ISO2022Reset(UConverter *converter) { +_ISO2022Reset(UConverter *converter, UConverterResetChoice choice) { UConverterDataISO2022 *myConverterData=(UConverterDataISO2022 *) (converter->extraInfo); if(! myConverterData->isLocaleSpecified){ - - /* re-append UTF-8 escape sequence */ - converter->charErrorBufferLength = 3; - converter->charErrorBuffer[0] = 0x1b; - converter->charErrorBuffer[1] = 0x28; - converter->charErrorBuffer[2] = 0x42; - if (converter->mode == UCNV_SO){ - ucnv_close (myConverterData->currentConverter); - myConverterData->currentConverter=NULL; + if(choice<=UCNV_RESET_TO_UNICODE) { + if (converter->mode == UCNV_SO){ + ucnv_close (myConverterData->currentConverter); + myConverterData->currentConverter=NULL; + } + } + if(choice!=UCNV_RESET_TO_UNICODE) { + /* re-append UTF-8 escape sequence */ + converter->charErrorBufferLength = 3; + converter->charErrorBuffer[0] = 0x1b; + converter->charErrorBuffer[1] = 0x28; + converter->charErrorBuffer[2] = 0x42; } } else { /* reset the state variables */ if(myConverterData->locale[0] == 'j' || myConverterData->locale[0] == 'c'){ - setInitialStateToUnicodeJPCN(converter, myConverterData); - setInitialStateFromUnicodeJPCN(myConverterData); + if(choice<=UCNV_RESET_TO_UNICODE) { + setInitialStateToUnicodeJPCN(converter, myConverterData); + } + if(choice!=UCNV_RESET_TO_UNICODE) { + setInitialStateFromUnicodeJPCN(myConverterData); + } } else if(myConverterData->locale[0] ='k'){ - setInitialStateToUnicodeKR(converter, myConverterData); - setInitialStateFromUnicodeKR(converter, myConverterData); + if(choice<=UCNV_RESET_TO_UNICODE) { + setInitialStateToUnicodeKR(converter, myConverterData); + } + if(choice!=UCNV_RESET_TO_UNICODE) { + setInitialStateFromUnicodeKR(converter, myConverterData); + } } } - - } + static const char* _ISO2022getName(const UConverter* cnv){ if(cnv->extraInfo){ UConverterDataISO2022* myData= (UConverterDataISO2022*)cnv->extraInfo; diff --git a/icu4c/source/common/ucnv_cnv.h b/icu4c/source/common/ucnv_cnv.h index 05b1411b107..73f982ce04a 100644 --- a/icu4c/source/common/ucnv_cnv.h +++ b/icu4c/source/common/ucnv_cnv.h @@ -143,7 +143,13 @@ typedef void (*UConverterUnload) (UConverterSharedData *sharedData); typedef void (*UConverterOpen) (UConverter *cnv, const char *name, const char *locale,uint32_t options, UErrorCode *pErrorCode); typedef void (*UConverterClose) (UConverter *cnv); -typedef void (*UConverterReset) (UConverter *cnv); +typedef enum UConverterResetChoice { + UCNV_RESET_BOTH, + UCNV_RESET_TO_UNICODE, + UCNV_RESET_FROM_UNICODE +} UConverterResetChoice; + +typedef void (*UConverterReset) (UConverter *cnv, UConverterResetChoice choice); typedef void (*T_ToUnicodeFunction) (UConverterToUnicodeArgs *, UErrorCode *); diff --git a/icu4c/source/common/ucnvhz.c b/icu4c/source/common/ucnvhz.c index b0d7835cdc4..f4cfafbe323 100644 --- a/icu4c/source/common/ucnvhz.c +++ b/icu4c/source/common/ucnvhz.c @@ -45,7 +45,7 @@ /*********** HZ Converter Protos ***********/ static void _HZOpen(UConverter *cnv, const char *name, const char *locale, uint32_t options,UErrorCode *errorCode); static void _HZClose(UConverter *converter); -static void _HZReset(UConverter *converter); +static void _HZReset(UConverter *converter, UConverterResetChoice choice); U_CFUNC void UConverter_toUnicode_HZ(UConverterToUnicodeArgs *args, UErrorCode *err); @@ -130,17 +130,23 @@ static void _HZClose(UConverter *cnv){ uprv_free(cnv->extraInfo); } -static void _HZReset(UConverter *cnv){ - cnv->toUnicodeStatus = 0; - cnv->fromUnicodeStatus= 0; - cnv->mode=0; - cnv->fromUSurrogateLead=0x0000; - if(cnv->extraInfo != NULL){ - ((UConverterDataHZ*)cnv->extraInfo)->isStateDBCS = FALSE; - ((UConverterDataHZ*)cnv->extraInfo)->isEscapeAppended = FALSE; - ((UConverterDataHZ*)cnv->extraInfo)->targetIndex = 0; - ((UConverterDataHZ*)cnv->extraInfo)->sourceIndex = 0; - ((UConverterDataHZ*)cnv->extraInfo)->isTargetUCharDBCS = FALSE; +static void _HZReset(UConverter *cnv, UConverterResetChoice choice){ + if(choice<=UCNV_RESET_TO_UNICODE) { + cnv->toUnicodeStatus = 0; + cnv->mode=0; + if(cnv->extraInfo != NULL){ + ((UConverterDataHZ*)cnv->extraInfo)->isStateDBCS = FALSE; + } + } + if(choice!=UCNV_RESET_TO_UNICODE) { + cnv->fromUnicodeStatus= 0; + cnv->fromUSurrogateLead=0x0000; + if(cnv->extraInfo != NULL){ + ((UConverterDataHZ*)cnv->extraInfo)->isEscapeAppended = FALSE; + ((UConverterDataHZ*)cnv->extraInfo)->targetIndex = 0; + ((UConverterDataHZ*)cnv->extraInfo)->sourceIndex = 0; + ((UConverterDataHZ*)cnv->extraInfo)->isTargetUCharDBCS = FALSE; + } } } @@ -351,7 +357,7 @@ SAVE_STATE: * the source and flush is true */ if( (mySource == mySourceLimit) && args->flush){ - _HZReset(args->converter); + _HZReset(args->converter, UCNV_RESET_TO_UNICODE); } args->target = myTarget; @@ -559,7 +565,7 @@ SAVE_STATE: * the source and flush is true */ if( (mySource == mySourceLimit) && args->flush){ - _HZReset(args->converter); + _HZReset(args->converter, UCNV_RESET_TO_UNICODE); } args->target = myTarget; @@ -806,7 +812,7 @@ CALLBACK: * the source and flush is true */ if( (mySourceIndex == sourceLength) && args->flush){ - _HZReset(args->converter); + _HZReset(args->converter, UCNV_RESET_FROM_UNICODE); } args->target += myTargetIndex; @@ -986,7 +992,7 @@ CALLBACK: * the source and flush is true */ if( (mySourceIndex == sourceLength) && args->flush){ - _HZReset(args->converter); + _HZReset(args->converter, UCNV_RESET_FROM_UNICODE); } args->target += myTargetIndex; diff --git a/icu4c/source/common/ucnvmbcs.c b/icu4c/source/common/ucnvmbcs.c index 415662907bc..a006880e457 100644 --- a/icu4c/source/common/ucnvmbcs.c +++ b/icu4c/source/common/ucnvmbcs.c @@ -314,15 +314,18 @@ _MBCSLoad(UConverterSharedData *sharedData, } U_CFUNC void -_MBCSReset(UConverter *cnv) { - /* toUnicode */ - cnv->toUnicodeStatus=0; /* offset */ - cnv->mode=0; /* state */ - cnv->toULength=0; /* byteIndex */ - - /* fromUnicode */ - cnv->fromUSurrogateLead=0; - cnv->fromUnicodeStatus=1; /* prevLength */ +_MBCSReset(UConverter *cnv, UConverterResetChoice choice) { + if(choice<=UCNV_RESET_TO_UNICODE) { + /* toUnicode */ + cnv->toUnicodeStatus=0; /* offset */ + cnv->mode=0; /* state */ + cnv->toULength=0; /* byteIndex */ + } + if(choice!=UCNV_RESET_TO_UNICODE) { + /* fromUnicode */ + cnv->fromUSurrogateLead=0; + cnv->fromUnicodeStatus=1; /* prevLength */ + } } U_CFUNC void @@ -331,7 +334,7 @@ _MBCSOpen(UConverter *cnv, const char *locale, uint32_t options, UErrorCode *pErrorCode) { - _MBCSReset(cnv); + _MBCSReset(cnv, UCNV_RESET_BOTH); if(uprv_strstr(name, "gb18030")!=NULL || uprv_strstr(name, "GB18030")!=NULL) { /* set a flag for GB 18030 mode, which changes the callback behavior */ cnv->extraInfo=(void *)gb18030Ranges; diff --git a/icu4c/source/common/ucnvscsu.c b/icu4c/source/common/ucnvscsu.c index 734b28d51cb..af3862c06de 100644 --- a/icu4c/source/common/ucnvscsu.c +++ b/icu4c/source/common/ucnvscsu.c @@ -150,10 +150,10 @@ enum { /* MBCS setup functions ----------------------------------------------------- */ U_CFUNC void -_SCSUReset(UConverter *cnv, uint8_t which) { +_SCSUReset(UConverter *cnv, UConverterResetChoice choice) { SCSUData *scsu=(SCSUData *)cnv->extraInfo; - if(which<2) { + if(choice<=UCNV_RESET_TO_UNICODE) { /* reset toUnicode */ uprv_memcpy(scsu->toUDynamicOffsets, initialDynamicOffsets, 32); @@ -164,7 +164,7 @@ _SCSUReset(UConverter *cnv, uint8_t which) { cnv->toULength=0; } - if(which!=1) { + if(choice!=UCNV_RESET_TO_UNICODE) { /* reset fromUnicode */ uprv_memcpy(scsu->fromUDynamicOffsets, initialDynamicOffsets, 32); @@ -185,11 +185,6 @@ _SCSUReset(UConverter *cnv, uint8_t which) { } } -U_CFUNC void -_SCSUOldfashionedReset(UConverter *cnv) { - _SCSUReset(cnv, 0); -} - U_CFUNC void _SCSUOpen(UConverter *cnv, const char *name, @@ -203,7 +198,7 @@ _SCSUOpen(UConverter *cnv, } else { ((SCSUData *)cnv->extraInfo)->locale=lGeneric; } - _SCSUReset(cnv, 0); + _SCSUReset(cnv, UCNV_RESET_BOTH); } else { *pErrorCode=U_MEMORY_ALLOCATION_ERROR; } @@ -536,7 +531,7 @@ endloop: /* a character byte sequence remains incomplete */ *pErrorCode=U_TRUNCATED_CHAR_FOUND; } - _SCSUReset(cnv, 1); + _SCSUReset(cnv, UCNV_RESET_TO_UNICODE); } else { /* set the converter state back into UConverter */ scsu->toUIsSingleByteMode=isSingleByteMode; @@ -600,7 +595,7 @@ callback: goto endloop; } else if(U_FAILURE(*pErrorCode)) { /* break on error */ - _SCSUReset(cnv, 1); + _SCSUReset(cnv, UCNV_RESET_TO_UNICODE); goto finish; } else { goto loop; @@ -1125,7 +1120,7 @@ endloop: /* a character byte sequence remains incomplete */ *pErrorCode=U_TRUNCATED_CHAR_FOUND; } - _SCSUReset(cnv, 2); + _SCSUReset(cnv, UCNV_RESET_FROM_UNICODE); } else { /* set the converter state back into UConverter */ scsu->fromUIsSingleByteMode=isSingleByteMode; @@ -1291,7 +1286,7 @@ callback: goto endloop; } else if(U_FAILURE(*pErrorCode)) { /* break on error */ - _SCSUReset(cnv, 2); + _SCSUReset(cnv, UCNV_RESET_FROM_UNICODE); goto finish; } else { goto loop; @@ -1308,7 +1303,7 @@ static const UConverterImpl _SCSUImpl={ _SCSUOpen, _SCSUClose, - _SCSUOldfashionedReset, + _SCSUReset, _SCSUToUnicodeWithOffsets, _SCSUToUnicodeWithOffsets,