Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

925 lines
30 KiB

// ============================================================================
// Internet Character Set Conversion: Input from ISO-2022-JP
// ============================================================================
#include "private.h"
#include "fechrcnv.h"
#include "jisobj.h"
#include "codepage.h"
/******************************************************************************
************************** C O N S T R U C T O R **************************
******************************************************************************/
CInccJisIn::CInccJisIn(UINT uCodePage, int nCodeSet) : CINetCodeConverter(uCodePage, nCodeSet)
{
Reset(); // initialization
return ;
}
/******************************************************************************
******************************* R E S E T *********************************
******************************************************************************/
void CInccJisIn::Reset()
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
m_fShift = FALSE;
m_fJapan = FALSE;
m_fLeadByte = FALSE ;
m_tcLeadByte = 0 ;
m_nESCBytes = 0 ;
m_eEscState = JIS_ASCII ;
return ;
}
/******************************************************************************
************************* C O N V E R T C H A R *************************
******************************************************************************/
HRESULT CInccJisIn::ConvertChar(UCHAR tc, int cchSrc)
{
BOOL fDone = (this->*m_pfnConv)(tc);
if (fDone)
return S_OK;
else
return E_FAIL;
}
/******************************************************************************
***************************** C L E A N U P *****************************
******************************************************************************/
BOOL CInccJisIn::CleanUp()
{
return (this->*m_pfnCleanUp)();
}
/******************************************************************************
**************************** C O N V M A I N ****************************
******************************************************************************/
BOOL CInccJisIn::ConvMain(UCHAR tc)
{
BOOL fDone = TRUE;
switch (tc) {
case SO:
m_fShift = TRUE;
break;
case SI:
m_fShift = FALSE;
m_fLeadByte = FALSE;
break;
default:
if (m_fShift) {
fDone = Output(tc | 0x80);
// it may continue to convert to Unicode, so we need to know
// whether current byte is a lead byte or not
m_fLeadByte = ~m_fLeadByte ;
} else {
if (tc == ESC) {
m_pfnConv = ConvEsc;
m_pfnCleanUp = CleanUpEsc;
m_nESCBytes++;
} else {
if (m_fJapan) {
if (tc == '*') {
m_pfnConv = ConvStar;
m_pfnCleanUp = CleanUpStar;
} else {
m_pfnConv = ConvDoubleByte;
m_pfnCleanUp = CleanUpDoubleByte;
m_tcLeadByte = tc;
}
} else {
switch ( m_eEscState )
{
case JIS_ASCII:
fDone = Output(tc);
break ;
case JIS_Roman:
#if 0
if ( tc == 0x7e ) /* tilde in ACSII -> overline */
{
Output(0x81);
fDone = Output(0x50);
}
else
fDone = Output(tc);
#else
fDone = Output(tc);
#endif
break ;
case JIS_Kana:
fDone = Output(tc | 0x80 );
break ;
default:
fDone = Output(tc);
break ;
}
}
}
}
break;
}
return fDone;
}
/******************************************************************************
************************ C L E A N U P M A I N ************************
******************************************************************************/
BOOL CInccJisIn::CleanUpMain()
{
return TRUE;
}
/******************************************************************************
***************************** C O N V E S C *****************************
******************************************************************************/
BOOL CInccJisIn::ConvEsc(UCHAR tc)
{
switch (tc) {
case ISO2022_IN_CHAR:
m_pfnConv = ConvIsoIn;
m_pfnCleanUp = CleanUpIsoIn;
m_nESCBytes++;
return TRUE;
case ISO2022_OUT_CHAR:
m_pfnConv = ConvIsoOut;
m_pfnCleanUp = CleanUpIsoOut;
m_nESCBytes++;
return TRUE;
default:
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
m_nESCBytes = 0 ;
(void)Output(ESC);
if (SUCCEEDED(ConvertChar(tc)))
return TRUE;
else
return FALSE;
}
}
/******************************************************************************
************************* C L E A N U P E S C *************************
******************************************************************************/
BOOL CInccJisIn::CleanUpEsc()
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
return Output(ESC);
}
/******************************************************************************
************************** C O N V I S O I N **************************
******************************************************************************/
BOOL CInccJisIn::ConvIsoIn(UCHAR tc)
{
switch (tc) {
case ISO2022_IN_JP_CHAR1: /* 'B' */
case ISO2022_IN_JP_CHAR2: /* '@' */
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
m_fJapan = TRUE;
m_nESCBytes = 0 ;
return TRUE;
case ISO2022_IN_JP_CHAR3_1: /* '(' */
m_pfnConv = ConvIsoInJp;
m_pfnCleanUp = CleanUpIsoInJp;
m_nESCBytes++ ;
return TRUE;
default:
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
m_nESCBytes = 0 ;
(void)Output(ESC);
(void)ConvertChar(ISO2022_IN_CHAR);
if (SUCCEEDED(ConvertChar(tc)))
return TRUE;
else
return FALSE;
}
}
/******************************************************************************
********************** C L E A N U P I S O I N **********************
******************************************************************************/
BOOL CInccJisIn::CleanUpIsoIn()
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
(void)Output(ESC);
(void)ConvertChar(ISO2022_IN_CHAR);
return CleanUp();
}
/******************************************************************************
*********************** C O N V I S O I N J P ***********************
******************************************************************************/
BOOL CInccJisIn::ConvIsoInJp(UCHAR tc)
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
m_nESCBytes = 0 ;
if (tc == ISO2022_IN_JP_CHAR3_2) {
m_fJapan = TRUE;
return TRUE;
} else {
(void)Output(ESC);
(void)ConvertChar(ISO2022_IN_CHAR);
(void)ConvertChar(ISO2022_IN_JP_CHAR3_1);
if (SUCCEEDED(ConvertChar(tc)))
return TRUE;
else
return FALSE;
}
}
/******************************************************************************
******************* C L E A N U P I S O I N J P *******************
******************************************************************************/
BOOL CInccJisIn::CleanUpIsoInJp()
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
m_nESCBytes = 0 ;
(void)Output(ESC);
(void)ConvertChar(ISO2022_IN_CHAR);
(void)ConvertChar(ISO2022_IN_JP_CHAR3_1);
return CleanUp();
}
/******************************************************************************
************************* C O N V I S O O U T *************************
******************************************************************************/
BOOL CInccJisIn::ConvIsoOut(UCHAR tc)
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
m_nESCBytes = 0 ;
switch (tc) {
case ISO2022_OUT_JP_CHAR1: /* B */
m_fJapan = FALSE;
m_eEscState = JIS_ASCII ;
return TRUE;
case ISO2022_OUT_JP_CHAR2: /* J */
case ISO2022_OUT_JP_CHAR4: /* H */
m_fJapan = FALSE;
m_eEscState = JIS_Roman ;
return TRUE;
case ISO2022_OUT_JP_CHAR3: /* I */
m_fJapan = FALSE;
m_eEscState = JIS_Kana ;
return TRUE;
default:
(void)Output(ESC);
(void)ConvertChar(ISO2022_OUT_CHAR);
if (SUCCEEDED(ConvertChar(tc)))
return TRUE;
else
return FALSE;
}
}
/******************************************************************************
********************* C L E A N U P I S O O U T *********************
******************************************************************************/
BOOL CInccJisIn::CleanUpIsoOut()
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
m_nESCBytes = 0 ;
(void)Output(ESC);
(void)ConvertChar(ISO2022_OUT_CHAR);
return CleanUp();
}
/******************************************************************************
**************************** C O N V S T A R ****************************
******************************************************************************/
BOOL CInccJisIn::ConvStar(UCHAR tc)
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
return Output(tc | 0x80);
}
/******************************************************************************
************************ C L E A N U P S T A R ************************
******************************************************************************/
BOOL CInccJisIn::CleanUpStar()
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
return Output('*');
}
/******************************************************************************
********************* C O N V D O U B L E B Y T E *********************
******************************************************************************/
BOOL CInccJisIn::ConvDoubleByte(UCHAR tc)
{
BOOL bRet ;
UCHAR tcSJisLB;
UCHAR tcSJisTB;
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
tcSJisLB = ((m_tcLeadByte - 0x21) >> 1) + 0x81;
if (tcSJisLB > 0x9f)
tcSJisLB += 0x40;
tcSJisTB = tc + (m_tcLeadByte & 1 ? 0x1f : 0x7d);
if (tcSJisTB >= 0x7f)
tcSJisTB++;
(void)Output(tcSJisLB);
bRet = Output(tcSJisTB);
m_tcLeadByte = 0 ;
return bRet ;
}
/******************************************************************************
***************** C L E A N U P D O U B L E B Y T E *****************
******************************************************************************/
BOOL CInccJisIn::CleanUpDoubleByte()
{
BOOL bRet ;
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
bRet = Output(m_tcLeadByte);
m_tcLeadByte = 0 ;
return bRet ;
}
int CInccJisIn::GetUnconvertBytes()
{
if ( m_tcLeadByte || m_fLeadByte )
return 1 ;
else if ( m_nESCBytes )
return m_nESCBytes < 4 ? m_nESCBytes : 3 ;
else
return 0 ;
}
DWORD CInccJisIn::GetConvertMode()
{
// 0xC42C -> 50220 ISO-2022-JP
return ( m_fJapan ? 1 : 0 ) + ( m_fShift ? 2 : 0 ) | 0xC42C0000 ;
}
void CInccJisIn::SetConvertMode(DWORD mode)
{
Reset();
if ( mode & 0x00000001 )
m_fJapan = TRUE ;
if ( mode & 0x00000002 )
m_fShift = TRUE ;
return ;
}
// ============================================================================
// Internet Character Set Conversion: Output to ISO-2022-JP
// ============================================================================
#define VOICE_MARK_OFFSET 0xA0
#define VOICE_MARK_DEDF_OFFSET 0xC8
#if 0 // Shift JIS Table - not used
// this is the table used to determine whether the kana char is voiced sound markable
// if it is, what is the combined full width kana.
static WCHAR g_wVoiceMarkKana[48] =
{
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, */
/* a0-af */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8394, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
/* b0-bf */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x834B, 0x834D, 0x834f, 0x8351, 0x8353, 0x8355, 0x8357, 0x8359, 0x835B, 0x835D,
/* c0-cf */ 0x835F, 0x8361, 0x8364, 0x8366, 0x8368, 0x0, 0x0, 0x0, 0x0, 0x0, 0x836F, 0x8372, 0x8375, 0x8378, 0x837B, 0x0,
};
// special voiced sound mark '0xde' conversion
static WCHAR g_wMarkDEKana[16] =
{
/* c8-cf */ 0x0, 0x0, 0x836F, 0x8372, 0x8375, 0x8378, 0x837B, 0x0,
};
// special voiced sound mark '0xdf' conversion
static WCHAR g_wMarkDFKana[16] =
{
/* c8-cf */ 0x0, 0x0, 0x8370, 0x8373, 0x8376, 0x8379, 0x837C, 0x0,
};
// this is the table used to convert half width kana to full width kana
static WCHAR g_wFullWKana[64] =
{
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, */
/* a0-af */ 0x0, 0x8142, 0x8175, 0x8176, 0x8141, 0x8145, 0x8392, 0x8340, 0x8342, 0x8344, 0x8346, 0x8348, 0x8383, 0x8385, 0x8387, 0x8362,
/* b0-bf */ 0x815B, 0x8341, 0x8343, 0x8345, 0x8347, 0x8349, 0x834A, 0x834C, 0x834E, 0x8350, 0x8352, 0x8354, 0x8356, 0x8358, 0x835A, 0x835C,
/* c0-cf */ 0x835E, 0x8360, 0x8363, 0x8365, 0x8367, 0x8369, 0x836A, 0x836B, 0x836C, 0x836D, 0x836E, 0x8371, 0x8374, 0x8377, 0x837A, 0x837D,
/* d0-df */ 0x837E, 0x8380, 0x8381, 0x8382, 0x8384, 0x8386, 0x8388, 0x8389, 0x838A, 0x838B, 0x838C, 0x838D, 0x838F, 0x8393, 0x814A, 0x814B,
};
#endif
// JIS Table
// this is the table used to determine whether the kana char is voiced sound markable
// if it is, what is the combined full width kana.
static WCHAR g_wVoiceMarkKana[48] =
{
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, */
/* a0-af */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2574, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
/* b0-bf */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x252c, 0x252e, 0x2530, 0x2532, 0x2534, 0x2536, 0x2538, 0x253A, 0x253C, 0x253E,
/* c0-cf */ 0x2540, 0x2542, 0x2545, 0x2547, 0x2549, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2550, 0x2553, 0x2556, 0x2559, 0x255C, 0x0,
};
// special voiced sound mark '0xde' conversion
static WCHAR g_wMarkDEKana[16] =
{
/* c8-cf */ 0x0, 0x0, 0x2550, 0x2553, 0x2556, 0x2559, 0x255C, 0x0,
};
// special voiced sound mark '0xdf' conversion
static WCHAR g_wMarkDFKana[16] =
{
/* c8-cf */ 0x0, 0x0, 0x2551, 0x2554, 0x2557, 0x255A, 0x255D, 0x0,
};
// this is the table used to convert half width kana to full width kana
static WCHAR g_wFullWKana[64] =
{
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, */
/* a0-af */ 0x0, 0x2123, 0x2156, 0x2157, 0x2122, 0x2126, 0x2572, 0x2521, 0x2523, 0x2525, 0x2527, 0x2529, 0x2563, 0x2565, 0x2567, 0x2543,
/* b0-bf */ 0x213C, 0x2522, 0x2524, 0x2526, 0x2528, 0x252A, 0x252B, 0x252D, 0x252f, 0x2531, 0x2533, 0x2535, 0x2537, 0x2539, 0x253B, 0x253D,
/* c0-cf */ 0x253F, 0x2541, 0x2544, 0x2546, 0x2548, 0x254A, 0x254B, 0x254C, 0x254D, 0x254E, 0x254F, 0x2552, 0x2555, 0x2558, 0x255B, 0x255E,
/* d0-df */ 0x255F, 0x2560, 0x2561, 0x2562, 0x2564, 0x2566, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x256D, 0x256F, 0x2573, 0x212B, 0x212C,
};
/******************************************************************************
************************** C O N S T R U C T O R **************************
******************************************************************************/
CInccJisOut::CInccJisOut(UINT uCodePage, int nCodeSet, DWORD dwFlag, WCHAR *lpFallBack) : CINetCodeConverter(uCodePage, nCodeSet)
{
m_dwFlag = dwFlag;
// Per Office team's request, we should disable BESTFITCHARS feature for now.
m_dwFlag &= ~MLCONVCHARF_NOBESTFITCHARS;
m_lpFallBack = lpFallBack;
Reset(); // initialization
return ;
}
/******************************************************************************
******************************* R E S E T *********************************
******************************************************************************/
void CInccJisOut::Reset()
{
m_fDoubleByte = FALSE;
m_fKana = FALSE;
m_fJapan = FALSE;
m_fSaveByte = FALSE;
m_tcLeadByte = 0 ;
m_tcPrevByte = 0 ;
m_eKanaMode = SIO_MODE ;
return ;
}
/******************************************************************************
************************* C O N V E R T C H A R *************************
******************************************************************************/
HRESULT CInccJisOut::ConvertChar(UCHAR tc, int cchSrc)
{
BOOL fDone = TRUE;
HRESULT hr = S_OK;
if (!m_fDoubleByte) {
if ((tc >= 0x81 && tc <= 0x9f) || (tc >= 0xe0 && tc <= 0xfc )) {
// Switch to Double Byte Code
if (m_fKana) {
if ( SIO_MODE == m_eKanaMode )
fDone = Output(SI);
else if ( (FULL_MODE == m_eKanaMode) && !(m_dwFlag & MLCONVCHARF_NOBESTFITCHARS))
{
fDone = KanaCleanUp();
m_fJapan = TRUE; // in FULL mode, Kana are bouble byte code too.
}
m_fKana = FALSE;
}
if (!m_fJapan) {
(void)Output(ESC); // ESC $ B - JIS-83
(void)Output(ISO2022_IN_CHAR);
fDone = Output(ISO2022_IN_JP_CHAR1);
m_fJapan = TRUE;
}
m_fDoubleByte = TRUE;
m_tcLeadByte = tc;
} else if (tc >= 0xa1 && tc <= 0xdf) {
// Single Byte Katakana Code
if (m_fJapan) {
if ( (FULL_MODE == m_eKanaMode) && !(m_dwFlag & MLCONVCHARF_NOBESTFITCHARS))
m_fKana = TRUE; // no mode changing
else if ( (SIO_MODE == m_eKanaMode) || (FULL_MODE == m_eKanaMode))
{
(void)Output(ESC); // ESC ( B - ACSII
(void)Output(ISO2022_OUT_CHAR);
fDone = Output(ISO2022_OUT_JP_CHAR1);
}
m_fJapan = FALSE;
}
if (!m_fKana) {
switch ( m_eKanaMode )
{
case SIO_MODE :
fDone = Output(SO);
break ;
case ESC_MODE :
(void)Output(ESC); // ESC ( I - Kana mode
(void)Output(ISO2022_OUT_CHAR);
fDone = Output(ISO2022_OUT_JP_CHAR3);
break ;
case FULL_MODE :
// Don't switch if NO_BEST_FIT_CHAR
if (!(m_dwFlag & MLCONVCHARF_NOBESTFITCHARS))
{
(void)Output(ESC); // ESC $ B - JIS 83
(void)Output(ISO2022_IN_CHAR);
fDone = Output(ISO2022_IN_JP_CHAR1);
}
break;
}
m_fKana = TRUE;
}
if ( FULL_MODE == m_eKanaMode )
{
hr = ConvFullWidthKana(tc);
if (SUCCEEDED(hr))
fDone = TRUE;
else
fDone = FALSE;
}
else
fDone = Output(tc & 0x7f);
} else {
// Single Byte Code
if (m_fKana) {
if ( SIO_MODE == m_eKanaMode )
fDone = Output(SI);
else {
if ( FULL_MODE == m_eKanaMode )
fDone = KanaCleanUp();
(void)Output(ESC); // ESC ( B - ACSII
(void)Output(ISO2022_OUT_CHAR);
fDone = Output(ISO2022_OUT_JP_CHAR1);
}
m_fKana = FALSE;
}
if (m_fJapan) {
(void)Output(ESC); // ESC ( B - ACSII
(void)Output(ISO2022_OUT_CHAR);
fDone = Output(ISO2022_OUT_JP_CHAR1);
m_fJapan = FALSE;
}
fDone = Output(tc);
}
} else {
// map extended char (0xfa40-0xfc4b) to a special range
if (m_tcLeadByte >= 0xfa && m_tcLeadByte <= 0xfc && tc >= 0x40 )
{
WCHAR wcDBCS ;
wcDBCS = ((WCHAR) m_tcLeadByte ) << 8 | tc ;
if ( wcDBCS >= 0xfa40 && wcDBCS <= 0xfa5b )
{
if ( wcDBCS <= 0xfa49 )
wcDBCS = wcDBCS - 0x0b51 ;
else if ( wcDBCS >= 0xfa4a && wcDBCS <= 0xfa53 )
wcDBCS = wcDBCS - 0x072f6 ;
else if ( wcDBCS >= 0xfa54 && wcDBCS <= 0xfa57 )
wcDBCS = wcDBCS - 0x0b5b ;
else if ( wcDBCS == 0xfa58 )
wcDBCS = 0x878a ;
else if ( wcDBCS == 0xfa59 )
wcDBCS = 0x8782 ;
else if ( wcDBCS == 0xfa5a )
wcDBCS = 0x8784 ;
else if ( wcDBCS == 0xfa5b )
wcDBCS = 0x879a ;
}
else if ( wcDBCS >= 0xfa5c && wcDBCS <= 0xfc4b )
{
if ( tc < 0x5c )
wcDBCS = wcDBCS - 0x0d5f;
else if ( tc >= 0x80 && tc <= 0x9B )
wcDBCS = wcDBCS - 0x0d1d;
else
wcDBCS = wcDBCS - 0x0d1c;
}
tc = (UCHAR) wcDBCS ;
m_tcLeadByte = (UCHAR) ( wcDBCS >> 8 ) ;
}
// Convert Double Byte Code
m_tcLeadByte -= ((m_tcLeadByte > 0x9f) ? 0xb1 : 0x71);
m_tcLeadByte = m_tcLeadByte * 2 + 1;
if (tc > 0x9e) {
tc -= 0x7e;
m_tcLeadByte++;
} else {
if (tc > 0x7e)
tc--;
tc -= 0x1f;
}
(void)Output(m_tcLeadByte);
fDone = Output(tc);
m_fDoubleByte = FALSE;
m_tcLeadByte = 0 ;
}
if (fDone)
return hr;
else
return E_FAIL;
}
/******************************************************************************
***************************** C L E A N U P *****************************
******************************************************************************/
BOOL CInccJisOut::CleanUp()
{
BOOL fDone = TRUE;
// Discard m_byLeadByte: if (m_fDoubleByte) Output(m_byLeadByte);
fDone = KanaCleanUp();
if (m_fKana)
{
if ( SIO_MODE == m_eKanaMode )
fDone = Output(SI);
else if (!(m_dwFlag & MLCONVCHARF_NOBESTFITCHARS)) // FULL mode and ESC mode
{
(void)Output(ESC); // ESC ( B - ASCII
(void)Output(ISO2022_OUT_CHAR);
fDone = Output(ISO2022_OUT_JP_CHAR1);
}
m_fKana = FALSE ;
}
if (m_fJapan) {
(void)Output(ESC); // ESC ( B - ASCII
(void)Output(ISO2022_OUT_CHAR);
fDone = Output(ISO2022_OUT_JP_CHAR1);
m_fJapan = FALSE ;
}
return fDone;
}
/******************************************************************************
************************* C O N V E R T C H A R *************************
******************************************************************************/
HRESULT CInccJisOut::ConvFullWidthKana(UCHAR tc)
{
BOOL fDone = TRUE ;
int index ;
WCHAR DoubleBytes ;
HRESULT hr = S_OK;
if (m_dwFlag & MLCONVCHARF_NOBESTFITCHARS)
{
UCHAR szDefaultChar[3] = {0x3f}; // possible DBCS + null
if (m_lpFallBack && (m_dwFlag & MLCONVCHARF_USEDEFCHAR))
{
// only take SBCS, no DBCS character
if ( 1 != WideCharToMultiByte(CP_JPN_SJ, 0,
(LPCWSTR)m_lpFallBack, 1,
(LPSTR)szDefaultChar, ARRAYSIZE(szDefaultChar), NULL, NULL ))
szDefaultChar[0] = 0x3f;
}
if (m_dwFlag & (MLCONVCHARF_NCR_ENTITIZE|MLCONVCHARF_NAME_ENTITIZE))
{
char szChar[2] = {0};
char szDstStr[10] = {0};
WCHAR szwChar[2];
int cCount;
szChar[0] = tc;
if (MultiByteToWideChar(CP_JPN_SJ, 0, szChar, -1, szwChar, ARRAYSIZE(szwChar)))
{
// Output NCR entity
Output('&');
Output('#');
_ultoa((unsigned long)szwChar[0], (char*)szDstStr, 10);
cCount = lstrlenA(szDstStr);
for (int i=0; i< cCount; i++)
{
Output(szDstStr[i]);
}
fDone = Output(';');
}
else
{
fDone = Output(szDefaultChar[0]); // use default char
hr = S_FALSE;
}
}
else
{
fDone = Output(szDefaultChar[0]); // use default char
hr = S_FALSE;
}
}
else
{
// voiced sound mark or semi-voiced sound mark
if ( m_fSaveByte && ( tc == 0xde || tc == 0xdf ) )
{
if ( m_tcPrevByte >= 0x0CA && m_tcPrevByte <= 0x0CE )
{
index = m_tcPrevByte - VOICE_MARK_DEDF_OFFSET ;
if ( tc == 0xde )
DoubleBytes = g_wMarkDEKana[index] ;
else
DoubleBytes = g_wMarkDFKana[index] ;
Output( (UCHAR) (DoubleBytes >> 8 ));
fDone = Output( (UCHAR) DoubleBytes );
m_fSaveByte = FALSE ;
m_tcPrevByte = '\0' ;
}
else
{
index = m_tcPrevByte - VOICE_MARK_OFFSET ;
// Invalid trail byte could cause buffer overrun, skip it
if (index < ARRAYSIZE(g_wVoiceMarkKana))
{
DoubleBytes = g_wVoiceMarkKana[index] ;
Output( (UCHAR) (DoubleBytes >> 8 ));
fDone = Output( (UCHAR) DoubleBytes );
m_fSaveByte = FALSE ;
m_tcPrevByte = '\0' ;
}
}
}
else
{
// output previous saved voice sound markable char
if ( m_fSaveByte )
{
index = m_tcPrevByte - VOICE_MARK_OFFSET ;
DoubleBytes = g_wFullWKana[index] ;
Output( (UCHAR) (DoubleBytes >> 8 ) );
fDone = Output( (UCHAR) DoubleBytes );
m_fSaveByte = FALSE ;
m_tcPrevByte = '\0' ;
}
// half width kana
if ( tc >= 0xa1 && tc <= 0xdf )
{
index = tc - VOICE_MARK_OFFSET ;
// check if this char can be combined with voice sound mark
if ( index < ARRAYSIZE(g_wVoiceMarkKana) && g_wVoiceMarkKana[index] )
{
m_fSaveByte = TRUE ;
m_tcPrevByte = tc ;
}
// convert half width kana to full width kana
else
{
DoubleBytes = g_wFullWKana[index] ;
Output( (UCHAR) ( DoubleBytes >> 8 ));
fDone = Output( (UCHAR) DoubleBytes );
}
}
else
fDone = Output(tc);
}
}
if (fDone)
return hr;
else
return E_FAIL;
}
/******************************************************************************
*************************** K A N A C L E A N U P ************************
******************************************************************************/
BOOL CInccJisOut::KanaCleanUp()
{
BOOL fDone = TRUE;
WCHAR DoubleBytes ;
int index ;
// output previous saved voice sound markable char
if ( m_fSaveByte )
{
index = m_tcPrevByte - VOICE_MARK_OFFSET ;
DoubleBytes = g_wFullWKana[index] ;
Output( (UCHAR) ( DoubleBytes >> 8 ));
fDone = Output( (UCHAR) DoubleBytes );
m_fSaveByte = FALSE ;
m_tcPrevByte = '\0' ;
}
return fDone;
}
int CInccJisOut::GetUnconvertBytes()
{
if ( m_tcLeadByte )
return 1 ;
else
return 0 ;
}
DWORD CInccJisOut::GetConvertMode()
{
return ( m_fJapan ? 1 : 0 ) + ( m_fKana ? 2 : 0 ) ;
}
void CInccJisOut::SetConvertMode(DWORD mode)
{
Reset();
if ( mode & 0x00000001 )
m_fJapan = TRUE ;
if ( mode & 0x00000002 )
m_fKana = TRUE ;
return ;
}
void CInccJisOut::SetKanaMode(UINT uCodePage)
{
switch ( uCodePage )
{
case CP_ISO_2022_JP_ESC:
m_eKanaMode = ESC_MODE ;
break ;
case CP_ISO_2022_JP_SIO:
m_eKanaMode = SIO_MODE ;
break ;
default :
m_eKanaMode = FULL_MODE ;
break ;
}
return ;
}