#include "pch.h"
#include "CharConvert.h"

/* string to utf8 */
std::string stringToUTF8(const std::string& str)
{
	int nwLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
	wchar_t* pwBuf = new wchar_t[nwLen + 1];
	ZeroMemory(pwBuf, nwLen * 2 + 2);

	MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen);

	int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);

	char* pBuf = new char[nLen + 1];
	ZeroMemory(pBuf, nLen + 1);

	WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

	std::string retStr(pBuf);

	delete[] pwBuf;
	delete[] pBuf;

	pwBuf = NULL;
	pBuf = NULL;

	return(retStr);
}

/* utf8 to string */
std::string UTF8Tostring(const std::string& str)
{
	int nwLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);

	wchar_t* pwBuf = new wchar_t[nwLen + 1];
	memset(pwBuf, 0, nwLen * 2 + 2);

	MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), pwBuf, nwLen);

	int nLen = WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, NULL, NULL, NULL, NULL);

	char* pBuf = new char[nLen + 1];
	memset(pBuf, 0, nLen + 1);

	WideCharToMultiByte(CP_ACP, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

	std::string retStr = pBuf;

	delete[] pwBuf;
	delete[] pBuf;

	pwBuf = NULL;
	pBuf = NULL;

	return(retStr);
}

/* UTF8 to URL String */
std::string UTF8ToURLString(const std::string& str)
{
	std::string	strRes;
	unsigned int iIndex = 0, iCount = str.length();

	while(iIndex < iCount)
	{
		if((unsigned char)str.c_str()[iIndex] < 0x7F)
		{
			if ((unsigned char)str.c_str()[iIndex] == (unsigned char)(' '))
			{
				strRes.append(1, '+');
			}
			else
			{
				strRes.append(1, (unsigned char)str.c_str()[iIndex]);
			}
			++iIndex;
		}
		else
		{
			char chBuf[10];

			sprintf_s(chBuf, "%%%02X%%%02X%%%02X", (unsigned char)str.c_str()[iIndex], (unsigned char)str.c_str()[iIndex + 1], (unsigned char)str.c_str()[iIndex + 3]);

			std::string strTmp = chBuf;
			strRes += strTmp;
			iIndex += 3;
		}
	}

	return strRes;
}

/* Hex string to char */
char HexStrToChar(const std::string& str)
{
	char chRet = 0;

	for (char i = 0; i < 2; i++)
	{
		char chTemp = str.at(i);
		chRet *= 16;
		
		if(chTemp >= '0' && chTemp <= '9')
			chRet += chTemp - '0';
		else if(chTemp >= 'a' && chTemp <= 'f')
			chRet += (chTemp - 'a') + 10;
		else if(chTemp >= 'A' && chTemp <= 'F')
			chRet += (chTemp - 'A') + 10;
	}

	return(chRet);
}

/* string to int */
unsigned int StrToInt(const std::string& str)
{
	unsigned int uiRet = 0;

	for(unsigned char ucIndex = 0; ucIndex < str.length(); ucIndex++)
	{
		char chTemp = str.at(ucIndex);
		uiRet *= 10;
		uiRet += chTemp - '0';
	}

	return(uiRet);
}

/************************************************************************/
/*  函数：[4/2/2019 Wang];
/*  描述：;
/*  参数：;
/*  	[IN] ：;
/*  	[OUT] ：;
/*  	[IN/OUT] ：;
/*  返回：void;
/************************************************************************/
unsigned char TwoHexCharToChar(char ch1,char ch2)  
{
	char Numb1;
	char Numb2;

	if (ch1 >= 'A')
		Numb1 = (toupper(ch1)-'0'-7)*16;
	else
		Numb1 = (ch1 - '0')*16;

	if (ch2 >= 'A')
		Numb2 = (toupper(ch2) - '0' - 7);
	else
		Numb2 = (ch2 - '0');

	return (Numb1 + Numb2);
}


/************************************************************************/
/*  函数：[4/2/2019 Wang];
/*  描述：16进制字符串转字节，16进制字符以空格间隔，如"AA BB CC 0A";
/*  参数：;
/*  	[IN] ：;
/*  	[OUT] ：;
/*  	[IN/OUT] ：;
/*  返回：void;
/************************************************************************/
std::string HexStr2Bytes(std::string strHex)
{
	byte value = 0;
	std::string strBytes;
	int nSize = strHex.size();
	for (int i = 0; i < nSize; i+=3 )
	{
		strBytes.push_back(TwoHexCharToChar(strHex[i], strHex[i+1]));
	}

	return strBytes;
}


std::string Bytes2HexStr(const unsigned char *pbuffer, int nLen )
{
	std::string hex;
	char szhex[5] = {0};
	for ( int i = 0; i < nLen; i++ )
	{
		memset(szhex, 0, 5);
		_stprintf_s(szhex, "%02X ", pbuffer[i]);
		hex.append(szhex);
	}

	return hex;
}

//BYTE HexStrToChar(const string& szData)
//{
//	BYTE	byteRet = 0;
//
//	for (int i = 0; i < 2; ++i)
//	{
//		BYTE byteTmp = szData.at(i);
//
//		byteRet *= 16;
//
//		if (byteTmp >= '0' && byteTmp <= '9')
//			byteRet += byteTmp - '0';
//		else if (byteTmp >= 'a' && byteTmp <= 'f')
//			byteRet += (byteTmp - 'a') + 10;
//		else if (byteTmp >= 'A' && byteTmp <= 'F')
//			byteRet += (byteTmp - 'A') + 10;
//	}
//
//	return(byteRet);
//}

//std::string CString2string(CString csStrData)
//{
//	int iLen = csStrData.GetLength() + 1;
//	char* pSrc = new char[iLen];
//	if (pSrc == NULL)
//	{
//		return "";
//	}
//
//	memset(pSrc, 0, iLen);
//
//	wchar_t* pwSrc = NULL;
//	pwSrc = (wchar_t*)(csStrData.GetBuffer(iLen * sizeof(wchar_t)));
//	WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pwSrc, -1, pSrc, iLen, NULL, NULL);
//
//	string strRet = string(pSrc);
//	delete[] pSrc;
//	csStrData.ReleaseBuffer(iLen);
//	return strRet;
//}
