#include "pch.h"
#include "CUtils.h"


CUtils::CUtils()
{
	
}

CUtils::~CUtils()
{
	
}


int CUtils::MultiByToUtf8(const char* multi, char*& utf8)
{
	int size = 0;
	size = MultiByteToWideChar(CP_ACP, NULL, multi, -1, NULL, 0);
	wchar_t* buff = NULL;
	buff = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));
	if (!buff)
	{
		return 0;
	}
	wmemset(buff, 0, size + 1);
	MultiByteToWideChar(CP_ACP, NULL, multi, -1, buff, size);
	int len = 0;
	len = WideCharToMultiByte(CP_UTF8, NULL, buff, size, NULL, 0, NULL, NULL);
	utf8 = NULL;
	utf8 = (char*)malloc(sizeof(char) * (len + 1));
	if (!utf8)
	{
		free(buff);
		return 0;
	}
	memset(utf8, 0, len + 1);
	WideCharToMultiByte(CP_UTF8, NULL, buff, size, utf8, len, NULL, NULL);
	free(buff);
	return len;
}


int CUtils::Utf8ToMultiBy(const char* utf8, char*& multi)
{
	int size = 0;
	size = MultiByteToWideChar(CP_UTF8, NULL, utf8, -1, NULL, 0);
	wchar_t* buff = NULL;
	buff = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));
	if (!buff)
	{
		return 0;
	}
	wmemset(buff, 0, size + 1);
	MultiByteToWideChar(CP_ACP, NULL, utf8, -1, buff, size);
	int len = 0;
	len = WideCharToMultiByte(CP_ACP, NULL, buff, size, NULL, 0, NULL, NULL);
	multi = NULL;
	multi = (char*)malloc(sizeof(char) * (len + 1));
	if (!multi)
	{
		free(buff);
		return 0;
	}
	memset(multi, 0, len + 1);
	WideCharToMultiByte(CP_ACP, NULL, buff, size, multi, len, NULL, NULL);
	free(buff);
	return len;
}


//utf8转unicode
int CUtils::Utf8ToUnicode(const char* utf8, wchar_t*& unicode)
{
	int len = 0;
	len = MultiByteToWideChar(CP_UTF8, NULL, utf8, -1, NULL, 0);
	unicode = NULL;
	unicode = (wchar_t*)malloc(sizeof(wchar_t) * (len + 1));
	if (!unicode)
	{
		return 0;
	}
	wmemset(unicode, 0, len + 1);
	MultiByteToWideChar(CP_UTF8, NULL, utf8, -1, unicode, len);
	return len;
}

//unicode转utf8
int  CUtils::UnicodeToUtf8(const wchar_t* unicode, char*& utf8)
{
	int len = 0;
	len = WideCharToMultiByte(CP_UTF8, NULL, unicode, -1, NULL, 0, NULL, NULL);
	utf8 = NULL;
	utf8 = (char*)malloc(sizeof(char) * (len + 1));
	memset(utf8, 0, len + 1);
	if (!utf8)
	{
		return 0;
	}
	WideCharToMultiByte(CP_UTF8, NULL, unicode, -1, utf8, len, NULL, NULL);
	return len;
}

//多字节转unicode
int  CUtils::MultiByToUnicode(const char* multi, wchar_t*& unicode)
{
	int len = 0;
	len = MultiByteToWideChar(CP_ACP, NULL, multi, -1, NULL, 0);
	unicode = NULL;
	unicode = (wchar_t*)malloc(sizeof(wchar_t) * (len + 1));
	if (!unicode)
	{
		return 0;
	}
	wmemset(unicode, 0, len + 1);
	MultiByteToWideChar(CP_ACP, NULL, multi, -1, unicode, len);
	return len;
}

//unicode转多字节
int  CUtils::UnicodeToMultiBy(const wchar_t* unicode, char*& multi)
{
	int len = 0;
	len = WideCharToMultiByte(CP_ACP, NULL, unicode, -1, NULL, 0, NULL, NULL);
	multi = NULL;
	multi = (char*)malloc(sizeof(char) * (len + 1));
	memset(multi, 0, len + 1);
	if (!multi)
	{
		return 0;
	}
	WideCharToMultiByte(CP_ACP, NULL, unicode, -1, multi, len, NULL, NULL);
	return len;
}

int CUtils::fnmatch_win(const char* pattern, const char* name, int flags)
{
	if (SafeFNMatch(pattern, strlen(pattern), name, strlen(name)))
		return 0;
	else
		return FNM_NOMATCH;
}

/**copy from Google-glog*/
bool CUtils::SafeFNMatch(const char* pattern, size_t patt_len, const char* str, size_t str_len)
{
	size_t p = 0;
	size_t s = 0;
	while (1)
	{
		if (p == patt_len && s == str_len)
			return true;
		if (p == patt_len)
			return false;
		if (s == str_len)
			return p + 1 == patt_len && pattern[p] == '*';
		if (pattern[p] == str[s] || pattern[p] == '?')
		{
			p += 1;
			s += 1;
			continue;
		}
		if (pattern[p] == '*')
		{
			if (p + 1 == patt_len) return true;
			do
			{
				if (SafeFNMatch(pattern + (p + 1), patt_len - (p + 1), str + s, str_len - s))
				{
					return true;
				}
				s += 1;
			} while (s != str_len);

			return false;
		}

		return false;
	}
}


std::string  CUtils::CvtA2A(const
	std::string& str, unsigned int cpFrom/*=CP_UTF8*/, unsigned int cpTo/*=CP_ACP*/)
{
	if (cpTo == cpFrom)
		return str;
	std::wstring strw = CvtA2W(str, cpFrom);
	return CvtW2A(strw, cpTo);
}

std::wstring CUtils::CvtW2W(const std::wstring& str, unsigned int cp)
{
	return str; 
}



std::wstring CUtils::CvtA2W(const std::string& str, unsigned int cp, unsigned int cp2)
{
	UNREFERENCED_PARAMETER(cp2);
	wchar_t szBuf[1024];
	int nRet = MultiByteToWideChar(cp, 0, str.c_str(), str.length(), szBuf, 1024);
	if (nRet > 0)
	{
		return std::wstring(szBuf, nRet);
	}
	if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
	{
		int nRet = MultiByteToWideChar(cp, 0, str.c_str(), str.length(), NULL, 0);
		if (nRet > 0)
		{
			wchar_t* pBuf = new wchar_t[nRet];
			MultiByteToWideChar(cp, 0, str.c_str(), str.length(), pBuf, nRet);
			std::wstring strRet(pBuf, nRet);
			delete[]pBuf;
			return strRet;
		}
	}
	return L"";
}



std::string CUtils::CvtW2A(const std::wstring& str, unsigned int cp/*=CP_ACP*/)
{
	char szBuf[1024];
	int nRet = WideCharToMultiByte(cp, 0, str.c_str(), str.length(), szBuf, 1024, NULL, NULL);
	if (nRet > 0) return std::string(szBuf, nRet);
	if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
	{
		int nRet = WideCharToMultiByte(cp, 0, str.c_str(), str.length(), NULL, 0, NULL, NULL);
		if (nRet > 0)
		{
			char* pBuf = new char[nRet];
			WideCharToMultiByte(cp, 0, str.c_str(), str.length(), pBuf, nRet, NULL, NULL);
			std::string strRet(pBuf, nRet);
			delete[]pBuf;
			return strRet;
		}
	}
	return "";
}
