windows-nt/Source/XPSP1/NT/shell/ext/mlang/eucjobj.cpp
2020-09-26 16:20:57 +08:00

366 lines
11 KiB
C++

// ============================================================================
// Internet Character Set Conversion: Input from EUC-JP
// ============================================================================
#include "private.h"
#include "fechrcnv.h"
#include "eucjobj.h"
#include "codepage.h"
/******************************************************************************
************************** C O N S T R U C T O R **************************
******************************************************************************/
CInccEucJIn::CInccEucJIn(UINT uCodePage, int nCodeSet) : CINetCodeConverter(uCodePage, nCodeSet)
{
Reset(); // initialization
return ;
}
/******************************************************************************
******************************* R E S E T *********************************
******************************************************************************/
void CInccEucJIn::Reset()
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
m_tcLeadByte = 0 ;
return ;
}
/******************************************************************************
************************* C O N V E R T C H A R *************************
******************************************************************************/
HRESULT CInccEucJIn::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 CInccEucJIn::CleanUp()
{
return (this->*m_pfnCleanUp)();
}
/******************************************************************************
**************************** C O N V M A I N ****************************
******************************************************************************/
BOOL CInccEucJIn::ConvMain(UCHAR tc)
{
BOOL fDone = TRUE;
if (tc >= 0xa1 && tc <= 0xfe) {
m_pfnConv = ConvDoubleByte;
m_pfnCleanUp = CleanUpDoubleByte;
m_tcLeadByte = tc;
} else if (tc == 0x8e) { // Single Byte Katakana
m_pfnConv = ConvKatakana;
m_pfnCleanUp = CleanUpKatakana;
} else {
fDone = Output(tc);
}
return fDone;
}
/******************************************************************************
************************ C L E A N U P M A I N ************************
******************************************************************************/
BOOL CInccEucJIn::CleanUpMain()
{
return TRUE;
}
/******************************************************************************
********************* C O N V D O U B L E B Y T E *********************
******************************************************************************/
BOOL CInccEucJIn::ConvDoubleByte(UCHAR tc)
{
BOOL fRet ;
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
if (m_tcLeadByte <= 0xde) { // && m_tcLeadByte >= 0xa1
if (m_tcLeadByte % 2) // odd
(void)Output((m_tcLeadByte - 0xa1) / 2 + 0x81);
else // even
(void)Output((m_tcLeadByte - 0xa2) / 2 + 0x81);
} else { // m_tcLeadByte >= 0xdf && m_tcLeadByte <= 0xfe
if (m_tcLeadByte % 2) // odd
(void)Output((m_tcLeadByte - 0xdf) / 2 + 0xe0);
else // even
(void)Output((m_tcLeadByte - 0xe0) / 2 + 0xe0);
}
if (m_tcLeadByte % 2) { // odd
if (tc >= 0xa1 && tc <= 0xdf)
fRet = Output(tc - 0x61);
else
fRet = Output(tc - 0x60);
} else { // even
fRet = Output(tc - 2);
}
m_tcLeadByte = 0 ;
return fRet ;
}
/******************************************************************************
***************** C L E A N U P D O U B L E B Y T E *****************
******************************************************************************/
BOOL CInccEucJIn::CleanUpDoubleByte()
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
return TRUE;
}
/******************************************************************************
************************ C O N V K A T A K A N A ************************
******************************************************************************/
BOOL CInccEucJIn::ConvKatakana(UCHAR tc)
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
return Output(tc);
}
/******************************************************************************
******************** C L E A N U P K A T A K A N A ********************
******************************************************************************/
BOOL CInccEucJIn::CleanUpKatakana()
{
m_pfnConv = ConvMain;
m_pfnCleanUp = CleanUpMain;
return TRUE;
}
int CInccEucJIn::GetUnconvertBytes()
{
if (m_tcLeadByte || m_pfnConv == ConvKatakana)
return 1;
else
return 0;
}
DWORD CInccEucJIn::GetConvertMode()
{
// 0xCADC -> 51932 EUC-JP (codepage)
return 0xCADC0000 ;
}
void CInccEucJIn::SetConvertMode(DWORD mode)
{
Reset();
return ;
}
// ============================================================================
// Internet Character Set Conversion: Output to EUC-JP
// ============================================================================
/******************************************************************************
************************** C O N S T R U C T O R **************************
******************************************************************************/
CInccEucJOut::CInccEucJOut(UINT uCodePage, int nCodeSet, DWORD dwFlag, WCHAR *lpFallBack) : CINetCodeConverter(uCodePage, nCodeSet)
{
Reset(); // initialization
_dwFlag = dwFlag;
_lpFallBack = lpFallBack;
return ;
}
/******************************************************************************
******************************* R E S E T *********************************
******************************************************************************/
void CInccEucJOut::Reset()
{
m_fDoubleByte = FALSE;
m_tcLeadByte = 0 ;
return ;
}
/******************************************************************************
************************* C O N V E R T C H A R *************************
******************************************************************************/
HRESULT CInccEucJOut::ConvertChar(UCHAR tc, int cchSrc)
{
BOOL fDone = TRUE;
HRESULT hr = S_OK;
if (!m_fDoubleByte) {
if ((tc >= 0x81 && tc <= 0x9f) || (tc >= 0xe0 && tc <= 0xfc )) { // Double Byte Code
m_fDoubleByte = TRUE;
m_tcLeadByte = tc;
} else if (tc >= 0xa1 && tc <= 0xdf) { // Single Byte Katakana Code
(void) Output( (UCHAR) 0x8e);
fDone = Output(tc);
} else {
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 ) ;
}
// Do conversion
if (m_tcLeadByte <= 0xef) {
if (m_tcLeadByte <= 0x9f) { // && m_tcLeadByte >= 0x81
if (tc <= 0x9e)
(void)Output((m_tcLeadByte - 0x81) * 2 + 0xa1);
else
(void)Output((m_tcLeadByte - 0x81) * 2 + 0xa2);
} else { // m_tcLeadByte >= 0xe0 && m_tcLeadByte <= 0xef
if (tc <= 0x9e)
(void)Output((m_tcLeadByte - 0xe0) * 2 + 0xdf);
else
(void)Output((m_tcLeadByte - 0xe0) * 2 + 0xe0);
}
if (tc >= 0x40 && tc <= 0x7e)
fDone = Output(tc + 0x61);
else if (tc >= 0x80 && tc <= 0x9e)
fDone = Output(tc + 0x60);
else
fDone = Output(tc + 0x02);
} else if (m_tcLeadByte >= 0xfa) { // && m_tcLeadByte <= 0xfc; IBM Extended Char
UCHAR szDefaultChar[3] = {0x3f}; // possible DBCS + null
if (_lpFallBack && (_dwFlag & MLCONVCHARF_USEDEFCHAR))
{
// only take SBCS, no DBCS character
if ( 1 != WideCharToMultiByte(CP_JPN_SJ, 0,
(LPCWSTR)_lpFallBack, 1,
(LPSTR)szDefaultChar, ARRAYSIZE(szDefaultChar), NULL, NULL ))
szDefaultChar[0] = 0x3f;
}
if (_dwFlag & (MLCONVCHARF_NCR_ENTITIZE|MLCONVCHARF_NAME_ENTITIZE))
{
char szChar[2];
char szDstStr[10];
WCHAR szwChar[2];
int cCount;
szChar[0] = m_tcLeadByte;
szChar[1] = tc;
if (MultiByteToWideChar(CP_JPN_SJ, 0, szChar, 2, 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]);
hr = S_FALSE;
}
}
else
{
fDone = Output(szDefaultChar[0]);
hr = S_FALSE;
}
} else {
(void)Output(m_tcLeadByte);
fDone = Output(tc);
}
m_fDoubleByte = FALSE;
m_tcLeadByte = 0 ;
}
if (!fDone)
hr = E_FAIL;
return hr;
}
/******************************************************************************
***************************** C L E A N U P *****************************
******************************************************************************/
BOOL CInccEucJOut::CleanUp()
{
m_fDoubleByte = FALSE;
return TRUE;
}
int CInccEucJOut::GetUnconvertBytes()
{
if (m_tcLeadByte)
return 1;
else
return 0;
}
DWORD CInccEucJOut::GetConvertMode()
{
return 0 ;
}
void CInccEucJOut::SetConvertMode(DWORD mode)
{
Reset();
return ;
}