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

Windows Kernel

Development Platform:

Visual C++

  1. #include "private.h"
  2. #include "jisobj.h"
  3. #include "eucjobj.h"
  4. #include "hzgbobj.h"
  5. #include "kscobj.h"
  6. #include "utf8obj.h"
  7. #include "utf7obj.h"
  8. #include "fechrcnv.h"
  9. #include "codepage.h"
  10. #include "ichrcnv.h"
  11. HRESULT CICharConverter::KSC5601ToEUCKR(LPCSTR lpSrcStr, LPINT lpnSrcSize, LPSTR lpDestStr, int cchDest, LPINT lpnSize)
  12. {
  13.     int nSize=0;
  14.     int i=0;
  15.     HRESULT hr = S_OK;
  16.     UCHAR szDefaultChar[3] = {0x3f}; // possible DBCS + null    
  17.     if (_lpFallBack && (_dwFlag & MLCONVCHARF_USEDEFCHAR))
  18.     {
  19.         // only take SBCS, no DBCS character
  20.         if ( 1 != WideCharToMultiByte(CP_KOR_5601, 0,
  21.                                (LPCWSTR)_lpFallBack, 1,
  22.                                (LPSTR)szDefaultChar, ARRAYSIZE(szDefaultChar), NULL, NULL ))
  23.             szDefaultChar[0] = 0x3f;
  24.     }
  25.     while(i < *lpnSrcSize)
  26.     {
  27.         // Check space
  28.         if (lpDestStr && (nSize > cchDest))
  29.             break;
  30.         //  DBCS
  31.         if (((UCHAR)lpSrcStr[i] >= 0x81 && (UCHAR)lpSrcStr[i] <= 0xFE) && (i+1 < *lpnSrcSize))
  32.         {
  33.             // UHC 
  34.             if (!((UCHAR)lpSrcStr[i] >= 0xA1 && (UCHAR)lpSrcStr[i] <= 0xFE &&
  35.                   (UCHAR)lpSrcStr[i+1] >= 0xA1 && (UCHAR)lpSrcStr[i+1] <= 0xFE))
  36.             {
  37.                 // use NCR if flag specified
  38.                 if (_dwFlag & (MLCONVCHARF_NCR_ENTITIZE|MLCONVCHARF_NAME_ENTITIZE))
  39.                 {
  40.                     char    szDstStr[10] = {0};
  41.                     WCHAR   szwChar[2];
  42.                     int     cCount;
  43.                
  44.                     if (MultiByteToWideChar(CP_KOR_5601, 0, &lpSrcStr[i], 2, szwChar, ARRAYSIZE(szwChar)))
  45.                     {
  46.                         // Caculate NCR length
  47.                         _ultoa((unsigned long)szwChar[0], (char*)szDstStr, 10);
  48.                         cCount = lstrlenA(szDstStr)+3;
  49.                         // Not enough space for NCR entity
  50.                         if (lpDestStr)
  51.                         {
  52.                             if (nSize+cCount > cchDest)
  53.                                 break;
  54.                             // Output NCR entity
  55.                             else
  56.                             {                                    
  57.                                 *lpDestStr ++= '&';
  58.                                 *lpDestStr ++= '#';
  59.                                 for (int j=0; j< cCount-3; j++)
  60.                                     *lpDestStr++=szDstStr[j];
  61.                                 *lpDestStr ++= ';';
  62.                             }
  63.                         }
  64.                         nSize += cCount;
  65.                     }
  66.                     else
  67.                     {
  68.                         if (lpDestStr)
  69.                         {
  70.                             if (nSize+1 > cchDest)
  71.                                 break;
  72.                             *lpDestStr++=szDefaultChar[0];
  73.                         }
  74.                         nSize++;
  75.                         hr = S_FALSE;
  76.                     }
  77.                 }
  78.                 // use default char, question mark
  79.                 else
  80.                 {
  81.                     if (lpDestStr)
  82.                     {
  83.                         if (nSize+1 > cchDest)
  84.                             break;
  85.                         *lpDestStr++=szDefaultChar[0];
  86.                     }
  87.                     nSize++;
  88.                     hr = S_FALSE;
  89.                 }
  90.                 i += 2;
  91.             }
  92.             // Wansung
  93.             else
  94.             {
  95.                 if (lpDestStr)
  96.                 {
  97.                     if (nSize+2 > cchDest)
  98.                         break;
  99.                     *lpDestStr++=lpSrcStr[i];
  100.                     *lpDestStr++=lpSrcStr[i+1];
  101.                 }
  102.                 i+=2;
  103.                 nSize += 2;
  104.             }
  105.         }
  106.         // SBCS
  107.         else
  108.         {
  109.             if (lpDestStr)
  110.             {
  111.                 if (nSize+1 > cchDest)
  112.                     break; 
  113.                 *lpDestStr++=lpSrcStr[i];
  114.             }
  115.             nSize++;
  116.             i++;
  117.         }
  118.     } // End of loop
  119.     if (lpnSize)
  120.         *lpnSize = nSize;
  121.     return hr;
  122. }
  123. /******************************************************************************
  124. ******************   C O N V E R T   I N E T   S T R I N G   ******************
  125. ******************************************************************************/
  126. HRESULT CICharConverter::CreateINetString(BOOL fInbound, UINT uCodePage, int nCodeSet)
  127. {
  128.     if (_hcins)
  129.     {
  130.         delete _hcins ;
  131.         _hcins = NULL ;
  132.     }
  133. if (fInbound) { // Inbound
  134. if (uCodePage == CP_JPN_SJ && ( nCodeSet == CP_ISO_2022_JP ||
  135.     nCodeSet == CP_ISO_2022_JP_ESC || nCodeSet == CP_ISO_2022_JP_SIO ))
  136.     // JIS
  137. _hcins = new CInccJisIn(uCodePage, nCodeSet);
  138. else if (uCodePage == CP_JPN_SJ && nCodeSet == CP_EUC_JP ) // EUC
  139. _hcins = new CInccEucJIn(uCodePage, nCodeSet);
  140. else if (uCodePage == CP_CHN_GB && nCodeSet == CP_CHN_HZ ) // HZ-GB
  141. _hcins = new CInccHzGbIn(uCodePage, nCodeSet);
  142. else if (uCodePage == CP_KOR_5601 && nCodeSet == CP_ISO_2022_KR )
  143. _hcins = new CInccKscIn(uCodePage, nCodeSet);
  144. else if (uCodePage == CP_UCS_2 && nCodeSet == CP_UTF_8 )
  145. _hcins = new CInccUTF8In(uCodePage, nCodeSet);
  146. else if (uCodePage == CP_UCS_2 && nCodeSet == CP_UTF_7 )
  147. _hcins = new CInccUTF7In(uCodePage, nCodeSet);
  148. } else { // Outbound
  149. if (uCodePage == CP_JPN_SJ && ( nCodeSet == CP_ISO_2022_JP ||
  150.     nCodeSet == CP_ISO_2022_JP_ESC || nCodeSet == CP_ISO_2022_JP_SIO ))
  151.             // JIS
  152. _hcins = new CInccJisOut(uCodePage, nCodeSet);
  153. else if (uCodePage == CP_JPN_SJ && nCodeSet == CP_EUC_JP ) // EUC
  154. _hcins = new CInccEucJOut(uCodePage, nCodeSet, _dwFlag, _lpFallBack);
  155. else if (uCodePage == CP_CHN_GB && nCodeSet == CP_CHN_HZ ) // HZ-GB
  156. _hcins = new CInccHzGbOut(uCodePage, nCodeSet, _dwFlag, _lpFallBack);
  157. else if (uCodePage == CP_KOR_5601 && nCodeSet == CP_ISO_2022_KR )
  158. _hcins = new CInccKscOut(uCodePage, nCodeSet, _dwFlag, _lpFallBack);
  159. else if (uCodePage == CP_UCS_2 && nCodeSet == CP_UTF_8 )
  160. _hcins = new CInccUTF8Out(uCodePage, nCodeSet);
  161. else if (uCodePage == CP_UCS_2 && nCodeSet == CP_UTF_7 )
  162. _hcins = new CInccUTF7Out(uCodePage, nCodeSet);
  163. }
  164.     // recode the dst codepage
  165.     if ( _hcins )
  166.         _hcins_dst =  nCodeSet ;
  167.     return S_OK ;
  168. }
  169. HRESULT CICharConverter::DoConvertINetString(LPDWORD lpdwMode, BOOL fInbound, UINT uCodePage, int nCodeSet,
  170.       LPCSTR lpSrcStr, LPINT lpnSrcSize, LPSTR lpDestStr, int cchDest, LPINT lpnSize)
  171. {
  172.     HRESULT hr = S_OK;
  173. HCINS hcins = NULL;
  174. int nSize = 0 ;
  175.     int cchSrc = *lpnSrcSize ;
  176. if (!lpnSize)
  177. lpnSize = &nSize;
  178. if (!uCodePage) // Get default code page if nothing speicified
  179. uCodePage = GetACP();
  180. if (!lpSrcStr && cchSrc < 0) // Get length of lpSrcStr if not given, assuming lpSrcStr is a zero terminate string.
  181. cchSrc = lstrlenA(lpSrcStr) + 1;
  182. if (!_hcins || ( nCodeSet != _hcins_dst ) )
  183.         CreateINetString(fInbound,uCodePage,nCodeSet);
  184. if (_hcins ) { // Context created, it means DBCS
  185. int nTempSize = 0 ;
  186.         
  187.         // restore previous mode SO/SI ESC etc.
  188.         ((CINetCodeConverter*)_hcins)->SetConvertMode(*lpdwMode);
  189. // if it is a JIS output set Kana mode
  190. if (!fInbound && uCodePage == CP_JPN_SJ && ( nCodeSet == CP_ISO_2022_JP ||
  191.     nCodeSet == CP_ISO_2022_JP_ESC || nCodeSet == CP_ISO_2022_JP_SIO ))
  192.     // JIS
  193.     ((CInccJisOut*)_hcins)->SetKanaMode(nCodeSet);
  194. if (!lpDestStr || !cchDest) // Get the converted size
  195. {
  196. hr = ((CINetCodeConverter*)_hcins)->GetStringSizeA(lpSrcStr, cchSrc, lpnSize);
  197. if (0 == fInbound) 
  198.     hr = ((CINetCodeConverter*)_hcins)->GetStringSizeA(NULL, 0, &nTempSize);
  199. }
  200. else // Perform actual converting
  201. {
  202. hr = ((CINetCodeConverter*)_hcins)->ConvertStringA(lpSrcStr, cchSrc, lpDestStr, cchDest, lpnSize);
  203. if (0 == fInbound) 
  204.             {
  205.                 HRESULT _hr = ((CINetCodeConverter*)_hcins)->ConvertStringA(NULL, 0, lpDestStr+*lpnSize, cchDest-*lpnSize, &nTempSize);
  206.     if (S_OK != _hr)
  207.                     hr = _hr;
  208.             }
  209. }
  210. *lpnSize += nTempSize;
  211.         // get number of unconvetable bytes 
  212.         if ( lpnSrcSize && ((CINetCodeConverter*)_hcins)->GetUnconvertBytes() )
  213.             *lpnSrcSize = cchSrc -((CINetCodeConverter*)_hcins)->GetUnconvertBytes();
  214.         // only save current mode SO/SI ESC if we are perform actual converting
  215.         // we need this if statement because for two stages plus conversion.
  216.         // It will inquire the size first then convert from IWUU or UUWI.
  217. if (lpDestStr && lpdwMode )
  218.             *lpdwMode = ((CINetCodeConverter*)_hcins)->GetConvertMode();
  219. //        delete hcins;
  220. } else { 
  221.         // Internet encodings that have same encoding scheme as their family encodings
  222.         switch (nCodeSet)
  223.         {
  224.             case CP_EUC_KR:
  225.                 hr = KSC5601ToEUCKR(lpSrcStr, lpnSrcSize, lpDestStr, cchDest, lpnSize);
  226.                 break;
  227.             default:
  228.                 if (!lpDestStr || !cchDest) // Get the converted size
  229.                    *lpnSize = cchSrc ;
  230.                 else
  231.                 {
  232.                    *lpnSize = min(cchSrc, cchDest);
  233.                    if (*lpnSize)
  234.                       MoveMemory(lpDestStr, lpSrcStr, *lpnSize);
  235.                 }
  236.         }
  237. }
  238.     return hr;
  239. }