From 9e9fdc25bcf6519e9800b5ab8175459eb724e841 Mon Sep 17 00:00:00 2001 From: zilmar Date: Wed, 17 Apr 2013 20:29:48 +1000 Subject: [PATCH] Common: Update std string class --- Source/Common/Trace.h | 2 +- Source/Common/Version.cpp | 2 +- Source/Common/path.cpp | 24 ++- Source/Common/path.h | 1 + Source/Common/std string.cpp | 344 +++++++++++++++++------------------ Source/Common/std string.h | 63 +++---- 6 files changed, 212 insertions(+), 224 deletions(-) diff --git a/Source/Common/Trace.h b/Source/Common/Trace.h index 00c294ee7..4c8d21fd3 100644 --- a/Source/Common/Trace.h +++ b/Source/Common/Trace.h @@ -39,7 +39,7 @@ public: OutputDebugString(Message); if (EndOfLine) { - OutputDebugString(_T("\n")); + OutputDebugString("\n"); } } }; diff --git a/Source/Common/Version.cpp b/Source/Common/Version.cpp index 0e40d28b3..e73a9e897 100644 --- a/Source/Common/Version.cpp +++ b/Source/Common/Version.cpp @@ -101,7 +101,7 @@ stdstr FileVersionInfo( LPCTSTR Info, LPCTSTR FileName ) { if (strcmp(Info,VERSION_PRODUCT_VERSION) == 0) { - Result.replace(" ",""); + Result.Replace(" ",""); } } else { WriteTraceF(TraceError,_T("FileVersionInfo(%s), ReadVersionInfo() failed"), FileName); diff --git a/Source/Common/path.cpp b/Source/Common/path.cpp index 0684292ce..dffd79696 100644 --- a/Source/Common/path.cpp +++ b/Source/Common/path.cpp @@ -2496,16 +2496,26 @@ BOOL CPath::CreateDirectory(BOOL bCreateIntermediates /*= TRUE*/) //------------------------------------------------------------------------ void CPath::cleanPathString(stdstr& rDirectory) const { - rDirectory.replace(DIRECTORY_DELIMITER2,DIRECTORY_DELIMITER); + LPCSTR const DIR_DOUBLEDELIM = "\\\\"; - if(!_tcsnicmp(rDirectory.c_str(), _T("\\\\"), 2)) + std::string::size_type pos = rDirectory.find( DIRECTORY_DELIMITER2 ); + while ( pos != std::string::npos ) { - rDirectory.replace(DIR_DOUBLEDELIM,DIRECTORY_DELIMITER); - - rDirectory.insert(0, _T("\\")); + rDirectory.replace( pos, 1, &DIRECTORY_DELIMITER ); + pos = rDirectory.find( DIRECTORY_DELIMITER2, pos + 1 ); + } + + bool AppendEnd = !_strnicmp(rDirectory.c_str(), "\\\\", 2); + pos = rDirectory.find( DIR_DOUBLEDELIM ); + while ( pos != std::string::npos ) + { + rDirectory.replace( pos, 1, &DIRECTORY_DELIMITER ); + pos = rDirectory.find( DIR_DOUBLEDELIM, pos + 1 ); + } + if (AppendEnd) + { + rDirectory.insert(0, "\\"); } - else - rDirectory.replace(DIR_DOUBLEDELIM,DIRECTORY_DELIMITER); } void CPath::StripLeadingChar(stdstr& rText, TCHAR chLeading) const diff --git a/Source/Common/path.h b/Source/Common/path.h index 00bbf866a..f3193d72d 100644 --- a/Source/Common/path.h +++ b/Source/Common/path.h @@ -18,6 +18,7 @@ #include "std string.h" #include #include +#include class CPathException { diff --git a/Source/Common/std string.cpp b/Source/Common/std string.cpp index 694716042..83fb97a49 100644 --- a/Source/Common/std string.cpp +++ b/Source/Common/std string.cpp @@ -1,43 +1,72 @@ #include "stdafx.h" - -void stdstr::ArgFormat(const TCHAR * strFormat, va_list & args) -{ - if (strFormat != NULL) { - // declare buffer (default max buffer size = 32k) - const int nMaxSize = 32*1024; - TCHAR pBuffer[nMaxSize]; - - _vsntprintf(pBuffer,nMaxSize - 1,strFormat,args); - pBuffer[nMaxSize - 1] = 0; - - tstring * _this = this; - *_this = pBuffer; - } else { - *((tstring *)this) = _T(""); - } -} +#include stdstr::stdstr() { - } -stdstr::stdstr( const tstring & str ) -{ - *((tstring *)this) = str; -} - -stdstr::stdstr( const stdstr & str ) +stdstr::stdstr( const std::string & str ) : + std::string(str) { - *((tstring *)this) = (tstring)str; } -stdstr::stdstr( const TCHAR * str ) +stdstr::stdstr( const stdstr & str ) : + std::string((const std::string &)str) { - *((tstring *)this) = str ? str : ""; } -void stdstr::Format(const TCHAR * strFormat, ...) +stdstr::stdstr( const char * str ) : +std::string(str ? str : "") +{ +} + +strvector stdstr::Tokenize(const char * delimiter) const +{ + strvector tokens; + + stdstr::size_type lastPos = find_first_not_of(delimiter, 0); + stdstr::size_type pos = find_first_of(delimiter, lastPos); + while (stdstr::npos != pos || stdstr::npos != lastPos) + { + tokens.push_back(substr(lastPos, pos - lastPos)); + lastPos = find_first_not_of(delimiter, pos); + pos = find_first_of(delimiter, lastPos); + } + return tokens; +} + +strvector stdstr::Tokenize(char delimiter) const +{ + strvector tokens; + + stdstr::size_type lastPos = find_first_not_of(delimiter, 0); + stdstr::size_type pos = find_first_of(delimiter, lastPos); + while (stdstr::npos != pos || stdstr::npos != lastPos) + { + tokens.push_back(substr(lastPos, pos - lastPos)); + lastPos = find_first_not_of(delimiter, pos); + pos = find_first_of(delimiter, lastPos); + } + return tokens; +} + +void stdstr::ArgFormat(const char * strFormat, va_list & args) +{ +#pragma warning(push) +#pragma warning(disable:4996) + + size_t nlen = _vscprintf( strFormat, args ) + 1; + char * buffer = (char *)alloca(nlen * sizeof(char)); + buffer[nlen - 1] = 0; + if(buffer != NULL) + { + vsprintf( buffer, strFormat , args ); + *this = buffer; + } +#pragma warning(pop) +} + +void stdstr::Format(const char * strFormat, ...) { va_list args; va_start(args, strFormat); @@ -45,210 +74,165 @@ void stdstr::Format(const TCHAR * strFormat, ...) va_end(args); } -void stdstr::replace(const TCHAR search, const TCHAR replace ) +stdstr& stdstr::ToLower(void) { - tstring& str = *this; - tstring::size_type pos = str.find( search ); - while ( pos != tstring::npos ) + std::transform(begin(), end(), begin(), (int(*)(int)) tolower); + return *this; +} + +stdstr& stdstr::ToUpper(void) +{ + std::transform(begin(), end(), begin(), (int(*)(int)) toupper); + return *this; +} + +void stdstr::Replace(const char search, const char replace ) +{ + std::string& str = *this; + std::string::size_type pos = str.find( search ); + while ( pos != std::string::npos ) { str.replace( pos, 1, &replace ); pos = str.find( search, pos + 1 ); } } -void stdstr::replace(const TCHAR * search, const TCHAR replace ) +void stdstr::Replace(const char * search, const char replace ) { - tstring& str = *this; - tstring::size_type pos = str.find( search ); - size_t SearchSize = _tcslen(search); - while ( pos != tstring::npos ) + std::string& str = *this; + std::string::size_type pos = str.find( search ); + size_t SearchSize = strlen(search); + while ( pos != std::string::npos ) { str.replace( pos, SearchSize, &replace ); pos = str.find( search, pos + 1 ); } } -void stdstr::replace(const tstring& search, const tstring& replace ) +void stdstr::Replace(const std::string& search, const std::string& replace ) { - tstring& str = *this; - tstring::size_type pos = str.find( search ); + std::string& str = *this; + std::string::size_type pos = str.find( search ); size_t SearchSize = search.size(); - while ( pos != tstring::npos ) + while ( pos != std::string::npos ) { str.replace( pos, SearchSize, replace ); pos = str.find( search, pos + replace.length() ); } } -stdstr& stdstr::Trim(bool StripEnter) -{ - tstring& str = *this; - while ((str.size() && str[0] == ' ') || - (StripEnter && (str[0] == '\r' || str[0] == '\n'))) - { - str = str.substr(1); - } - - while (str.size() && (str[str.size()-1] == ' ' || - (StripEnter && (str[str.size()-1] == '\r' || str[str.size()-1] == '\n')))) - { - str = str.substr(0, str.size() - 1); - } - return *this; -} - -stdstr& stdstr::ToLower(void) -{ - tstring& str = *this; - std::transform(str.begin(), str.end(), str.begin(), (int(*)(int)) tolower); - return *this; -} - -stdstr& stdstr::ToUpper(void) -{ - tstring& str = *this; - std::transform(str.begin(), str.end(), str.begin(), (int(*)(int)) toupper); - return *this; -} - -strvector stdstr::Tokenize(const stdstr& delimiters) const -{ - const stdstr& str = *this; - - strvector tokens; - - // skip delimiters at beginning. - stdstr::size_type lastPos = str.find_first_not_of(delimiters, 0); - - // find first "non-delimiter". - stdstr::size_type pos = str.find_first_of(delimiters, lastPos); - - while (stdstr::npos != pos || stdstr::npos != lastPos) - { - // found a token, add it to the vector. - tokens.push_back(str.substr(lastPos, pos - lastPos)); - - // skip delimiters. Note the "not_of" - lastPos = str.find_first_not_of(delimiters, pos); - - // find next "non-delimiter" - pos = str.find_first_of(delimiters, lastPos); - } - - return tokens; -} - -void stdstr::TrimLeft (const TCHAR * chars2remove) +stdstr & stdstr::TrimLeft (const char * chars2remove) { if (!empty()) { - tstring::size_type pos = find_first_not_of(chars2remove); - if (pos != tstring::npos) + std::string::size_type pos = find_first_not_of(chars2remove); + if (pos != std::string::npos) { erase(0,pos); } else { erase(begin(), end()); // make empty } } + return *this; } -void stdstr::TrimRight (const TCHAR * chars2remove) +stdstr & stdstr::TrimRight (const char * chars2remove) { if (!empty()) { - tstring::size_type pos = find_last_not_of(chars2remove); - if (pos != tstring::npos) + std::string::size_type pos = find_last_not_of(chars2remove); + if (pos != std::string::npos) { erase(pos+1); } else { erase(begin(), end()); // make empty } } + return *this; } -stdstr stdstr::toTString(const char *pstrSource) +stdstr & stdstr::Trim (const char * chars2remove) { -#ifndef _UNICODE - return pstrSource; -#else - stdstr strRet; - // Allocate enough space for the UNICODE string - int nNeeded = MultiByteToWideChar(CP_UTF8, - 0, - pstrSource, - -1, //str is null terminated - NULL, - 0); - if (nNeeded == 0) + if (!empty()) { - return strRet; + std::string::size_type pos = find_first_not_of(chars2remove); + if (pos != std::string::npos) + { + erase(0,pos); + } else { + erase(begin(), end()); // make empty + } + + pos = find_last_not_of(chars2remove); + if (pos != std::string::npos) + { + erase(pos+1); + } else { + erase(begin(), end()); // make empty + } } - - wchar_t* lpStrW = new wchar_t[nNeeded + 1]; - ZeroMemory(lpStrW, (nNeeded + 1)*sizeof(wchar_t)); - - // Convert the string from ansi to Unicode - nNeeded= MultiByteToWideChar(CP_UTF8, - 0, - pstrSource, - -1, //str is null terminated - lpStrW, - nNeeded+1); - if (!nNeeded) - { - delete [] lpStrW; - return strRet; - } - strRet = lpStrW; - delete [] lpStrW; - - return strRet; -#endif + return *this; } -std::string stdstr::fromTString(const stdstr &strSource) +stdstr & stdstr::FromUTF16 ( const wchar_t * UTF16Source, bool * bSuccess ) { -#ifndef _UNICODE - return strSource; -#else - std::string strRet; - // Get the size of the Unicode string + bool bConverted = false; - // Allocate enough space for the Ansi string - int nNeeded = WideCharToMultiByte(CP_UTF8, - 0, - strSource.c_str(), - -1, //str is null terminated - NULL, - 0, - NULL, - NULL); - if (nNeeded == 0) + if (UTF16Source == NULL) { - return strRet; - } - - char* lpStrA = new char[nNeeded + 1]; - ZeroMemory(lpStrA, nNeeded + 1); - - // Convert the string from Unicode to ansi - nNeeded= WideCharToMultiByte(CP_UTF8, - 0, - strSource.c_str(), - -1, //str is null terminated - lpStrA, - nNeeded+1, - NULL, - NULL); - if (!nNeeded) + *this = ""; + bConverted = true; + } + else if(wcslen(UTF16Source) > 0) { - delete [] lpStrA; - return strRet; + DWORD nNeeded = WideCharToMultiByte(CP_UTF8, 0, UTF16Source, -1, NULL, 0, NULL, NULL); + if(nNeeded > 0) + { + char * buf = (char *)alloca(nNeeded + 1); + if( buf != NULL ) + { + memset(buf, 0, nNeeded + 1); + + nNeeded = WideCharToMultiByte(CP_UTF8, 0, UTF16Source, -1, buf, nNeeded, NULL, NULL); + if (nNeeded) + { + *this = buf; + bConverted = true; + } + } + } } - - strRet = lpStrA; - delete [] lpStrA; - - return strRet; -#endif + if (bSuccess) + { + *bSuccess = bConverted; + } + return *this; +} + +std::wstring stdstr::ToUTF16 ( bool * bSuccess) +{ + bool bConverted = false; + std::wstring res; + + DWORD nNeeded = MultiByteToWideChar(CP_UTF8, 0, this->c_str(), (int)this->length(), NULL, 0); + if(nNeeded > 0) + { + wchar_t * buf = (wchar_t *)alloca((nNeeded + 1) * sizeof(wchar_t)); + if( buf != NULL ) + { + memset(buf, 0, (nNeeded + 1) * sizeof(wchar_t)); + + nNeeded = MultiByteToWideChar(CP_UTF8, 0, this->c_str(), (int)this->length(), buf, nNeeded); + if (nNeeded) + { + res = buf; + bConverted = true; + } + } + } + if (bSuccess) + { + *bSuccess = bConverted; + } + return res; } diff --git a/Source/Common/std string.h b/Source/Common/std string.h index ea1be7baa..8b61aa99b 100644 --- a/Source/Common/std string.h +++ b/Source/Common/std string.h @@ -1,55 +1,48 @@ #pragma once -#pragma warning(disable:4786) - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _UNICODE -typedef std::wstring tstring; -#else -typedef std::string tstring; -#endif - class stdstr; +#include +#include +#include +#include + typedef std::vector strvector; -class stdstr: public tstring +class stdstr : + public std::string { public: stdstr(); - stdstr( const tstring & str ); + stdstr( const std::string & str ); stdstr( const stdstr & str ); - stdstr( const TCHAR * str ); -// stdstr( const TCHAR * strBuff, size_t buffSize); + stdstr( const char * str ); - void Format(const TCHAR * strFormat, ...); - void ArgFormat(const TCHAR * strFormat, va_list & args); + strvector Tokenize ( char delimiter ) const; + strvector Tokenize ( const char * delimiter ) const; + void Format ( const char * strFormat, ... ); + stdstr& ToLower ( void ); + stdstr& ToUpper ( void ); + + void Replace ( const char search, const char replace ); + void Replace ( const char * search, const char replace ); + void Replace ( const std::string & search, const std::string & replace ); + + stdstr & Trim ( const char * chars2remove = "\t " ); + stdstr & TrimLeft ( const char * chars2remove = "\t " ); + stdstr & TrimRight ( const char * chars2remove = "\t " ); + + stdstr & FromUTF16 ( const wchar_t * UTF16Source, bool * bSuccess = NULL); + std::wstring ToUTF16 ( bool * bSuccess = NULL); + + void ArgFormat( const char * strFormat, va_list & args); - //stdstr& operator=(const TCHAR * rhs); - void replace(const TCHAR search, const TCHAR replace ); - void replace(const TCHAR * search, const TCHAR replace ); - void replace(const tstring& search, const tstring& replace ); - stdstr& Trim(bool StripEnter = false); - stdstr& ToLower(void); - stdstr& ToUpper(void); - strvector Tokenize(const stdstr& delimiters) const; - void TrimLeft (const TCHAR * chars2remove = _T(" ")); - void TrimRight (const TCHAR * chars2remove = _T(" ")); - static stdstr toTString(const char *pstrSource); - static std::string fromTString(const stdstr &strSource); }; class stdstr_f: public stdstr { public: - stdstr_f(const TCHAR * strFormat, ...) + stdstr_f(const char * strFormat, ...) { va_list args; va_start(args, strFormat);