X Tutup
/* * 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
X Tutup