#include "StdAfx.h"
#include "AesSQLite3.h"

#include <shlwapi.h>

AesSQLite3::AesSQLite3(void)
{
	m_pSQLite3 = NULL;
	memset(m_szKey, 0, MAX_PATH);
	m_nKeyLen = 0;
	m_bSetKey = FALSE;
}

AesSQLite3::~AesSQLite3(void)
{
	if ( m_pSQLite3 )
		sqlite3_close(m_pSQLite3);
	m_pSQLite3 = NULL;
}

void AesSQLite3::SetKey(IN LPCTSTR lpKey)
{
	if ( lpKey == NULL || lpKey[0] == _T('\0'))
		return;

#ifdef UNICODE
	if ( UNICODE2ASCII(lpKey, m_szKey, MAX_PATH) == FALSE )
#else
	if ( _stprintf_s(m_szKey, MAX_PATH, _T("%s"), lpKey) == -1)
#endif
		return;

	m_nKeyLen = strlen(m_szKey);
	m_bSetKey = TRUE;
}

WCHAR* AesSQLite3::ASCII2UNICODE(IN LPCCH lpASCIIStr)
{
	if ( lpASCIIStr == NULL )
		return NULL;

	// 获取宽字符字节数;
	int cchWideChar  = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, NULL, 0);
	if ( cchWideChar == 0)
		return NULL;

	// 转换成宽字符串;
	WCHAR *pWideChar = new WCHAR[cchWideChar + 1];
	memset(pWideChar, 0 , sizeof(WCHAR)*(cchWideChar + 1));
	int nWriteNum = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, pWideChar, cchWideChar );
	if ( nWriteNum != cchWideChar)
	{ 
		if (pWideChar) 
			delete []pWideChar;
		return NULL;
	}

	return pWideChar;
}

BOOL AesSQLite3::ASCII2UNICODE(IN LPCCH lpASCIIStr, OUT PWCH pUNICODEStr, IN CONST INT& nUNICODEStrLen)
{
	if ( lpASCIIStr == NULL )
		return FALSE;

	// 获取宽字符字节数;
	int cchWideChar  = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, NULL, 0);
	if ( cchWideChar == 0 || cchWideChar >= nUNICODEStrLen)
		return FALSE;

	// 转换成宽字符串;
	memset(pUNICODEStr, 0 , sizeof(WCHAR)*nUNICODEStrLen);
	int nWriteNum = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, pUNICODEStr, cchWideChar );
	if ( nWriteNum != cchWideChar)
		return FALSE;

	return TRUE;
}

CHAR* AesSQLite3::UNICODE2ASCII(IN LPWCH lpUNICODEStr)
{
	if ( lpUNICODEStr == NULL )
		return NULL;

	// 获取多字节字符字节数;
	int cbMultiByte = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
	if ( cbMultiByte == 0 )
		return NULL;

	// 转换成多字节字符;
	CHAR *pMultiByteStr = new CHAR[cbMultiByte+1];
	memset(pMultiByteStr, 0, cbMultiByte + 1);
	int nWriteNum = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, pMultiByteStr, cbMultiByte, NULL, NULL);
	if (nWriteNum != cbMultiByte)
	{
		if (pMultiByteStr) 
			delete []pMultiByteStr;
		return NULL;
	}

	return pMultiByteStr;
}

BOOL AesSQLite3::UNICODE2ASCII(IN LPWCH lpUNICODEStr, OUT LPCH pASCIIStr, IN CONST INT& nASCIIStrLen)
{
	if ( lpUNICODEStr == NULL )
		return FALSE;

	// 获取多字节字符字节数;
	int cbMultiByte = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
	if ( cbMultiByte == 0 || cbMultiByte >= nASCIIStrLen )
		return FALSE;

	// 转换成多字节字符;
	memset((void*)pASCIIStr, 0, nASCIIStrLen);
	int nWriteNum = WideCharToMultiByte(CP_OEMCP, 0, lpUNICODEStr, -1, pASCIIStr, cbMultiByte, NULL, NULL);
	if (nWriteNum != cbMultiByte)
	{
		return FALSE;
	}

	return TRUE;
}

CHAR* AesSQLite3::UNICODE2UTF8(IN LPWCH lpUNICODEStr)
{
	if ( lpUNICODEStr == NULL )
		return NULL;

	// 获取多字节字符字节数;
	int cbMultiByte = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
	if ( cbMultiByte == 0 )
		return NULL;

	// 转换成多字节字符;
	CHAR* pMultiByteStr = new CHAR[cbMultiByte+1];
	memset(pMultiByteStr, 0, cbMultiByte + 1);
	int nWriteNum = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, pMultiByteStr, cbMultiByte, NULL, NULL);
	if (nWriteNum != cbMultiByte)
	{
		if (pMultiByteStr) 
			delete []pMultiByteStr;
		return NULL;
	}

	return pMultiByteStr;
}

BOOL AesSQLite3::UNICODE2UTF8(IN LPWCH lpUNICODEStr, OUT LPCH pUTF8Str, IN CONST INT& nUTF8StrLen)
{
	if ( lpUNICODEStr == NULL )
		return FALSE;

	// 获取多字节字符字节数;
	int cbMultiByte = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, NULL, 0, NULL, NULL);
	if ( cbMultiByte == 0 || cbMultiByte >= nUTF8StrLen )
		return FALSE;

	// 转换成多字节字符;
	memset(pUTF8Str, 0, nUTF8StrLen);
	int nWriteNum = WideCharToMultiByte(CP_UTF8, 0, lpUNICODEStr, -1, pUTF8Str, cbMultiByte, NULL, NULL);
	if (nWriteNum != cbMultiByte)
	{
		return FALSE;
	}

	return TRUE;
}

CHAR* AesSQLite3::ASCII2UTF8(IN LPCCH lpASCIIStr)
{
	// 将ASCII字符串转成UNICODE字符串;
	WCHAR* pWideChar = ASCII2UNICODE(lpASCIIStr);
	if ( pWideChar == NULL )
		return NULL;

	// 再将UICODE转成UTF8;
	CHAR* pUTF8 = UNICODE2UTF8(pWideChar);
	if ( pWideChar )
		delete []pWideChar;

	return pUTF8;
}

BOOL AesSQLite3::ASCII2UTF8(IN LPCCH lpASCIIStr, OUT LPCH pUTF8Str, IN CONST INT& nUTF8StrLen)
{
	// 将ASCII字符串转成UNICODE字符串;
	WCHAR* pWideChar = ASCII2UNICODE(lpASCIIStr);
	if ( pWideChar == NULL )
		return FALSE;

	// 再将UICODE转成UTF8;
	BOOL bResult = UNICODE2UTF8(pWideChar, pUTF8Str, nUTF8StrLen);
	
	if ( pWideChar )
		delete []pWideChar;

	return bResult;
}

BOOL AesSQLite3::Open(IN LPCTSTR lpSQLitePath)
{
	if ( lpSQLitePath == NULL || PathFileExists(lpSQLitePath) == FALSE )
	{
		return FALSE;
	}

	CHAR szUTF8Path[MAX_PATH] = {0};
#ifdef UNICODE
	if ( !UNICODE2UTF8(lpSQLitePath, szUTF8Path, MAX_PATH) )
#else
	if ( !ASCII2UTF8(lpSQLitePath, szUTF8Path, MAX_PATH) )
#endif
	{
		return FALSE;
	}

	INT nSQLiteError = sqlite3_open(szUTF8Path, &m_pSQLite3);
	if ( nSQLiteError != SQLITE_OK )
		return FALSE;

	if ( m_bSetKey)
		nSQLiteError = sqlite3_key(m_pSQLite3, m_szKey, m_nKeyLen);

	return TRUE;
}

void AesSQLite3::Close()
{
	if ( m_pSQLite3 )
	{
		INT nError = sqlite3_close(m_pSQLite3);
		if ( nError != SQLITE_OK )
		{
			printf("关闭数据库失败\n");
		}
		else
			m_pSQLite3 = NULL;
	}
}

INT AesSQLite3::Execute(IN LPCTSTR lpSQL)
{
	if ( m_pSQLite3 || lpSQL == NULL )
		return SQLITE_ERROR;

	CHAR* psError = NULL;
	INT nRet = SQLITE_ERROR;
#ifdef UNICODE
	CHAR* pSQL = UNICODE2ASCII(lpSQL);
	if ( pSQL == NULL )
		return SQLITE_ERROR;
	
	nRet = sqlite3_exec(m_pSQLite3, pSQL, NULL, 0, &psError);
	if ( pSQL )
		delete []pSQL;
#else
	nRet = sqlite3_exec(m_pSQLite3, lpSQL, NULL, 0, &psError);
#endif
	
	return nRet;
}