#include "OpStrHelper.h"

#ifdef WIN32
#include <windows.h>
#endif

#define CP_GBK      (936)       

std::wstring OpStrHelper::ansi_2_wstring(const char* in)
{
	std::wstring out;
	auto len = strlen(in);

#ifdef WIN32

    int wbufferlen = (int)::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, (int)len, NULL, 0);
    wchar_t* pwbuffer = new wchar_t[wbufferlen + 4];

    wbufferlen = (int)::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, (int)len, pwbuffer, wbufferlen + 2);
    pwbuffer[wbufferlen] = '\0';
    out.assign(pwbuffer, wbufferlen);
    delete[] pwbuffer;

#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("WCHAR_T", "MS-ANSI");
    size_t out_len = (len + 1) * sizeof(wchar_t);
    wchar_t* pbuffer = new wchar_t[len + 1];
    memset(pbuffer, 0, out_len);
    wchar_t* pResult = pbuffer;
    iconv(env, (char**)&in, (size_t*)&len, (char**)&pbuffer, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
    delete[] pResult;
#endif

	return out;
}

std::wstring OpStrHelper::gbk_2_wstring(const char* in)
{
    std::wstring out;
    auto len = strlen(in);

#ifdef WIN32
    int wbufferlen = (int)::MultiByteToWideChar(CP_GBK, MB_PRECOMPOSED, in, (int)len, NULL, 0);
    wchar_t* pwbuffer = new wchar_t[wbufferlen + 4];

    wbufferlen = (int)::MultiByteToWideChar(CP_GBK, MB_PRECOMPOSED, in, (int)len, pwbuffer, wbufferlen + 2);
    pwbuffer[wbufferlen] = '\0';
    out.assign(pwbuffer, wbufferlen);
    delete[] pwbuffer;

#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("WCHAR_T", "GBK");
    size_t out_len = (len + 1) * sizeof(wchar_t);
    wchar_t* pbuffer = new wchar_t[len + 1];
    memset(pbuffer, 0, out_len);
    wchar_t* pResult = pbuffer;
    iconv(env, (char**)&in, (size_t*)&len, (char**)&pbuffer, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
    delete[] pResult;
#endif

    return out;
}

std::wstring OpStrHelper::utf8_2_wstring(const char* in)
{
    std::wstring out;
    auto len = strlen(in);

    wchar_t* pBuf = new wchar_t[len + 1];

    size_t out_len = (len + 1) * sizeof(wchar_t);
    memset(pBuf, 0, (len + 1) * sizeof(wchar_t));
    wchar_t* pResult = pBuf;

#ifdef WIN32
    out_len = ::MultiByteToWideChar(CP_UTF8, 0, in, len, pBuf, len * sizeof(wchar_t));
    out.assign(pResult, out_len);
#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("WCHAR_T", "UTF-8");
    iconv(env, (char**)&in, (size_t*)&len, (char**)&pBuf, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
#endif

    delete[] pResult;
    pResult = NULL;

    return out;
}

std::string OpStrHelper::wstring_2_ansi(const wchar_t* in)
{
    std::string out;

    auto len = wcslen(in);

#ifdef WIN32
    int bufferlen = (int)::WideCharToMultiByte(CP_ACP, 0, in, (int)len, NULL, 0, NULL, NULL);
    char* pBuffer = new char[bufferlen + 4];

    int out_len = ::WideCharToMultiByte(CP_ACP, 0, in, (int)len, pBuffer, bufferlen + 2, NULL, NULL);
    pBuffer[bufferlen] = '\0';
    out.assign(pBuffer, out_len);
    delete[] pBuffer;

#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("MS-ANSI", "WCHAR_T");
    size_t out_len = len * 2 + 1;
    size_t in_len = len * sizeof(wchar_t);
    char* pbuffer = new char[out_len];
    memset(pbuffer, 0, out_len);
    char* pResult = pbuffer;
    iconv(env, (char**)&in, (size_t*)&in_len, (char**)&pbuffer, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
    delete[] pResult;
#endif

    return out;
}

std::string OpStrHelper::wstring_2_utf8(const wchar_t* in)
{
    std::string out;
    auto len = wcslen(in);

    size_t out_len = len * 3 + 1;
    char* pBuf = new char[out_len];

    char* pResult = pBuf;
    memset(pBuf, 0, out_len);

#ifdef WIN32
    out_len = ::WideCharToMultiByte(CP_UTF8, 0, in, len, pBuf, len * 3, NULL, NULL);
    out.assign(pResult, out_len);
#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("UTF-8", "WCHAR_T");
    size_t in_len = len * sizeof(wchar_t);
    iconv(env, (char**)&in, (size_t*)&in_len, (char**)&pBuf, (size_t*)&out_len);

    iconv_close(env);
    out = pResult;
#endif
    delete[] pResult;
    pResult = NULL;

    return out;
}

std::string OpStrHelper::wstring_2_gbk(const wchar_t* in)
{
    std::string out;
    auto len = wcslen(in);

#ifdef WIN32
    int bufferlen = (int)::WideCharToMultiByte(CP_GBK, 0, in, (int)len, NULL, 0, NULL, NULL);
    char* pBuffer = new char[bufferlen + 4];

    int out_len = ::WideCharToMultiByte(CP_GBK, 0, in, (int)len, pBuffer, bufferlen + 2, NULL, NULL);
    pBuffer[bufferlen] = '\0';
    out.assign(pBuffer, out_len);
    delete[] pBuffer;
#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("GBK", "WCHAR_T");
    size_t out_len = len * 2 + 1;
    size_t in_len = len * sizeof(wchar_t);
    char* pbuffer = new char[out_len];
    memset(pbuffer, 0, out_len);
    char* pResult = pbuffer;
    iconv(env, (char**)&in, (size_t*)&in_len, (char**)&pbuffer, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
    delete[] pResult;
#endif

    return out;
}
#include "OpStrHelper.h"

#ifdef WIN32
#include <windows.h>
#endif

#define CP_GBK      (936)       // 简体中文code page

std::wstring OpStrHelper::ansi_2_wstring(const char* in)
{
	std::wstring out;
	auto len = strlen(in);

#ifdef WIN32
    //assert( _mbslen((const unsigned char*)in) == strlen(in) ); // ANSI 要求必须是纯英文
    int wbufferlen = (int)::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, (int)len, NULL, 0);
    wchar_t* pwbuffer = new wchar_t[wbufferlen + 4];

    wbufferlen = (int)::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, (int)len, pwbuffer, wbufferlen + 2);
    pwbuffer[wbufferlen] = '\0';
    out.assign(pwbuffer, wbufferlen);
    delete[] pwbuffer;

#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("WCHAR_T", "MS-ANSI");
    size_t out_len = (len + 1) * sizeof(wchar_t);
    wchar_t* pbuffer = new wchar_t[len + 1];
    memset(pbuffer, 0, out_len);
    wchar_t* pResult = pbuffer;
    iconv(env, (char**)&in, (size_t*)&len, (char**)&pbuffer, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
    delete[] pResult;
#endif

	return out;
}

std::wstring OpStrHelper::gbk_2_wstring(const char* in)
{
    std::wstring out;
    auto len = strlen(in);

#ifdef WIN32
    int wbufferlen = (int)::MultiByteToWideChar(CP_GBK, MB_PRECOMPOSED, in, (int)len, NULL, 0);
    wchar_t* pwbuffer = new wchar_t[wbufferlen + 4];

    wbufferlen = (int)::MultiByteToWideChar(CP_GBK, MB_PRECOMPOSED, in, (int)len, pwbuffer, wbufferlen + 2);
    pwbuffer[wbufferlen] = '\0';
    out.assign(pwbuffer, wbufferlen);
    delete[] pwbuffer;

#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("WCHAR_T", "GBK");
    size_t out_len = (len + 1) * sizeof(wchar_t);
    wchar_t* pbuffer = new wchar_t[len + 1];
    memset(pbuffer, 0, out_len);
    wchar_t* pResult = pbuffer;
    iconv(env, (char**)&in, (size_t*)&len, (char**)&pbuffer, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
    delete[] pResult;
#endif

    return out;
}

std::wstring OpStrHelper::utf8_2_wstring(const char* in)
{
    std::wstring out;
    auto len = strlen(in);

    wchar_t* pBuf = new wchar_t[len + 1];

    size_t out_len = (len + 1) * sizeof(wchar_t);
    memset(pBuf, 0, (len + 1) * sizeof(wchar_t));
    wchar_t* pResult = pBuf;

#ifdef WIN32
    out_len = ::MultiByteToWideChar(CP_UTF8, 0, in, len, pBuf, len * sizeof(wchar_t));
    out.assign(pResult, out_len);
#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("WCHAR_T", "UTF-8");
    iconv(env, (char**)&in, (size_t*)&len, (char**)&pBuf, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
#endif

    delete[] pResult;
    pResult = NULL;

    return out;
}

std::string OpStrHelper::wstring_2_ansi(const wchar_t* in)
{
    std::string out;
    
    auto len = wcslen(in);

#ifdef WIN32
    int bufferlen = (int)::WideCharToMultiByte(CP_ACP, 0, in, (int)len, NULL, 0, NULL, NULL);
    char* pBuffer = new char[bufferlen + 4];

    int out_len = ::WideCharToMultiByte(CP_ACP, 0, in, (int)len, pBuffer, bufferlen + 2, NULL, NULL);
    pBuffer[bufferlen] = '\0';
    out.assign(pBuffer, out_len);
    delete[] pBuffer;
    //assert( _mbslen((const unsigned char*)out.c_str()) == strlen(out.c_str()) );
#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("MS-ANSI", "WCHAR_T");
    size_t out_len = len * 2 + 1;
    size_t in_len = len * sizeof(wchar_t);
    char* pbuffer = new char[out_len];
    memset(pbuffer, 0, out_len);
    char* pResult = pbuffer;
    iconv(env, (char**)&in, (size_t*)&in_len, (char**)&pbuffer, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
    delete[] pResult;
#endif

    return out;
}

std::string OpStrHelper::wstring_2_utf8(const wchar_t* in)
{
    std::string out;
    auto len = wcslen(in);

    size_t out_len = len * 3 + 1;
    char* pBuf = new char[out_len];

    char* pResult = pBuf;
    memset(pBuf, 0, out_len);

#ifdef WIN32
    out_len = ::WideCharToMultiByte(CP_UTF8, 0, in, len, pBuf, len * 3, NULL, NULL);
    out.assign(pResult, out_len);
#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("UTF-8", "WCHAR_T");
    size_t in_len = len * sizeof(wchar_t);
    iconv(env, (char**)&in, (size_t*)&in_len, (char**)&pBuf, (size_t*)&out_len);

    iconv_close(env);
    out = pResult;
#endif
    delete[] pResult;
    pResult = NULL;

    return out;
}

std::string OpStrHelper::wstring_2_gbk(const wchar_t* in)
{
    std::string out;
    auto len = wcslen(in);

#ifdef WIN32
    int bufferlen = (int)::WideCharToMultiByte(CP_GBK, 0, in, (int)len, NULL, 0, NULL, NULL);
    char* pBuffer = new char[bufferlen + 4];

    int out_len = ::WideCharToMultiByte(CP_GBK, 0, in, (int)len, pBuffer, bufferlen + 2, NULL, NULL);
    pBuffer[bufferlen] = '\0';
    out.assign(pBuffer, out_len);
    delete[] pBuffer;
#elif defined __LINUX__
    iconv_t env;
    env = iconv_open("GBK", "WCHAR_T");
    size_t out_len = len * 2 + 1;
    size_t in_len = len * sizeof(wchar_t);
    char* pbuffer = new char[out_len];
    memset(pbuffer, 0, out_len);
    char* pResult = pbuffer;
    iconv(env, (char**)&in, (size_t*)&in_len, (char**)&pbuffer, (size_t*)&out_len);
    iconv_close(env);
    out = pResult;
    delete[] pResult;
#endif

    return out;
}