#include "unicode/utypes.h"
#if !UCONFIG_NO_LEGACY_CONVERSION
#include "unicode/ucnv.h"
#include "unicode/uset.h"
#include "unicode/ucnv_err.h"
#include "unicode/ucnv_cb.h"
#include "ucnv_bld.h"
#include "ucnv_cnv.h"
#include "ucnvmbcs.h"
#include "cstring.h"
#include "cmemory.h"
static const char UCNV_SS2[] = "\x1B\x4E";
static const char UCNV_SS3[] = "\x1B\x4F";
#define UCNV_SS2_LEN 2
#define UCNV_SS3_LEN 2
#define CR 0x0D
#define LF 0x0A
#define H_TAB 0x09
#define V_TAB 0x0B
#define SPACE 0x20
typedef enum {
ASCII = 0,
ISO8859_1 = 1 ,
ISO8859_7 = 2 ,
JISX201 = 3,
JISX208 = 4,
JISX212 = 5,
GB2312 =6,
KSC5601 =7,
HWKANA_7BIT=8,
INVALID_STATE=-1
} StateEnum;
typedef enum {
ASCII1=0,
LATIN1,
SBCS,
DBCS,
MBCS
}Cnv2022Type;
#define UCNV_OPTIONS_VERSION_MASK 0xf
#define UCNV_2022_MAX_CONVERTERS 10
typedef struct{
UConverter *currentConverter;
UConverter *fromUnicodeConverter;
UBool isFirstBuffer;
StateEnum toUnicodeCurrentState;
StateEnum fromUnicodeCurrentState;
StateEnum toUnicodeSaveState;
Cnv2022Type currentType;
int plane;
UConverter* myConverterArray[UCNV_2022_MAX_CONVERTERS];
UBool isEscapeAppended;
UBool isShiftAppended;
UBool isLocaleSpecified;
uint32_t key;
uint32_t version;
char locale[3];
char name[30];
}UConverterDataISO2022;
U_CFUNC void
T_UConverter_fromUnicode_UTF8 (UConverterFromUnicodeArgs * args,
UErrorCode * err);
U_CFUNC void
T_UConverter_fromUnicode_UTF8_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args,
UErrorCode * err);
U_CFUNC void
_MBCSFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
UErrorCode *pErrorCode);
U_CFUNC void
_MBCSToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
UErrorCode *pErrorCode);
static void
_ISO_2022_GetUnicodeSet(const UConverter *cnv,
USet *set,
UConverterUnicodeSet which,
UErrorCode *pErrorCode);
static void
T_UConverter_toUnicode_ISO_2022(UConverterToUnicodeArgs * args,
UErrorCode * err);
static void
T_UConverter_toUnicode_ISO_2022_OFFSETS_LOGIC (UConverterToUnicodeArgs * args,
UErrorCode * err);
static UChar32
T_UConverter_getNextUChar_ISO_2022 (UConverterToUnicodeArgs * args,
UErrorCode * err);
static void
UConverter_fromUnicode_ISO_2022_JP_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args,
UErrorCode* err);
static void
UConverter_toUnicode_ISO_2022_JP_OFFSETS_LOGIC(UConverterToUnicodeArgs* args,
UErrorCode* err);
static void
UConverter_fromUnicode_ISO_2022_KR_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args,
UErrorCode* err);
static void
UConverter_toUnicode_ISO_2022_KR_OFFSETS_LOGIC(UConverterToUnicodeArgs* args,
UErrorCode* err);
static void
UConverter_toUnicode_ISO_2022_KR_OFFSETS_LOGIC_IBM(UConverterToUnicodeArgs *args,
UErrorCode* err);
static void
UConverter_fromUnicode_ISO_2022_KR_OFFSETS_LOGIC_IBM(UConverterFromUnicodeArgs* args,
UErrorCode* err);
static void
UConverter_fromUnicode_ISO_2022_CN_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args,
UErrorCode* err);
static void
UConverter_toUnicode_ISO_2022_CN_OFFSETS_LOGIC(UConverterToUnicodeArgs* args,
UErrorCode* err);
#define ESC_2022 0x1B
typedef enum
{
INVALID_2022 = -1,
VALID_NON_TERMINAL_2022 = 0,
VALID_TERMINAL_2022 = 1,
VALID_MAYBE_TERMINAL_2022 = 2,
VALID_SS2_SEQUENCE=3,
VALID_SS3_SEQUENCE=4
} UCNV_TableStates_2022;
static const int8_t normalize_esq_chars_2022[256] = {
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,4 ,7 ,29 ,0
,2 ,24 ,26 ,27 ,0 ,3 ,23 ,6 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,5 ,8 ,9 ,10 ,11 ,12
,13 ,14 ,15 ,16 ,17 ,18 ,19 ,20 ,25 ,28
,0 ,0 ,21 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,22 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
,0 ,0 ,0 ,0 ,0 ,0
};
#define MAX_STATES_2022 74
static const int32_t escSeqStateTable_Key_2022[MAX_STATES_2022] = {
1 ,34 ,36 ,39 ,55 ,57 ,60 ,61 ,1093 ,1096
,1097 ,1098 ,1099 ,1100 ,1101 ,1102 ,1103 ,1104 ,1105 ,1106
,1109 ,1154 ,1157 ,1160 ,1161 ,1176 ,1178 ,1179 ,1254 ,1257
,1768 ,1773 ,1957 ,35105 ,36933 ,36936 ,36937 ,36938 ,36939 ,36940
,36942 ,36943 ,36944 ,36945 ,36946 ,36947 ,36948 ,37640 ,37642 ,37644
,37646 ,37711 ,37744 ,37745 ,37746 ,37747 ,37748 ,40133 ,40136 ,40138
,40139 ,40140 ,40141 ,1123363 ,35947624 ,35947625 ,35947626 ,35947627 ,35947629 ,35947630
,35947631 ,35947635 ,35947636 ,35947638
};
static const char* const escSeqStateTable_Result_2022[MAX_STATES_2022] = {
NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,"latin1" ,"latin1"
,"latin1" ,"ibm-865" ,"ibm-865" ,"ibm-865" ,"ibm-865" ,"ibm-865" ,"ibm-865" ,"JISX-201" ,"JISX-201" ,"latin1"
,"latin1" ,NULL ,"JISX-208" ,"ibm-5478" ,"JISX-208" ,NULL ,NULL ,NULL ,NULL ,"UTF8"
,"ISO-8859-1" ,"ISO-8859-7" ,"JIS-X-208" ,NULL ,"ibm-955" ,"ibm-367" ,"ibm-952" ,"ibm-949" ,"JISX-212" ,"ibm-1383"
,"ibm-952" ,"ibm-964" ,"ibm-964" ,"ibm-964" ,"ibm-964" ,"ibm-964" ,"ibm-964" ,"ibm-5478" ,"ibm-949" ,"ISO-IR-165"
,"CNS-11643-1992,1" ,"CNS-11643-1992,2" ,"CNS-11643-1992,3" ,"CNS-11643-1992,4" ,"CNS-11643-1992,5" ,"CNS-11643-1992,6" ,"CNS-11643-1992,7" ,"UTF16_PlatformEndian" ,"UTF16_PlatformEndian" ,"UTF16_PlatformEndian"
,"UTF16_PlatformEndian" ,"UTF16_PlatformEndian" ,"UTF16_PlatformEndian" ,NULL ,"latin1" ,"ibm-912" ,"ibm-913" ,"ibm-914" ,"ibm-813" ,"ibm-1089"
,"ibm-920" ,"ibm-915" ,"ibm-915" ,"latin1"
};
static const UCNV_TableStates_2022 escSeqStateTable_Value_2022[MAX_STATES_2022] = {
VALID_NON_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_SS2_SEQUENCE ,VALID_SS3_SEQUENCE ,VALID_NON_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022
,VALID_MAYBE_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022
,VALID_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_TERMINAL_2022
,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022
,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022
,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022
,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_NON_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022
,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022 ,VALID_TERMINAL_2022
};
static const char* getEndOfBuffer_2022(const char** source,
const char* sourceLimit,
UBool flush);
typedef enum{
ISO_2022=0,
ISO_2022_JP=1,
ISO_2022_KR=2,
ISO_2022_CN=3
} Variant2022;
static void
changeState_2022(UConverter* _this,
const char** source,
const char* sourceLimit,
UBool flush,Variant2022 var,int* plane,
UErrorCode* err);
static UCNV_TableStates_2022
getKey_2022(char source,
int32_t* key,
int32_t* offset);
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, UConverterResetChoice choice);
static const char*
_ISO2022getName(const UConverter* cnv);
static void
_ISO_2022_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *err);
static UConverter *
_ISO_2022_SafeClone(const UConverter *cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status);
static void
setInitialStateToUnicodeJPCN(UConverter* converter,UConverterDataISO2022 *myConverterData);
static void
setInitialStateFromUnicodeJPCN(UConverter* converter,UConverterDataISO2022 *myConverterData);
static void
setInitialStateToUnicodeKR(UConverter* converter,UConverterDataISO2022 *myConverterData);
static void
setInitialStateFromUnicodeKR(UConverter* converter,UConverterDataISO2022 *myConverterData);
static const UConverterImpl _ISO2022Impl={
UCNV_ISO_2022,
NULL,
NULL,
_ISO2022Open,
_ISO2022Close,
_ISO2022Reset,
T_UConverter_toUnicode_ISO_2022,
T_UConverter_toUnicode_ISO_2022_OFFSETS_LOGIC,
T_UConverter_fromUnicode_UTF8,
T_UConverter_fromUnicode_UTF8_OFFSETS_LOGIC,
T_UConverter_getNextUChar_ISO_2022,
NULL,
_ISO2022getName,
_ISO_2022_WriteSub,
_ISO_2022_SafeClone,
_ISO_2022_GetUnicodeSet
};
static const UConverterStaticData _ISO2022StaticData={
sizeof(UConverterStaticData),
"ISO_2022",
2022,
UCNV_IBM,
UCNV_ISO_2022,
1,
4,
{ 0x1a, 0, 0, 0 },
1,
FALSE,
FALSE,
0,
0,
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
};
const UConverterSharedData _ISO2022Data={
sizeof(UConverterSharedData),
~((uint32_t) 0),
NULL,
NULL,
&_ISO2022StaticData,
FALSE,
&_ISO2022Impl,
0
};
static const UConverterImpl _ISO2022JPImpl={
UCNV_ISO_2022,
NULL,
NULL,
_ISO2022Open,
_ISO2022Close,
_ISO2022Reset,
UConverter_toUnicode_ISO_2022_JP_OFFSETS_LOGIC,
UConverter_toUnicode_ISO_2022_JP_OFFSETS_LOGIC,
UConverter_fromUnicode_ISO_2022_JP_OFFSETS_LOGIC,
UConverter_fromUnicode_ISO_2022_JP_OFFSETS_LOGIC,
NULL,
NULL,
_ISO2022getName,
_ISO_2022_WriteSub,
_ISO_2022_SafeClone,
_ISO_2022_GetUnicodeSet
};
static const UConverterStaticData _ISO2022JPStaticData={
sizeof(UConverterStaticData),
"ISO_2022_JP",
0,
UCNV_IBM,
UCNV_ISO_2022,
1,
6,
{ 0x1a, 0, 0, 0 },
1,
FALSE,
FALSE,
0,
0,
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
};
const UConverterSharedData _ISO2022JPData={
sizeof(UConverterSharedData),
~((uint32_t) 0),
NULL,
NULL,
&_ISO2022JPStaticData,
FALSE,
&_ISO2022JPImpl,
0
};
static const UConverterImpl _ISO2022KRImpl={
UCNV_ISO_2022,
NULL,
NULL,
_ISO2022Open,
_ISO2022Close,
_ISO2022Reset,
UConverter_toUnicode_ISO_2022_KR_OFFSETS_LOGIC,
UConverter_toUnicode_ISO_2022_KR_OFFSETS_LOGIC,
UConverter_fromUnicode_ISO_2022_KR_OFFSETS_LOGIC,
UConverter_fromUnicode_ISO_2022_KR_OFFSETS_LOGIC,
NULL,
NULL,
_ISO2022getName,
_ISO_2022_WriteSub,
_ISO_2022_SafeClone,
_ISO_2022_GetUnicodeSet
};
static const UConverterStaticData _ISO2022KRStaticData={
sizeof(UConverterStaticData),
"ISO_2022_KR",
0,
UCNV_IBM,
UCNV_ISO_2022,
1,
3,
{ 0x1a, 0, 0, 0 },
1,
FALSE,
FALSE,
0,
0,
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
};
const UConverterSharedData _ISO2022KRData={
sizeof(UConverterSharedData),
~((uint32_t) 0),
NULL,
NULL,
&_ISO2022KRStaticData,
FALSE,
&_ISO2022KRImpl,
0
};
static const UConverterImpl _ISO2022CNImpl={
UCNV_ISO_2022,
NULL,
NULL,
_ISO2022Open,
_ISO2022Close,
_ISO2022Reset,
UConverter_toUnicode_ISO_2022_CN_OFFSETS_LOGIC,
UConverter_toUnicode_ISO_2022_CN_OFFSETS_LOGIC,
UConverter_fromUnicode_ISO_2022_CN_OFFSETS_LOGIC,
UConverter_fromUnicode_ISO_2022_CN_OFFSETS_LOGIC,
NULL,
NULL,
_ISO2022getName,
_ISO_2022_WriteSub,
_ISO_2022_SafeClone,
_ISO_2022_GetUnicodeSet
};
static const UConverterStaticData _ISO2022CNStaticData={
sizeof(UConverterStaticData),
"ISO_2022_CN",
0,
UCNV_IBM,
UCNV_ISO_2022,
2,
8,
{ 0x1a, 0, 0, 0 },
1,
FALSE,
FALSE,
0,
0,
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
};
const UConverterSharedData _ISO2022CNData={
sizeof(UConverterSharedData),
~((uint32_t) 0),
NULL,
NULL,
&_ISO2022CNStaticData,
FALSE,
&_ISO2022CNImpl,
0
};
static void
_ISO2022Open(UConverter *cnv, const char *name, const char *locale,uint32_t options, UErrorCode *errorCode){
char myLocale[6]={' ',' ',' ',' ',' ',' '};
cnv->extraInfo = uprv_malloc (sizeof (UConverterDataISO2022));
if(cnv->extraInfo != NULL) {
UConverterDataISO2022 *myConverterData=(UConverterDataISO2022 *) cnv->extraInfo;
myConverterData->currentConverter = NULL;
myConverterData->fromUnicodeConverter = NULL;
myConverterData->currentType= ASCII1;
myConverterData->plane = -1;
myConverterData->key =0;
myConverterData->isFirstBuffer = TRUE;
cnv->fromUnicodeStatus =FALSE;
if(locale){
uprv_strncpy(myLocale, locale, sizeof(myLocale));
myConverterData->isLocaleSpecified = TRUE;
}
myConverterData->version= 0;
myConverterData->myConverterArray[0] =NULL;
if(myLocale[0]=='j' && (myLocale[1]=='a'|| myLocale[1]=='p') &&
(myLocale[2]=='_' || myLocale[2]=='\0')){
int len=0;
myConverterData->myConverterArray[0]= ucnv_open("ASCII", errorCode );
myConverterData->myConverterArray[1]= ucnv_open("ISO8859_1", errorCode);
myConverterData->myConverterArray[2]= ucnv_open("ISO8859_7", errorCode);
myConverterData->myConverterArray[3]= ucnv_open("jisx-201", errorCode);
myConverterData->myConverterArray[4]= ucnv_open("jisx-208", errorCode);
myConverterData->myConverterArray[5]= ucnv_open("jisx-212", errorCode);
myConverterData->myConverterArray[6]= ucnv_open("ibm-5478", errorCode);
myConverterData->myConverterArray[7]= ucnv_open("ksc_5601", errorCode);
myConverterData->myConverterArray[8]= ucnv_open("jisx-201", errorCode);
myConverterData->myConverterArray[9]= NULL;
setInitialStateToUnicodeJPCN(cnv, myConverterData);
setInitialStateFromUnicodeJPCN(cnv,myConverterData);
cnv->sharedData=(UConverterSharedData*)(&_ISO2022JPData);
uprv_strcpy(myConverterData->locale,"ja");
myConverterData->version =options & UCNV_OPTIONS_VERSION_MASK;
uprv_strcpy(myConverterData->name,"ISO_2022,locale=ja,version=");
len=strlen(myConverterData->name);
myConverterData->name[len]=(char)(myConverterData->version+(int)'0');
myConverterData->name[len+1]='\0';
}
else if(myLocale[0]=='k' && (myLocale[1]=='o'|| myLocale[1]=='r') &&
(myLocale[2]=='_' || myLocale[2]=='\0')){
setInitialStateToUnicodeKR(cnv, myConverterData);
setInitialStateFromUnicodeKR(cnv,myConverterData);
if ((options & UCNV_OPTIONS_VERSION_MASK)==1){
myConverterData->version = 1;
myConverterData->currentConverter=myConverterData->fromUnicodeConverter=
ucnv_open("icu-internal-25546",errorCode);
uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=1");
}else{
myConverterData->currentConverter=myConverterData->fromUnicodeConverter = ucnv_open("ibm-949",errorCode);
myConverterData->version = 0;
uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=0");
}
cnv->sharedData=(UConverterSharedData*)&_ISO2022KRData;
cnv->mode=UCNV_SI;
uprv_strcpy(myConverterData->locale,"ko");
}
else if(((myLocale[0]=='z' && myLocale[1]=='h') || (myLocale[0]=='c'&& myLocale[1]=='n'))&&
(myLocale[2]=='_' || myLocale[2]=='\0')){
myConverterData->myConverterArray[0] = ucnv_open("ASCII",errorCode);
myConverterData->myConverterArray[1] = ucnv_open("ibm-5478",errorCode);
myConverterData->myConverterArray[2] = ucnv_open("iso-ir-165",errorCode);
myConverterData->myConverterArray[3] = ucnv_open("cns-11643-1992",errorCode);
myConverterData->myConverterArray[4] = NULL;
setInitialStateToUnicodeJPCN(cnv, myConverterData);
setInitialStateFromUnicodeJPCN(cnv,myConverterData);
cnv->sharedData=(UConverterSharedData*)&_ISO2022CNData;
uprv_strcpy(myConverterData->locale,"cn");
if ((options & UCNV_OPTIONS_VERSION_MASK)==1){
myConverterData->version = 1;
uprv_strcpy(myConverterData->name,"ISO_2022,locale=zh,version=1");
}else{
uprv_strcpy(myConverterData->name,"ISO_2022,locale=zh,version=0");
myConverterData->version = 0;
}
}
else{
cnv->charErrorBufferLength = 3;
cnv->charErrorBuffer[0] = 0x1b;
cnv->charErrorBuffer[1] = 0x25;
cnv->charErrorBuffer[2] = 0x42;
cnv->sharedData=(UConverterSharedData*)&_ISO2022Data;
myConverterData->isLocaleSpecified=FALSE;
uprv_strcpy(myConverterData->name,"ISO_2022");
}
} else {
*errorCode = U_MEMORY_ALLOCATION_ERROR;
}
}
static void
_ISO2022Close(UConverter *converter) {
UConverterDataISO2022* myData =(UConverterDataISO2022 *) (converter->extraInfo);
UConverter **array = myData->myConverterArray;
if (converter->extraInfo != NULL) {
while(*array!=NULL){
if(*array==myData->currentConverter){
myData->currentConverter=NULL;
}
ucnv_close(*array++);
}
ucnv_close(myData->currentConverter);
if(!converter->isExtraLocal){
uprv_free (converter->extraInfo);
}
}
}
static void
_ISO2022Reset(UConverter *converter, UConverterResetChoice choice) {
UConverterDataISO2022 *myConverterData=(UConverterDataISO2022 *) (converter->extraInfo);
if(! myConverterData->isLocaleSpecified){
if(choice<=UCNV_RESET_TO_UNICODE) {
myConverterData->isFirstBuffer = TRUE;
if (converter->mode == UCNV_SO){
ucnv_close (myConverterData->currentConverter);
myConverterData->currentConverter=NULL;
}
converter->mode = UCNV_SI;
}
if(choice!=UCNV_RESET_TO_UNICODE) {
converter->charErrorBufferLength = 3;
converter->charErrorBuffer[0] = 0x1b;
converter->charErrorBuffer[1] = 0x28;
converter->charErrorBuffer[2] = 0x42;
}
}
else {
if(myConverterData->locale[0] == 'j' || myConverterData->locale[0] == 'c'){
if(choice<=UCNV_RESET_TO_UNICODE) {
setInitialStateToUnicodeJPCN(converter, myConverterData);
}
if(choice!=UCNV_RESET_TO_UNICODE) {
setInitialStateFromUnicodeJPCN(converter,myConverterData);
}
}
else if(myConverterData->locale[0] == 'k'){
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;
return myData->name;
}
return NULL;
}
static void
setInitialStateToUnicodeJPCN(UConverter* converter,UConverterDataISO2022 *myConverterData ){
myConverterData->toUnicodeCurrentState =ASCII;
myConverterData->currentConverter = NULL;
myConverterData->isFirstBuffer = TRUE;
myConverterData->toUnicodeSaveState = INVALID_STATE;
converter->mode = UCNV_SI;
}
static void
setInitialStateFromUnicodeJPCN(UConverter* converter,UConverterDataISO2022 *myConverterData){
myConverterData->fromUnicodeCurrentState= ASCII;
myConverterData->isEscapeAppended=FALSE;
myConverterData->isShiftAppended=FALSE;
myConverterData->isLocaleSpecified=TRUE;
myConverterData->currentType = ASCII1;
converter->fromUnicodeStatus = FALSE;
}
static void
setInitialStateToUnicodeKR(UConverter* converter, UConverterDataISO2022 *myConverterData){
myConverterData->isLocaleSpecified=TRUE;
converter->mode = UCNV_SI;
myConverterData->currentConverter = myConverterData->fromUnicodeConverter;
}
static void
setInitialStateFromUnicodeKR(UConverter* converter,UConverterDataISO2022 *myConverterData){
if( converter->charErrorBufferLength==0){
converter->charErrorBufferLength = 4;
converter->charErrorBuffer[0] = 0x1b;
converter->charErrorBuffer[1] = 0x24;
converter->charErrorBuffer[2] = 0x29;
converter->charErrorBuffer[3] = 0x43;
}
myConverterData->isLocaleSpecified=TRUE;
myConverterData->isShiftAppended=FALSE;
}
static U_INLINE void
CONCAT_ESCAPE_EX(UConverterFromUnicodeArgs* args,
const UChar* source,
unsigned char** target,
const unsigned char* targetLimit,
int32_t** offsets,
const char* strToAppend,
int len,
UErrorCode* err);
static U_INLINE void
MBCS_FROM_UCHAR32_ISO2022(UConverterSharedData* sharedData,
UChar32 c,
uint32_t* value,
UBool useFallback,
int* length,
int outputType);
static U_INLINE void
MBCS_SINGLE_FROM_UCHAR32(UConverterSharedData* sharedData,
UChar32 c,
uint32_t* retval,
UBool useFallback);
static U_INLINE void
CONCAT_ESCAPE_EX(UConverterFromUnicodeArgs* args,
const UChar* source,
unsigned char** target,
const unsigned char* targetLimit,
int32_t** offsets,
const char* strToAppend,
int len,
UErrorCode* err)
{
unsigned char* myTarget = *target;
int32_t* myOffsets = *offsets;
while(len-->0){
if(myTarget < targetLimit){
*(myTarget++) = (unsigned char) *(strToAppend++);
if(myOffsets){
*(myOffsets++) = source - args->source -1;
}
}
else{
args->converter->charErrorBuffer[(int)args->converter->charErrorBufferLength++] = (unsigned char) *(strToAppend++);
*err =U_BUFFER_OVERFLOW_ERROR;
}
}
*target = myTarget;
*offsets = myOffsets;
}
static U_INLINE void
MBCS_FROM_UCHAR32_ISO2022(UConverterSharedData* sharedData,
UChar32 c,
uint32_t* value,
UBool useFallback,
int* length,
int outputType)
{
const uint16_t *table=sharedData->table->mbcs.fromUnicodeTable;
uint32_t stage2Entry;
uint32_t myValue=0;
const uint8_t *p;
if(c<0x10000 || (sharedData->table->mbcs.unicodeMask&UCNV_HAS_SUPPLEMENTARY)) {
stage2Entry=MBCS_STAGE_2_FROM_U(table, c);
if(outputType==MBCS_OUTPUT_2){
myValue=MBCS_VALUE_2_FROM_STAGE_2(sharedData->table->mbcs.fromUnicodeBytes, stage2Entry, c);
if(myValue<=0xff) {
*length=1;
} else {
*length=2;
}
}else if(outputType==MBCS_OUTPUT_3){
p=MBCS_POINTER_3_FROM_STAGE_2(sharedData->table->mbcs.fromUnicodeBytes, stage2Entry, c);
myValue=((uint32_t)*p<<16)|((uint32_t)p[1]<<8)|p[2];
if(myValue<=0xff) {
*length=1;
} else if(myValue<=0xffff) {
*length=2;
} else {
*length=3;
}
}
if( (stage2Entry&(1<<(16+(c&0xf))))!=0 ||
(FROM_U_USE_FALLBACK(useFallback, c) && (myValue!=0 || c==0))
) {
*value=myValue;
} else {
*length=0;
}
}else{
*length=0;
}
}
static U_INLINE void
MBCS_SINGLE_FROM_UCHAR32(UConverterSharedData* sharedData,
UChar32 c,
uint32_t* retval,
UBool useFallback)
{
const uint16_t *table;
int32_t value;
if(c>=0x10000 && !(sharedData->table->mbcs.unicodeMask&UCNV_HAS_SUPPLEMENTARY)) {
value= -1;
}
table=sharedData->table->mbcs.fromUnicodeTable;
value=MBCS_SINGLE_RESULT_FROM_U(table, (uint16_t *)sharedData->table->mbcs.fromUnicodeBytes, c);
if(useFallback ? value>=0x800 : value>=0xc00) {
value &=0xff;
} else {
value= -1;
}
*retval=(uint16_t) value;
}
static UChar32
T_UConverter_getNextUChar_ISO_2022(UConverterToUnicodeArgs* args,
UErrorCode* err){
const char* mySourceLimit;
int plane=0;
UConverterDataISO2022* myData =((UConverterDataISO2022*)(args->converter->extraInfo));
if (args->sourceLimit < args->source){
*err = U_ILLEGAL_ARGUMENT_ERROR;
return 0xffff;
}
while(1){
mySourceLimit = getEndOfBuffer_2022(&(args->source), args->sourceLimit, TRUE);
if (args->converter->mode == UCNV_SO && mySourceLimit!=args->source)
{
return ucnv_getNextUChar(myData->currentConverter,
&(args->source),
mySourceLimit,
err);
}
changeState_2022(args->converter,
&(args->source),
args->sourceLimit,
TRUE,
ISO_2022,
&plane,
err);
if(args->source >= args->sourceLimit){
*err = U_INDEX_OUTOFBOUNDS_ERROR;
break;
}
}
if( (args->source == args->sourceLimit) && args->flush){
_ISO2022Reset(args->converter,UCNV_RESET_TO_UNICODE);
}
return 0xffff;
}
static void
T_UConverter_toUnicode_ISO_2022(UConverterToUnicodeArgs *args,
UErrorCode* err){
const char *mySourceLimit;
char const* sourceStart;
UConverter *saveThis;
int plane =0;
UConverterDataISO2022* myData;
if ((args->converter == NULL) || (args->targetLimit < args->target) || (args->sourceLimit < args->source)){
*err = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
myData= ((UConverterDataISO2022*)(args->converter->extraInfo));
while (args->source < args->sourceLimit) {
mySourceLimit = getEndOfBuffer_2022(&(args->source), args->sourceLimit, args->flush);
if (args->converter->mode == UCNV_SO) {
saveThis = args->converter;
args->offsets = NULL;
args->converter = myData->currentConverter;
ucnv_toUnicode(args->converter,
&args->target,
args->targetLimit,
&args->source,
mySourceLimit,
args->offsets,
args->flush,
err);
args->converter = saveThis;
myData->isFirstBuffer = FALSE;
}
if((myData->isFirstBuffer) && (args->source[0]!=(char)ESC_2022)
&& (myData->currentConverter==NULL)){
saveThis = args->converter;
args->offsets = NULL;
myData->currentConverter = ucnv_open("ASCII",err);
if(U_FAILURE(*err)){
break;
}
args->converter = myData->currentConverter;
ucnv_toUnicode(args->converter,
&args->target,
args->targetLimit,
&args->source,
mySourceLimit,
args->offsets,
args->flush,
err);
args->converter = saveThis;
args->converter->mode = UCNV_SO;
myData->isFirstBuffer=FALSE;
}
if (U_FAILURE(*err) || (args->source == args->sourceLimit))
return;
sourceStart = args->source;
changeState_2022(args->converter,
&(args->source),
args->sourceLimit,
TRUE,
ISO_2022,
&plane,
err);
}
myData->isFirstBuffer=FALSE;
if( (args->source == args->sourceLimit) && args->flush){
_ISO2022Reset(args->converter,UCNV_RESET_FROM_UNICODE);
}
}
static void
T_UConverter_toUnicode_ISO_2022_OFFSETS_LOGIC(UConverterToUnicodeArgs* args,
UErrorCode* err){
int32_t myOffset=0;
int32_t base = 0;
const char* mySourceLimit;
char const* sourceStart;
UConverter* saveThis;
int plane =0;
UConverterDataISO2022* myData;
if ((args->converter == NULL) || (args->targetLimit < args->target) || (args->sourceLimit < args->source)){
*err = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
myData=((UConverterDataISO2022*)(args->converter->extraInfo));
while (args->source < args->sourceLimit) {
mySourceLimit = getEndOfBuffer_2022(&(args->source), args->sourceLimit, args->flush);
if (args->converter->mode == UCNV_SO) {
const UChar* myTargetStart = args->target;
saveThis = args->converter;
args->converter = myData->currentConverter;
ucnv_toUnicode(args->converter,
&(args->target),
args->targetLimit,
&(args->source),
mySourceLimit,
args->offsets,
args->flush,
err);
myData->isFirstBuffer = FALSE;
args->converter = saveThis;
{
int32_t lim = args->target - myTargetStart;
int32_t i = 0;
for (i=base; i < lim;i++){
args->offsets[i] += myOffset;
}
base += lim;
}
}
if(myData->isFirstBuffer && args->source[0]!=ESC_2022
&& (myData->currentConverter==NULL)){
const UChar* myTargetStart = args->target;
saveThis = args->converter;
args->offsets = NULL;
myData->currentConverter = ucnv_open("ASCII",err);
if(U_FAILURE(*err)){
break;
}
args->converter = myData->currentConverter;
ucnv_toUnicode(args->converter,
&args->target,
args->targetLimit,
&args->source,
mySourceLimit,
args->offsets,
args->flush,
err);
args->converter = saveThis;
args->converter->mode = UCNV_SO;
myData->isFirstBuffer=FALSE;
{
int32_t lim = args->target - myTargetStart;
int32_t i = 0;
for (i=base; i < lim;i++){
args->offsets[i] += myOffset;
}
base += lim;
}
}
if (U_FAILURE(*err) || (args->source == args->sourceLimit))
return;
sourceStart = args->source;
changeState_2022(args->converter,
&(args->source),
args->sourceLimit,
TRUE,
ISO_2022,
&plane,
err);
myOffset += args->source - sourceStart;
}
if( (args->source == args->sourceLimit) && args->flush){
_ISO2022Reset(args->converter,UCNV_RESET_TO_UNICODE);
}
}
static UCNV_TableStates_2022
getKey_2022(char c,int32_t* key,int32_t* offset){
int32_t togo = *key;
int32_t low = 0;
int32_t hi = MAX_STATES_2022;
int32_t oldmid=0;
if (*key == 0){
togo = (int8_t)normalize_esq_chars_2022[(int)c];
}
else{
togo <<= 5;
togo += (int8_t)normalize_esq_chars_2022[(int)c];
}
while (hi != low) {
register int32_t mid = (hi+low) >> 1;
if (mid == oldmid)
break;
if (escSeqStateTable_Key_2022[mid] > togo){
hi = mid;
}
else if (escSeqStateTable_Key_2022[mid] < togo){
low = mid;
}
else {
*key = togo;
*offset = mid;
return escSeqStateTable_Value_2022[mid];
}
oldmid = mid;
}
*key = 0;
*offset = 0;
return INVALID_2022;
}
static const char*
getEndOfBuffer_2022(const char** source,
const char* sourceLimit,
UBool flush){
const char* mySource = *source;
if (*source >= sourceLimit)
return sourceLimit;
do{
if (*mySource == ESC_2022){
int8_t i;
int32_t key = 0;
int32_t offset;
UCNV_TableStates_2022 value = VALID_NON_TERMINAL_2022;
for (i=0;
(mySource+i < sourceLimit)&&(value == VALID_NON_TERMINAL_2022);
i++) {
value = getKey_2022(*(mySource+i), &key, &offset);
}
if (value > 0 || *mySource==ESC_2022)
return mySource;
if ((value == VALID_NON_TERMINAL_2022)&&(!flush) )
return sourceLimit;
}
}while (++mySource < sourceLimit);
return sourceLimit;
}
static void
fromUnicodeCallback(UConverterFromUnicodeArgs* args,const UChar32 sourceChar,const UChar** pSource,
unsigned char** pTarget,int32_t** pOffsets,UConverterCallbackReason reason, UErrorCode* err){
const UChar* saveSource =NULL;
char* saveTarget =NULL;
int32_t* saveOffsets =NULL;
int currentOffset =0;
int saveIndex =0;
int32_t* offsets = *pOffsets;
const UChar* source = *pSource;
unsigned char* target = *pTarget;
args->converter->invalidUCharLength = 0;
if(sourceChar>0xffff){
args->converter->invalidUCharBuffer[args->converter->invalidUCharLength++] =(uint16_t)(((sourceChar)>>10)+0xd7c0);
args->converter->invalidUCharBuffer[args->converter->invalidUCharLength++] =(uint16_t)(((sourceChar)&0x3ff)|0xdc00);
}
else{
args->converter->invalidUCharBuffer[args->converter->invalidUCharLength++] =(UChar)sourceChar;
}
if(offsets)
currentOffset = *(offsets-1)+1;
saveSource = args->source;
saveTarget = args->target;
saveOffsets = args->offsets;
args->target = (char*)target;
args->source = source;
args->offsets = offsets;
args->converter->fromUCharErrorBehaviour ( args->converter->fromUContext,
args,
args->converter->invalidUCharBuffer,
args->converter->invalidUCharLength,
(UChar32) (sourceChar),
reason,
err);
saveIndex = args->target - (char*)target;
if(args->offsets){
args->offsets = saveOffsets;
while(saveIndex-->0){
*offsets = currentOffset;
offsets++;
}
}
target = (unsigned char*)args->target;
*pTarget=target;
*pOffsets=offsets;
args->source=saveSource;
args->target=saveTarget;
args->offsets=saveOffsets;
args->converter->fromUSurrogateLead=0x00;
}
static void
toUnicodeCallback(UConverterToUnicodeArgs* args, const uint32_t sourceChar,const char** pSource,
const uint32_t targetUniChar,UChar** pTarget,UErrorCode* err){
const char *saveSource = args->source;
UChar *saveTarget = args->target;
const char* source = *pSource;
UChar* target = *pTarget;
int32_t *saveOffsets = NULL;
UConverterCallbackReason reason;
int32_t currentOffset;
int32_t saveIndex = target - args->target;
args->converter->invalidCharLength=0;
if(sourceChar>0xff){
currentOffset= source - args->source - 2;
args->converter->invalidCharBuffer[args->converter->invalidCharLength++] = (char)(sourceChar>>8);
args->converter->invalidCharBuffer[args->converter->invalidCharLength++] = (char)sourceChar;
}
else{
currentOffset= source - args->source -1;
args->converter->invalidCharBuffer[args->converter->invalidCharLength++] =(char) sourceChar;
}
if(targetUniChar == (missingCharMarker-1)){
reason = UCNV_UNASSIGNED;
*err = U_INVALID_CHAR_FOUND;
}
else{
reason = UCNV_ILLEGAL;
*err = U_ILLEGAL_CHAR_FOUND;
}
if(args->offsets){
saveOffsets=args->offsets;
args->offsets = args->offsets+(target - args->target);
}
args->target =target;
target =saveTarget;
args->source = source;
args->converter->fromCharErrorBehaviour (
args->converter->toUContext,
args,
args->converter->invalidCharBuffer,
args->converter->invalidCharLength,
reason,
err);
if(args->offsets){
args->offsets = saveOffsets;
for (;saveIndex < (args->target - target);saveIndex++) {
args->offsets[saveIndex] += currentOffset;
}
}
target=args->target;
*pTarget=target;
args->source = saveSource;
args->target = saveTarget;
}
#define MAX_VALID_CP_JP 9
static const Cnv2022Type myConverterType[MAX_VALID_CP_JP]={
ASCII1,
LATIN1,
SBCS,
SBCS,
DBCS,
DBCS,
DBCS,
DBCS,
SBCS,
};
static const StateEnum nextStateArray[5][MAX_VALID_CP_JP]= {
{JISX201 ,INVALID_STATE,INVALID_STATE,JISX208,ASCII,INVALID_STATE,INVALID_STATE,INVALID_STATE,INVALID_STATE},
{JISX201,INVALID_STATE,INVALID_STATE,JISX208,JISX212,ASCII,INVALID_STATE,INVALID_STATE,INVALID_STATE},
{ISO8859_1,ISO8859_7,JISX201,JISX208,JISX212,GB2312,KSC5601,ASCII,INVALID_STATE},
{JISX201,INVALID_STATE,INVALID_STATE,JISX208,JISX212,HWKANA_7BIT,INVALID_STATE,INVALID_STATE,ASCII},
{JISX201,INVALID_STATE,INVALID_STATE,JISX208,JISX212,ASCII,INVALID_STATE,INVALID_STATE,INVALID_STATE},
};
static const char escSeqChars[MAX_VALID_CP_JP][6] ={
"\x1B\x28\x42",
"\x1B\x2E\x41",
"\x1B\x2E\x46",
"\x1B\x28\x4A",
"\x1B\x24\x42",
"\x1B\x24\x28\x44",
"\x1B\x24\x41",
"\x1B\x24\x28\x43",
"\x1B\x28\x49"
};
static const int32_t escSeqCharsLen[MAX_VALID_CP_JP] ={
3,
3,
3,
3,
3,
4,
3,
4,
3
};
static void
UConverter_fromUnicode_ISO_2022_JP_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args, UErrorCode* err){
UConverterDataISO2022 *converterData;
unsigned char* target = (unsigned char*) args->target;
const unsigned char* targetLimit = (const unsigned char*) args->targetLimit;
const UChar* source = args->source;
const UChar* sourceLimit = args->sourceLimit;
int32_t* offsets = args->offsets;
int32_t offset = 0;
uint32_t targetByteUnit = missingCharMarker;
UChar32 sourceChar =0x0000;
const char* escSeq = NULL;
int len =0;
UConverterCallbackReason reason;
UConverterSharedData* sharedData=NULL;
UBool useFallback;
StateEnum* currentState;
StateEnum initIterState;
UConverter** currentConverter;
Cnv2022Type* currentType;
UConverter** convArray;
if ((args->converter == NULL) || (targetLimit < target) || (sourceLimit < source)){
*err = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
converterData = (UConverterDataISO2022*)args->converter->extraInfo;
useFallback = args->converter->useFallback;
currentState = &converterData->fromUnicodeCurrentState;
initIterState = ASCII;
currentConverter = &converterData->fromUnicodeConverter;
convArray = converterData->myConverterArray;
initIterState = *currentState;
currentType = &converterData->currentType;
if(args->converter->fromUSurrogateLead!=0 && target< targetLimit) {
goto getTrail;
}
*currentConverter = convArray[(*currentConverter==NULL) ? 0 : (int)*currentState];
sharedData= (*currentConverter)->sharedData;
while( source < sourceLimit){
targetByteUnit = missingCharMarker;
if(target < targetLimit){
sourceChar = *(source++);
if(sourceChar > SPACE) {
do{
switch (*currentType){
case DBCS:
{
uint32_t value=0;
int length=0;
MBCS_FROM_UCHAR32_ISO2022(sharedData,sourceChar,&value,useFallback,&length,MBCS_OUTPUT_2);
if(length==2){
targetByteUnit = value;
}
}
break;
case ASCII1:
if(sourceChar < 0x7f){
targetByteUnit = sourceChar;
}
break;
case SBCS:
MBCS_SINGLE_FROM_UCHAR32(sharedData,sourceChar,&targetByteUnit,useFallback);
if(0xFF9F-sourceChar<=(0xFF9F-0xFF61)){
if( converterData->version==3){
targetByteUnit-=0x80;
*currentState = HWKANA_7BIT;
}
else if( converterData->version==4){
*currentState = JISX201;
}
else{
targetByteUnit=missingCharMarker;
}
*currentConverter = convArray[(*currentConverter==NULL) ? 0 : (int)*currentState];
*currentType = (Cnv2022Type) myConverterType[*currentState];
}
break;
case LATIN1:
if(sourceChar <= 0x00FF){
targetByteUnit = sourceChar;
}
break;
default:
break;
}
if(targetByteUnit==missingCharMarker){
*currentState = nextStateArray[converterData->version][*currentState];
*currentConverter = convArray[(*currentConverter==NULL) ? 0 : (int)*currentState];
*currentType = (Cnv2022Type) myConverterType[*currentState];
sharedData= (*currentConverter)->sharedData;
}
else
break;
}while(initIterState != *currentState);
}
else{
targetByteUnit = sourceChar;
*currentState = ASCII;
*currentType = (Cnv2022Type) myConverterType[*currentState];
}
if(targetByteUnit != missingCharMarker){
if( *currentState != initIterState){
escSeq = escSeqChars[(int)*currentState];
len = escSeqCharsLen[(int)*currentState];
CONCAT_ESCAPE_EX(args,source, &target,targetLimit, &offsets, escSeq,len,err);
if(*currentState==ISO8859_1 || *currentState==ISO8859_7){
escSeq = UCNV_SS2;
len = UCNV_SS2_LEN;
CONCAT_ESCAPE_EX(args, source, &target, targetLimit,&offsets, escSeq,len,err);
}
}
initIterState = *currentState;
offset = source - args->source -1;
if(targetByteUnit <= 0x00FF){
if( target <targetLimit){
*(target++) = (unsigned char) targetByteUnit;
if(offsets){
*(offsets++) = offset;
}
}else{
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) targetByteUnit;
*err = U_BUFFER_OVERFLOW_ERROR;
}
}else{
if(target < targetLimit){
*(target++) =(unsigned char) (targetByteUnit>>8);
if(offsets){
*(offsets++) = offset;
}
if(target < targetLimit){
*(target++) =(unsigned char) (targetByteUnit);
if(offsets){
*(offsets++) = offset;
}
}else{
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) (targetByteUnit);
*err = U_BUFFER_OVERFLOW_ERROR;
}
}else{
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) (targetByteUnit>>8);
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) (targetByteUnit);
*err = U_BUFFER_OVERFLOW_ERROR;
}
}
}
else{
reason = UCNV_UNASSIGNED;
*err = U_INVALID_CHAR_FOUND;
if(UTF_IS_SURROGATE(sourceChar)) {
if(UTF_IS_SURROGATE_FIRST(sourceChar)) {
args->converter->fromUSurrogateLead=(UChar)sourceChar;
getTrail:
if(source < sourceLimit) {
UChar trail=(UChar) *source;
if(UTF_IS_SECOND_SURROGATE(trail)) {
source++;
sourceChar=UTF16_GET_PAIR_VALUE(args->converter->fromUSurrogateLead, trail);
args->converter->fromUSurrogateLead=0x00;
reason =UCNV_UNASSIGNED;
*err = U_INVALID_CHAR_FOUND;
} else {
reason=UCNV_ILLEGAL;
*err=U_ILLEGAL_CHAR_FOUND;
}
} else {
*err = U_ZERO_ERROR;
break;
}
} else {
reason=UCNV_ILLEGAL;
*err=U_ILLEGAL_CHAR_FOUND;
}
}
fromUnicodeCallback(args,sourceChar,&source,&target,&offsets,reason,err);
initIterState = *currentState;
if (U_FAILURE (*err)){
break;
}
}
}
else{
*err =U_BUFFER_OVERFLOW_ERROR;
break;
}
}
if (args->converter->fromUSurrogateLead !=0 && (source == sourceLimit) && args->flush){
*err = U_TRUNCATED_CHAR_FOUND;
}
if( (source == sourceLimit) && args->flush){
setInitialStateFromUnicodeJPCN(args->converter,converterData);
}
args->source = source;
args->target = (char*)target;
}
static const StateEnum nextStateToUnicodeJP[5][MAX_STATES_2022]= {
{
INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,ASCII ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,JISX201 ,HWKANA_7BIT ,JISX201 ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,JISX208 ,INVALID_STATE ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
},
{
INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,ASCII ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,JISX201 ,HWKANA_7BIT ,JISX201 ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,JISX208 ,INVALID_STATE ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,JISX212 ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
},
{
INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,ASCII ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,JISX201 ,HWKANA_7BIT ,JISX201 ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,JISX208 ,GB2312 ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,ISO8859_1 ,ISO8859_7 ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,KSC5601 ,JISX212 ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
},
{
INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,ASCII ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,JISX201 ,HWKANA_7BIT ,JISX201 ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,JISX208 ,GB2312 ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,ISO8859_1 ,ISO8859_7 ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,KSC5601 ,JISX212 ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
},
{
INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,ASCII ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,JISX201 ,HWKANA_7BIT ,JISX201 ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,JISX208 ,GB2312 ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,ISO8859_1 ,ISO8859_7 ,JISX208 ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,KSC5601 ,JISX212 ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
,INVALID_STATE ,INVALID_STATE ,INVALID_STATE ,INVALID_STATE
}
};
static void
UConverter_toUnicode_ISO_2022_JP_OFFSETS_LOGIC(UConverterToUnicodeArgs *args,
UErrorCode* err){
char tempBuf[2];
const char *mySource = ( char *) args->source;
UChar *myTarget = args->target;
const char *mySourceLimit = args->sourceLimit;
uint32_t targetUniChar = 0x0000;
uint32_t mySourceChar = 0x0000;
UConverterDataISO2022* myData;
StateEnum* currentState;
uint32_t* toUnicodeStatus;
int plane = 0;
if ((args->converter == NULL) || (myTarget < args->target) || (mySource < args->source)){
*err = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
myData=(UConverterDataISO2022*)(args->converter->extraInfo);
currentState = &myData->toUnicodeCurrentState;
toUnicodeStatus = &args->converter->toUnicodeStatus;
while(mySource< args->sourceLimit){
targetUniChar = missingCharMarker;
if(myTarget < args->targetLimit){
mySourceChar= (unsigned char) *mySource++;
if(mySourceChar==UCNV_SI){
if(myData->version==3 && *toUnicodeStatus==0x00){
if(myData->toUnicodeSaveState!=INVALID_STATE){
*currentState = (StateEnum) myData->toUnicodeSaveState;
continue;
}
else{
*err =U_ILLEGAL_CHAR_FOUND;
goto CALLBACK;
}
}
else{
goto CALLBACK;
}
}else if(mySourceChar==UCNV_SO){
if(myData->version==3 && *toUnicodeStatus==0x00){
myData->toUnicodeSaveState= (int) *currentState;
*currentState = HWKANA_7BIT;
continue;
}
else{
goto CALLBACK;
}
}else if(mySourceChar==ESC_2022 || myData->key!=0){
if(*toUnicodeStatus== 0x00){
mySource--;
changeState_2022(args->converter,&(mySource),
args->sourceLimit, args->flush,ISO_2022_JP,&plane, err);
if(U_SUCCESS(*err)){
continue;
}
else{
args->target = myTarget;
args->source = mySource;
return;
}
}
else{
goto CALLBACK;
}
}
switch(myConverterType[*currentState]){
case DBCS:
if(*toUnicodeStatus== 0x00){
*toUnicodeStatus= (UChar) mySourceChar;
continue;
}
else{
const char *pBuf;
tempBuf[0] = (char) args->converter->toUnicodeStatus;
tempBuf[1] = (char) mySourceChar;
mySourceChar+= (args->converter->toUnicodeStatus)<<8;
*toUnicodeStatus= 0;
pBuf = tempBuf;
targetUniChar = _MBCSSimpleGetNextUChar(myData->currentConverter->sharedData, &pBuf, tempBuf+2, args->converter->useFallback);
}
break;
case ASCII1:
if( mySourceChar < 0x7F){
targetUniChar = (UChar) mySourceChar;
}
else if((uint8_t)(mySourceChar - 0xa1) <= (0xdf - 0xa1) && myData->version==4) {
targetUniChar = _MBCS_SINGLE_SIMPLE_GET_NEXT_BMP(myData->myConverterArray[JISX201]->sharedData, mySourceChar);
}
break;
case SBCS:
if((uint8_t)(mySourceChar - 0xa1) <= (0xdf - 0xa1) && myData->version==4) {
targetUniChar = _MBCS_SINGLE_SIMPLE_GET_NEXT_BMP(myData->myConverterArray[JISX201]->sharedData, mySourceChar);
}
else if(*currentState==HWKANA_7BIT){
targetUniChar = _MBCS_SINGLE_SIMPLE_GET_NEXT_BMP(myData->myConverterArray[JISX201]->sharedData, mySourceChar+0x80);
}
else {
targetUniChar = _MBCS_SINGLE_SIMPLE_GET_NEXT_BMP(myData->currentConverter->sharedData, mySourceChar);
}
break;
case LATIN1:
targetUniChar = (UChar) mySourceChar;
break;
case INVALID_STATE:
*err = U_ILLEGAL_ESCAPE_SEQUENCE;
args->target = myTarget;
args->source = mySource;
return;
default:
break;
}
if(targetUniChar < (missingCharMarker-1)){
if(args->offsets){
args->offsets[myTarget - args->target]= mySource - args->source - 2
+(myConverterType[*currentState] <= SBCS);
}
*(myTarget++)=(UChar)targetUniChar;
targetUniChar=missingCharMarker;
}
else{
CALLBACK:
toUnicodeCallback(args,mySourceChar,&mySource,targetUniChar,&myTarget,err);
if(U_FAILURE(*err))
break;
}
}
else{
*err =U_BUFFER_OVERFLOW_ERROR;
break;
}
}
if((args->flush==TRUE)
&& (mySource == mySourceLimit)
&& ( *toUnicodeStatus!=0x00)){
*err = U_TRUNCATED_CHAR_FOUND;
*toUnicodeStatus= 0x00;
}
if( (mySource == mySourceLimit) && args->flush){
setInitialStateToUnicodeJPCN(args->converter,myData);
}
args->target = myTarget;
args->source = mySource;
}
static void
UConverter_fromUnicode_ISO_2022_KR_OFFSETS_LOGIC_IBM(UConverterFromUnicodeArgs* args, UErrorCode* err){
UConverter* saveConv = args->converter;
UConverterDataISO2022 *myConverterData=(UConverterDataISO2022*)args->converter->extraInfo;
args->converter=myConverterData->currentConverter;
_MBCSFromUnicodeWithOffsets(args,err);
if(U_FAILURE(*err)){
if(args->converter->charErrorBufferLength!=0){
uprv_memcpy(saveConv->charErrorBuffer, args->converter->charErrorBuffer,
args->converter->charErrorBufferLength);
saveConv->charErrorBufferLength=args->converter->charErrorBufferLength;
args->converter->charErrorBufferLength=0;
}
if(args->converter->invalidUCharLength!=0){
uprv_memcpy(saveConv->invalidUCharBuffer, args->converter->invalidUCharBuffer,
args->converter->invalidUCharLength);
saveConv->invalidUCharLength=args->converter->invalidUCharLength;
args->converter->invalidCharLength=0;
}
}
args->converter=saveConv;
}
static void
UConverter_fromUnicode_ISO_2022_KR_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args, UErrorCode* err){
const UChar *source = args->source;
const UChar *sourceLimit = args->sourceLimit;
unsigned char *target = (unsigned char *) args->target;
unsigned char *targetLimit = (unsigned char *) args->targetLimit;
int32_t* offsets = args->offsets;
uint32_t targetByteUnit = 0x0000;
UChar32 sourceChar = 0x0000;
UBool isTargetByteDBCS;
UBool oldIsTargetByteDBCS;
UConverterDataISO2022 *converterData;
UConverterCallbackReason reason;
UConverterSharedData* sharedData;
UBool useFallback;
int32_t length =0;
if ((args->converter == NULL) || (args->targetLimit < args->target) || (args->sourceLimit < args->source)){
*err = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
converterData=(UConverterDataISO2022*)args->converter->extraInfo;
sharedData = converterData->fromUnicodeConverter->sharedData;
useFallback = args->converter->useFallback;
isTargetByteDBCS=(UBool)args->converter->fromUnicodeStatus;
oldIsTargetByteDBCS = isTargetByteDBCS;
if(converterData->version==1){
UConverter_fromUnicode_ISO_2022_KR_OFFSETS_LOGIC_IBM(args,err);
return;
}
isTargetByteDBCS = (UBool) args->converter->fromUnicodeStatus;
if(args->converter->fromUSurrogateLead!=0 && target <targetLimit) {
goto getTrail;
}
while(source < sourceLimit){
targetByteUnit = missingCharMarker;
if(target < (unsigned char*) args->targetLimit){
sourceChar = *source++;
MBCS_FROM_UCHAR32_ISO2022(sharedData,sourceChar,&targetByteUnit,useFallback,(int*)&length,MBCS_OUTPUT_2);
if(length > 2 || length==0 ||(((targetByteUnit & 0x8080) != 0x8080)&& length==2)){
targetByteUnit=missingCharMarker;
}
if (targetByteUnit != missingCharMarker){
oldIsTargetByteDBCS = isTargetByteDBCS;
isTargetByteDBCS = (UBool)(targetByteUnit>0x00FF);
if (oldIsTargetByteDBCS != isTargetByteDBCS ){
if (isTargetByteDBCS)
*target++ = UCNV_SO;
else
*target++ = UCNV_SI;
if(offsets)
*(offsets++)= source - args->source-1;
}
if(targetByteUnit <= 0x00FF){
if( target < targetLimit){
*(target++) = (unsigned char) targetByteUnit;
if(offsets){
*(offsets++) = source - args->source-1;
}
}else{
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) (targetByteUnit);
*err = U_BUFFER_OVERFLOW_ERROR;
}
}else{
if(target < targetLimit){
*(target++) =(unsigned char) ((targetByteUnit>>8) -0x80);
if(offsets){
*(offsets++) = source - args->source-1;
}
if(target < targetLimit){
*(target++) =(unsigned char) (targetByteUnit -0x80);
if(offsets){
*(offsets++) = source - args->source-1;
}
}else{
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) (targetByteUnit -0x80);
*err = U_BUFFER_OVERFLOW_ERROR;
}
}else{
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) ((targetByteUnit>>8) -0x80);
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) (targetByteUnit-0x80);
*err = U_BUFFER_OVERFLOW_ERROR;
}
}
}
else{
reason =UCNV_UNASSIGNED;
*err =U_INVALID_CHAR_FOUND;
if(UTF_IS_SURROGATE(sourceChar)) {
if(UTF_IS_SURROGATE_FIRST(sourceChar)) {
args->converter->fromUSurrogateLead=(UChar)sourceChar;
getTrail:
if(source < sourceLimit) {
UChar trail=(UChar) *source;
if(UTF_IS_SECOND_SURROGATE(trail)) {
source++;
sourceChar=UTF16_GET_PAIR_VALUE(args->converter->fromUSurrogateLead, trail);
args->converter->fromUSurrogateLead=0x00;
*err = U_INVALID_CHAR_FOUND;
reason =UCNV_UNASSIGNED;
} else {
reason=UCNV_ILLEGAL;
*err=U_ILLEGAL_CHAR_FOUND;
}
} else {
*err = U_ZERO_ERROR;
break;
}
} else {
reason=UCNV_ILLEGAL;
*err=U_ILLEGAL_CHAR_FOUND;
}
}
args->converter->fromUnicodeStatus = (int32_t)isTargetByteDBCS;
fromUnicodeCallback(args,sourceChar,&source,&target,&offsets,reason,err);
isTargetByteDBCS=(UBool)args->converter->fromUnicodeStatus;
if (U_FAILURE (*err)){
break;
}
}
}
else{
*err =U_BUFFER_OVERFLOW_ERROR;
break;
}
}
if (args->converter->fromUSurrogateLead !=0 && (source == sourceLimit) && args->flush){
*err = U_TRUNCATED_CHAR_FOUND;
}
if( (source == sourceLimit) && args->flush){
setInitialStateFromUnicodeKR(args->converter,converterData);
}
args->source = source;
args->target = (char*)target;
args->converter->fromUnicodeStatus = (uint32_t)isTargetByteDBCS;
}
static void
UConverter_toUnicode_ISO_2022_KR_OFFSETS_LOGIC_IBM(UConverterToUnicodeArgs *args,
UErrorCode* err){
const char* mySourceLimit;
char const* sourceStart;
UConverter* saveThis;
int plane =0;
UConverterDataISO2022* myData=(UConverterDataISO2022*)(args->converter->extraInfo);
do{
mySourceLimit = getEndOfBuffer_2022(&(args->source), args->sourceLimit, args->flush);
if (args->converter->mode == UCNV_SO) {
saveThis = args->converter;
args->offsets = NULL;
args->converter = myData->currentConverter;
_MBCSToUnicodeWithOffsets(args,err);
if(U_FAILURE(*err)){
uprv_memcpy(saveThis->invalidUCharBuffer, args->converter->invalidUCharBuffer,
args->converter->invalidUCharLength);
saveThis->invalidUCharLength=args->converter->invalidUCharLength;
}
args->converter = saveThis;
}
if (U_FAILURE(*err) || (args->source == args->sourceLimit))
return;
sourceStart = args->source;
changeState_2022(args->converter,
&(args->source),
args->sourceLimit,
TRUE,
ISO_2022_KR,
&plane,
err);
}while(args->source < args->sourceLimit);
}
static void
UConverter_toUnicode_ISO_2022_KR_OFFSETS_LOGIC(UConverterToUnicodeArgs *args,
UErrorCode* err){
char tempBuf[3];
const char* pBuf;
const char *mySource = ( char *) args->source;
UChar *myTarget = args->target;
const char *mySourceLimit = args->sourceLimit;
UChar32 targetUniChar = 0x0000;
UChar mySourceChar = 0x0000;
UConverterDataISO2022* myData;
int plane =0;
UConverterSharedData* sharedData ;
UBool useFallback;
if ((args->converter == NULL) || (args->targetLimit < args->target) || (args->sourceLimit < args->source)){
*err = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
myData=(UConverterDataISO2022*)(args->converter->extraInfo);
sharedData = myData->fromUnicodeConverter->sharedData;
useFallback = args->converter->useFallback;
if(myData->version==1){
UConverter_toUnicode_ISO_2022_KR_OFFSETS_LOGIC_IBM(args,err);
return;
}
while(mySource< args->sourceLimit){
targetUniChar = missingCharMarker;
if(myTarget < args->targetLimit){
mySourceChar= (unsigned char) *mySource++;
if(mySourceChar==UCNV_SI){
myData->currentType = SBCS;
continue;
}else if(mySourceChar==UCNV_SO){
myData->currentType = DBCS;
continue;
}else if(mySourceChar==ESC_2022 || myData->key!=0){
mySource--;
changeState_2022(args->converter,&(mySource),
args->sourceLimit, args->flush,ISO_2022_KR,&plane, err);
if(U_FAILURE(*err)){
args->target = myTarget;
args->source = mySource;
return;
}
continue;
}
if(myData->currentType==DBCS){
if(args->converter->toUnicodeStatus == 0x00){
args->converter->toUnicodeStatus = (UChar) mySourceChar;
continue;
}
else{
tempBuf[0] = (char) (args->converter->toUnicodeStatus+0x80);
tempBuf[1] = (char) (mySourceChar+0x80);
mySourceChar = (UChar)(mySourceChar + (args->converter->toUnicodeStatus<<8));
args->converter->toUnicodeStatus =0x00;
pBuf = tempBuf;
targetUniChar = _MBCSSimpleGetNextUChar(sharedData,
&pBuf,(pBuf+2),useFallback);
}
}
else{
if(args->converter->fromUnicodeStatus == 0x00){
targetUniChar = _MBCS_SINGLE_SIMPLE_GET_NEXT_BMP(sharedData, mySourceChar);
}
}
if(targetUniChar != missingCharMarker){
if(args->offsets)
args->offsets[myTarget - args->target]= mySource - args->source - 1-(myData->currentType==DBCS);
*(myTarget++)=(UChar)targetUniChar;
}
else {
toUnicodeCallback(args,mySourceChar,&mySource,targetUniChar,&myTarget,err);
if(U_FAILURE(*err)){
break;
}
}
}
else{
*err =U_BUFFER_OVERFLOW_ERROR;
break;
}
}
if((args->flush==TRUE)
&& (mySource == mySourceLimit)
&& ( args->converter->toUnicodeStatus !=0x00)){
*err = U_TRUNCATED_CHAR_FOUND;
args->converter->toUnicodeStatus = 0x00;
}
if( (mySource == mySourceLimit) && args->flush){
setInitialStateToUnicodeKR(args->converter,myData);
}
args->target = myTarget;
args->source = mySource;
}
static const char EMPTY_STR[] = "";
static const char SHIFT_IN_STR[] = "\x0F";
static const char SHIFT_OUT_STR[] = "\x0E";
static const char GB_2312_80_STR[] = "\x1B\x24\x29\x41";
static const char ISO_IR_165_STR[] = "\x1B\x24\x29\x45";
static const char CNS_11643_1992_Plane_1_STR[] = "\x1B\x24\x29\x47";
static const char CNS_11643_1992_Plane_2_STR[] = "\x1B\x24\x2A\x48";
static const char CNS_11643_1992_Plane_3_STR[] = "\x1B\x24\x2B\x49";
static const char CNS_11643_1992_Plane_4_STR[] = "\x1B\x24\x2B\x4A";
static const char CNS_11643_1992_Plane_5_STR[] = "\x1B\x24\x2B\x4B";
static const char CNS_11643_1992_Plane_6_STR[] = "\x1B\x24\x2B\x4C";
static const char CNS_11643_1992_Plane_7_STR[] = "\x1B\x24\x2B\x4D";
static const char* const escSeqCharsCN[10] ={
SHIFT_IN_STR,
GB_2312_80_STR,
ISO_IR_165_STR,
CNS_11643_1992_Plane_1_STR,
CNS_11643_1992_Plane_2_STR,
CNS_11643_1992_Plane_3_STR,
CNS_11643_1992_Plane_4_STR,
CNS_11643_1992_Plane_5_STR,
CNS_11643_1992_Plane_6_STR,
CNS_11643_1992_Plane_7_STR
};
static const int escSeqCharsLenCN[10] = {
1,
4,
4,
4,
4,
4,
4,
4,
4,
4
};
static const char* const shiftSeqCharsCN[10] ={
EMPTY_STR,
SHIFT_OUT_STR,
SHIFT_OUT_STR,
SHIFT_OUT_STR,
UCNV_SS2,
UCNV_SS3,
UCNV_SS3,
UCNV_SS3,
UCNV_SS3,
UCNV_SS3
};
static const int shiftSeqCharsLenCN[10] ={
0,
1,
1,
1,
2,
2,
2,
2,
2,
2
};
typedef enum {
ASCII_1=0,
GB2312_1=1,
ISO_IR_165=2,
CNS_11643=3,
INVALID_STATE_CN=-1
} StateEnumCN;
static const Cnv2022Type myConverterTypeCN[4]={
ASCII1,
DBCS,
DBCS,
MBCS
};
static void
UConverter_fromUnicode_ISO_2022_CN_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args, UErrorCode* err){
UConverterDataISO2022 *converterData;
unsigned char* target = (unsigned char*) args->target;
const unsigned char* targetLimit = (const unsigned char*) args->targetLimit;
const UChar* source = args->source;
const UChar* sourceLimit = args->sourceLimit;
int32_t* offsets = args->offsets;
uint32_t targetByteUnit = missingCharMarker;
uint32_t sourceChar =0x0000;
const char* escSeq = NULL;
int len =0;
uint32_t targetValue=0;
uint8_t planeVal=0;
UConverterCallbackReason reason;
UConverterSharedData* sharedData=NULL;
UBool useFallback;
StateEnumCN* currentState;
StateEnumCN initIterState;
UConverter** currentConverter;
UBool* isShiftAppended;
UBool* isEscapeAppended;
int* plane;
int lPlane=0;
if ((args->converter == NULL) || (targetLimit < target) || (sourceLimit < source)){
*err = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
converterData = (UConverterDataISO2022*)args->converter->extraInfo;
useFallback = args->converter->useFallback;
currentState = (StateEnumCN*)&converterData->fromUnicodeCurrentState;
initIterState = ASCII_1;
currentConverter = &converterData->fromUnicodeConverter;
isShiftAppended = &converterData->isShiftAppended;
isEscapeAppended = &converterData->isEscapeAppended;
plane = &converterData->plane;
initIterState = *currentState;
*currentConverter = converterData->myConverterArray[(*currentConverter==NULL) ? 0 : (int)*currentState];
sharedData = (*currentConverter)->sharedData;
if(args->converter->fromUSurrogateLead!=0 && target< targetLimit) {
goto getTrail;
}
while( source < sourceLimit){
targetByteUnit =missingCharMarker;
lPlane =0;
if(target < targetLimit){
sourceChar = *(source++);
if(UTF_IS_SURROGATE(sourceChar)) {
if(UTF_IS_SURROGATE_FIRST(sourceChar)) {
args->converter->fromUSurrogateLead=(UChar)sourceChar;
getTrail:
if(source < sourceLimit) {
UChar trail=(UChar) *source;
if(UTF_IS_SECOND_SURROGATE(trail)) {
source++;
sourceChar=UTF16_GET_PAIR_VALUE(args->converter->fromUSurrogateLead, trail);
args->converter->fromUSurrogateLead=0x00;
} else {
reason=UCNV_ILLEGAL;
*err=U_ILLEGAL_CHAR_FOUND;
goto callback;
}
} else {
break;
}
} else {
reason=UCNV_ILLEGAL;
*err=U_ILLEGAL_CHAR_FOUND;
goto callback;
}
}
if(sourceChar < 0x007f ){
targetByteUnit = sourceChar;
if(*currentState!= ASCII_1){
*currentState = ASCII_1;
*isEscapeAppended = FALSE;
}
}
else{
do{
if(myConverterTypeCN[*currentState] == MBCS){
MBCS_FROM_UCHAR32_ISO2022(sharedData,sourceChar,&targetValue,useFallback,&len,MBCS_OUTPUT_3);
if(len==3){
targetByteUnit = (UChar32) targetValue;
planeVal = (uint8_t) ((targetValue)>>16);
if(planeVal >0x80 && planeVal<0x89){
lPlane = (int)(planeVal - 0x80);
targetByteUnit -= (planeVal<<16);
}else {
lPlane =-1;
targetByteUnit=missingCharMarker;
}
if(converterData->version == 0 && lPlane >2){
targetByteUnit = missingCharMarker;
}
}
}else if(myConverterTypeCN[*currentState] == DBCS){
MBCS_FROM_UCHAR32_ISO2022(sharedData,sourceChar,&targetValue,useFallback,&len,MBCS_OUTPUT_2);
if(len==2){
if(( converterData->version) == 0 && *currentState ==ISO_IR_165){
targetByteUnit = missingCharMarker;
}else{
targetByteUnit = (UChar32) targetValue;
}
}
}else{
if(sourceChar < 0x7f){
targetByteUnit = sourceChar;
}
}
if(targetByteUnit==missingCharMarker){
*currentState=(StateEnumCN)((*currentState<3)? *currentState+1:0);
*currentConverter =converterData->myConverterArray[(*currentConverter==NULL) ? 0 : (int)*currentState];
targetByteUnit =missingCharMarker;
*isEscapeAppended = FALSE;
*isShiftAppended = FALSE;
sharedData=(*currentConverter)->sharedData;
}
else
break;
}while(initIterState != *currentState);
}
if(targetByteUnit != missingCharMarker){
args->converter->fromUnicodeStatus=(UBool) (*currentState > ASCII_1);
if(!*isEscapeAppended ||(*plane != lPlane)){
int temp =0;
temp =(*currentState==CNS_11643) ? ((int)*currentState+lPlane-1):(int)*currentState ;
escSeq = escSeqCharsCN[temp];
len =escSeqCharsLenCN[temp];
CONCAT_ESCAPE_EX(args,source, &target, targetLimit, &offsets, escSeq,len,err);
*plane=lPlane;
*isEscapeAppended=TRUE;
*isShiftAppended=FALSE;
}
if(*currentState == GB2312_1 || *currentState==ISO_IR_165){
if(!*isShiftAppended){
len =shiftSeqCharsLenCN[*currentState];
escSeq = shiftSeqCharsCN[*currentState];
CONCAT_ESCAPE_EX(args,source, &target, targetLimit, &offsets, escSeq,len,err);
*isShiftAppended=TRUE;
}
}else if(*currentState!=ASCII1){
int temp =*currentState+*plane-1;
if(*plane ==1 && *isShiftAppended){
temp=0;
}
len =shiftSeqCharsLenCN[temp];
escSeq = shiftSeqCharsCN[temp];
CONCAT_ESCAPE_EX(args,source, &target, targetLimit, &offsets, escSeq,len,err);
*isShiftAppended=TRUE;
}
initIterState = *currentState;
if(targetByteUnit <= 0x00FF){
if( target <targetLimit){
*(target++) = (unsigned char) targetByteUnit;
if(offsets){
*(offsets++) =source-args->source-1;
}
}else{
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) targetByteUnit;
*err = U_BUFFER_OVERFLOW_ERROR;
}
}else{
if(target < targetLimit){
*(target++) =(unsigned char) (targetByteUnit>>8);
if(offsets){
*(offsets++) = source-args->source-1;
}
if(target < targetLimit){
*(target++) =(unsigned char) (targetByteUnit);
if(offsets){
*(offsets++) = source-args->source-1;
}
}else{
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) (targetByteUnit);
*err = U_BUFFER_OVERFLOW_ERROR;
}
}else{
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) (targetByteUnit>>8);
args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (unsigned char) (targetByteUnit);
*err = U_BUFFER_OVERFLOW_ERROR;
}
}
}
else{
reason = UCNV_UNASSIGNED;
*err = U_INVALID_CHAR_FOUND;
callback:
fromUnicodeCallback(args,sourceChar,&source,&target,&offsets,reason,err);
initIterState = *currentState;
if (U_FAILURE (*err)){
break;
}
}
}
else{
*err =U_BUFFER_OVERFLOW_ERROR;
break;
}
}
if (args->converter->fromUSurrogateLead !=0 && (source == sourceLimit) && args->flush){
*err = U_TRUNCATED_CHAR_FOUND;
}
if( (source == sourceLimit) && args->flush){
setInitialStateFromUnicodeJPCN(args->converter,converterData);
}
args->source = source;
args->target = (char*)target;
}
static const StateEnumCN nextStateToUnicodeCN[2][MAX_STATES_2022]= {
{
INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,GB2312_1 ,INVALID_STATE_CN ,INVALID_STATE_CN
,CNS_11643 ,CNS_11643 ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
},
{
INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,GB2312_1 ,INVALID_STATE_CN ,ISO_IR_165
,CNS_11643 ,CNS_11643 ,CNS_11643 ,CNS_11643 ,CNS_11643 ,CNS_11643 ,CNS_11643 ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN ,INVALID_STATE_CN
}
};
static void
changeState_2022(UConverter* _this,
const char** source,
const char* sourceLimit,
UBool flush,Variant2022 var,
int* plane,
UErrorCode* err){
UConverter* myUConverter;
UCNV_TableStates_2022 value;
UConverterDataISO2022* myData2022 = ((UConverterDataISO2022*)_this->extraInfo);
uint32_t key = myData2022->key;
const char* chosenConverterName = NULL;
int32_t offset;
do{
value = getKey_2022(**source,(int32_t *) &key, &offset);
switch (value){
case VALID_NON_TERMINAL_2022 :
break;
case VALID_TERMINAL_2022:
{
(*source)++;
chosenConverterName = escSeqStateTable_Result_2022[offset];
key = 0;
goto DONE;
};
break;
case INVALID_2022:
{
myData2022->key = 0;
*err = U_ILLEGAL_ESCAPE_SEQUENCE;
return;
}
case VALID_SS2_SEQUENCE:
case VALID_SS3_SEQUENCE:
{
(*source)++;
key = 0;
goto DONE;
}
case VALID_MAYBE_TERMINAL_2022:
{
const char* mySource = (*source+1);
int32_t myKey = key;
UCNV_TableStates_2022 myValue = value;
int32_t myOffset=0;
if(*mySource==ESC_2022){
while ((mySource < sourceLimit) &&
((myValue == VALID_MAYBE_TERMINAL_2022)||(myValue == VALID_NON_TERMINAL_2022))){
myValue = getKey_2022(*(mySource++), &myKey, &myOffset);
}
}
else{
(*source)++;
myValue=(UCNV_TableStates_2022) 1;
myOffset = 8;
}
switch (myValue){
case INVALID_2022:
{
chosenConverterName = escSeqStateTable_Result_2022[offset];
value = VALID_TERMINAL_2022;
goto DONE;
};
break;
case VALID_TERMINAL_2022:
{
chosenConverterName = escSeqStateTable_Result_2022[myOffset];
key = 0;
value = VALID_TERMINAL_2022;
goto DONE;
};
break;
case VALID_SS2_SEQUENCE:
case VALID_SS3_SEQUENCE:
{
(*source)++;
key = 0;
goto DONE;
}
case VALID_NON_TERMINAL_2022:
case VALID_MAYBE_TERMINAL_2022:
{
if (flush){
chosenConverterName = escSeqStateTable_Result_2022[offset];
value = VALID_TERMINAL_2022;
key = 0;
goto DONE;
}
else{
key = myKey;
value = VALID_NON_TERMINAL_2022;
}
};
break;
};
break;
};
break;
}
}while (++(*source) < sourceLimit);
DONE:
myData2022->key = key;
if(offset<57 && offset>49){
*plane = offset-49;
}
if ((value == VALID_NON_TERMINAL_2022) || (value == VALID_MAYBE_TERMINAL_2022)) {
return;
}
else if (value != INVALID_2022 ) {
if(value==3 || value==4 ){
_this->mode = UCNV_SI;
myUConverter =myData2022->currentConverter;
}
else{
switch(var){
case ISO_2022:
_this->mode = UCNV_SI;
ucnv_close(myData2022->currentConverter);
myData2022->currentConverter = myUConverter = ucnv_open(chosenConverterName, err);
break;
case ISO_2022_JP:
{
StateEnum tempState=nextStateToUnicodeJP[myData2022->version][offset];
_this->mode = UCNV_SI;
myData2022->currentConverter = myUConverter =
(tempState!=INVALID_STATE)? myData2022->myConverterArray[tempState]:NULL;
myData2022->toUnicodeCurrentState = tempState;
*err= (tempState==INVALID_STATE)?U_ILLEGAL_ESCAPE_SEQUENCE :U_ZERO_ERROR;
}
break;
case ISO_2022_CN:
{
StateEnumCN tempState=nextStateToUnicodeCN[myData2022->version][offset];
_this->mode = UCNV_SI;
myData2022->currentConverter = myUConverter =
(tempState!=INVALID_STATE)? myData2022->myConverterArray[tempState]:NULL;
myData2022->toUnicodeCurrentState =(StateEnum) tempState;
*err= (tempState==INVALID_STATE)?U_ILLEGAL_ESCAPE_SEQUENCE :U_ZERO_ERROR;
}
break;
case ISO_2022_KR:
if(offset==0x30){
_this->mode = UCNV_SI;
myUConverter = myData2022->currentConverter=myData2022->fromUnicodeConverter;
break;
}
default:
myUConverter=NULL;
*err = U_ILLEGAL_ESCAPE_SEQUENCE;
}
}
if (U_SUCCESS(*err)){
myUConverter->fromUCharErrorBehaviour = _this->fromUCharErrorBehaviour;
myUConverter->fromUContext = _this->fromUContext;
myUConverter->fromCharErrorBehaviour = _this->fromCharErrorBehaviour;
myUConverter->toUContext = _this->toUContext;
uprv_memcpy(myUConverter->subChar,
_this->subChar,
myUConverter->subCharLen = _this->subCharLen);
myUConverter->subChar1 = 0;
_this->mode = UCNV_SO;
}
}
}
static void
UConverter_toUnicode_ISO_2022_CN_OFFSETS_LOGIC(UConverterToUnicodeArgs *args,
UErrorCode* err){
char tempBuf[3];
int plane=0;
const char* pBuf;
const char *mySource = ( char *) args->source;
UChar *myTarget = args->target;
char *tempLimit = &tempBuf[3];
const char *mySourceLimit = args->sourceLimit;
uint32_t targetUniChar = 0x0000;
uint32_t mySourceChar = 0x0000;
UConverterDataISO2022* myData;
if ((args->converter == NULL) || (args->targetLimit < myTarget) || (args->sourceLimit < mySource)){
*err = U_ILLEGAL_ARGUMENT_ERROR;
return;
}
myData=(UConverterDataISO2022*)(args->converter->extraInfo);
plane=myData->plane;
while(mySource< args->sourceLimit){
targetUniChar =missingCharMarker;
if(myTarget < args->targetLimit){
mySourceChar= (unsigned char) *mySource++;
switch(mySourceChar){
case UCNV_SI:
if(args->converter->toUnicodeStatus != 0x00){
break;
}
myData->currentType = ASCII1;
myData->plane=plane = 0;
continue;
case UCNV_SO:
if(args->converter->toUnicodeStatus != 0x00){
break;
}
myData->currentType = MBCS;
continue;
case CR:
case LF:
if(args->converter->toUnicodeStatus != 0x00){
break;
}
myData->currentType = ASCII1;
myData->plane=plane = 0;
default:
if(myData->key==0){
if(myData->currentType != ASCII1){
if(args->converter->toUnicodeStatus == 0x00){
args->converter->toUnicodeStatus = (UChar) mySourceChar;
continue;
}
else{
if(plane >0){
tempBuf[0] = (char) (0x80+plane);
tempBuf[1] = (char) (args->converter->toUnicodeStatus);
tempBuf[2] = (char) (mySourceChar);
tempLimit = &tempBuf[2]+1;
}else{
tempBuf[0] = (char) args->converter->toUnicodeStatus;
tempBuf[1] = (char) mySourceChar;
tempLimit = &tempBuf[2];
}
mySourceChar+= (uint32_t) args->converter->toUnicodeStatus<<8;
args->converter->toUnicodeStatus = 0;
pBuf = tempBuf;
if(myData->currentConverter!=NULL){
targetUniChar = _MBCSSimpleGetNextUChar(myData->currentConverter->sharedData, &pBuf, tempLimit, FALSE);
}else{
*err=U_INVALID_CHAR_FOUND;
break;
}
}
}
else{
if(args->converter->toUnicodeStatus == 0x00 && mySourceChar < 0x7f){
targetUniChar = (UChar) mySourceChar;
}
}
break;
}
case ESC_2022:
if(args->converter->toUnicodeStatus != 0x00){
break;
}
mySource--;
changeState_2022(args->converter,&(mySource),
args->sourceLimit, args->flush,ISO_2022_CN,&plane,err);
myData->plane=plane;
if(plane>0){
myData->currentType = MBCS;
}else{
myData->currentType=DBCS;
}
if(U_FAILURE(*err)){
args->target = myTarget;
args->source = mySource;
return;
}
continue;
}
if(targetUniChar < (missingCharMarker-1)){
if(args->offsets){
args->offsets[myTarget - args->target]= mySource - args->source - 2
+(myData->currentType==ASCII);
}
*(myTarget++)=(UChar)targetUniChar;
}
else if(targetUniChar > missingCharMarker){
targetUniChar-=0x0010000;
*(myTarget++) = (UChar)(0xd800+(UChar)(targetUniChar>>10));
if(args->offsets){
args->offsets[myTarget - args->target]= mySource - args->source - 2
+(myData->currentType==ASCII);
}
if(myTarget< args->targetLimit){
*(myTarget)++ = (UChar)(0xdc00+(UChar)(targetUniChar&0x3ff));
if(args->offsets){
args->offsets[myTarget - args->target]= mySource - args->source - 2
+(myData->currentType==ASCII);
}
}else{
args->converter->UCharErrorBuffer[args->converter->UCharErrorBufferLength++]=
(UChar)(0xdc00+(UChar)(targetUniChar&0x3ff));
}
}
else{
toUnicodeCallback(args,mySourceChar,&mySource,targetUniChar,&myTarget,err);
if(U_FAILURE(*err))
break;
}
}
else{
*err =U_BUFFER_OVERFLOW_ERROR;
break;
}
}
if((args->flush==TRUE)
&& (mySource == mySourceLimit)
&& ( args->converter->toUnicodeStatus !=0x00)){
*err = U_TRUNCATED_CHAR_FOUND;
args->converter->toUnicodeStatus = 0x00;
}
if( (mySource == mySourceLimit) && args->flush){
setInitialStateToUnicodeJPCN(args->converter,myData);
}
args->target = myTarget;
args->source = mySource;
}
static void
_ISO_2022_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *err) {
UConverter *cnv = args->converter;
UConverterDataISO2022 *myConverterData=(UConverterDataISO2022 *) cnv->extraInfo;
char *p;
char buffer[4];
p = buffer;
switch(myConverterData->locale[0]){
case 'j':
if(myConverterData->fromUnicodeCurrentState!= ASCII){
myConverterData->fromUnicodeCurrentState= ASCII;
myConverterData->currentType = (Cnv2022Type) myConverterType[myConverterData->fromUnicodeCurrentState];
*p++ = '\x1b';
*p++ = '\x28';
*p++ = '\x42';
}
*p++ = cnv->subChar[0];
break;
case 'c':
if(args->converter->fromUnicodeStatus) {
myConverterData->fromUnicodeCurrentState=ASCII;
*p++ = UCNV_SI;
}
*p++ = cnv->subChar[0];
break;
case 'k':
if(args->converter->fromUnicodeStatus){
args->converter->fromUnicodeStatus=0x00;
*p++= UCNV_SI;
}
*p++ = cnv->subChar[0];
default:
break;
}
ucnv_cbFromUWriteBytes(args,
buffer, (int32_t)(p - buffer),
offsetIndex, err);
}
struct cloneStruct
{
UConverter cnv;
UConverterDataISO2022 mydata;
UConverter currentCnv;
UConverter clonedConverters[1];
};
static UConverter *
_ISO_2022_SafeClone(
const UConverter *cnv,
void *stackBuffer,
int32_t *pBufferSize,
UErrorCode *status)
{
struct cloneStruct * localClone;
int32_t bufferSizeNeeded = sizeof(struct cloneStruct);
UConverterDataISO2022* cnvData = (UConverterDataISO2022*)cnv->extraInfo;
int32_t i;
int32_t sizes[UCNV_2022_MAX_CONVERTERS];
int32_t numConverters = 0;
int32_t currentConverterIndex = -1;
int32_t fromUnicodeConverterIndex = -1;
int32_t currentConverterSize = 0;
char *ptr;
if (U_FAILURE(*status)) {
return 0;
}
for(i=0;(i<UCNV_2022_MAX_CONVERTERS)&&cnvData->myConverterArray[i];i++) {
int32_t size;
size = 0;
ucnv_safeClone(cnvData->myConverterArray[i], NULL, &size, status);
bufferSizeNeeded += size;
sizes[i] = size;
numConverters++;
if(cnvData->currentConverter == cnvData->myConverterArray[i]) {
currentConverterIndex = i;
}
if(cnvData->fromUnicodeConverter == cnvData->myConverterArray[i]) {
fromUnicodeConverterIndex = i;
}
}
if(currentConverterIndex == -1) {
currentConverterSize = 0;
if(cnvData->currentConverter) {
ucnv_safeClone(cnvData->currentConverter, NULL, ¤tConverterSize, status);
bufferSizeNeeded += currentConverterSize;
}
}
for(;i<UCNV_2022_MAX_CONVERTERS;i++) {
sizes[i]=0;
}
if (*pBufferSize == 0) {
*pBufferSize = bufferSizeNeeded;
return 0;
}
if(*pBufferSize < bufferSizeNeeded) {
*status = U_BUFFER_OVERFLOW_ERROR;
return 0;
}
localClone = (struct cloneStruct *)stackBuffer;
uprv_memcpy(&localClone->cnv, cnv, sizeof(UConverter));
uprv_memcpy(&localClone->mydata, cnv->extraInfo, sizeof(UConverterDataISO2022));
ptr = (char*)&localClone->clonedConverters;
for(i=0;i<numConverters;i++) {
int32_t size;
size = sizes[i];
localClone->mydata.myConverterArray[i] = ucnv_safeClone(cnvData->myConverterArray[i], (UConverter*)ptr, &size, status);
ptr += size;
}
for(;i<UCNV_2022_MAX_CONVERTERS;i++) {
localClone->mydata.myConverterArray[i] = NULL;
}
if(currentConverterIndex == -1) {
if(cnvData->currentConverter) {
localClone->mydata.currentConverter = ucnv_safeClone(cnvData->currentConverter, ptr, ¤tConverterSize, status);
ptr += currentConverterSize;
} else {
localClone->mydata.currentConverter = NULL;
}
} else {
localClone->mydata.currentConverter = localClone->mydata.myConverterArray[currentConverterIndex];
}
if(fromUnicodeConverterIndex != -1) {
localClone->mydata.fromUnicodeConverter = localClone->mydata.myConverterArray[fromUnicodeConverterIndex];
} else if(cnvData->currentConverter == cnvData->fromUnicodeConverter) {
localClone->mydata.fromUnicodeConverter = localClone->mydata.currentConverter;
} else {
localClone->mydata.fromUnicodeConverter = NULL;
}
localClone->cnv.extraInfo = &localClone->mydata;
return &localClone->cnv;
}
static void
_ISO_2022_GetUnicodeSet(const UConverter *cnv,
USet *set,
UConverterUnicodeSet which,
UErrorCode *pErrorCode)
{
int32_t i;
USet *cnvSet;
UConverterDataISO2022* cnvData;
if (U_FAILURE(*pErrorCode)) {
return;
}
if (cnv->sharedData == &_ISO2022Data) {
uset_addRange(set, 0, 0xd7FF);
uset_addRange(set, 0xE000, 0x10FFFF);
return;
}
cnvData = (UConverterDataISO2022*)cnv->extraInfo;
if (cnv->sharedData == &_ISO2022KRData && cnvData->currentConverter != NULL) {
ucnv_getUnicodeSet(cnvData->currentConverter, set, which, pErrorCode);
return;
}
cnvSet = uset_open(0, 0);
if (!cnvSet) {
*pErrorCode =U_MEMORY_ALLOCATION_ERROR;
return;
}
for (i=0; (i<UCNV_2022_MAX_CONVERTERS) && cnvData->myConverterArray[i]; i++) {
ucnv_getUnicodeSet(cnvData->myConverterArray[i], cnvSet, which, pErrorCode);
uset_addAll(set, cnvSet );
}
uset_close(cnvSet);
}
#endif