1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00
Files
winscp/libs/mfc/source/strex.cpp
Martin Prikryl efe94d6c08 Using actual types and functions instead of WinAPI and Unicode/Ansi macros
Source commit: b7fec4d069296b58bb43e7a4a97dd85d558212b7
2025-12-21 01:34:21 +01:00

236 lines
5.7 KiB
C++

// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include <StrUtils.hpp>
//////////////////////////////////////////////////////////////////////////////
// More sophisticated construction
CString::CString(const wchar_t * lpch, int nLength)
{
m_Data = UnicodeString(lpch, nLength);
}
/////////////////////////////////////////////////////////////////////////////
// Special conversion constructors
CString::CString(const char * lpsz, int nLength)
{
m_Data = UnicodeString(AnsiString(lpsz, nLength));
}
//////////////////////////////////////////////////////////////////////////////
// Assignment operators
const CString& CString::operator=(wchar_t ch)
{
m_Data = ch;
return *this;
}
//////////////////////////////////////////////////////////////////////////////
// less common string expressions
CString operator+(const CString& string1, wchar_t ch)
{
return CString(string1.m_Data + ch);
}
CString operator+(wchar_t ch, const CString& string)
{
return CString(UnicodeString(ch) + string.m_Data);
}
//////////////////////////////////////////////////////////////////////////////
// Advanced manipulation
int CString::Delete(int nIndex, int nCount /* = 1 */)
{
if (nIndex < 0)
nIndex = 0;
int nNewLength = m_Data.Length();
m_Data.Delete(nIndex + 1, nCount);
return nNewLength;
}
int CString::Replace(wchar_t chOld, wchar_t chNew)
{
int nCount = 0;
// short-circuit the nop case
if (chOld != chNew)
{
// otherwise modify each character that matches in the string
m_Data.Unique();
wchar_t * psz = m_Data.c_str();
wchar_t * pszEnd = psz + m_Data.Length();
while (psz < pszEnd)
{
// replace instances of the specified character only
if (*psz == chOld)
{
*psz = chNew;
nCount++;
}
psz = _wcsinc(psz);
}
}
return nCount;
}
BOOL CString::Replace(const wchar_t * lpszOld, const wchar_t * lpszNew)
{
UnicodeString prev = m_Data;
m_Data = ReplaceStr(m_Data, lpszOld, lpszNew);
return (prev != m_Data);
}
//////////////////////////////////////////////////////////////////////////////
// Very simple sub-string extraction
CString CString::Mid(int nFirst) const
{
return Mid(nFirst, m_Data.Length() - nFirst);
}
CString CString::Mid(int nFirst, int nCount) const
{
// out-of-bounds requests return sensible things
if (nFirst < 0)
nFirst = 0;
if (nCount < 0)
nCount = 0;
if (nFirst + nCount > m_Data.Length())
nCount = m_Data.Length() - nFirst;
if (nFirst > m_Data.Length())
nCount = 0;
ASSERT(nFirst >= 0);
ASSERT(nFirst + nCount <= m_Data.Length());
// optimize case of returning entire string
if (nFirst == 0 && nFirst + nCount == m_Data.Length())
return *this;
return CString(m_Data.SubString(nFirst + 1, nCount));
}
CString CString::Right(int nCount) const
{
if (nCount < 0)
nCount = 0;
if (nCount >= m_Data.Length())
return *this;
return CString(m_Data.SubString(m_Data.Length() - nCount + 1, nCount));
}
CString CString::Left(int nCount) const
{
if (nCount < 0)
nCount = 0;
if (nCount >= m_Data.Length())
return *this;
return CString(m_Data.SubString(1, nCount));
}
//////////////////////////////////////////////////////////////////////////////
// Finding
int CString::ReverseFind(wchar_t ch) const
{
// find last single character
wchar_t * lpsz = wcsrchr(m_Data.c_str(), ch);
// return -1 if not found, distance from beginning otherwise
return (lpsz == NULL) ? -1 : (int)(lpsz - m_Data.c_str());
}
// find a sub-string (like strstr)
int CString::Find(const wchar_t * lpszSub) const
{
return Find(lpszSub, 0);
}
int CString::Find(const wchar_t * lpszSub, int nStart) const
{
int nLength = m_Data.Length();
if (nStart > nLength)
return -1;
// find first matching substring
wchar_t * lpsz = wcsstr(m_Data.c_str() + nStart, lpszSub);
// return -1 for not found, distance from beginning otherwise
return (lpsz == NULL) ? -1 : (int)(lpsz - m_Data.c_str());
}
/////////////////////////////////////////////////////////////////////////////
// CString formatting
void CString::FormatV(const wchar_t * lpszFormat, va_list argList)
{
m_Data.vprintf(lpszFormat, argList);
}
// formatting (using wsprintf style formatting)
void CString::Format(const wchar_t * lpszFormat, ...)
{
va_list argList;
va_start(argList, lpszFormat);
FormatV(lpszFormat, argList);
va_end(argList);
}
void CString::Format(UINT nFormatID, ...)
{
UnicodeString strFormat = LoadStr(nFormatID);
va_list argList;
va_start(argList, nFormatID);
FormatV(strFormat.c_str(), argList);
va_end(argList);
}
void CString::TrimRight(const wchar_t * lpszTargetList)
{
UnicodeString TargetList(lpszTargetList);
while (!m_Data.IsEmpty() && m_Data.IsDelimiter(TargetList, m_Data.Length()))
{
m_Data.SetLength(m_Data.Length() - 1);
}
}
void CString::TrimRight(wchar_t chTarget)
{
TrimRight(UnicodeString(chTarget).c_str());
}
void CString::TrimLeft(const wchar_t * lpszTargets)
{
UnicodeString Targets(lpszTargets);
while (!m_Data.IsEmpty() && m_Data.IsDelimiter(Targets, 1))
{
m_Data.Delete(1, 1);
}
}
void CString::TrimLeft(wchar_t chTarget)
{
TrimLeft(UnicodeString(chTarget).c_str());
}
///////////////////////////////////////////////////////////////////////////////