/* 
 * Copyright (C) 2012 Yee Young Han <websearch@naver.com> (http://blog.naver.com/websearch)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */

#include "StringUtility.h"
#include <string.h>
#include <stdlib.h>
#include "MemoryDebug.h"

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­¿¡ Æ÷ÇÔµÈ ¹®ÀÚ¿­À» ¼öÁ¤ÇÑ´Ù.
 * @param strCallId	¹®ÀÚ¿­
 * @param pszBefore ¼öÁ¤ ´ë»ó ¹®ÀÚ¿­
 * @param pszAfter	¼öÁ¤ ´ë»ó ¹®ÀÚ¿­À» ¼öÁ¤ÇÒ ¹®ÀÚ¿­
 */
void ReplaceString( std::string & strCallId, const char * pszBefore, const char * pszAfter )
{
	size_t iPos = strCallId.find( pszBefore );
	size_t iBeforeLen = strlen( pszBefore );
	size_t iAfterLen = strlen( pszAfter );

	while( iPos < std::string::npos )
	{
		strCallId.replace( iPos, iBeforeLen, pszAfter );
		iPos = strCallId.find( pszBefore, iPos + iAfterLen );
	}
}

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­¿¡ Æ÷ÇÔµÈ Å°ÀÇ °ªÀ» ÃßÃâÇÑ´Ù. 
 *				"app=36;msg=36;hotline=46;presence=36; broadcast=46" ¹®ÀÚ¿­¿¡¼­ 
 *				app ÀÇ °ªÀ» ÃßÃâÇÏ°í ½ÍÀ¸¸é pszKey ¿¡ "app=" ¸¦ ÀÔ·ÂÇÏ°í cSep ¿¡ ';' ¸¦ ÀÔ·ÂÇÏ¸é µÈ´Ù.
 * @param strText		¹®ÀÚ¿­
 * @param pszKey		Å°
 * @param cSep			±¸ºÐÀÚ
 * @param strValue	Å°ÀÇ °ªÀ» ÀúÀåÇÒ º¯¼ö
 * @returns ¼º°øÇÏ¸é true ¸¦ ¸®ÅÏÇÏ°í ½ÇÆÐÇÏ¸é false ¸¦ ¸®ÅÏÇÑ´Ù.
 */
bool SearchValue( std::string & strText, const char * pszKey, char cSep, std::string & strValue )
{
	strValue.clear();

	size_t iPos = strText.find( pszKey );
	if( iPos < std::string::npos )
	{
		size_t iKeyLen = strlen( pszKey );
		size_t iEndPos = strText.find( cSep, iPos + iKeyLen );

		if( iEndPos < std::string::npos )
		{
			strValue = strText.substr( iPos + iKeyLen, iEndPos - ( iPos + iKeyLen ) );
		}
		else
		{
			strValue = strText.substr( iPos + iKeyLen );
		}

		return true;
	}

	return false;
}

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­¿¡ Æ÷ÇÔµÈ Å°ÀÇ °ªÀ» ÃßÃâÇÑ´Ù. 
 *				"app=36;msg=36;hotline=46;presence=36; broadcast=46" ¹®ÀÚ¿­¿¡¼­ 
 *				app ÀÇ °ªÀ» ÃßÃâÇÏ°í ½ÍÀ¸¸é pszKey ¿¡ "app=" ¸¦ ÀÔ·ÂÇÏ°í cSep ¿¡ ';' ¸¦ ÀÔ·ÂÇÏ¸é µÈ´Ù.
 * @param strText		¹®ÀÚ¿­
 * @param pszKey		Å°
 * @param cSep			±¸ºÐÀÚ
 * @param iValue		Å°ÀÇ °ªÀ» ÀúÀåÇÒ º¯¼ö
 * @returns ¼º°øÇÏ¸é true ¸¦ ¸®ÅÏÇÏ°í ½ÇÆÐÇÏ¸é false ¸¦ ¸®ÅÏÇÑ´Ù.
 */
bool SearchValue( std::string & strText, const char * pszKey, char cSep, int & iValue )
{
	std::string	strValue;

	if( SearchValue( strText, pszKey, cSep, strValue ) )
	{
		iValue = atoi( strValue.c_str() );

		return true;
	}

	return false;
}

/**
 * @ingroup SipPlatform
 * @brief °Ë»ö ¹®ÀÚ¿­ÀÌ ¹®ÀÚ¿­ ¸®½ºÆ®¿¡ Á¸ÀçÇÏ´ÂÁö °Ë»çÇÑ´Ù.
 * @param clsList ¹®ÀÚ¿­ ¸®½ºÆ®
 * @param pszKey	°Ë»ö ¹®ÀÚ¿­
 * @returns °Ë»ö ¹®ÀÚ¿­ÀÌ ¹®ÀÚ¿­ ¸®½ºÆ®¿¡ Á¸ÀçÇÏ¸é true ¸¦ ¸®ÅÏÇÏ°í ±×·¸Áö ¾ÊÀ¸¸é false ¸¦ ¸®ÅÏÇÑ´Ù.
 */
bool SearchStringList( STRING_LIST & clsList, const char * pszKey )
{
	STRING_LIST::iterator itList;

	for( itList = clsList.begin(); itList != clsList.end(); ++itList )
	{
		if( !strcmp( pszKey, itList->c_str() ) )
		{
			return true;
		}
	}

	return false;
}

/**
 * @ingroup SipPlatform
 * @brief °Ë»ö ¹®ÀÚ¿­ÀÌ ¹®ÀÚ¿­ ¸®½ºÆ®¿¡ Á¸ÀçÇÏ¸é »èÁ¦ÇÑ´Ù.
 * @param clsList ¹®ÀÚ¿­ ¸®½ºÆ®
 * @param pszKey	°Ë»ö ¹®ÀÚ¿­
 * @returns °Ë»ö ¹®ÀÚ¿­ÀÌ ¹®ÀÚ¿­ ¸®½ºÆ®¿¡ Á¸ÀçÇÏ¸é true ¸¦ ¸®ÅÏÇÏ°í ±×·¸Áö ¾ÊÀ¸¸é false ¸¦ ¸®ÅÏÇÑ´Ù.
 */
bool DeleteStringList( STRING_LIST & clsList, const char * pszKey )
{
	STRING_LIST::iterator itList;

	for( itList = clsList.begin(); itList != clsList.end(); ++itList )
	{
		if( !strcmp( pszKey, itList->c_str() ) )
		{
			clsList.erase( itList );
			return true;
		}
	}

	return false;
}

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­ÀÌ ¹®ÀÚ¿­ ¸®½ºÆ®¿¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é Ãß°¡ÇÑ´Ù.
 * @param clsList ¹®ÀÚ¿­ ¸®½ºÆ®
 * @param pszKey	¹®ÀÚ¿­
 */
void InsertStringList( STRING_LIST & clsList, const char * pszKey )
{
	STRING_LIST::iterator itList;

	for( itList = clsList.begin(); itList != clsList.end(); ++itList )
	{
		if( !strcmp( pszKey, itList->c_str() ) )
		{
			return;
		}
	}

	clsList.push_back( pszKey );
}

/**
 * @ingroup SipPlatform
 * @brief ÀÔ·Â ¹®ÀÚ¿­ ¸®½ºÆ®ÀÇ °¢ ¹®ÀÚ¿­ÀÌ ÀúÀå ¹®ÀÚ¿­ ¸®½ºÆ®¿¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é ÀúÀå ¹®ÀÚ¿­ ¸®½ºÆ®¿¡ ÀúÀåÇÑ´Ù.
 * @param clsList			ÀúÀå ¹®ÀÚ¿­ ¸®½ºÆ®
 * @param clsSrcList	ÀÔ·Â ¹®ÀÚ¿­ ¸®½ºÆ®
 */
void InsertStringList( STRING_LIST & clsList, STRING_LIST & clsSrcList )
{
	STRING_LIST::iterator itList;

	for( itList = clsSrcList.begin(); itList != clsSrcList.end(); ++itList )
	{
		InsertStringList( clsList, itList->c_str() );
	}
}

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­ ¸®½ºÆ®¸¦ ·Î±×·Î Ãâ·ÂÇÑ´Ù.
 * @param eLevel	·Î±× ·¹º§
 * @param pszName ·Î±× ¸Þ½ÃÁö ÀÌ¸§
 * @param clsList ¹®ÀÚ¿­ ¸®½ºÆ®
 */
void LogStringList( EnumLogLevel eLevel, const char * pszName, STRING_LIST & clsList )
{
	if( CLog::IsPrintLogLevel( eLevel ) )
	{
		STRING_LIST::iterator itList;
		std::string strData;

		for( itList = clsList.begin(); itList != clsList.end(); ++itList )
		{
			if( strData.empty() == false ) strData.append( ", " );
			strData.append( *itList );
		}

		CLog::Print( eLevel, "%s [%s]", pszName, strData.c_str() );
	}
}


/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­ÀÇ ¿ÞÂÊ °ø¹éÀ» Á¦°ÅÇÑ´Ù.
 * @param strText ¹®ÀÚ¿­
 */
void LeftTrimString( std::string & strText )
{
	int iIndex;
	int iLen = (int)strText.length();
	for( iIndex = 0; iIndex < iLen; ++iIndex )
	{
		char c = strText.at(iIndex);
		if( c == ' ' || c == '\t' ) continue;

		strText.erase( 0, iIndex );
		break;
	}

	if( iIndex == iLen )
	{
		strText.clear();
	}
}

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­ÀÇ ¿À¸¥ÂÊ °ø¹éÀ» Á¦°ÅÇÑ´Ù.
 * @param strText ¹®ÀÚ¿­
 */
void RightTrimString( std::string & strText )
{
	int iIndex;
	int iLen = (int)strText.length();
	for( iIndex = iLen - 1; iIndex >= 0; --iIndex )
	{
		char c = strText.at(iIndex);
		if( c == ' ' || c == '\t' ) continue;

		if( iIndex != ( iLen - 1 ) )
		{
			strText.erase( iIndex + 1 );
		}

		break;
	}

	if( iIndex == -1 )
	{
		strText.clear();
	}
}

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­ÀÇ ¿ÞÂÊ, ¿À¸¥ÂÊ °ø¹éÀ» Á¦°ÅÇÑ´Ù.
 * @param strText ¹®ÀÚ¿­
 */
void TrimString( std::string & strText )
{
	LeftTrimString( strText );
	RightTrimString( strText );
}

/**
 * @ingroup SipPlatform
 * @brief ÀÔ·Â ¹®ÀÚ¿­À» ±¸ºÐÀÚ·Î ºÐ¸®ÇÏ¿©¼­ ¹®ÀÚ¿­ ¸®½ºÆ®¿¡ ÀúÀåÇÑ´Ù.
 * @param pszText ÀÔ·Â ¹®ÀÚ¿­
 * @param clsList ¹®ÀÚ¿­ ¸®½ºÆ®
 * @param cSep		±¸ºÐÀÚ
 */
void SplitString( const char * pszText, STRING_LIST & clsList, char cSep )
{
	int iStartPos = -1, i;

	clsList.clear();

	for( i = 0; pszText[i]; ++i )
	{
		if( pszText[i] == cSep )
		{
			if( iStartPos >= 0 && iStartPos != i )
			{
				std::string strTemp;

				strTemp.append( pszText + iStartPos, i - iStartPos );
				clsList.push_back( strTemp );
			}

			iStartPos = i + 1;
		}
		else if( i == 0 )
		{
			iStartPos = 0;
		}
	}

	if( iStartPos >= 0 && iStartPos != i )
	{
		std::string strTemp;

		strTemp.append( pszText + iStartPos, i - iStartPos );
		clsList.push_back( strTemp );
	}
}

/**
 * @ingroup SipPlatform
 * @brief ÀÔ·Â ¹®ÀÚ¿­À» ±¸ºÐÀÚ·Î ºÐ¸®ÇÏ¿©¼­ ¹®ÀÚ¿­ ¸®½ºÆ®¿¡ ÀúÀåÇÑ´Ù.
 * @param pszText ÀÔ·Â ¹®ÀÚ¿­
 * @param clsList ¹®ÀÚ¿­ ¸®½ºÆ®
 * @param cSep		±¸ºÐÀÚ
 */
void SplitString( const char * pszText, STRING_VECTOR & clsList, char cSep )
{
	int iStartPos = -1, i;

	clsList.clear();

	for( i = 0; pszText[i]; ++i )
	{
		if( pszText[i] == cSep )
		{
			if( iStartPos >= 0 && iStartPos != i )
			{
				std::string strTemp;

				strTemp.append( pszText + iStartPos, i - iStartPos );
				clsList.push_back( strTemp );
			}

			iStartPos = i + 1;
		}
		else if( i == 0 )
		{
			iStartPos = 0;
		}
	}

	if( iStartPos >= 0 && iStartPos != i )
	{
		std::string strTemp;

		strTemp.append( pszText + iStartPos, i - iStartPos );
		clsList.push_back( strTemp );
	}
}

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­À» unsigned int ·Î º¯È¯ÇÑ´Ù.
 * @param pszText ¹®ÀÚ¿­
 * @returns unsigned int ¸¦ ¸®ÅÏÇÑ´Ù.
 */
uint32_t GetUInt32( const char * pszText )
{
	if( pszText == NULL ) return 0;

	return strtoul( pszText, NULL, 10 );
}

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­À» unsigned long long À¸·Î º¯È¯ÇÑ´Ù.
 * @param pszText ¹®ÀÚ¿­
 * @returns unsigned long long À» ¸®ÅÏÇÑ´Ù.
 */
uint64_t GetUInt64( const char * pszText )
{
	if( pszText == NULL ) return 0;

#ifdef WIN32
	return _strtoui64( pszText, NULL, 10 );
#else
	return strtoull( pszText, NULL, 10 );
#endif
}

/**
 * @ingroup SipPlatform
 * @brief ÁöÁ¤µÉ ±æÀÌ¸¸Å­ÀÇ ¹®ÀÚ¿­À» ¼ýÀÚ·Î º¯È¯ÇÑ´Ù.
 * @param pszText		¼ýÀÚ ¹®ÀÚ¿­
 * @param iTextLen	¹®ÀÚ¿­ ±æÀÌ
 * @returns ¼º°øÇÏ¸é ¿øÇÏ´Â ¼ýÀÚ°¡ ¸®ÅÏµÇ°í ½ÇÆÐÇÏ¸é 0 ÀÌ ¸®ÅÏµÈ´Ù.
 */
int GetInt( const char * pszText, int iTextLen )
{
	char szNum[11];

	if( iTextLen > 10 || iTextLen <= 0 ) return 0;

	memcpy( szNum, pszText, iTextLen );
	szNum[iTextLen] = '\0';

	return atoi( szNum );
}

/**
 * @ingroup SipPlatform
 * @brief HEX ¸¸ ÀúÀåµÈ ¹®ÀÚ¿­À» ¼ýÀÚ·Î º¯È¯ÇÑ ¹®ÀÚ¿­·Î º¯È¯ÇÑ´Ù.
 * @param pszInput	HEX ¸¸ ÀúÀåµÈ ¹®ÀÚ¿­
 * @param strOutput [out] ¼ýÀÚ·Î º¯È¯µÈ ¹®ÀÚ¿­
 * @returns ¼º°øÇÏ¸é true ¸¦ ¸®ÅÏÇÏ°í ½ÇÆÐÇÏ¸é false ¸¦ ¸®ÅÏÇÑ´Ù.
 */
bool HexToString( const char * pszInput, std::string & strOutput )
{
	int iLen = (int)strlen( pszInput );
	int iValue;

	strOutput.clear();

	if( iLen >= 2 )
	{
		if( pszInput[0] == '0' && pszInput[1] == 'x' )
		{
			pszInput += 2;
			iLen -= 2;
		}
	}

	if( iLen == 0 || iLen % 2 == 1 ) return false;

	for( int i = 0; i < iLen; i += 2 )
	{
		sscanf( pszInput + i, "%02x", &iValue );
		strOutput.push_back( (char)iValue );
	}

	return true;
}

/**
 * @ingroup SipPlatform
 * @brief ¼ýÀÚ°¡ ÀúÀåµÈ ¹®ÀÚ¿­À» HEX ¸¸ ÀúÀåµÈ ¹®ÀÚ¿­·Î º¯È¯ÇÑ´Ù.
 * @param pszInput	¼ýÀÚ°¡ ÀúÀåµÈ ¹®ÀÚ¿­
 * @param iInputLen	pszInput º¯¼öÀÇ ±æÀÌ
 * @param strOutput [out] HEX ¸¸ ÀúÀåµÈ ¹®ÀÚ¿­
 */
void StringToHex( const char * pszInput, int iInputLen, std::string & strOutput )
{
	char szHex[3];

	strOutput.clear();

	for( int i = 0; i < iInputLen; ++i )
	{
		snprintf( szHex, sizeof(szHex), "%02x", (uint8_t)pszInput[i] );
		strOutput.append( szHex );
	}
}

/**
 * @ingroup SipPlatform
 * @brief ¹®ÀÚ¿­ÀÌ Ãâ·Â °¡´ÉÇÑÁö °Ë»çÇÑ´Ù.
 * @param pszText		¹®ÀÚ¿­
 * @param iTextLen	¹®ÀÚ¿­ ±æÀÌ
 * @returns ¹®ÀÚ¿­ÀÌ Ãâ·Â °¡´ÉÇÏ¸é true ¸¦ ¸®ÅÏÇÏ°í ±×·¸Áö ¾ÊÀ¸¸é false ¸¦ ¸®ÅÏÇÑ´Ù.
 */
bool IsPrintString( const char * pszText, int iTextLen )
{
	for( int i = 0; i < iTextLen; ++i )
	{
		if( isprint( (uint8_t)pszText[i] ) == 0 ) return false;
	}

	return true;
}

/**
 * @ingroup SipPlatform
 * @brief ÀÔ·ÂµÈ ¹®ÀÚ¿­¿¡¼­ " ¸¦ Á¦°ÅÇÑ Ãâ·Â ¹®ÀÚ¿­À» ÀúÀåÇÑ´Ù.
 * @param strInput	ÀÔ·Â ¹®ÀÚ¿­
 * @param strOutput Ãâ·Â ¹®ÀÚ¿­
 */
void DeQuoteString( std::string & strInput, std::string & strOutput )
{
	int iLen = (int)strInput.length();

	strOutput.clear();

	if( iLen > 0 )
	{
		if( strInput.at( 0 ) != '"' || strInput.at( iLen - 1 ) != '"' )
		{
			strOutput = strInput;
		}
		else
		{
			strOutput.append( strInput, 1, iLen - 2 );
		}
	}
}

#ifdef WIN32

#include <windows.h>

/**
 * @ingroup SipPlatform
 * @brief UTF8 ¹®ÀÚ¿­À» ANSI ¹®ÀÚ¿­·Î º¯È¯ÇÑ´Ù.
 * @param pszUtf8		UTF8 ¹®ÀÚ¿­ (input)
 * @param strOutput ANSI ¹®ÀÚ¿­ (output)
 * @returns ¼º°øÇÏ¸é true ¸¦ ¸®ÅÏÇÏ°í ½ÇÆÐÇÏ¸é false ¸¦ ¸®ÅÏÇÑ´Ù.
 */
bool Utf8ToAnsi( const char * pszUtf8, std::string & strOutput )
{
	BSTR    strWide = NULL;
	char*   pszAnsi = NULL;
	int     iLength;
	int			iUtf8Length = (int)strlen(pszUtf8) + 1;
	
	iLength = MultiByteToWideChar( CP_UTF8, 0, pszUtf8, iUtf8Length, NULL, NULL );
	if( iLength == 0 )
	{
		CLog::Print( LOG_ERROR, "%s MultiByteToWideChar error(%d)", __FUNCTION__, GetLastError() );
		return false;
	}

	strWide = SysAllocStringLen( NULL, iLength );
	if( strWide == NULL )
	{
		CLog::Print( LOG_ERROR, "%s SysAllocStringLen error(%d)", __FUNCTION__, GetLastError() );
		return false;
	}

	MultiByteToWideChar( CP_UTF8, 0, pszUtf8, iUtf8Length, strWide, iLength );

	iLength = WideCharToMultiByte( CP_ACP, 0, strWide, -1, NULL, 0, NULL, NULL );
	if( iLength == 0 )
	{
		SysFreeString( strWide );
		CLog::Print( LOG_ERROR, "%s WideCharToMultiByte error(%d)", __FUNCTION__, GetLastError() );
		return false;
	}

	pszAnsi = new char[iLength];
	if( pszAnsi == NULL )
	{
		SysFreeString( strWide );
		CLog::Print( LOG_ERROR, "%s new error(%d)", __FUNCTION__, GetLastError() );
		return false;
	}

	WideCharToMultiByte( CP_ACP, 0, strWide, -1, pszAnsi, iLength, NULL, NULL );
	strOutput = pszAnsi;
	
	SysFreeString( strWide );
	delete [] pszAnsi;
	
	return true;
}

/**
 * @ingroup SipPlatform
 * @brief ANSI ¹®ÀÚ¿­À» UTF-8 ¹®ÀÚ¿­·Î º¯È¯ÇÑ´Ù. EUC-KR ¹®ÀÚ¿­À» UTF-8 ¹®ÀÚ¿­·Î º¯È¯ÇÑ´Ù.
 * @param pszAnsi		ANSI ¹®ÀÚ¿­
 * @param strOutput UTF-8 ¹®ÀÚ¿­À» ÀúÀåÇÒ º¯¼ö
 * @returns ¼º°øÇÏ¸é true ¸¦ ¸®ÅÏÇÏ°í ½ÇÆÐÇÏ¸é false ¸¦ ¸®ÅÏÇÑ´Ù.
 */
bool AnsiToUtf8( const char * pszAnsi, std::string & strOutput )
{
	BSTR    strWide = NULL;
	char*   pszUtf8 = NULL;
	int     iLength;
	int			iAnsiLength = (int)strlen(pszAnsi) + 1;
	
	iLength = MultiByteToWideChar( CP_ACP, 0, pszAnsi, iAnsiLength, NULL, NULL );
	if( iLength == 0 )
	{
		CLog::Print( LOG_ERROR, "%s MultiByteToWideChar error(%d)", __FUNCTION__, GetLastError() );
		return false;
	}

	strWide = SysAllocStringLen( NULL, iLength );
	if( strWide == NULL )
	{
		CLog::Print( LOG_ERROR, "%s SysAllocStringLen error(%d)", __FUNCTION__, GetLastError() );
		return false;
	}

	MultiByteToWideChar( CP_ACP, 0, pszAnsi, iAnsiLength, strWide, iLength );

	iLength = WideCharToMultiByte( CP_UTF8, 0, strWide, -1, NULL, 0, NULL, NULL );
	if( iLength == 0 )
	{
		SysFreeString( strWide );
		CLog::Print( LOG_ERROR, "%s WideCharToMultiByte error(%d)", __FUNCTION__, GetLastError() );
		return false;
	}

	pszUtf8 = new char[iLength];
	if( pszUtf8 == NULL )
	{
		SysFreeString( strWide );
		CLog::Print( LOG_ERROR, "%s new error(%d)", __FUNCTION__, GetLastError() );
		return false;
	}

	WideCharToMultiByte( CP_UTF8, 0, strWide, -1, pszUtf8, iLength, NULL, NULL );
	strOutput = pszUtf8;
	
	SysFreeString( strWide );
	delete [] pszUtf8;
	
	return true;
}

#endif
