VC++ UTF8 변환 관련 매크로

by digipine posted Nov 02, 2017
?

Shortcut

PrevPrev Article

NextNext Article

ESCClose

Larger Font Smaller Font Up Down Go comment Print

/**
* The names of the UTF-8 string conversion macros take the form.
* SourceType2DestinationType[EX] ex) W2UTF8, UTF82A_EX
*
* SourceType and DestinationType are described below.
* A (ANSI character string.)
* W (Unicode character string.)
* T (Generic character string.)
* UTF8 (UTF-8 encoded character string.)
*
* When using an UTF-8 conversion macro, specify the UTF8_CONVERSION[EX] macro
* at the beginning of your function in order to avoid compiler errors.
*
* Sample code
* void SampleFunc(LPCTSTR lpsz)
* {
* UTF8_CONVERSION;
* LPSTR utf8 = T2UTF8(lpsz);
*
* // Do something with utf8
* ...
* }
*/

#pragma once
#include <malloc.h>
#include <vector>

template <typename Ty>
class _SafeAllocator
{
public:
 _SafeAllocator() {}
 ~_SafeAllocator()
 {
  int nCount = static_cast<int>(_parray.size());
  for (int i = 0; i < nCount; ++i)
  {
   if (_parray[i] != NULL)
    delete [] _parray[i];
  }
 }

 int Alloc(int nSize)
 {  
  Ty* ptr;
  ptr = new(nothrow) Ty[nSize];
  if (!ptr)
   return -1;

  _parray.push_back(ptr);
  return static_cast<int>(_parray.size() - 1);
 }

 void Free(int nIndex)
 {
  delete _parray[nIndex];
  _parray[nIndex] = NULL;
 }

 Ty* GetPtr(int nIndex) const
 {   
  return _parray[nIndex];
 }

private: 
 std::vector<Ty*> _parray;
};

inline LPSTR WINAPI _W2UTF8Helper(LPSTR lpu, LPCWSTR lpw, int nChars)
{
 ASSERT(lpu != NULL);
 ASSERT(lpw != NULL);
 if (lpu == NULL || lpw == NULL)
  return NULL;

 lpu[0] = '\0';
 int ret = WideCharToMultiByte(CP_UTF8, 0, lpw, -1, lpu, nChars, 0, 0);
 if (ret == 0)
 {
  ASSERT(FALSE);
  return NULL;
 }
 return lpu;
}

inline LPWSTR WINAPI _UTF82WHelper(LPWSTR lpw, LPCSTR lpu, int nChars)
{
 ASSERT(lpw != NULL);
 ASSERT(lpu != NULL);
 if (lpw == NULL || lpu == NULL)
  return NULL;

 lpw[0] = '\0';
 int ret = MultiByteToWideChar(CP_UTF8, 0, lpu, -1, lpw, nChars);
 if (ret == 0)
 {
  ASSERT(FALSE);
  return NULL;
 }
 return lpw;
}

inline LPWSTR WINAPI _A2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
{
 ASSERT(lpw != NULL);
 ASSERT(lpa != NULL);
 if (lpw == NULL || lpa == NULL)
  return NULL;

 lpw[0] = '\0';
 int ret = MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars);
 if (ret == 0)
 {
  ASSERT(FALSE);
  return NULL;
 }
 return lpw;
}

inline LPSTR WINAPI _W2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars)
{
 ASSERT(lpa != NULL);
 ASSERT(lpw != NULL);
 if (lpa == NULL || lpw == NULL)
  return NULL;

 lpa[0] = '\0';
 int ret = WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, 0, 0);
 if (ret == 0)
 {
  ASSERT(FALSE);
  return NULL;
 }
 return lpa;
}

#define UTF8_CONVERSION int _conv_uc; (_conv_uc); LPCWSTR _lpw_uc; (_lpw_uc); LPCSTR _lpa_uc; (_lpa_uc); LPCSTR _lpu_uc; (_lpu_uc);

#define A2UTF8(lpa) (\
     ((_lpa_uc = lpa) == NULL) ? NULL : (\
     _conv_uc = MultiByteToWideChar(CP_ACP, 0, _lpa_uc, -1, NULL, 0) * sizeof(WCHAR),\
     _lpw_uc = _A2WHelper((LPWSTR)_alloca(_conv_uc), _lpa_uc, _conv_uc),\
     _conv_uc = WideCharToMultiByte(CP_UTF8, 0, _lpw_uc, -1, NULL, 0, 0, 0) * sizeof(CHAR),\
     _W2UTF8Helper((LPSTR)_alloca(_conv_uc), _lpw_uc, _conv_uc)))

#define W2UTF8(lpw) (\
     ((_lpw_uc = lpw) == NULL) ? NULL : (\
     _conv_uc = WideCharToMultiByte(CP_UTF8, 0, _lpw_uc, -1, NULL, 0, 0, 0) * sizeof(CHAR),\
     _W2UTF8Helper((LPSTR)_alloca(_conv_uc), _lpw_uc, _conv_uc)))

#define UTF82A(lpu) (\
     ((_lpu_uc = lpu) == NULL) ? NULL : (\
     _conv_uc = MultiByteToWideChar(CP_UTF8, 0, _lpu_uc, -1, NULL, 0) * sizeof(WCHAR),\
     _lpw_uc = _UTF82WHelper((LPWSTR)_alloca(_conv_uc), _lpu_uc, _conv_uc),\
     _conv_uc = WideCharToMultiByte(CP_ACP, 0, _lpw_uc, -1, NULL, 0, 0, 0)  * sizeof(CHAR),\
     _W2AHelper((LPSTR)_alloca(_conv_uc), _lpw_uc, _conv_uc)))

#define UTF82W(lpu) (\
     ((_lpu_uc = lpu) == NULL) ? NULL : (\
     _conv_uc = MultiByteToWideChar(CP_UTF8, 0, _lpu_uc, -1, NULL, 0) * sizeof(WCHAR),\
     _UTF82WHelper((LPWSTR)_alloca(_conv_uc), _lpu_uc, _conv_uc)))

#ifdef _UNICODE
 #define T2UTF8 W2UTF8
 #define UTF82T UTF82W
#else
 #define T2UTF8 A2UTF8
 #define UTF82T UTF82A
#endif

#define UTF8_CONVERSION_EX int _conv_uc_ex, _idx1, _idx2; (_conv_uc_ex); (_idx1); (_idx2);\
       _SafeAllocator<WCHAR> _saw; _SafeAllocator<CHAR> _saa; _SafeAllocator<CHAR> _sau

#define A2UTF8_EX(lpa) (\
      ((LPCSTR)lpa == NULL) ? NULL : (\
      _conv_uc_ex = MultiByteToWideChar(CP_ACP, 0, lpa, -1, NULL, 0),\
      ((_idx1 = _saw.Alloc(_conv_uc_ex)) == -1) ? NULL : (\
      _A2WHelper(_saw.GetPtr(_idx1), lpa, _conv_uc_ex),\
      _conv_uc_ex = WideCharToMultiByte(CP_UTF8, 0, _saw.GetPtr(_idx1), -1, NULL, 0, 0, 0),\
      ((_idx2 = _sau.Alloc(_conv_uc_ex)) == -1) ? _saw.Free(_idx1), NULL : (\
      _W2UTF8Helper(_sau.GetPtr(_idx2), _saw.GetPtr(_idx1), _conv_uc_ex),\
      _saw.Free(_idx1), _sau.GetPtr(_idx2)))))

#define W2UTF8_EX(lpw) (\
      ((LPCWSTR)lpw == NULL) ? NULL : (\
      _conv_uc_ex = WideCharToMultiByte(CP_UTF8, 0, lpw, -1, NULL, 0, 0, 0),\
      ((_idx1 = _sau.Alloc(_conv_uc_ex)) == -1) ? NULL : (\
      _W2UTF8Helper(_sau.GetPtr(_idx1), lpw, _conv_uc_ex))))

#define UTF82A_EX(lpu) (\
      ((LPCSTR)lpu == NULL) ? NULL : (\
      _conv_uc_ex = MultiByteToWideChar(CP_UTF8, 0, lpu, -1, NULL, 0),\
      ((_idx1 = _saw.Alloc(_conv_uc_ex)) == -1) ? NULL : (\
      _UTF82WHelper(_saw.GetPtr(_idx1), lpu, _conv_uc_ex),\
      _conv_uc_ex = WideCharToMultiByte(CP_ACP, 0, _saw.GetPtr(_idx1), -1, NULL, 0, 0, 0),\
      ((_idx2 = _saa.Alloc(_conv_uc_ex)) == -1) ? _saw.Free(_idx1), NULL : (\
      _W2AHelper(_saa.GetPtr(_idx2), _saw.GetPtr(_idx1), _conv_uc_ex),\
      _saw.Free(_idx1), _saa.GetPtr(_idx2)))))

#define UTF82W_EX(lpu) (\
      ((LPCSTR)lpu == NULL) ? NULL : (\
      _conv_uc_ex = MultiByteToWideChar(CP_UTF8, 0, lpu, -1, NULL, 0),\
      ((_idx1 = _saw.Alloc(_conv_uc_ex)) == -1) ? NULL : (\
      _UTF82WHelper(_saw.GetPtr(_idx1), lpu, _conv_uc_ex))))

#ifdef _UNICODE
 #define T2UTF8_EX W2UTF8_EX
 #define UTF82T_EX UTF82W_EX
#else
 #define T2UTF8_EX A2UTF8_EX
 #define UTF82T_EX UTF82A_EX
#endif

 
TAG •

Articles

1 2 3