home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 39 / IOPROG_39.ISO / SOFT / sdkjava40.exe / data1.cab / fg_Samples / Samples / Profiler / heapmon / utf8.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-04  |  5.6 KB  |  251 lines

  1. // utf8.cpp
  2. //
  3. // Created 12/09/97
  4. //
  5. // (C)Copyright 1997-1999 Microsoft Corporation, All rights reserved.
  6. //
  7.  
  8. #include "pch.hpp"
  9. #pragma hdrstop
  10.  
  11. #include "utf8.hpp"
  12. #include "ansibuf.hpp"
  13.  
  14.  
  15. // Returns number of characters in a Utf8 string that's assumed to be
  16. // terminated with a single 0 byte (Our constant pool always stores strings
  17. // this way.)
  18. DWORD Utf8NumChars(LPCSTR pszUtf8)
  19. {
  20.     LPCSTR        p;
  21.     DWORD         nChars = 0;
  22.     unsigned char c;
  23.     p = pszUtf8;
  24.     while ( '\0' != (c = *((unsigned char*)(p)))) {
  25.         nChars++;
  26.         if (!(c & 0x80)) {
  27.             // Normal single-byte character.
  28.             p++;
  29.         } else if (0xc0 == (c & 0xe0)) {
  30.             // Double-byte char
  31.             p += 2;
  32.         } else {
  33.             ASSERT(0xe0 == (c & 0xf0));
  34.             p += 3;
  35.         }
  36.     }
  37.     return nChars;
  38. }
  39.  
  40. //----------------------------------------------------------------------
  41. // Utf8ToUnicode
  42. //
  43. // Converts the first cbUtf characters of a utf8 string to its unicode
  44. //  equivalent.  pwsz must be large enough to hold the unicode string.
  45. // This function does NOT put a null-terminater at the end of the buffer.
  46. //
  47.  
  48. VOID Utf8ToUnicode(
  49.     LPCSTR  pUtf,
  50.     int     cbUtf,
  51.     LPWSTR  pwsz )
  52. {
  53.     unsigned char c;
  54.  
  55.     while( cbUtf-- > 0 )
  56.     {
  57.         c = *(unsigned char *)pUtf;
  58.  
  59.         if( !(c & 0x80) )
  60.         {
  61.             // Normal single-byte character.
  62.             *pwsz = (WCHAR)c;
  63.             pUtf++;
  64.         }
  65.         else if( 0xc0 == (c & 0xe0) )
  66.         {
  67.             // Double-byte char
  68.             unsigned char   c2 = *(unsigned char *)(pUtf + 1);
  69.             ASSERT( 0x80 == (c2 & 0xc0) );
  70.  
  71.             *pwsz = (WCHAR)((  (WCHAR)((WCHAR)(c & 0x1f)) << 6  ) |
  72.                             (         ((WCHAR)(c2 & 0x3f))      ));
  73.  
  74.             pUtf += 2;
  75.         }
  76.         else
  77.         {
  78.             unsigned char c2 = *(unsigned char*)(pUtf + 1);
  79.             unsigned char c3 = *(unsigned char*)(pUtf + 2);
  80.             ASSERT( 0xe0 == (c & 0xf0) );
  81.             ASSERT( 0x80 == (c2 & 0xc0) );
  82.             ASSERT( 0x80 == (c2 & 0xc0) );
  83.  
  84.             *pwsz = (WCHAR)((  (WCHAR)((WCHAR)(c & 0x0f))  << 12  ) |
  85.                             (  (WCHAR)((WCHAR)(c2 & 0x3f)) <<  6  ) |
  86.                             (         ((WCHAR)(c3 & 0x3f))        ));
  87.  
  88.  
  89.             pUtf += 3;
  90.         }
  91.  
  92.         pwsz++;
  93.     }
  94. }
  95.  
  96. //----------------------------------------------------------------------
  97. // Utf8ToUnicode
  98. //
  99. // Converts a utf8 string to its unicode equivalent, returning a
  100. // dynamically allocated buffer.
  101. //
  102.  
  103. HRESULT Utf8ToUnicode(
  104.     LPCSTR pUtf,
  105.     LPWSTR *ppwsz)
  106. {
  107.     HRESULT hr;
  108.     UINT cbUtf = Utf8NumChars(pUtf);
  109.  
  110.     *ppwsz = new(WCHAR[cbUtf+1]);
  111.  
  112.     if (*ppwsz)
  113.     {
  114.         Utf8ToUnicode( pUtf, cbUtf, *ppwsz );
  115.         (*ppwsz)[cbUtf] = L'\0';
  116.         hr = S_OK;
  117.     }
  118.     else
  119.         hr = E_OUTOFMEMORY;
  120.  
  121.     return hr;
  122. }
  123.  
  124. //----------------------------------------------------------------------
  125. // Utf8ToUnicode
  126. //
  127. // Converts a utf8 string to its unicode equivalent, returning a
  128. // dynamically allocated buffer.
  129. //
  130.  
  131. HRESULT CoUtf8ToUnicode(
  132.     LPCSTR pUtf,
  133.     LPWSTR *ppwsz)
  134. {
  135.     HRESULT hr;
  136.     UINT cbUtf = Utf8NumChars(pUtf);
  137.  
  138.     *ppwsz = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR)*(cbUtf+1));
  139.  
  140.     if (*ppwsz)
  141.     {
  142.         Utf8ToUnicode( pUtf, cbUtf, *ppwsz );
  143.         (*ppwsz)[cbUtf] = L'\0';
  144.         hr = S_OK;
  145.     }
  146.     else
  147.         hr = E_OUTOFMEMORY;
  148.  
  149.     return hr;
  150. }
  151.  
  152.  
  153. HRESULT Utf8ToAnsi(
  154.     PCUTF8  pUtf,
  155.     LPSTR  *ppAnsi)
  156. {
  157.     HRESULT hr = E_OUTOFMEMORY;
  158.     int ncLen;
  159.  
  160.     *ppAnsi = NULL;
  161.  
  162.     DWORD  dwStrLen = Utf8NumChars( pUtf );
  163.     WCHAR *wszSimpleName = new( WCHAR[ dwStrLen + 1 ] );  // add one for NULL terminator
  164.  
  165.     if (!wszSimpleName) {
  166.         goto exit;
  167.     }
  168.  
  169.     Utf8ToUnicode( pUtf, dwStrLen, wszSimpleName );
  170.  
  171.     ncLen = WideCharToMultiByte(CP_ACP, 0, wszSimpleName, dwStrLen, NULL, 0, NULL, NULL);
  172.     if (ncLen < 0) {
  173.         hr = E_UNEXPECTED;
  174.         goto exit;
  175.     }
  176.  
  177.     *ppAnsi = new(CHAR[ncLen + 1]);
  178.     if (!*ppAnsi)
  179.         goto exit;
  180.  
  181.     if( WideCharToMultiByte( CP_ACP, 0, wszSimpleName, dwStrLen,
  182.         *ppAnsi, ncLen, NULL, NULL ) >= 0 )
  183.     {
  184.         (*ppAnsi)[ ncLen ] = '\0';  // NULL-terminate
  185.     } else {
  186.         delete(*ppAnsi);
  187.         *ppAnsi = NULL;
  188.         hr = E_UNEXPECTED;
  189.         goto exit;
  190.     }
  191.  
  192.     hr = S_OK;
  193.  
  194. exit:
  195.     if (wszSimpleName)
  196.         delete wszSimpleName;
  197.  
  198.     return hr;
  199. }
  200.  
  201.  
  202. //------------------------------------------------------------------------
  203.  
  204.  
  205. BOOL ANSIStringBuffer::EnsureSpace (int needed)
  206. {
  207.     int newlen = m_len + needed;
  208.     if (newlen < m_size)
  209.         return TRUE;
  210.  
  211.     int newsize = (m_size+1)*2;
  212.     if (newsize < newlen)
  213.         newsize = newlen+1;
  214.     PSTR newstr = new(CHAR[newsize]);
  215.     if (newstr != NULL)
  216.     {
  217.         if (m_str != NULL)
  218.         {
  219.             CopyMemory(newstr, m_str, m_len+1);
  220.             delete(m_str);
  221.         }
  222.         m_str = newstr;
  223.         m_size = newsize;
  224.         return TRUE;
  225.     }
  226.     return FALSE;
  227. }
  228.  
  229.  
  230. BOOL ANSIStringBuffer::AppendUtf8 (PCSTR pUtf)
  231. {
  232.     BOOL ret = FALSE;
  233.  
  234.     DWORD  dwStrLen = Utf8NumChars( pUtf );
  235.     WCHAR *wszSimpleName = new( WCHAR[ dwStrLen + 1 ] );  // add one for NULL terminator
  236.  
  237.     if (wszSimpleName != NULL)
  238.     {
  239.         Utf8ToUnicode( pUtf, dwStrLen, wszSimpleName );
  240.  
  241.         wszSimpleName[dwStrLen] = L'\0';
  242.  
  243.         ret = Append(wszSimpleName);
  244.  
  245.         delete wszSimpleName;
  246.     }
  247.  
  248.     return ret;
  249. }
  250.  
  251.