#include "stdafx.h"
#include <Windows.h>
#include <stdlib.h> //malloc
#include <math.h>

///ANSI 문자열에서 유니코드로 변환
LPWSTR  AnsiToUnicode(LPSTR szAnsi)
{
 LPWSTR szUniStr;
 
 // 유니코드로 변환 전 return 되는 길이얻기
 int nLen = MultiByteToWideChar(CP_ACP, 0, szAnsi, -1, NULL, NULL);

 nLen = nLen * sizeof(WCHAR);
 
 szUniStr = (LPWSTR)malloc(nLen+1);// 메모리를 할당한다.
 memset(szUniStr,0,nLen+1);
 
 // 이제 변환을 수행한다.
 MultiByteToWideChar(CP_ACP, 0, szAnsi, -1, szUniStr, nLen);
   
 return szUniStr;
}

//유니코드에서 ANSI 문자열로 변환
LPSTR UnicodeToAnsi(LPWSTR szUniStr)
{
 LPSTR  szAnsi;
 int nLen = WideCharToMultiByte(CP_ACP, 0, szUniStr, -1, NULL, 0, NULL, NULL);

 szAnsi = (LPSTR) malloc(nLen+1);
 memset(szAnsi,0,nLen+1);

 WideCharToMultiByte(CP_ACP, 0, szUniStr, -1, szAnsi, nLen, NULL, NULL);

 return szAnsi;
}

//유니코드에서 UTF8 문자열로 변환
LPWSTR UnicodeToUTF8(LPWSTR szUniStr)
{
 int idx=0;
 WCHAR uc;
 LPWSTR  szUtf8;

 int nLen = sizeof(WCHAR) * wcslen(szUniStr);

 nLen = nLen*3+sizeof(WCHAR); //최대 값
 szUtf8 = (LPWSTR) malloc(nLen);

 memset(szUtf8,0,nLen);
 LPSTR pszUTF8 = (LPSTR)szUtf8;

 for(int i=0;szUniStr[i];i++)
 {
  uc = szUniStr[i];
  if (uc <= 0x7f)
  {
   pszUTF8[idx++] = (char) uc;
  }
  else if (uc <= 0x7ff)
  {
   pszUTF8[idx++] = (char) 0xc0 + uc / (wchar_t) pow(2, 6);
   pszUTF8[idx++] = (char) 0x80 + uc % (wchar_t) pow(2, 6);
  }
  else if (uc <= 0xffff)
  {
   pszUTF8[idx++] = (char) 0xe0 + uc / (wchar_t) pow(2, 12);
   pszUTF8[idx++] = (char) 0x80 + uc / (wchar_t) pow(2, 6) % (wchar_t) pow(2, 6);
   pszUTF8[idx++] = (char) 0x80 + uc % (wchar_t) pow(2, 6);
  }

 }

 return szUtf8;

/**  //Win95에서만 안되는 코드
    //http://support.microsoft.com/default.aspx?scid=kb%3Bko%3B601368
 LPWSTR  szUtf8;
 int nLen = WideCharToMultiByte(CP_UTF8, 0, szUniStr, -1, NULL, 0, NULL, NULL);
 szUtf8 = (LPWSTR) malloc(nLen+1);
 memset(szUtf8,0,nLen+1);
 WideCharToMultiByte(CP_UTF8, 0, szUniStr, -1, (LPSTR)szUtf8, nLen, NULL, NULL);

 return szUtf8;
**/
}

//유니코드에서 UTF8 문자열로 변환
LPWSTR UTF8ToUnicode(LPWSTR szUtf8)
{
 LPWSTR  szUniStr;
 int nLen = sizeof(WCHAR) * wcslen(szUtf8);

 nLen = nLen+sizeof(WCHAR);
 szUniStr = (LPWSTR) malloc(nLen);
 memset(szUniStr,0,nLen);

 LPSTR src = (LPSTR)szUtf8;

 int p = 0;
    int q = 0;
    WCHAR d;
    while( src[p] )
 {
        if( (src[p]&0xE0)==0xE0 )
  {
   d = ((src[p]&0x0f)<<12) | ((src[p+1]&0x3F)<<6) | (src[p+2]&0x3F);
   p+=3;
        }
  else if( (src[p]&0xC0)==0xC0 )
  {
   d = ((src[p]&0x1F)<<6) | (src[p+1]&0x3F);
   p+=2;
        }
  else
  {
   d = src[p]&0x7F;
   p++;
        }
        szUniStr[q] = d;
        q++;
    }
    szUniStr[q] = NULL;
    return szUniStr;
}

int main()
{
 LPSTR s="한글";
 LPWSTR szUniStr   = AnsiToUnicode(s);
 LPWSTR szUtf8     = UnicodeToUTF8(szUniStr);
 LPWSTR szUniStr2  = UTF8ToUnicode(szUtf8);
 LPSTR szAnsi     = UnicodeToAnsi(szUniStr);

 free(szUniStr);
 free(szUtf8);
 free(szUniStr2);
 free(szAnsi);
 return 0;
}