// ============================================================================ // 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 ; }