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.

365 lines
12 KiB

  1. // ============================================================================
  2. // Internet Character Set Conversion: Input from EUC-JP
  3. // ============================================================================
  4. #include "private.h"
  5. #include "fechrcnv.h"
  6. #include "eucjobj.h"
  7. #include "codepage.h"
  8. /******************************************************************************
  9. ************************** C O N S T R U C T O R **************************
  10. ******************************************************************************/
  11. CInccEucJIn::CInccEucJIn(UINT uCodePage, int nCodeSet) : CINetCodeConverter(uCodePage, nCodeSet)
  12. {
  13. Reset(); // initialization
  14. return ;
  15. }
  16. /******************************************************************************
  17. ******************************* R E S E T *********************************
  18. ******************************************************************************/
  19. void CInccEucJIn::Reset()
  20. {
  21. m_pfnConv = ConvMain;
  22. m_pfnCleanUp = CleanUpMain;
  23. m_tcLeadByte = 0 ;
  24. return ;
  25. }
  26. /******************************************************************************
  27. ************************* C O N V E R T C H A R *************************
  28. ******************************************************************************/
  29. HRESULT CInccEucJIn::ConvertChar(UCHAR tc, int cchSrc)
  30. {
  31. BOOL fDone = (this->*m_pfnConv)(tc);
  32. if (fDone)
  33. return S_OK;
  34. else
  35. return E_FAIL;
  36. }
  37. /******************************************************************************
  38. ***************************** C L E A N U P *****************************
  39. ******************************************************************************/
  40. BOOL CInccEucJIn::CleanUp()
  41. {
  42. return (this->*m_pfnCleanUp)();
  43. }
  44. /******************************************************************************
  45. **************************** C O N V M A I N ****************************
  46. ******************************************************************************/
  47. BOOL CInccEucJIn::ConvMain(UCHAR tc)
  48. {
  49. BOOL fDone = TRUE;
  50. if (tc >= 0xa1 && tc <= 0xfe) {
  51. m_pfnConv = ConvDoubleByte;
  52. m_pfnCleanUp = CleanUpDoubleByte;
  53. m_tcLeadByte = tc;
  54. } else if (tc == 0x8e) { // Single Byte Katakana
  55. m_pfnConv = ConvKatakana;
  56. m_pfnCleanUp = CleanUpKatakana;
  57. } else {
  58. fDone = Output(tc);
  59. }
  60. return fDone;
  61. }
  62. /******************************************************************************
  63. ************************ C L E A N U P M A I N ************************
  64. ******************************************************************************/
  65. BOOL CInccEucJIn::CleanUpMain()
  66. {
  67. return TRUE;
  68. }
  69. /******************************************************************************
  70. ********************* C O N V D O U B L E B Y T E *********************
  71. ******************************************************************************/
  72. BOOL CInccEucJIn::ConvDoubleByte(UCHAR tc)
  73. {
  74. BOOL fRet ;
  75. m_pfnConv = ConvMain;
  76. m_pfnCleanUp = CleanUpMain;
  77. if (m_tcLeadByte <= 0xde) { // && m_tcLeadByte >= 0xa1
  78. if (m_tcLeadByte % 2) // odd
  79. (void)Output((m_tcLeadByte - 0xa1) / 2 + 0x81);
  80. else // even
  81. (void)Output((m_tcLeadByte - 0xa2) / 2 + 0x81);
  82. } else { // m_tcLeadByte >= 0xdf && m_tcLeadByte <= 0xfe
  83. if (m_tcLeadByte % 2) // odd
  84. (void)Output((m_tcLeadByte - 0xdf) / 2 + 0xe0);
  85. else // even
  86. (void)Output((m_tcLeadByte - 0xe0) / 2 + 0xe0);
  87. }
  88. if (m_tcLeadByte % 2) { // odd
  89. if (tc >= 0xa1 && tc <= 0xdf)
  90. fRet = Output(tc - 0x61);
  91. else
  92. fRet = Output(tc - 0x60);
  93. } else { // even
  94. fRet = Output(tc - 2);
  95. }
  96. m_tcLeadByte = 0 ;
  97. return fRet ;
  98. }
  99. /******************************************************************************
  100. ***************** C L E A N U P D O U B L E B Y T E *****************
  101. ******************************************************************************/
  102. BOOL CInccEucJIn::CleanUpDoubleByte()
  103. {
  104. m_pfnConv = ConvMain;
  105. m_pfnCleanUp = CleanUpMain;
  106. return TRUE;
  107. }
  108. /******************************************************************************
  109. ************************ C O N V K A T A K A N A ************************
  110. ******************************************************************************/
  111. BOOL CInccEucJIn::ConvKatakana(UCHAR tc)
  112. {
  113. m_pfnConv = ConvMain;
  114. m_pfnCleanUp = CleanUpMain;
  115. return Output(tc);
  116. }
  117. /******************************************************************************
  118. ******************** C L E A N U P K A T A K A N A ********************
  119. ******************************************************************************/
  120. BOOL CInccEucJIn::CleanUpKatakana()
  121. {
  122. m_pfnConv = ConvMain;
  123. m_pfnCleanUp = CleanUpMain;
  124. return TRUE;
  125. }
  126. int CInccEucJIn::GetUnconvertBytes()
  127. {
  128. if (m_tcLeadByte || m_pfnConv == ConvKatakana)
  129. return 1;
  130. else
  131. return 0;
  132. }
  133. DWORD CInccEucJIn::GetConvertMode()
  134. {
  135. // 0xCADC -> 51932 EUC-JP (codepage)
  136. return 0xCADC0000 ;
  137. }
  138. void CInccEucJIn::SetConvertMode(DWORD mode)
  139. {
  140. Reset();
  141. return ;
  142. }
  143. // ============================================================================
  144. // Internet Character Set Conversion: Output to EUC-JP
  145. // ============================================================================
  146. /******************************************************************************
  147. ************************** C O N S T R U C T O R **************************
  148. ******************************************************************************/
  149. CInccEucJOut::CInccEucJOut(UINT uCodePage, int nCodeSet, DWORD dwFlag, WCHAR *lpFallBack) : CINetCodeConverter(uCodePage, nCodeSet)
  150. {
  151. Reset(); // initialization
  152. _dwFlag = dwFlag;
  153. _lpFallBack = lpFallBack;
  154. return ;
  155. }
  156. /******************************************************************************
  157. ******************************* R E S E T *********************************
  158. ******************************************************************************/
  159. void CInccEucJOut::Reset()
  160. {
  161. m_fDoubleByte = FALSE;
  162. m_tcLeadByte = 0 ;
  163. return ;
  164. }
  165. /******************************************************************************
  166. ************************* C O N V E R T C H A R *************************
  167. ******************************************************************************/
  168. HRESULT CInccEucJOut::ConvertChar(UCHAR tc, int cchSrc)
  169. {
  170. BOOL fDone = TRUE;
  171. HRESULT hr = S_OK;
  172. if (!m_fDoubleByte) {
  173. if ((tc >= 0x81 && tc <= 0x9f) || (tc >= 0xe0 && tc <= 0xfc )) { // Double Byte Code
  174. m_fDoubleByte = TRUE;
  175. m_tcLeadByte = tc;
  176. } else if (tc >= 0xa1 && tc <= 0xdf) { // Single Byte Katakana Code
  177. (void) Output( (UCHAR) 0x8e);
  178. fDone = Output(tc);
  179. } else {
  180. fDone = Output(tc);
  181. }
  182. } else {
  183. // map extended char (0xfa40-0xfc4b) to a special range
  184. if (m_tcLeadByte >= 0xfa && m_tcLeadByte <= 0xfc && tc >= 0x40 )
  185. {
  186. WCHAR wcDBCS ;
  187. wcDBCS = ((WCHAR) m_tcLeadByte ) << 8 | tc ;
  188. if ( wcDBCS >= 0xfa40 && wcDBCS <= 0xfa5b )
  189. {
  190. if ( wcDBCS <= 0xfa49 )
  191. wcDBCS = wcDBCS - 0x0b51 ;
  192. else if ( wcDBCS >= 0xfa4a && wcDBCS <= 0xfa53 )
  193. wcDBCS = wcDBCS - 0x072f6 ;
  194. else if ( wcDBCS >= 0xfa54 && wcDBCS <= 0xfa57 )
  195. wcDBCS = wcDBCS - 0x0b5b ;
  196. else if ( wcDBCS == 0xfa58 )
  197. wcDBCS = 0x878a ;
  198. else if ( wcDBCS == 0xfa59 )
  199. wcDBCS = 0x8782 ;
  200. else if ( wcDBCS == 0xfa5a )
  201. wcDBCS = 0x8784 ;
  202. else if ( wcDBCS == 0xfa5b )
  203. wcDBCS = 0x879a ;
  204. }
  205. else if ( wcDBCS >= 0xfa5c && wcDBCS <= 0xfc4b )
  206. {
  207. if ( tc < 0x5c )
  208. wcDBCS = wcDBCS - 0x0d5f;
  209. else if ( tc >= 0x80 && tc <= 0x9B )
  210. wcDBCS = wcDBCS - 0x0d1d;
  211. else
  212. wcDBCS = wcDBCS - 0x0d1c;
  213. }
  214. tc = (UCHAR) wcDBCS ;
  215. m_tcLeadByte = (UCHAR) ( wcDBCS >> 8 ) ;
  216. }
  217. // Do conversion
  218. if (m_tcLeadByte <= 0xef) {
  219. if (m_tcLeadByte <= 0x9f) { // && m_tcLeadByte >= 0x81
  220. if (tc <= 0x9e)
  221. (void)Output((m_tcLeadByte - 0x81) * 2 + 0xa1);
  222. else
  223. (void)Output((m_tcLeadByte - 0x81) * 2 + 0xa2);
  224. } else { // m_tcLeadByte >= 0xe0 && m_tcLeadByte <= 0xef
  225. if (tc <= 0x9e)
  226. (void)Output((m_tcLeadByte - 0xe0) * 2 + 0xdf);
  227. else
  228. (void)Output((m_tcLeadByte - 0xe0) * 2 + 0xe0);
  229. }
  230. if (tc >= 0x40 && tc <= 0x7e)
  231. fDone = Output(tc + 0x61);
  232. else if (tc >= 0x80 && tc <= 0x9e)
  233. fDone = Output(tc + 0x60);
  234. else
  235. fDone = Output(tc + 0x02);
  236. } else if (m_tcLeadByte >= 0xfa) { // && m_tcLeadByte <= 0xfc; IBM Extended Char
  237. UCHAR szDefaultChar[3] = {0x3f}; // possible DBCS + null
  238. if (_lpFallBack && (_dwFlag & MLCONVCHARF_USEDEFCHAR))
  239. {
  240. // only take SBCS, no DBCS character
  241. if ( 1 != WideCharToMultiByte(CP_JPN_SJ, 0,
  242. (LPCWSTR)_lpFallBack, 1,
  243. (LPSTR)szDefaultChar, ARRAYSIZE(szDefaultChar), NULL, NULL ))
  244. szDefaultChar[0] = 0x3f;
  245. }
  246. if (_dwFlag & (MLCONVCHARF_NCR_ENTITIZE|MLCONVCHARF_NAME_ENTITIZE))
  247. {
  248. char szChar[2];
  249. char szDstStr[10];
  250. WCHAR szwChar[2];
  251. int cCount;
  252. szChar[0] = m_tcLeadByte;
  253. szChar[1] = tc;
  254. if (MultiByteToWideChar(CP_JPN_SJ, 0, szChar, 2, szwChar, ARRAYSIZE(szwChar)))
  255. {
  256. // Output NCR entity
  257. Output('&');
  258. Output('#');
  259. _ultoa((unsigned long)szwChar[0], (char*)szDstStr, 10);
  260. cCount = lstrlenA(szDstStr);
  261. for (int i=0; i< cCount; i++)
  262. {
  263. Output(szDstStr[i]);
  264. }
  265. fDone = Output(';');
  266. }
  267. else
  268. {
  269. fDone = Output(szDefaultChar[0]);
  270. hr = S_FALSE;
  271. }
  272. }
  273. else
  274. {
  275. fDone = Output(szDefaultChar[0]);
  276. hr = S_FALSE;
  277. }
  278. } else {
  279. (void)Output(m_tcLeadByte);
  280. fDone = Output(tc);
  281. }
  282. m_fDoubleByte = FALSE;
  283. m_tcLeadByte = 0 ;
  284. }
  285. if (!fDone)
  286. hr = E_FAIL;
  287. return hr;
  288. }
  289. /******************************************************************************
  290. ***************************** C L E A N U P *****************************
  291. ******************************************************************************/
  292. BOOL CInccEucJOut::CleanUp()
  293. {
  294. m_fDoubleByte = FALSE;
  295. return TRUE;
  296. }
  297. int CInccEucJOut::GetUnconvertBytes()
  298. {
  299. if (m_tcLeadByte)
  300. return 1;
  301. else
  302. return 0;
  303. }
  304. DWORD CInccEucJOut::GetConvertMode()
  305. {
  306. return 0 ;
  307. }
  308. void CInccEucJOut::SetConvertMode(DWORD mode)
  309. {
  310. Reset();
  311. return ;
  312. }