kscobj.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 13k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. // ============================================================================
  2. // Internet Character Set Conversion: Input from ISO-2022-KR
  3. // ============================================================================
  4. #include "private.h"
  5. #include "fechrcnv.h"
  6. #include "kscobj.h"
  7. #include "codepage.h"
  8. /******************************************************************************
  9. **************************   C O N S T R U C T O R   **************************
  10. ******************************************************************************/
  11. CInccKscIn::CInccKscIn(UINT uCodePage, int nCodeSet) : CINetCodeConverter(uCodePage, nCodeSet)
  12. {
  13.     Reset();    // initialization
  14.     return ;
  15. }
  16. /******************************************************************************
  17. *******************************   R E S E T   *********************************
  18. ******************************************************************************/
  19. void CInccKscIn::Reset()
  20. {
  21. m_pfnConv = ConvMain;
  22. m_pfnCleanUp = CleanUpMain;
  23. m_fShift = FALSE;
  24.     // BUGBUG: bug #57570, Korean ISP DACOM only labels one designator in the 
  25.     // conversion of a MIME mail. To decode the other part of MIME correctly, 
  26.     // we need to decode the ISO document or MIME message even there is no
  27.     // designator "esc ) C".
  28. m_fKorea = TRUE;
  29. m_nESCBytes = 0 ;
  30. m_fLeadByte = FALSE ;
  31.     return ;
  32. }
  33. /******************************************************************************
  34. *************************   C O N V E R T   C H A R   *************************
  35. ******************************************************************************/
  36. HRESULT CInccKscIn::ConvertChar(UCHAR tc, int cchSrc)
  37. {
  38. BOOL fDone = (this->*m_pfnConv)(tc);
  39.     if (fDone)
  40.         return S_OK;
  41.     else
  42.         return E_FAIL;
  43. }
  44. /******************************************************************************
  45. *****************************   C L E A N   U P   *****************************
  46. ******************************************************************************/
  47. BOOL CInccKscIn::CleanUp()
  48. {
  49. return (this->*m_pfnCleanUp)();
  50. }
  51. /******************************************************************************
  52. ****************************   C O N V   M A I N   ****************************
  53. ******************************************************************************/
  54. BOOL CInccKscIn::ConvMain(UCHAR tc)
  55. {
  56. BOOL fDone = TRUE;
  57. if (tc == ESC) {
  58. m_pfnConv = ConvEsc;
  59. m_pfnCleanUp = CleanUpEsc;
  60. m_nESCBytes++ ;
  61. } else {
  62. if (m_fKorea) {
  63. switch (tc) {
  64. case SO:
  65. m_fShift = TRUE;
  66. break;
  67. case SI:
  68. m_fShift = FALSE;
  69. m_fLeadByte = FALSE ;
  70. break;
  71. default:
  72. if (m_fShift) {
  73. switch (tc) {
  74. case ' ':
  75. case 't':
  76. case 'n':
  77. fDone = Output(tc);
  78. break;
  79. default:
  80. fDone = Output(tc | 0x80);
  81. m_fLeadByte = ~m_fLeadByte ;
  82. break;
  83. }
  84. } else {
  85. fDone = Output(tc);
  86. }
  87. break;
  88. }
  89. } else {
  90. fDone = Output(tc);
  91. }
  92. }
  93. return fDone;
  94. }
  95. /******************************************************************************
  96. ************************   C L E A N   U P   M A I N   ************************
  97. ******************************************************************************/
  98. BOOL CInccKscIn::CleanUpMain()
  99. {
  100. return TRUE;
  101. }
  102. /******************************************************************************
  103. *****************************   C O N V   E S C   *****************************
  104. ******************************************************************************/
  105. BOOL CInccKscIn::ConvEsc(UCHAR tc)
  106. {
  107. if (tc == ISO2022_IN_CHAR) {
  108. m_pfnConv = ConvIsoIn;
  109. m_pfnCleanUp = CleanUpIsoIn;
  110. m_nESCBytes++ ;
  111. return TRUE;
  112. } else {
  113. m_pfnConv = ConvMain;
  114. m_pfnCleanUp = CleanUpMain;
  115. m_nESCBytes = 0 ;
  116. (void)Output(ESC);
  117.         if (SUCCEEDED(ConvertChar(tc)))
  118.             return TRUE;
  119.         else
  120.             return FALSE;
  121.     }
  122. }
  123. /******************************************************************************
  124. *************************   C L E A N   U P   E S C   *************************
  125. ******************************************************************************/
  126. BOOL CInccKscIn::CleanUpEsc()
  127. {
  128. m_pfnConv = ConvMain;
  129. m_pfnCleanUp = CleanUpMain;
  130. m_nESCBytes = 0 ;
  131. return Output(ESC);
  132. }
  133. /******************************************************************************
  134. **************************   C O N V   I S O   I N   **************************
  135. ******************************************************************************/
  136. BOOL CInccKscIn::ConvIsoIn(UCHAR tc)
  137. {
  138. if (tc == ISO2022_IN_KR_CHAR_1) {
  139. m_pfnConv = ConvIsoInKr;
  140. m_pfnCleanUp = CleanUpIsoInKr;
  141. m_nESCBytes++ ;
  142. return TRUE;
  143. } else {
  144. m_pfnConv = ConvMain;
  145. m_pfnCleanUp = CleanUpMain;
  146. m_nESCBytes = 0 ;
  147. (void)Output(ESC);
  148. (void)ConvertChar(ISO2022_IN_CHAR);
  149.         if (SUCCEEDED(ConvertChar(tc)))
  150.             return TRUE;
  151.         else
  152.             return FALSE;
  153. }
  154. }
  155. /******************************************************************************
  156. **********************   C L E A N   U P   I S O   I N   **********************
  157. ******************************************************************************/
  158. BOOL CInccKscIn::CleanUpIsoIn()
  159. {
  160. m_pfnConv = ConvMain;
  161. m_pfnCleanUp = CleanUpMain;
  162.     m_nESCBytes = 0 ;
  163. (void)Output(ESC);
  164. (void)ConvertChar(ISO2022_IN_CHAR);
  165. return CleanUp();
  166. }
  167. /******************************************************************************
  168. ***********************   C O N V   I S O   I N   K R   ***********************
  169. ******************************************************************************/
  170. BOOL CInccKscIn::ConvIsoInKr(UCHAR tc)
  171. {
  172. m_pfnConv = ConvMain;
  173. m_pfnCleanUp = CleanUpMain;
  174.     m_nESCBytes = 0 ;
  175. if (tc == ISO2022_IN_KR_CHAR_2) {
  176. m_fKorea = TRUE;
  177. return TRUE;
  178. } else {
  179. (void)Output(ESC);
  180. (void)ConvertChar(ISO2022_IN_CHAR);
  181. (void)ConvertChar(ISO2022_IN_KR_CHAR_1);
  182.         if (SUCCEEDED(ConvertChar(tc)))
  183.             return TRUE;
  184.         else
  185.             return FALSE;
  186. }
  187. }
  188. /******************************************************************************
  189. *******************   C L E A N   U P   I S O   I N   K R   *******************
  190. ******************************************************************************/
  191. BOOL CInccKscIn::CleanUpIsoInKr()
  192. {
  193. m_pfnConv = ConvMain;
  194. m_pfnCleanUp = CleanUpMain;
  195.     m_nESCBytes = 0 ;
  196. (void)Output(ESC);
  197. (void)ConvertChar(ISO2022_IN_CHAR);
  198. (void)ConvertChar(ISO2022_IN_KR_CHAR_1);
  199. return CleanUp();
  200. }
  201. int CInccKscIn::GetUnconvertBytes()
  202. {
  203.     if ( m_fLeadByte )
  204.         return 1 ;
  205.     else if ( m_nESCBytes )
  206.         return m_nESCBytes < 4 ? m_nESCBytes : 3 ;
  207.     else
  208.         return 0 ;
  209. }
  210. DWORD CInccKscIn::GetConvertMode()
  211. {
  212.     // 0xC431 -> 50225 ISO-2022-KR
  213.     return ( m_fKorea ? 1 : 0 ) + ( m_fShift ? 2 : 0 ) | 0xC4310000 ;
  214. }
  215. void CInccKscIn::SetConvertMode(DWORD mode)
  216. {
  217.     Reset();    // initialization
  218.     if ( mode & 0x00000001 )
  219.         m_fKorea = TRUE ;
  220.     if ( mode & 0x00000002 ) 
  221.         m_fShift = TRUE ;
  222.     return ;
  223. }
  224. // ============================================================================
  225. // Internet Character Set Conversion: Output to ISO-2022-KSC
  226. // ============================================================================
  227. /******************************************************************************
  228. **************************   C O N S T R U C T O R   **************************
  229. ******************************************************************************/
  230. CInccKscOut::CInccKscOut(UINT uCodePage, int nCodeSet, DWORD dwFlag, WCHAR *lpFallBack) : CINetCodeConverter(uCodePage, nCodeSet)
  231. {
  232.     Reset();    // initialization
  233.     _dwFlag = dwFlag;
  234.     _lpFallBack = lpFallBack;
  235.     return ;
  236. }
  237. /******************************************************************************
  238. *******************************   R E S E T   *********************************
  239. ******************************************************************************/
  240. void CInccKscOut::Reset()
  241. {
  242. m_fDoubleByte = FALSE;
  243. m_fShift = FALSE;
  244. m_fKorea = FALSE;
  245. m_tcLeadByte = 0 ;
  246.     return ;
  247. }
  248. /******************************************************************************
  249. *************************   C O N V E R T   C H A R   *************************
  250. ******************************************************************************/
  251. HRESULT CInccKscOut::ConvertChar(UCHAR tc, int cchSrc)
  252. {
  253. BOOL fDone = TRUE;
  254.     HRESULT hr = S_OK;
  255.     // put designator to the top of the document
  256. if (!m_fKorea) {
  257. (void)Output(ESC);
  258. (void)Output(ISO2022_IN_CHAR);
  259. (void)Output(ISO2022_IN_KR_CHAR_1);
  260. (void)Output(ISO2022_IN_KR_CHAR_2);
  261. m_fKorea = TRUE;
  262. }
  263. if (!m_fDoubleByte) {
  264. if (tc > 0x80) {
  265. m_fDoubleByte = TRUE;
  266. m_tcLeadByte = tc;
  267. } else {
  268. if (m_fKorea && m_fShift) {
  269. (void)Output(SI);
  270. m_fShift = FALSE;
  271. }
  272. fDone = Output(tc);
  273. }
  274. } else {
  275. m_fDoubleByte = FALSE;
  276. if (tc > 0x40) { // Check if trail byte indicates Hangeul
  277. if (m_tcLeadByte > 0xa0 && tc > 0xa0) { // Check if it's a Wansung
  278.     if (!m_fShift) {
  279.     if (!m_fKorea) {
  280.     (void)Output(ESC);
  281.     (void)Output(ISO2022_IN_CHAR);
  282.     (void)Output(ISO2022_IN_KR_CHAR_1);
  283.     (void)Output(ISO2022_IN_KR_CHAR_2);
  284.     m_fKorea = TRUE;
  285.     }
  286.     (void)Output(SO);
  287.     m_fShift = TRUE;
  288.     }                
  289. (void)Output(m_tcLeadByte & 0x7f);
  290. fDone = Output(tc & 0x7f);
  291. } else {
  292.                 UCHAR szDefaultChar[3] = {0x3f}; // possible DBCS + null    
  293.                 if (_lpFallBack && (_dwFlag & MLCONVCHARF_USEDEFCHAR))
  294.                 {
  295.                     // only take SBCS, no DBCS character
  296.                     if ( 1 != WideCharToMultiByte(CP_KOR_5601, 0,
  297.                                (LPCWSTR)_lpFallBack, 1,
  298.                                (LPSTR)szDefaultChar, ARRAYSIZE(szDefaultChar), NULL, NULL ))
  299.                         szDefaultChar[0] = 0x3f;
  300.                 }
  301.     // shift out if we're in DBCS mode
  302.                 if (m_fKorea && m_fShift) {
  303.     (void)Output(SI);
  304.     m_fShift = FALSE;
  305.     }
  306.                 if (_dwFlag & (MLCONVCHARF_NCR_ENTITIZE|MLCONVCHARF_NAME_ENTITIZE))
  307.                 {
  308.                     char    szChar[3] = {0};
  309.                     char    szDstStr[10] = {0};
  310.                     WCHAR   szwChar[2];
  311.                     int     cCount;
  312.                     szChar[0] = m_tcLeadByte;
  313.                     szChar[1] = tc;
  314.                 
  315.                     if (MultiByteToWideChar(CP_KOR_5601, 0, szChar, -1, szwChar, ARRAYSIZE(szwChar)))
  316.                     {
  317.                         // Output NCR entity
  318.                         Output('&');
  319.                         Output('#');
  320.                         _ultoa((unsigned long)szwChar[0], (char*)szDstStr, 10);
  321.                         cCount = lstrlenA(szDstStr);
  322.                         for (int i=0; i< cCount; i++)
  323.                         {
  324.                             Output(szDstStr[i]);
  325.                         }
  326.                         fDone = Output(';');
  327.                     }
  328.                     else
  329.                     {
  330.         fDone = Output(szDefaultChar[0]); // use default char
  331.                         hr = S_FALSE;
  332.                     }
  333.                 }
  334.                 else
  335.                 {
  336.     fDone = Output(szDefaultChar[0]); // use default char
  337.                     hr = S_FALSE;
  338.                 }
  339. }
  340. } else {
  341. if (m_fKorea && m_fShift) {
  342. (void)Output(SI);
  343. m_fShift = FALSE;
  344. }
  345. (void)Output(m_tcLeadByte);
  346. fDone = Output(tc);
  347. }
  348. m_tcLeadByte = 0 ;
  349. }
  350.     if (!fDone)
  351.         hr = E_FAIL;
  352. return hr;
  353. }
  354. /******************************************************************************
  355. *****************************   C L E A N   U P   *****************************
  356. ******************************************************************************/
  357. BOOL CInccKscOut::CleanUp()
  358. {
  359.     BOOL fDone = TRUE;
  360.     if ( m_fShift) 
  361.     {
  362.         fDone = Output(SI);
  363.         m_fShift = FALSE;
  364.     }
  365.     return fDone ;
  366. }
  367. int CInccKscOut::GetUnconvertBytes()
  368. {
  369.     if (m_tcLeadByte)
  370.         return 1 ;
  371.     else
  372.         return 0 ;
  373. }
  374. DWORD CInccKscOut::GetConvertMode()
  375. {
  376.     // for output, we don't need write back code page. 0xC431 -> 50225 ISO-2022-KR
  377.     return ( m_fKorea ? 1 : 0 ) +  ( m_fShift ? 2 : 0 ) ;
  378. }
  379. void CInccKscOut::SetConvertMode(DWORD mode)
  380. {
  381.     Reset();    // initialization
  382.     if ( mode & 0x00000001 ) 
  383.         m_fKorea = TRUE ;
  384.     if ( mode & 0x00000002 ) 
  385.         m_fShift = TRUE ;
  386.     return ;
  387. }