/*
* Copyright (C) 2012 Yee Young Han (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
#include
#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
/**
* @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