Explorar o código

Reimplementing CString using UnicodeString and replacing CStringA with RawByteString

Source commit: 5232a4e3833b8e9dac4ebaa3c12151ff981ac6cf
Martin Prikryl hai 2 meses
pai
achega
fc1ad2eea0

+ 7 - 121
libs/mfc/include/afx.h

@@ -54,16 +54,11 @@ struct CFileStatus;                   // file status information
 #ifndef _INC_STDDEF
 	#include <stddef.h>
 #endif
-
-#ifdef _AFX_PACKING
-#pragma pack(push, _AFX_PACKING)
-#endif
+#include <System.hpp>
 
 /////////////////////////////////////////////////////////////////////////////
 // Basic types
 
-struct _AFX_DOUBLE  { BYTE doubleBits[sizeof(double)]; };
-
 // Standard constants
 #undef FALSE
 #undef TRUE
@@ -115,17 +110,6 @@ struct _AFX_DOUBLE  { BYTE doubleBits[sizeof(double)]; };
 /////////////////////////////////////////////////////////////////////////////
 // Strings
 
-struct CStringData
-{
-	long nRefs;             // reference count
-	int nDataLength;        // length of data (including terminator)
-	int nAllocLength;       // length of allocation
-	// TCHAR data[nAllocLength]
-
-	TCHAR* data()           // TCHAR* to managed data
-		{ return (TCHAR*)(this+1); }
-};
-
 class CString
 {
 public:
@@ -135,6 +119,8 @@ public:
 	CString();
 	// copy constructor
 	CString(const CString& stringSrc);
+	// copy constructor
+	explicit CString(const UnicodeString& str);
 	// from an ANSI string (converts to TCHAR)
 	CString(LPCSTR lpsz);
 	// from a UNICODE string (converts to TCHAR)
@@ -239,7 +225,7 @@ public:
 	int Replace(TCHAR chOld, TCHAR chNew);
 	// replace occurrences of substring lpszOld with lpszNew;
 	// empty lpszNew removes instances of lpszOld
-	int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew);
+	BOOL Replace(LPCTSTR lpszOld, LPCTSTR lpszNew);
 	// delete nCount characters starting at zero-based index
 	int Delete(int nIndex, int nCount = 1);
 
@@ -270,35 +256,9 @@ public:
 	// load from string resource
 	BOOL LoadString(UINT nID);
 
-	// Access to string implementation buffer as "C" character array
-
-	// get pointer to modifiable buffer at least as long as nMinBufLength
-	LPTSTR GetBuffer(int nMinBufLength);
-	// release buffer, setting length to nNewLength (or to first nul if -1)
-	void ReleaseBuffer(int nNewLength = -1);
-
 // Implementation
-public:
-	~CString();
-	int GetAllocLength() const;
-
 protected:
-	LPTSTR m_pchData;   // pointer to ref counted string data
-
-	// implementation helpers
-	CStringData* GetData() const;
-	void Init();
-	void AllocCopy(CString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
-	void AllocBuffer(int nLen);
-	void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData);
-	void ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data);
-	void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData);
-	void CopyBeforeWrite();
-	void AllocBeforeWrite(int nLen);
-	void Release();
-	static void PASCAL Release(CStringData* pData);
-	static int PASCAL SafeStrlen(LPCTSTR lpsz);
-	static void FASTCALL FreeData(CStringData* pData);
+	UnicodeString m_Data;
 };
 
 // Compare helpers
@@ -312,18 +272,10 @@ bool AFXAPI operator<(const CString& s1, const CString& s2);
 bool AFXAPI operator<(const CString& s1, LPCTSTR s2);
 bool AFXAPI operator<(LPCTSTR s1, const CString& s2);
 
-// conversion helpers
-int AFX_CDECL _mbstowcsz(wchar_t* wcstr, const char* mbstr, size_t count);
-
-// Globals
-extern TCHAR afxChNil;
-extern LPCTSTR _afxPchNil;
-#define afxEmptyString ((CString&)*(CString*)&_afxPchNil)
-
 /////////////////////////////////////////////////////////////////////////////
 // class CObject is the root of all compliant objects
 
-class AFX_NOVTABLE CObject
+class CObject
 {
 public:
 
@@ -343,15 +295,13 @@ private:
 /////////////////////////////////////////////////////////////////////////////
 // Exceptions
 
-class AFX_NOVTABLE CException : public CObject
+class CException : public CObject
 {
 public:
 // Constructors
 	CException();
 
 // Operations
-	void Delete();  // use to delete exception in 'catch' block
-
 	virtual BOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
 		PUINT pnHelpContext = NULL);
 
@@ -360,65 +310,6 @@ public:
 	virtual ~CException();
 };
 
-// for THROW_LAST auto-delete backward compatiblity
-void AFXAPI AfxThrowLastCleanup();
-
-// other out-of-line helper functions
-void AFXAPI AfxTryCleanup();
-
-// Placed on frame for EXCEPTION linkage, or CException cleanup
-struct AFX_EXCEPTION_LINK
-{
-	AFX_EXCEPTION_LINK* m_pLinkPrev;    // previous top, next in handler chain
-	CException* m_pException;   // current exception (NULL in TRY block)
-
-	AFX_EXCEPTION_LINK();       // for initialization and linking
-	~AFX_EXCEPTION_LINK()       // for cleanup and unlinking
-		{ AfxTryCleanup(); };
-};
-
-// Exception global state - never access directly
-struct AFX_EXCEPTION_CONTEXT
-{
-	AFX_EXCEPTION_LINK* m_pLinkTop;
-
-	// Note: most of the exception context is now in the AFX_EXCEPTION_LINK
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// Exception macros using try, catch and throw
-//  (for backward compatibility to previous versions of MFC)
-
-#define TRY { AFX_EXCEPTION_LINK _afxExceptionLink; try {
-
-#define CATCH(class, e) } catch (class* e) \
-	{ ASSERT(e->IsKindOf(RUNTIME_CLASS(class))); \
-		_afxExceptionLink.m_pException = e;
-
-#define AND_CATCH(class, e) } catch (class* e) \
-	{ ASSERT(e->IsKindOf(RUNTIME_CLASS(class))); \
-		_afxExceptionLink.m_pException = e;
-
-#define END_CATCH } }
-
-#define THROW(e) throw e
-#define THROW_LAST() (AfxThrowLastCleanup(), throw)
-
-// Advanced macros for smaller code
-#define CATCH_ALL(e) } catch (CException* e) \
-	{ { ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \
-		_afxExceptionLink.m_pException = e;
-
-#define AND_CATCH_ALL(e) } catch (CException* e) \
-	{ { ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \
-		_afxExceptionLink.m_pException = e;
-
-#define END_CATCH_ALL } } }
-
-#define END_TRY } catch (CException* e) \
-	{ ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \
-		_afxExceptionLink.m_pException = e; } }
-
 /////////////////////////////////////////////////////////////////////////////
 // Standard Exception classes
 
@@ -509,7 +400,6 @@ public:
 
 // Constructors
 	CFile();
-	CFile(int hFile);
         void PASCAL operator delete(void * p);
 
 // Attributes
@@ -619,10 +509,6 @@ struct CFileStatus
 /////////////////////////////////////////////////////////////////////////////
 // Special include for Win32s compatibility
 
-#ifdef _AFX_PACKING
-#pragma pack(pop)
-#endif
-
 /////////////////////////////////////////////////////////////////////////////
 // Inline function declarations
 

+ 11 - 19
libs/mfc/include/afx.inl

@@ -29,14 +29,10 @@ _AFX_INLINE CFileException::~CFileException()
 	{ }
 
 // CString
-_AFX_INLINE CStringData* CString::GetData() const
-	{ ASSERT(m_pchData != NULL); return ((CStringData*)m_pchData)-1; }
-_AFX_INLINE void CString::Init()
-	{ m_pchData = afxEmptyString.m_pchData; }
 _AFX_INLINE CString::CString()
-	{ m_pchData = afxEmptyString.m_pchData; }
+	{ }
 _AFX_INLINE CString::CString(const unsigned char* lpsz)
-	{ Init(); *this = (LPCSTR)lpsz; }
+	{ *this = (LPCSTR)lpsz; }
 _AFX_INLINE const CString& CString::operator=(const unsigned char* lpsz)
 	{ *this = (LPCSTR)lpsz; return *this; }
 _AFX_INLINE const CString& CString::operator+=(char ch)
@@ -49,34 +45,30 @@ _AFX_INLINE CString AFXAPI operator+(char ch, const CString& string)
 	{ return (TCHAR)ch + string; }
 
 _AFX_INLINE int CString::GetLength() const
-	{ return GetData()->nDataLength; }
-_AFX_INLINE int CString::GetAllocLength() const
-	{ return GetData()->nAllocLength; }
+	{ return m_Data.Length(); }
 _AFX_INLINE BOOL CString::IsEmpty() const
-	{ return GetData()->nDataLength == 0; }
+	{ return m_Data.IsEmpty(); }
 _AFX_INLINE CString::operator LPCTSTR() const
-	{ return m_pchData; }
-_AFX_INLINE int PASCAL CString::SafeStrlen(LPCTSTR lpsz)
-	{ return (lpsz == NULL) ? 0 : lstrlen(lpsz); }
+	{ return m_Data.c_str(); }
 
 // CString support (windows specific)
 _AFX_INLINE int CString::Compare(LPCTSTR lpsz) const
-	{ ASSERT(AfxIsValidString(lpsz)); return _tcscmp(m_pchData, lpsz); }    // MBCS/Unicode aware
+	{ ASSERT(AfxIsValidString(lpsz)); return _tcscmp(m_Data.c_str(), lpsz); }    // MBCS/Unicode aware
 _AFX_INLINE int CString::CompareNoCase(LPCTSTR lpsz) const
-	{ ASSERT(AfxIsValidString(lpsz)); return _tcsicmp(m_pchData, lpsz); }   // MBCS/Unicode aware
+	{ ASSERT(AfxIsValidString(lpsz)); return _tcsicmp(m_Data.c_str(), lpsz); }   // MBCS/Unicode aware
 
 _AFX_INLINE TCHAR CString::GetAt(int nIndex) const
 {
 	ASSERT(nIndex >= 0);
-	ASSERT(nIndex < GetData()->nDataLength);
-	return m_pchData[nIndex];
+	ASSERT(nIndex < m_Data.Length());
+	return m_Data[nIndex + 1];
 }
 _AFX_INLINE TCHAR CString::operator[](int nIndex) const
 {
 	// same as GetAt
 	ASSERT(nIndex >= 0);
-	ASSERT(nIndex < GetData()->nDataLength);
-	return m_pchData[nIndex];
+	ASSERT(nIndex < m_Data.Length());
+	return m_Data[nIndex + 1];
 }
 _AFX_INLINE bool AFXAPI operator==(const CString& s1, const CString& s2)
 	{ return s1.Compare(s2) == 0; }

+ 0 - 45
libs/mfc/include/afxplex_.h

@@ -1,45 +0,0 @@
-// 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.
-
-#ifndef __AFXPLEX_H__
-#define __AFXPLEX_H__
-
-#ifndef __AFX_H__
-	#include <afx.h>
-#endif
-
-#ifdef _AFX_PACKING
-#pragma pack(push, _AFX_PACKING)
-#endif
-
-struct CPlex     // warning variable length structure
-{
-	CPlex* pNext;
-#if (_AFX_PACKING >= 8)
-	DWORD dwReserved[1];    // align on 8 byte boundary
-#endif
-	// BYTE data[maxNum*elementSize];
-
-	void* data() { return this+1; }
-
-	static CPlex* PASCAL Create(CPlex*& head, UINT nMax, UINT cbElement);
-			// like 'calloc' but no zero fill
-			// may throw memory exceptions
-
-	void FreeDataChain();       // free this one and links
-};
-
-#ifdef _AFX_PACKING
-#pragma pack(pop)
-#endif
-
-#endif //__AFXPLEX_H__
-
-/////////////////////////////////////////////////////////////////////////////

+ 0 - 30
libs/mfc/include/afxver_.h

@@ -31,13 +31,6 @@
 
 #include <afxv_w32.h>
 
-#if defined (__BORLANDC__)
-#define _AFX_PACKING 8      // __BORLANDC__
-#else
-// setup default packing value
-#define _AFX_PACKING    4   // default packs structs at 4 bytes
-#endif
-
 /////////////////////////////////////////////////////////////////////////////
 // Standard preprocessor symbols if not already defined
 /////////////////////////////////////////////////////////////////////////////
@@ -71,27 +64,4 @@
 	#define AFX_CDECL __cdecl
 #endif
 
-#ifndef AFX_STATIC
-	#define AFX_STATIC extern
-	#define AFX_STATIC_DATA extern __declspec(selectany)
-#endif
-
-// The following macros are used to enable export/import
-
-// This macro is used to reduce size requirements of some classes
-#ifndef AFX_ALWAYS_VTABLE
-#ifndef AFX_NOVTABLE
-#if _MSC_VER >= 1100
-#define AFX_NOVTABLE __declspec(novtable)
-#else
-#define AFX_NOVTABLE
-#endif
-#endif
-#endif
-
-// for global data that should be in COMDATs (packaged data)
-#ifndef AFX_COMDAT
-	#define AFX_COMDAT
-#endif
-
 /////////////////////////////////////////////////////////////////////////////

+ 1 - 1
libs/mfc/source/borland.mak

@@ -41,7 +41,7 @@ OBJECT = except.obj
 	
 FILES = filecore.obj filex.obj filest.obj
 
-MISC = strcore.obj strex.obj timecore.obj fixalloc.obj plex.obj
+MISC = strcore.obj strex.obj timecore.obj
 
 WINMISC = winstr.obj
 

+ 0 - 63
libs/mfc/source/except.cpp

@@ -10,20 +10,6 @@
 
 #include "stdafx.h"
 
-/////////////////////////////////////////////////////////////////////////////
-// AFX_EXCEPTION_CONTEXT (thread global state)
-
-// WINSCP
-AFX_EXCEPTION_CONTEXT __thread m_exceptionContext;
-
-inline AFX_EXCEPTION_CONTEXT* AfxGetExceptionContext()
-{
-	DWORD lError = GetLastError();
-	AFX_EXCEPTION_CONTEXT* pContext = &m_exceptionContext;
-	SetLastError(lError);
-	return pContext;
-}
-
 /////////////////////////////////////////////////////////////////////////////
 // CException
 
@@ -31,11 +17,6 @@ CException::CException()
 {
 }
 
-void CException::Delete()
-{
-	delete this;
-}
-
 BOOL CException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
 	PUINT pnHelpContext /* = NULL */ )
 {
@@ -49,47 +30,3 @@ BOOL CException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
 }
 
 /////////////////////////////////////////////////////////////////////////////
-// AFX_EXCEPTION_LINK linked 'jmpbuf' and out-of-line helpers
-
-AFX_EXCEPTION_LINK::AFX_EXCEPTION_LINK()
-{
-	// setup initial link state
-	m_pException = NULL;    // no current exception yet
-
-	// wire into top of exception link stack
-	AFX_EXCEPTION_CONTEXT* pContext = AfxGetExceptionContext();
-	m_pLinkPrev = pContext->m_pLinkTop;
-	pContext->m_pLinkTop = this;
-}
-
-// out-of-line cleanup called from inline AFX_EXCEPTION_LINK destructor
-void AFXAPI AfxTryCleanup()
-{
-	AFX_EXCEPTION_CONTEXT* pContext = AfxGetExceptionContext();
-	AFX_EXCEPTION_LINK* pLinkTop = pContext->m_pLinkTop;
-
-	// delete current exception
-	ASSERT(pLinkTop != NULL);
-	if (pLinkTop->m_pException != NULL)
-		pLinkTop->m_pException->Delete();
-
-	// remove ourself from the top of the chain
-	pContext->m_pLinkTop = pLinkTop->m_pLinkPrev;
-}
-
-// special out-of-line implementation of THROW_LAST (for auto-delete behavior)
-void AFXAPI AfxThrowLastCleanup()
-{
-	AFX_EXCEPTION_CONTEXT* pContext = AfxGetExceptionContext();
-	AFX_EXCEPTION_LINK* pLinkTop = pContext->m_pLinkTop;
-
-	// check for THROW_LAST inside of auto-delete block
-	if (pLinkTop != NULL)
-	{
-		// make sure current exception does not get auto-deleted
-		pLinkTop->m_pException = NULL;
-	}
-
-	// THROW_LAST macro will do actual 'throw'
-}
-

+ 13 - 91
libs/mfc/source/filecore.cpp

@@ -9,11 +9,7 @@
 // Microsoft Foundation Classes product.
 
 #include "stdafx.h"
-
-AFX_STATIC inline BOOL IsDirSep(TCHAR ch)
-{
-	return (ch == '\\' || ch == '/');
-}
+#include <SysUtils.hpp>
 
 ////////////////////////////////////////////////////////////////////////////
 // CFile implementation
@@ -24,12 +20,6 @@ CFile::CFile()
 	m_bCloseOnDelete = FALSE;
 }
 
-CFile::CFile(int hFile)
-{
-	m_hFile = hFile;
-	m_bCloseOnDelete = FALSE;
-}
-
 CFile::~CFile()
 {
 	if (m_hFile != (UINT)hFileNull && m_bCloseOnDelete)
@@ -209,93 +199,25 @@ void CFile::Close()
 // CFile implementation helpers
 
 // turn a file, relative path or other into an absolute path
+// Used for error reporting only, so not critical.
 BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn)
 	// lpszPathOut = buffer of _MAX_PATH
 	// lpszFileIn = file, relative path or absolute path
 	// (both in ANSI character set)
 {
-	ASSERT(AfxIsValidAddress(lpszPathOut, _MAX_PATH));
-
-	// first, fully qualify the path name
-	LPTSTR lpszFilePart;
-	if (!GetFullPathName(lpszFileIn, _MAX_PATH, lpszPathOut, &lpszFilePart))
-	{
-		lstrcpyn(lpszPathOut, lpszFileIn, _MAX_PATH); // take it literally
-		return FALSE;
-	}
-
-	CString strRoot;
-	// determine the root name of the volume
-	AfxGetRoot(lpszPathOut, strRoot);
-
-	// get file system information for the volume
-	DWORD dwFlags, dwDummy;
-	if (!GetVolumeInformation(strRoot, NULL, 0, NULL, &dwDummy, &dwFlags,
-		NULL, 0))
-	{
-		TRACE1("Warning: could not get volume information '%s'.\n",
-			(LPCTSTR)strRoot);
-		return FALSE;   // preserving case may not be correct
-	}
-
-	// not all characters have complete uppercase/lowercase
-	if (!(dwFlags & FS_CASE_IS_PRESERVED))
-		CharUpper(lpszPathOut);
-
-	// assume non-UNICODE file systems, use OEM character set
-	if (!(dwFlags & FS_UNICODE_STORED_ON_DISK))
-	{
-		WIN32_FIND_DATA data;
-		HANDLE h = FindFirstFile(lpszFileIn, &data);
-		if (h != INVALID_HANDLE_VALUE)
-		{
-			FindClose(h);
-			lstrcpy(lpszFilePart, data.cFileName);
-		}
-	}
-	return TRUE;
-}
-
-void AFXAPI AfxGetRoot(LPCTSTR lpszPath, CString& strRoot)
-{
-	ASSERT(lpszPath != NULL);
-	// determine the root name of the volume
-	LPTSTR lpszRoot = strRoot.GetBuffer(_MAX_PATH);
-	memset(lpszRoot, 0, _MAX_PATH);
-	lstrcpyn(lpszRoot, lpszPath, _MAX_PATH);
-	for (LPTSTR lpsz = lpszRoot; *lpsz != '\0'; lpsz = _tcsinc(lpsz))
-	{
-		// find first double slash and stop
-		if (IsDirSep(lpsz[0]) && IsDirSep(lpsz[1]))
-			break;
+        UnicodeString Path;
+        BOOL Result;
+        try
+        {
+	        Path = ExpandFileName(lpszFileIn);
+	        Result = TRUE;
 	}
-	if (*lpsz != '\0')
+	catch (...)
 	{
-		// it is a UNC name, find second slash past '\\'
-		ASSERT(IsDirSep(lpsz[0]));
-		ASSERT(IsDirSep(lpsz[1]));
-		lpsz += 2;
-		while (*lpsz != '\0' && (!IsDirSep(*lpsz)))
-			lpsz = _tcsinc(lpsz);
-		if (*lpsz != '\0')
-			lpsz = _tcsinc(lpsz);
-		while (*lpsz != '\0' && (!IsDirSep(*lpsz)))
-			lpsz = _tcsinc(lpsz);
-		// terminate it just after the UNC root (ie. '\\server\share\')
-		if (*lpsz != '\0')
-			lpsz[1] = '\0';
+		Path = lpszFileIn; // take it literally
+	        Result = FALSE;
 	}
-	else
-	{
-		// not a UNC, look for just the first slash
-		lpsz = lpszRoot;
-		while (*lpsz != '\0' && (!IsDirSep(*lpsz)))
-			lpsz = _tcsinc(lpsz);
-		// terminate it just after root (ie. 'x:\')
-		if (*lpsz != '\0')
-			lpsz[1] = '\0';
-	}
-	strRoot.ReleaseBuffer();
+	lstrcpyn(lpszPathOut, Path.c_str(), _MAX_PATH);
+	return Result;
 }
-
 /////////////////////////////////////////////////////////////////////////////

+ 1 - 1
libs/mfc/source/filex.cpp

@@ -47,7 +47,7 @@ BOOL CFileException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
 void AFXAPI AfxThrowFileException(int cause, LONG lOsError,
 	LPCTSTR lpszFileName /* == NULL */)
 {
-	THROW(new CFileException(cause, lOsError, lpszFileName));
+	throw new CFileException(cause, lOsError, lpszFileName);
 }
 
 int PASCAL CFileException::OsErrorToException(LONG lOsErr)

+ 0 - 88
libs/mfc/source/fixalloc.cpp

@@ -1,88 +0,0 @@
-// fixalloc.cpp - implementation of fixed block allocator
-
-#include "stdafx.h"
-#include "fixalloc.h"
-
-/////////////////////////////////////////////////////////////////////////////
-// CFixedAlloc
-
-CFixedAlloc::CFixedAlloc(UINT nAllocSize, UINT nBlockSize)
-{
-	ASSERT(nAllocSize >= sizeof(CNode));
-	ASSERT(nBlockSize > 1);
-
-	m_nAllocSize = nAllocSize;
-	m_nBlockSize = nBlockSize;
-	m_pNodeFree = NULL;
-	m_pBlocks = NULL;
-	InitializeCriticalSection(&m_protect);
-}
-
-CFixedAlloc::~CFixedAlloc()
-{
-#ifndef __BORLANDC__  // Close your eyes, and hang on... here come the leaks!
-	FreeAll();
-	DeleteCriticalSection(&m_protect);
-#endif
-}
-
-void CFixedAlloc::FreeAll()
-{
-	EnterCriticalSection(&m_protect);
-	m_pBlocks->FreeDataChain();
-	m_pBlocks = NULL;
-	m_pNodeFree = NULL;
-	LeaveCriticalSection(&m_protect);
-}
-
-void* CFixedAlloc::Alloc()
-{
-	EnterCriticalSection(&m_protect);
-	if (m_pNodeFree == NULL)
-	{
-		CPlex* pNewBlock = NULL;
-		TRY
-		{
-			// add another block
-			pNewBlock = CPlex::Create(m_pBlocks, m_nBlockSize, m_nAllocSize);
-		}
-		CATCH_ALL(e)
-		{
-			LeaveCriticalSection(&m_protect);
-			THROW_LAST();
-		}
-		END_CATCH_ALL
-
-		// chain them into free list
-		CNode* pNode = (CNode*)pNewBlock->data();
-		// free in reverse order to make it easier to debug
-		(BYTE*&)pNode += (m_nAllocSize * m_nBlockSize) - m_nAllocSize;
-		for (int i = m_nBlockSize-1; i >= 0; i--, (BYTE*&)pNode -= m_nAllocSize)
-		{
-			pNode->pNext = m_pNodeFree;
-			m_pNodeFree = pNode;
-		}
-	}
-	ASSERT(m_pNodeFree != NULL);  // we must have something
-
-	// remove the first available node from the free list
-	void* pNode = m_pNodeFree;
-	m_pNodeFree = m_pNodeFree->pNext;
-
-	LeaveCriticalSection(&m_protect);
-	return pNode;
-}
-
-void CFixedAlloc::Free(void* p)
-{
-	if (p != NULL)
-	{
-		EnterCriticalSection(&m_protect);
-
-		// simply return the node to the free list
-		CNode* pNode = (CNode*)p;
-		pNode->pNext = m_pNodeFree;
-		m_pNodeFree = pNode;
-		LeaveCriticalSection(&m_protect);
-	}
-}

+ 0 - 68
libs/mfc/source/fixalloc.h

@@ -1,68 +0,0 @@
-// fixalloc.h - declarations for fixed block allocator
-
-#ifndef __FIXALLOC_H__
-#define __FIXALLOC_H__
-
-#include "afxplex_.h"
-
-/////////////////////////////////////////////////////////////////////////////
-// CFixedAlloc
-
-class CFixedAlloc
-{
-// Constructors
-public:
-	CFixedAlloc(UINT nAllocSize, UINT nBlockSize = 64);
-
-// Attributes
-	UINT GetAllocSize() { return m_nAllocSize; }
-
-// Operations
-public:
-	void* Alloc();  // return a chunk of memory of nAllocSize
-	void Free(void* p); // free chunk of memory returned from Alloc
-	void FreeAll(); // free everything allocated from this allocator
-
-// Implementation
-public:
-	~CFixedAlloc();
-
-protected:
-	struct CNode
-	{
-		CNode* pNext;   // only valid when in free list
-	};
-
-	UINT m_nAllocSize;  // size of each block from Alloc
-	UINT m_nBlockSize;  // number of blocks to get at a time
-	CPlex* m_pBlocks;   // linked list of blocks (is nBlocks*nAllocSize)
-	CNode* m_pNodeFree; // first free node (NULL if no free nodes)
-	CRITICAL_SECTION m_protect;
-};
-
-// DECLARE_FIXED_ALLOC -- used in class definition
-#define DECLARE_FIXED_ALLOC(class_name) \
-public: \
-	void* operator new(size_t size) \
-	{ \
-		ASSERT(size == s_alloc.GetAllocSize()); \
-		UNUSED(size); \
-		return s_alloc.Alloc(); \
-	} \
-	void* operator new(size_t, void* p) \
-		{ return p; } \
-	void operator delete(void* p) { s_alloc.Free(p); } \
-	void* operator new(size_t size, LPCSTR, int) \
-	{ \
-		ASSERT(size == s_alloc.GetAllocSize()); \
-		UNUSED(size); \
-		return s_alloc.Alloc(); \
-	} \
-protected: \
-	static CFixedAlloc s_alloc \
-
-// IMPLEMENT_FIXED_ALLOC -- used in class implementation file
-#define IMPLEMENT_FIXED_ALLOC(class_name, block_size) \
-CFixedAlloc class_name::s_alloc(sizeof(class_name), block_size) \
-
-#endif

+ 0 - 36
libs/mfc/source/plex.cpp

@@ -1,36 +0,0 @@
-// 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"
-
-/////////////////////////////////////////////////////////////////////////////
-// CPlex
-
-CPlex* PASCAL CPlex::Create(CPlex*& pHead, UINT nMax, UINT cbElement)
-{
-	ASSERT(nMax > 0 && cbElement > 0);
-	CPlex* p = (CPlex*) new BYTE[sizeof(CPlex) + nMax * cbElement];
-			// may throw exception
-	p->pNext = pHead;
-	pHead = p;  // change head (adds in reverse order for simplicity)
-	return p;
-}
-
-void CPlex::FreeDataChain()     // free this one and links
-{
-	CPlex* p = this;
-	while (p != NULL)
-	{
-		BYTE* bytes = (BYTE*) p;
-		CPlex* pNext = p->pNext;
-		delete[] bytes;
-		p = pNext;
-	}
-}

+ 0 - 20
libs/mfc/source/stdafx.h

@@ -14,11 +14,8 @@
 // MFC inline constructors (including compiler generated) can get deep
 #pragma inline_depth(16)
 
-#define AFX_COMDAT __declspec(selectany)
-
 // core headers
 #include "afx.h"
-#include "afxplex_.h"
 
 // public headers
 #include "afxres.h"
@@ -29,26 +26,12 @@ inline HINSTANCE AFXAPI AfxGetResourceHandle()
 int AFXAPI AfxLoadString(UINT nIDS, LPTSTR lpszBuf, UINT nMaxBuf = 256);
 #define _countof(array) (sizeof(array)/sizeof(array[0]))
 BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn);
-void AFXAPI AfxGetRoot(LPCTSTR lpszPath, CString& strRoot);
 
 #include <stddef.h>
 #include <limits.h>
 #include <malloc.h>
 #include <new.h>
 
-// implementation uses _AFX_PACKING as well
-#ifdef _AFX_PACKING
-#ifndef ALL_WARNINGS
-#pragma warning(disable: 4103)
-#endif
-#ifndef __BORLANDC__
-// In Borland C++ we set the packing to 4 in the BCC32.CFG file
-// This is because the inclusion of the following pragma line disables our
-// Pre-Compiled-Headers
-#pragma pack(_AFX_PACKING)
-#endif // __BORLANDC__
-#endif
-
 // MFC does not rely on auto-delete semantics of the TRY..CATCH macros,
 //  therefore those macros are mapped to something closer to the native
 //  C++ exception handling mechanism when building MFC itself.
@@ -82,7 +65,4 @@ void AFXAPI AfxGetRoot(LPCTSTR lpszPath, CString& strRoot);
 // Because of the above definitions of TRY...CATCH it is necessary to
 //  explicitly delete exception objects at the catch site.
 
-#define min std::min
-#define max std::max
-
 /////////////////////////////////////////////////////////////////////////////

+ 28 - 364
libs/mfc/source/strcore.cpp

@@ -9,211 +9,21 @@
 // Microsoft Foundation Classes product.
 
 #include "stdafx.h"
-#include "fixalloc.h"
+#include <SysUtils.hpp>
 
 HINSTANCE afxCurrentResourceHandle;
 
-/////////////////////////////////////////////////////////////////////////////
-// static class data, special inlines
-
-// afxChNil is left for backward compatibility
-TCHAR afxChNil = '\0';
-
-// For an empty string, m_pchData will point here
-// (note: avoids special case of checking for NULL m_pchData)
-// empty string data (and locked)
-AFX_STATIC_DATA int _afxInitData[] = { -1, 0, 0, 0 };
-AFX_STATIC_DATA CStringData* _afxDataNil = (CStringData*)&_afxInitData;
-AFX_COMDAT LPCTSTR _afxPchNil = (LPCTSTR)(((BYTE*)&_afxInitData)+sizeof(CStringData));
-// special function to make afxEmptyString work even during initialization
-const CString& AFXAPI AfxGetEmptyString()
-	{ return *(CString*)&_afxPchNil; }
-
 //////////////////////////////////////////////////////////////////////////////
 // Construction/Destruction
 
 CString::CString(const CString& stringSrc)
 {
-	ASSERT(stringSrc.GetData()->nRefs != 0);
-	if (stringSrc.GetData()->nRefs >= 0)
-	{
-		ASSERT(stringSrc.GetData() != _afxDataNil);
-		m_pchData = stringSrc.m_pchData;
-		InterlockedIncrement(&GetData()->nRefs);
-	}
-	else
-	{
-		Init();
-		*this = stringSrc.m_pchData;
-	}
-}
-
-#ifndef _DEBUG
-
-#define ROUND(x,y) (((x)+(y-1))&~(y-1))
-#define ROUND4(x) ROUND(x, 4)
-AFX_STATIC CFixedAlloc _afxAlloc64(ROUND4(65*sizeof(TCHAR)+sizeof(CStringData)));
-AFX_STATIC CFixedAlloc _afxAlloc128(ROUND4(129*sizeof(TCHAR)+sizeof(CStringData)));
-AFX_STATIC CFixedAlloc _afxAlloc256(ROUND4(257*sizeof(TCHAR)+sizeof(CStringData)));
-AFX_STATIC CFixedAlloc _afxAlloc512(ROUND4(513*sizeof(TCHAR)+sizeof(CStringData)));
-
-#endif //!_DEBUG
-
-void CString::AllocBuffer(int nLen)
-// always allocate one extra character for '\0' termination
-// assumes [optimistically] that data length will equal allocation length
-{
-	ASSERT(nLen >= 0);
-	ASSERT(nLen <= INT_MAX-1);    // max size (enough room for 1 extra)
-
-	if (nLen == 0)
-		Init();
-	else
-	{
-		CStringData* pData;
-#ifndef _DEBUG
-		if (nLen <= 64)
-		{
-			pData = (CStringData*)_afxAlloc64.Alloc();
-			pData->nAllocLength = 64;
-		}
-		else if (nLen <= 128)
-		{
-			pData = (CStringData*)_afxAlloc128.Alloc();
-			pData->nAllocLength = 128;
-		}
-		else if (nLen <= 256)
-		{
-			pData = (CStringData*)_afxAlloc256.Alloc();
-			pData->nAllocLength = 256;
-		}
-		else if (nLen <= 512)
-		{
-			pData = (CStringData*)_afxAlloc512.Alloc();
-			pData->nAllocLength = 512;
-		}
-		else
-#endif
-		{
-			pData = (CStringData*)
-				new BYTE[sizeof(CStringData) + (nLen+1)*sizeof(TCHAR)];
-			pData->nAllocLength = nLen;
-		}
-		pData->nRefs = 1;
-		pData->data()[nLen] = '\0';
-		pData->nDataLength = nLen;
-		m_pchData = pData->data();
-	}
-}
-
-void FASTCALL CString::FreeData(CStringData* pData)
-{
-#ifndef _DEBUG
-	int nLen = pData->nAllocLength;
-	if (nLen == 64)
-		_afxAlloc64.Free(pData);
-	else if (nLen == 128)
-		_afxAlloc128.Free(pData);
-	else if (nLen == 256)
-		_afxAlloc256.Free(pData);
-	else  if (nLen == 512)
-		_afxAlloc512.Free(pData);
-	else
-	{
-		ASSERT(nLen > 512);
-		delete[] (BYTE*)pData;
-	}
-#else
-	delete[] (BYTE*)pData;
-#endif
-}
-
-void CString::Release()
-{
-	if (GetData() != _afxDataNil)
-	{
-		ASSERT(GetData()->nRefs != 0);
-		if (InterlockedDecrement(&GetData()->nRefs) <= 0)
-			FreeData(GetData());
-		Init();
-	}
-}
-
-void PASCAL CString::Release(CStringData* pData)
-{
-	if (pData != _afxDataNil)
-	{
-		ASSERT(pData->nRefs != 0);
-		if (InterlockedDecrement(&pData->nRefs) <= 0)
-			FreeData(pData);
-	}
+	m_Data = stringSrc.m_Data;
 }
 
 void CString::Empty()
 {
-	if (GetData()->nDataLength == 0)
-		return;
-	if (GetData()->nRefs >= 0)
-		Release();
-	else
-		*this = &afxChNil;
-	ASSERT(GetData()->nDataLength == 0);
-	ASSERT(GetData()->nRefs < 0 || GetData()->nAllocLength == 0);
-}
-
-void CString::CopyBeforeWrite()
-{
-	if (GetData()->nRefs > 1)
-	{
-		CStringData* pData = GetData();
-		Release();
-		AllocBuffer(pData->nDataLength);
-		memcpy(m_pchData, pData->data(), (pData->nDataLength+1)*sizeof(TCHAR));
-	}
-	ASSERT(GetData()->nRefs <= 1);
-}
-
-void CString::AllocBeforeWrite(int nLen)
-{
-	if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
-	{
-		Release();
-		AllocBuffer(nLen);
-	}
-	ASSERT(GetData()->nRefs <= 1);
-}
-
-CString::~CString()
-//  free any attached data
-{
-	if (GetData() != _afxDataNil)
-	{
-		if (InterlockedDecrement(&GetData()->nRefs) <= 0)
-			FreeData(GetData());
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Helpers for the rest of the implementation
-
-void CString::AllocCopy(CString& dest, int nCopyLen, int nCopyIndex,
-	 int nExtraLen) const
-{
-	// will clone the data attached to this string
-	// allocating 'nExtraLen' characters
-	// Places results in uninitialized string 'dest'
-	// Will copy the part or all of original data to start of new string
-
-	int nNewLen = nCopyLen + nExtraLen;
-	if (nNewLen == 0)
-	{
-		dest.Init();
-	}
-	else
-	{
-		dest.AllocBuffer(nNewLen);
-		memcpy(dest.m_pchData, m_pchData+nCopyIndex, nCopyLen*sizeof(TCHAR));
-	}
+	m_Data = EmptyStr;
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -221,7 +31,6 @@ void CString::AllocCopy(CString& dest, int nCopyLen, int nCopyIndex,
 
 CString::CString(LPCTSTR lpsz)
 {
-	Init();
 	if (lpsz != NULL && HIWORD(lpsz) == NULL)
 	{
 		UINT nID = LOWORD((DWORD)lpsz);
@@ -230,12 +39,7 @@ CString::CString(LPCTSTR lpsz)
 	}
 	else
 	{
-		int nLen = SafeStrlen(lpsz);
-		if (nLen != 0)
-		{
-			AllocBuffer(nLen);
-			memcpy(m_pchData, lpsz, nLen*sizeof(TCHAR));
-		}
+		m_Data = lpsz;
 	}
 }
 
@@ -244,61 +48,31 @@ CString::CString(LPCTSTR lpsz)
 
 CString::CString(LPCSTR lpsz)
 {
-	Init();
-	int nSrcLen = lpsz != NULL ? lstrlenA(lpsz) : 0;
-	if (nSrcLen != 0)
-	{
-		AllocBuffer(nSrcLen);
-		_mbstowcsz(m_pchData, lpsz, nSrcLen+1);
-		ReleaseBuffer();
-	}
+	m_Data = UnicodeString(lpsz);
+}
+
+CString::CString(const UnicodeString& str)
+{
+	m_Data = str;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 // Assignment operators
 //  All assign a new value to the string
-//      (a) first see if the buffer is big enough
-//      (b) if enough room, copy on top of old buffer, set size and type
-//      (c) otherwise free old string data, and create a new one
 //
 //  All routines return the new string (but as a 'const CString&' so that
 //      assigning it again will cause a copy, eg: s1 = s2 = "hi there".
 //
 
-void CString::AssignCopy(int nSrcLen, LPCTSTR lpszSrcData)
-{
-	AllocBeforeWrite(nSrcLen);
-	memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(TCHAR));
-	GetData()->nDataLength = nSrcLen;
-	m_pchData[nSrcLen] = '\0';
-}
-
 const CString& CString::operator=(const CString& stringSrc)
 {
-	if (m_pchData != stringSrc.m_pchData)
-	{
-		if ((GetData()->nRefs < 0 && GetData() != _afxDataNil) ||
-			stringSrc.GetData()->nRefs < 0)
-		{
-			// actual copy necessary since one of the strings is locked
-			AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
-		}
-		else
-		{
-			// can just copy references around
-			Release();
-			ASSERT(stringSrc.GetData() != _afxDataNil);
-			m_pchData = stringSrc.m_pchData;
-			InterlockedIncrement(&GetData()->nRefs);
-		}
-	}
+	m_Data = stringSrc.m_Data;
 	return *this;
 }
 
 const CString& CString::operator=(LPCTSTR lpsz)
 {
-	ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
-	AssignCopy(SafeStrlen(lpsz), lpsz);
+	m_Data = lpsz;
 	return *this;
 }
 
@@ -307,10 +81,7 @@ const CString& CString::operator=(LPCTSTR lpsz)
 
 const CString& CString::operator=(LPCSTR lpsz)
 {
-	int nSrcLen = lpsz != NULL ? lstrlenA(lpsz) : 0;
-	AllocBeforeWrite(nSrcLen);
-	_mbstowcsz(m_pchData, lpsz, nSrcLen+1);
-	ReleaseBuffer();
+	m_Data = UnicodeString(lpsz);
 	return *this;
 }
 
@@ -324,136 +95,43 @@ const CString& CString::operator=(LPCSTR lpsz)
 //          CString + ?
 //          ? + CString
 
-void CString::ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data,
-	int nSrc2Len, LPCTSTR lpszSrc2Data)
-{
-  // -- master concatenation routine
-  // Concatenate two sources
-  // -- assume that 'this' is a new CString object
-
-	int nNewLen = nSrc1Len + nSrc2Len;
-	if (nNewLen != 0)
-	{
-		AllocBuffer(nNewLen);
-		memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(TCHAR));
-		memcpy(m_pchData+nSrc1Len, lpszSrc2Data, nSrc2Len*sizeof(TCHAR));
-	}
-}
-
 CString AFXAPI operator+(const CString& string1, const CString& string2)
 {
-	CString s;
-	s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData,
-		string2.GetData()->nDataLength, string2.m_pchData);
-	return s;
+	return CString(string1.m_Data + string2.m_Data);
 }
 
 CString AFXAPI operator+(const CString& string, LPCTSTR lpsz)
 {
-	ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
-	CString s;
-	s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData,
-		CString::SafeStrlen(lpsz), lpsz);
-	return s;
+	return CString(string.m_Data + lpsz);
 }
 
 CString AFXAPI operator+(LPCTSTR lpsz, const CString& string)
 {
-	ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
-	CString s;
-	s.ConcatCopy(CString::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength,
-		string.m_pchData);
-	return s;
+	return CString(lpsz + string.m_Data);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 // concatenate in place
 
-void CString::ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData)
-{
-	//  -- the main routine for += operators
-
-	// concatenating an empty string is a no-op!
-	if (nSrcLen == 0)
-		return;
-
-	// if the buffer is too small, or we have a width mis-match, just
-	//   allocate a new buffer (slow but sure)
-	if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength)
-	{
-		// we have to grow the buffer, use the ConcatCopy routine
-		CStringData* pOldData = GetData();
-		ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData);
-		ASSERT(pOldData != NULL);
-		CString::Release(pOldData);
-	}
-	else
-	{
-		// fast concatenation when buffer big enough
-		memcpy(m_pchData+GetData()->nDataLength, lpszSrcData, nSrcLen*sizeof(TCHAR));
-		GetData()->nDataLength += nSrcLen;
-		ASSERT(GetData()->nDataLength <= GetData()->nAllocLength);
-		m_pchData[GetData()->nDataLength] = '\0';
-	}
-}
-
 const CString& CString::operator+=(LPCTSTR lpsz)
 {
 	ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
-	ConcatInPlace(SafeStrlen(lpsz), lpsz);
+	m_Data += lpsz;
 	return *this;
 }
 
 const CString& CString::operator+=(TCHAR ch)
 {
-	ConcatInPlace(1, &ch);
+	m_Data += ch;
 	return *this;
 }
 
 const CString& CString::operator+=(const CString& string)
 {
-	ConcatInPlace(string.GetData()->nDataLength, string.m_pchData);
+	m_Data += string.m_Data;
 	return *this;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Advanced direct buffer access
-
-LPTSTR CString::GetBuffer(int nMinBufLength)
-{
-	ASSERT(nMinBufLength >= 0);
-
-	if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength)
-	{
-		// we have to grow the buffer
-		CStringData* pOldData = GetData();
-		int nOldLen = GetData()->nDataLength;   // AllocBuffer will tromp it
-		if (nMinBufLength < nOldLen)
-			nMinBufLength = nOldLen;
-		AllocBuffer(nMinBufLength);
-		memcpy(m_pchData, pOldData->data(), (nOldLen+1)*sizeof(TCHAR));
-		GetData()->nDataLength = nOldLen;
-		CString::Release(pOldData);
-	}
-	ASSERT(GetData()->nRefs <= 1);
-
-	// return a pointer to the character storage for this string
-	ASSERT(m_pchData != NULL);
-	return m_pchData;
-}
-
-void CString::ReleaseBuffer(int nNewLength)
-{
-	CopyBeforeWrite();  // just in case GetBuffer was not called
-
-	if (nNewLength == -1)
-		nNewLength = lstrlen(m_pchData); // zero terminated
-
-	ASSERT(nNewLength <= GetData()->nAllocLength);
-	GetData()->nDataLength = nNewLength;
-	m_pchData[nNewLength] = '\0';
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // Commonly used routines (rarely used routines in STREX.CPP)
 
@@ -464,55 +142,41 @@ int CString::Find(TCHAR ch) const
 
 int CString::Find(TCHAR ch, int nStart) const
 {
-	int nLength = GetData()->nDataLength;
+	int nLength = m_Data.Length();
 	if (nStart >= nLength)
 		return -1;
 
 	// find first single character
-	LPTSTR lpsz = _tcschr(m_pchData + nStart, (_TUCHAR)ch);
+	LPTSTR lpsz = _tcschr(m_Data.c_str() + nStart, (_TUCHAR)ch);
 
 	// return -1 if not found and index otherwise
-	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
+	return (lpsz == NULL) ? -1 : (int)(lpsz - m_Data.c_str());
 }
 
 int CString::FindOneOf(LPCTSTR lpszCharSet) const
 {
 	ASSERT(AfxIsValidString(lpszCharSet));
-	LPTSTR lpsz = _tcspbrk(m_pchData, lpszCharSet);
-	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
+	LPTSTR lpsz = _tcspbrk(m_Data.c_str(), lpszCharSet);
+	return (lpsz == NULL) ? -1 : (int)(lpsz - m_Data.c_str());
 }
 
 void CString::MakeLower()
 {
-	CopyBeforeWrite();
-	_tcslwr(m_pchData);
+	m_Data = m_Data.LowerCase();
 }
 
 void CString::SetAt(int nIndex, TCHAR ch)
 {
 	ASSERT(nIndex >= 0);
-	ASSERT(nIndex < GetData()->nDataLength);
+	ASSERT(nIndex < m_Data.Length());
 
-	CopyBeforeWrite();
-	m_pchData[nIndex] = ch;
+	// Implies Unique()
+	m_Data[nIndex + 1] = ch;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // CString conversion helpers (these use the current system locale)
 
-int AFX_CDECL _mbstowcsz(wchar_t* wcstr, const char* mbstr, size_t count)
-{
-	if (count == 0 && wcstr != NULL)
-		return 0;
-
-	int result = ::MultiByteToWideChar(CP_ACP, 0, mbstr, -1,
-		wcstr, count);
-	ASSERT(wcstr == NULL || result <= (int)count);
-	if (result > 0)
-		wcstr[result-1] = 0;
-	return result;
-}
-
 LPWSTR AFXAPI AfxA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
 {
 	if (lpa == NULL)

+ 40 - 460
libs/mfc/source/strex.cpp

@@ -9,23 +9,14 @@
 // Microsoft Foundation Classes product.
 
 #include "stdafx.h"
-// WINSCP
-#include <algorithm>
-#define max std::max
-#define min std::min
+#include <StrUtils.hpp>
 
 //////////////////////////////////////////////////////////////////////////////
 // More sophisticated construction
 
 CString::CString(LPCTSTR lpch, int nLength)
 {
-	Init();
-	if (nLength != 0)
-	{
-		ASSERT(AfxIsValidAddress(lpch, nLength, FALSE));
-		AllocBuffer(nLength);
-		memcpy(m_pchData, lpch, nLength*sizeof(TCHAR));
-	}
+	m_Data = UnicodeString(lpch, nLength);
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -33,13 +24,7 @@ CString::CString(LPCTSTR lpch, int nLength)
 
 CString::CString(LPCSTR lpsz, int nLength)
 {
-	Init();
-	if (nLength != 0)
-	{
-		AllocBuffer(nLength);
-		int n = ::MultiByteToWideChar(CP_ACP, 0, lpsz, nLength, m_pchData, nLength+1);
-		ReleaseBuffer(n >= 0 ? n : -1);
-	}
+	m_Data = UnicodeString(AnsiString(lpsz, nLength));
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -47,7 +32,7 @@ CString::CString(LPCSTR lpsz, int nLength)
 
 const CString& CString::operator=(TCHAR ch)
 {
-	AssignCopy(1, &ch);
+	m_Data = ch;
 	return *this;
 }
 
@@ -56,16 +41,12 @@ const CString& CString::operator=(TCHAR ch)
 
 CString AFXAPI operator+(const CString& string1, TCHAR ch)
 {
-	CString s;
-	s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, 1, &ch);
-	return s;
+	return CString(string1.m_Data + ch);
 }
 
 CString AFXAPI operator+(TCHAR ch, const CString& string)
 {
-	CString s;
-	s.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData);
-	return s;
+	return CString(UnicodeString(ch) + string.m_Data);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -75,16 +56,8 @@ int CString::Delete(int nIndex, int nCount /* = 1 */)
 {
 	if (nIndex < 0)
 		nIndex = 0;
-	int nNewLength = GetData()->nDataLength;
-	if (nCount > 0 && nIndex < nNewLength)
-	{
-		CopyBeforeWrite();
-		int nBytesToCopy = nNewLength - (nIndex + nCount) + 1;
-
-		memcpy(m_pchData + nIndex,
-			m_pchData + nIndex + nCount, nBytesToCopy * sizeof(TCHAR));
-		GetData()->nDataLength = nNewLength - nCount;
-	}
+	int nNewLength = m_Data.Length();
+	m_Data.Delete(nIndex + 1, nCount);
 
 	return nNewLength;
 }
@@ -97,9 +70,9 @@ int CString::Replace(TCHAR chOld, TCHAR chNew)
 	if (chOld != chNew)
 	{
 		// otherwise modify each character that matches in the string
-		CopyBeforeWrite();
-		LPTSTR psz = m_pchData;
-		LPTSTR pszEnd = psz + GetData()->nDataLength;
+		m_Data.Unique();
+		LPTSTR psz = m_Data.c_str();
+		LPTSTR pszEnd = psz + m_Data.Length();
 		while (psz < pszEnd)
 		{
 			// replace instances of the specified character only
@@ -114,71 +87,11 @@ int CString::Replace(TCHAR chOld, TCHAR chNew)
 	return nCount;
 }
 
-int CString::Replace(LPCTSTR lpszOld, LPCTSTR lpszNew)
+BOOL CString::Replace(LPCTSTR lpszOld, LPCTSTR lpszNew)
 {
-	// can't have empty or NULL lpszOld
-
-	int nSourceLen = SafeStrlen(lpszOld);
-	if (nSourceLen == 0)
-		return 0;
-	int nReplacementLen = SafeStrlen(lpszNew);
-
-	// loop once to figure out the size of the result string
-	int nCount = 0;
-	LPTSTR lpszStart = m_pchData;
-	LPTSTR lpszEnd = m_pchData + GetData()->nDataLength;
-	LPTSTR lpszTarget;
-	while (lpszStart < lpszEnd)
-	{
-		while ((lpszTarget = _tcsstr(lpszStart, lpszOld)) != NULL)
-		{
-			nCount++;
-			lpszStart = lpszTarget + nSourceLen;
-		}
-		lpszStart += lstrlen(lpszStart) + 1;
-	}
-
-	// if any changes were made, make them
-	if (nCount > 0)
-	{
-		CopyBeforeWrite();
-
-		// if the buffer is too small, just
-		//   allocate a new buffer (slow but sure)
-		int nOldLength = GetData()->nDataLength;
-		int nNewLength =  nOldLength + (nReplacementLen-nSourceLen)*nCount;
-		if (GetData()->nAllocLength < nNewLength || GetData()->nRefs > 1)
-		{
-			CStringData* pOldData = GetData();
-			LPTSTR pstr = m_pchData;
-			AllocBuffer(nNewLength);
-			memcpy(m_pchData, pstr, pOldData->nDataLength*sizeof(TCHAR));
-			CString::Release(pOldData);
-		}
-		// else, we just do it in-place
-		lpszStart = m_pchData;
-		lpszEnd = m_pchData + GetData()->nDataLength;
-
-		// loop again to actually do the work
-		while (lpszStart < lpszEnd)
-		{
-			while ( (lpszTarget = _tcsstr(lpszStart, lpszOld)) != NULL)
-			{
-				int nBalance = nOldLength - (lpszTarget - m_pchData + nSourceLen);
-				memmove(lpszTarget + nReplacementLen, lpszTarget + nSourceLen,
-					nBalance * sizeof(TCHAR));
-				memcpy(lpszTarget, lpszNew, nReplacementLen*sizeof(TCHAR));
-				lpszStart = lpszTarget + nReplacementLen;
-				lpszStart[nBalance] = '\0';
-				nOldLength += (nReplacementLen - nSourceLen);
-			}
-			lpszStart += lstrlen(lpszStart) + 1;
-		}
-		ASSERT(m_pchData[nNewLength] == '\0');
-		GetData()->nDataLength = nNewLength;
-	}
-
-	return nCount;
+	UnicodeString prev = m_Data;
+	m_Data = ReplaceStr(m_Data, lpszOld, lpszNew);
+	return (prev != m_Data);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -186,7 +99,7 @@ int CString::Replace(LPCTSTR lpszOld, LPCTSTR lpszNew)
 
 CString CString::Mid(int nFirst) const
 {
-	return Mid(nFirst, GetData()->nDataLength - nFirst);
+	return Mid(nFirst, m_Data.Length() - nFirst);
 }
 
 CString CString::Mid(int nFirst, int nCount) const
@@ -197,45 +110,39 @@ CString CString::Mid(int nFirst, int nCount) const
 	if (nCount < 0)
 		nCount = 0;
 
-	if (nFirst + nCount > GetData()->nDataLength)
-		nCount = GetData()->nDataLength - nFirst;
-	if (nFirst > GetData()->nDataLength)
+	if (nFirst + nCount > m_Data.Length())
+		nCount = m_Data.Length() - nFirst;
+	if (nFirst > m_Data.Length())
 		nCount = 0;
 
 	ASSERT(nFirst >= 0);
-	ASSERT(nFirst + nCount <= GetData()->nDataLength);
+	ASSERT(nFirst + nCount <= m_Data.Length());
 
 	// optimize case of returning entire string
-	if (nFirst == 0 && nFirst + nCount == GetData()->nDataLength)
+	if (nFirst == 0 && nFirst + nCount == m_Data.Length())
 		return *this;
 
-	CString dest;
-	AllocCopy(dest, nCount, nFirst, 0);
-	return dest;
+	return CString(m_Data.SubString(nFirst + 1, nCount));
 }
 
 CString CString::Right(int nCount) const
 {
 	if (nCount < 0)
 		nCount = 0;
-	if (nCount >= GetData()->nDataLength)
+	if (nCount >= m_Data.Length())
 		return *this;
 
-	CString dest;
-	AllocCopy(dest, nCount, GetData()->nDataLength-nCount, 0);
-	return dest;
+	return CString(m_Data.SubString(m_Data.Length() - nCount + 1, nCount));
 }
 
 CString CString::Left(int nCount) const
 {
 	if (nCount < 0)
 		nCount = 0;
-	if (nCount >= GetData()->nDataLength)
+	if (nCount >= m_Data.Length())
 		return *this;
 
-	CString dest;
-	AllocCopy(dest, nCount, 0, 0);
-	return dest;
+	return CString(m_Data.SubString(1, nCount));
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -244,10 +151,10 @@ CString CString::Left(int nCount) const
 int CString::ReverseFind(TCHAR ch) const
 {
 	// find last single character
-	LPTSTR lpsz = _tcsrchr(m_pchData, (_TUCHAR) ch);
+	LPTSTR lpsz = _tcsrchr(m_Data.c_str(), (_TUCHAR) ch);
 
 	// return -1 if not found, distance from beginning otherwise
-	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
+	return (lpsz == NULL) ? -1 : (int)(lpsz - m_Data.c_str());
 }
 
 // find a sub-string (like strstr)
@@ -260,278 +167,25 @@ int CString::Find(LPCTSTR lpszSub, int nStart) const
 {
 	ASSERT(AfxIsValidString(lpszSub));
 
-	int nLength = GetData()->nDataLength;
+	int nLength = m_Data.Length();
 	if (nStart > nLength)
 		return -1;
 
 	// find first matching substring
-	LPTSTR lpsz = _tcsstr(m_pchData + nStart, lpszSub);
+	LPTSTR lpsz = _tcsstr(m_Data.c_str() + nStart, lpszSub);
 
 	// return -1 for not found, distance from beginning otherwise
-	return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
+	return (lpsz == NULL) ? -1 : (int)(lpsz - m_Data.c_str());
 }
 
 
 /////////////////////////////////////////////////////////////////////////////
 // CString formatting
 
-#define TCHAR_ARG   TCHAR
-#define WCHAR_ARG   WCHAR
-#define CHAR_ARG    char
-
-#ifdef _X86_
-	#define DOUBLE_ARG  _AFX_DOUBLE
-#else
-	#define DOUBLE_ARG  double
-#endif
-
-#define FORCE_ANSI      0x10000
-#define FORCE_UNICODE   0x20000
-#define FORCE_INT64     0x40000
-#define _tclen(__a)         (1)
-
 void CString::FormatV(LPCTSTR lpszFormat, va_list argList)
 {
 	ASSERT(AfxIsValidString(lpszFormat));
-
-	va_list argListSave = argList;
-
-	// make a guess at the maximum length of the resulting string
-	int nMaxLen = 0;
-	for (LPCTSTR lpsz = lpszFormat; *lpsz != '\0'; lpsz = _tcsinc(lpsz))
-	{
-		// handle '%' character, but watch out for '%%'
-		if (*lpsz != '%' || *(lpsz = _tcsinc(lpsz)) == '%')
-		{
-			nMaxLen += _tclen(lpsz);
-			continue;
-		}
-
-		int nItemLen = 0;
-
-		// handle '%' character with format
-		int nWidth = 0;
-		for (; *lpsz != '\0'; lpsz = _tcsinc(lpsz))
-		{
-			// check for valid flags
-			if (*lpsz == '#')
-				nMaxLen += 2;   // for '0x'
-			else if (*lpsz == '*')
-				nWidth = va_arg(argList, int);
-			else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0' ||
-				*lpsz == ' ')
-				;
-			else // hit non-flag character
-				break;
-		}
-		// get width and skip it
-		if (nWidth == 0)
-		{
-			// width indicated by
-			nWidth = _ttoi(lpsz);
-			for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz))
-				;
-		}
-		ASSERT(nWidth >= 0);
-
-		int nPrecision = 0;
-		if (*lpsz == '.')
-		{
-			// skip past '.' separator (width.precision)
-			lpsz = _tcsinc(lpsz);
-
-			// get precision and skip it
-			if (*lpsz == '*')
-			{
-				nPrecision = va_arg(argList, int);
-				lpsz = _tcsinc(lpsz);
-			}
-			else
-			{
-				nPrecision = _ttoi(lpsz);
-				for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz))
-					;
-			}
-			ASSERT(nPrecision >= 0);
-		}
-
-		// should be on type modifier or specifier
-		int nModifier = 0;
-		if (_tcsncmp(lpsz, _T("I64"), 3) == 0)
-		{
-			lpsz += 3;
-			nModifier = FORCE_INT64;
-#if !defined(_X86_) && !defined(_ALPHA_)
-			// __int64 is only available on X86 and ALPHA platforms
-			ASSERT(FALSE);
-#endif
-		}
-		else
-		{
-			switch (*lpsz)
-			{
-			// modifiers that affect size
-			case 'h':
-				nModifier = FORCE_ANSI;
-				lpsz = _tcsinc(lpsz);
-				break;
-			case 'l':
-				nModifier = FORCE_UNICODE;
-				lpsz = _tcsinc(lpsz);
-				break;
-
-			// modifiers that do not affect size
-			case 'F':
-			case 'N':
-			case 'L':
-				lpsz = _tcsinc(lpsz);
-				break;
-			}
-		}
-
-		// now should be on specifier
-		switch (*lpsz | nModifier)
-		{
-		// single characters
-		case 'c':
-		case 'C':
-			nItemLen = 2;
-			va_arg(argList, TCHAR_ARG);
-			break;
-		case 'c'|FORCE_ANSI:
-		case 'C'|FORCE_ANSI:
-			nItemLen = 2;
-			va_arg(argList, CHAR_ARG);
-			break;
-		case 'c'|FORCE_UNICODE:
-		case 'C'|FORCE_UNICODE:
-			nItemLen = 2;
-			va_arg(argList, WCHAR_ARG);
-			break;
-
-		// strings
-		case 's':
-			{
-				LPCTSTR pstrNextArg = va_arg(argList, LPCTSTR);
-				if (pstrNextArg == NULL)
-				   nItemLen = 6;  // "(null)"
-				else
-				{
-				   nItemLen = lstrlen(pstrNextArg);
-				   nItemLen = max(1, nItemLen);
-				}
-			}
-			break;
-
-		case 'S':
-			{
-				LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
-				if (pstrNextArg == NULL)
-				   nItemLen = 6; // "(null)"
-				else
-				{
-				   nItemLen = lstrlenA(pstrNextArg);
-				   nItemLen = max(1, nItemLen);
-				}
-			}
-			break;
-
-		case 's'|FORCE_ANSI:
-		case 'S'|FORCE_ANSI:
-			{
-				LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
-				if (pstrNextArg == NULL)
-				   nItemLen = 6; // "(null)"
-				else
-				{
-				   nItemLen = lstrlenA(pstrNextArg);
-				   nItemLen = max(1, nItemLen);
-				}
-			}
-			break;
-
-		case 's'|FORCE_UNICODE:
-		case 'S'|FORCE_UNICODE:
-			{
-				LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
-				if (pstrNextArg == NULL)
-				   nItemLen = 6; // "(null)"
-				else
-				{
-				   nItemLen = wcslen(pstrNextArg);
-				   nItemLen = max(1, nItemLen);
-				}
-			}
-			break;
-		}
-
-		// adjust nItemLen for strings
-		if (nItemLen != 0)
-		{
-			if (nPrecision != 0)
-				nItemLen = min(nItemLen, nPrecision);
-			nItemLen = max(nItemLen, nWidth);
-		}
-		else
-		{
-			switch (*lpsz)
-			{
-			// integers
-			case 'd':
-			case 'i':
-			case 'u':
-			case 'x':
-			case 'X':
-			case 'o':
-				if (nModifier & FORCE_INT64)
-					va_arg(argList, __int64);
-				else
-					va_arg(argList, int);
-				nItemLen = 32;
-				nItemLen = max(nItemLen, nWidth+nPrecision);
-				break;
-
-			case 'e':
-			case 'g':
-			case 'G':
-				va_arg(argList, DOUBLE_ARG);
-				nItemLen = 128;
-				nItemLen = max(nItemLen, nWidth+nPrecision);
-				break;
-
-			case 'f':
-				va_arg(argList, DOUBLE_ARG);
-				nItemLen = 128; // width isn't truncated
-				// 312 == strlen("-1+(309 zeroes).")
-				// 309 zeroes == max precision of a double
-				nItemLen = max(nItemLen, 312+nPrecision);
-				break;
-
-			case 'p':
-				va_arg(argList, void*);
-				nItemLen = 32;
-				nItemLen = max(nItemLen, nWidth+nPrecision);
-				break;
-
-			// no output
-			case 'n':
-				va_arg(argList, int*);
-				break;
-
-			default:
-				ASSERT(FALSE);  // unknown formatting option
-			}
-		}
-
-		// adjust nMaxLen for output nItemLen
-		nMaxLen += nItemLen;
-	}
-
-	GetBuffer(nMaxLen);
-	VERIFY(_vstprintf(m_pchData, lpszFormat, argListSave) <= GetAllocLength());
-	ReleaseBuffer();
-
-	va_end(argListSave);
+	m_Data.vprintf(lpszFormat, argList);
 }
 
 // formatting (using wsprintf style formatting)
@@ -558,104 +212,30 @@ void AFX_CDECL CString::Format(UINT nFormatID, ...)
 
 void CString::TrimRight(LPCTSTR lpszTargetList)
 {
-	// find beginning of trailing matches
-	// by starting at beginning (DBCS aware)
-
-	CopyBeforeWrite();
-	LPTSTR lpsz = m_pchData;
-	LPTSTR lpszLast = NULL;
-
-	while (*lpsz != '\0')
-	{
-		if (_tcschr(lpszTargetList, *lpsz) != NULL)
-		{
-			if (lpszLast == NULL)
-				lpszLast = lpsz;
-		}
-		else
-			lpszLast = NULL;
-		lpsz = _tcsinc(lpsz);
-	}
-
-	if (lpszLast != NULL)
+	UnicodeString TargetList(lpszTargetList);
+	while (!m_Data.IsEmpty() && m_Data.IsDelimiter(TargetList, m_Data.Length()))
 	{
-		// truncate at left-most matching character
-		*lpszLast = '\0';
-		GetData()->nDataLength = lpszLast - m_pchData;
+		m_Data.SetLength(m_Data.Length() - 1);
 	}
 }
 
 void CString::TrimRight(TCHAR chTarget)
 {
-	// find beginning of trailing matches
-	// by starting at beginning (DBCS aware)
-
-	CopyBeforeWrite();
-	LPTSTR lpsz = m_pchData;
-	LPTSTR lpszLast = NULL;
-
-	while (*lpsz != '\0')
-	{
-		if (*lpsz == chTarget)
-		{
-			if (lpszLast == NULL)
-				lpszLast = lpsz;
-		}
-		else
-			lpszLast = NULL;
-		lpsz = _tcsinc(lpsz);
-	}
-
-	if (lpszLast != NULL)
-	{
-		// truncate at left-most matching character
-		*lpszLast = '\0';
-		GetData()->nDataLength = lpszLast - m_pchData;
-	}
+	TrimRight(UnicodeString(chTarget).c_str());
 }
 
 void CString::TrimLeft(LPCTSTR lpszTargets)
 {
-	// if we're not trimming anything, we're not doing any work
-	if (SafeStrlen(lpszTargets) == 0)
-		return;
-
-	CopyBeforeWrite();
-	LPCTSTR lpsz = m_pchData;
-
-	while (*lpsz != '\0')
+	UnicodeString Targets(lpszTargets);
+	while (!m_Data.IsEmpty() && m_Data.IsDelimiter(Targets, 1))
 	{
-		if (_tcschr(lpszTargets, *lpsz) == NULL)
-			break;
-		lpsz = _tcsinc(lpsz);
-	}
-
-	if (lpsz != m_pchData)
-	{
-		// fix up data and length
-		int nDataLength = GetData()->nDataLength - (lpsz - m_pchData);
-		memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(TCHAR));
-		GetData()->nDataLength = nDataLength;
+		m_Data.Delete(1, 1);
 	}
 }
 
 void CString::TrimLeft(TCHAR chTarget)
 {
-	// find first non-matching character
-
-	CopyBeforeWrite();
-	LPCTSTR lpsz = m_pchData;
-
-	while (chTarget == *lpsz)
-		lpsz = _tcsinc(lpsz);
-
-	if (lpsz != m_pchData)
-	{
-		// fix up data and length
-		int nDataLength = GetData()->nDataLength - (lpsz - m_pchData);
-		memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(TCHAR));
-		GetData()->nDataLength = nDataLength;
-	}
+	TrimLeft(UnicodeString(chTarget).c_str());
 }
 
 ///////////////////////////////////////////////////////////////////////////////

+ 4 - 2
libs/mfc/source/winstr.cpp

@@ -26,14 +26,16 @@ BOOL CString::LoadString(UINT nID)
 		return nLen > 0;
 	}
 
+	// Shouldn't happen as we do not have such long string in FileZilla
 	// try buffer size of 512, then larger size until entire string is retrieved
 	int nSize = 256;
 	do
 	{
 		nSize += 256;
-		nLen = AfxLoadString(nID, GetBuffer(nSize-1), nSize);
+		m_Data.SetLength(nSize - 1);
+		nLen = AfxLoadString(nID, m_Data.c_str(), nSize);
 	} while (nSize - nLen <= CHAR_FUDGE);
-	ReleaseBuffer();
+	m_Data.SetLength(nLen);
 
 	return nLen > 0;
 }

+ 1 - 3
source/filezilla/FileZillaIntf.cpp

@@ -398,14 +398,12 @@ bool __fastcall TFileZillaIntf::HandleMessage(WPARAM wParam, LPARAM lParam)
         try
         {
             TNeedPassRequestData Data;
-            Data.Password = AData->Password.GetBuffer(AData->Password.GetLength());
+            Data.Password = NULL;
             Result = HandleAsynchRequestNeedPass(Data, RequestResult);
-            AData->Password.ReleaseBuffer(AData->Password.GetLength());
             if (Result && (RequestResult == TFileZillaIntf::REPLY_OK))
             {
               AData->Password = Data.Password;
               free(Data.Password);
-              Data.Password = NULL;
             }
         }
         catch(...)

+ 35 - 35
source/filezilla/FtpControlSocket.cpp

@@ -846,18 +846,19 @@ void CFtpControlSocket::LogOnToServer(BOOL bSkipReply /*=FALSE*/)
   {
     if (GetReplyCode() == 2)
     {
-      const CStringA reply = m_RecvBuffer.front();
-      if (reply.GetLength() > 7 && reply.Mid(3, 4) == " MVS")
+      const RawByteString reply = m_RecvBuffer.front();
+      if (reply.Length() > 7 && reply.SubString(4, 4) == " MVS")
         m_mayBeMvsFilesystem = true;
-      else if (reply.GetLength() >= 11 && reply.Mid(3, 8) == " BS-2000")
+      else if (reply.Length() >= 11 && reply.SubString(4, 8) == " BS-2000")
         m_mayBeBS2000Filesystem = true;
 
-      if (reply.Left(4) == "VMS ")
+      // This is probably wrong
+      if (reply.SubString(1, 4) == "VMS ")
       {
         m_CurrentServer.nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS;
       }
 
-      if (reply.Find("FileZilla") != -1)
+      if (reply.Pos("FileZilla") > 0)
         m_isFileZilla = true;
     }
 
@@ -1229,7 +1230,7 @@ void CFtpControlSocket::OnReceive(int nErrorCode)
         if (m_bUTF8)
         {
           // convert from UTF-8 to ANSI
-          LPCSTR utf8 = (LPCSTR)m_RecvBuffer.back();
+          LPCSTR utf8 = m_RecvBuffer.back().c_str();
           if (DetectUTF8Encoding(RawByteString(utf8)) == etANSI)
           {
             if (m_CurrentServer.nUTF8 != 1)
@@ -1255,23 +1256,23 @@ void CFtpControlSocket::OnReceive(int nErrorCode)
         }
         else
         {
-          ShowStatus(A2CT(m_RecvBuffer.back()), FZ_LOG_REPLY);
+          ShowStatus(A2CT(m_RecvBuffer.back().c_str()), FZ_LOG_REPLY);
         }
         // Check for multi-line responses
         // Partially duplicated in TFTPFileSystem::HandleReplyStatus
-        if (m_RecvBuffer.back().GetLength() > 3)
+        if (m_RecvBuffer.back().Length() > 3)
         {
           if (m_MultiLine != "")
           {
-            if (m_RecvBuffer.back().Left(4) != m_MultiLine)
+            if (m_RecvBuffer.back().SubString(1, 4) != m_MultiLine)
             {
-              CStringA line = m_RecvBuffer.back();
-              if (line.Left(4) == m_MultiLine.Left(3) + '-')
+              RawByteString line = m_RecvBuffer.back();
+              if (line.SubString(1, 4) == m_MultiLine.SubString(1, 3) + '-')
               {
-                line = line.Mid(4, line.GetLength() - 4);
+                line = line.SubString(5, line.Length() - 4);
               }
               DiscardLine(line);
-               m_RecvBuffer.pop_back();
+              m_RecvBuffer.pop_back();
             }
             else // end of multi-line found
             {
@@ -1284,10 +1285,10 @@ void CFtpControlSocket::OnReceive(int nErrorCode)
             }
           }
           // start of new multi-line
-          else if (m_RecvBuffer.back()[3] == '-')
+          else if (m_RecvBuffer.back()[4] == '-')
           {
             // DDD<SP> is the end of a multi-line response
-            m_MultiLine = m_RecvBuffer.back().Left(3) + ' ';
+            m_MultiLine = m_RecvBuffer.back().SubString(1, 3) + ' ';
             m_RecvBuffer.pop_back();
           }
           else
@@ -1312,7 +1313,7 @@ void CFtpControlSocket::OnReceive(int nErrorCode)
       //send extremely large commands to fill the memory of the server
       if (m_RecvBuffer.empty())
         m_RecvBuffer.push_back("");
-      if (m_RecvBuffer.back().GetLength() < 2000)
+      if (m_RecvBuffer.back().Length() < 2000)
         m_RecvBuffer.back() += buffer[i];
     }
   }
@@ -1531,12 +1532,12 @@ int CFtpControlSocket::TryGetReplyCode()
 {
   if (m_RecvBuffer.empty())
     return 0;
-  CStringA str = m_RecvBuffer.front();
+  RawByteString str = m_RecvBuffer.front();
   if (str == "")
   {
     return -1;
   }
-  else if ((str[0] < '1') || (str[0] > '9'))
+  else if ((str[1] < '1') || (str[1] > '9'))
   {
     UnicodeString Error = FMTLOAD(FTP_MALFORMED_RESPONSE, (UnicodeString(str)));
     LogMessageRaw(FZ_LOG_WARNING, Error.c_str());
@@ -1544,7 +1545,7 @@ int CFtpControlSocket::TryGetReplyCode()
   }
   else
   {
-    return str[0]-'0';
+    return str[1]-'0';
   }
 }
 
@@ -2427,10 +2428,10 @@ void CFtpControlSocket::ListFile(CString filename, const CServerPath &path)
     }
     else
     {
-      CStringA Buf = m_ListFile + '\n';
+      RawByteString Buf = m_ListFile + '\n';
       const bool mlst = true;
       CFtpListResult * pListResult = CreateListResult(mlst);
-      pListResult->AddData(static_cast<const char *>(Buf), Buf.GetLength());
+      pListResult->AddData(Buf.c_str(), Buf.Length());
       pData->direntry = pListResult->getList(num);
       if (pListResult->m_server.nServerType & FZ_SERVERTYPE_SUB_FTP_VMS && m_CurrentServer.nServerType & FZ_SERVERTYPE_FTP)
         m_CurrentServer.nServerType |= FZ_SERVERTYPE_SUB_FTP_VMS;
@@ -5046,12 +5047,12 @@ int CFtpControlSocket::CheckOverwriteFile()
 
 
       CTime *localtime = NULL;
-      TRY
+      try
       {
         if (status.m_has_mtime && status.m_mtime != -1)
           localtime = new CTime(status.m_mtime);
       }
-      CATCH_ALL(e)
+      catch (CException* e)
       {
         TCHAR buffer[1024];
         CString str =L"Exception creating CTime object: ";
@@ -5062,7 +5063,6 @@ int CFtpControlSocket::CheckOverwriteFile()
         LogMessageRaw(FZ_LOG_WARNING, str);
         localtime = NULL;
       }
-      END_CATCH_ALL;
       BOOL bRemoteFileExists = FALSE;
       __int64 remotesize = -1;
       t_directory::t_direntry::t_date remotetime;
@@ -6172,23 +6172,23 @@ BOOL CFtpControlSocket::ParsePwdReply(CString& rawpwd, CServerPath & realPath)
   return TRUE;
 }
 
-void CFtpControlSocket::DiscardLine(CStringA line)
+void CFtpControlSocket::DiscardLine(RawByteString line)
 {
   if (m_Operation.nOpMode == CSMODE_CONNECT && m_Operation.nOpState == CONNECT_FEAT)
   {
-    line.MakeUpper();
-    while (line.Left(1) == " ")
+    line = line.UpperCase();
+    while (line.SubString(1, 1) == " ")
     {
-      line = line.Mid(1, line.GetLength() - 1);
+      line = line.SubString(2, line.Length() - 1);
     }
 #ifndef MPEXT_NO_ZLIB
-    if (line == "MODE Z" || line.Left(7) == "MODE Z ")
+    if (line == "MODE Z" || line.SubString(1, 7) == "MODE Z ")
       m_zlibSupported = true;
     else
 #endif
       if (line == "UTF8" && m_CurrentServer.nUTF8 != 2)
       m_bAnnouncesUTF8 = true;
-    else if (line == "CLNT" || line.Left(5) == "CLNT ")
+    else if (line == "CLNT" || line.SubString(1, 5) == "CLNT ")
       m_hasClntCmd = true;
     else if (line == "MLSD")
     {
@@ -6198,12 +6198,12 @@ void CFtpControlSocket::DiscardLine(CStringA line)
     {
       m_serverCapabilities.SetCapability(mdtm_command, yes);
     }
-    else if (line.Left(4) == "MLST")
+    else if (line.SubString(1, 4) == "MLST")
     {
       std::string facts;
-      if (line.GetLength() > 5)
+      if (line.Length() > 5)
       {
-        facts = (LPCSTR)line.Mid(5, line.GetLength() - 5);
+        facts = line.SubString(6, line.Length() - 5).c_str();
       }
       m_serverCapabilities.SetCapability(mlsd_command, yes, facts);
     }
@@ -6275,11 +6275,11 @@ CString CFtpControlSocket::GetReply()
       (GetReplyCode() == 2))
   {
     // this is probably never used anyway
-    line = (LPCSTR)m_ListFile;
+    line = m_ListFile.c_str();
   }
   else
   {
-    line = (LPCSTR)m_RecvBuffer.front();
+    line = m_RecvBuffer.front().c_str();
   }
 
   if (m_bUTF8)

+ 4 - 4
source/filezilla/FtpControlSocket.h

@@ -133,7 +133,7 @@ protected:
   BOOL ParsePwdReply(CString & rawpwd, CServerPath & realPath);
   BOOL SendAuthSsl();
 
-  void DiscardLine(CStringA line);
+  void DiscardLine(RawByteString line);
   int FileTransferListState(bool get);
   bool NeedModeCommand();
   bool NeedOptsCommand();
@@ -183,11 +183,11 @@ protected:
 
   CFile * m_pDataFile;
   CTransferSocket * m_pTransferSocket;
-  CStringA m_MultiLine;
+  RawByteString m_MultiLine;
   CTime m_LastSendTime;
 
   CString m_ServerName;
-  std::list<CStringA> m_RecvBuffer;
+  std::list<RawByteString> m_RecvBuffer;
   CTime m_LastRecvTime;
   class CLogonData;
   class CListData;
@@ -204,7 +204,7 @@ protected:
   bool m_bAnnouncesUTF8;
   bool m_hasClntCmd;
   TFTPServerCapabilities m_serverCapabilities;
-  CStringA m_ListFile;
+  RawByteString m_ListFile;
   __int64 m_ListFileSize;
   bool m_isFileZilla;
 

+ 5 - 4
source/filezilla/FtpListResult.cpp

@@ -714,12 +714,13 @@ BOOL CFtpListResult::parseAsVMS(const char *line, const int linelen, t_directory
   if (dir.dir)
   {
     int i;
-    LPTSTR pBuffer = dir.name.GetBuffer(tokenlen - 4);
+    UnicodeString Buf;
+    Buf.SetLength(tokenlen - 4);
     for (i = 0; i < (separator - str - 4); i++)
-      pBuffer[i] = str[i];
+      Buf[i + 1] = str[i];
     for (i = 0; i < (tokenlen - (separator - str)); i++)
-      pBuffer[i + (separator - str) - 4] = separator[i];
-    dir.name.ReleaseBuffer(tokenlen - 4);
+      Buf[i + (separator - str) - 4 + 1] = separator[i];
+    dir.name = CString(Buf);
   }
   else
     copyStr(dir.name, 0, str, tokenlen);

+ 6 - 9
source/filezilla/MFC64bitFix.cpp

@@ -40,38 +40,35 @@ BOOL PASCAL GetStatus64(LPCTSTR lpszFileName, CFileStatus64& rStatus)
   rStatus.m_size = ((_int64)findFileData.nFileSizeHigh<<32)+findFileData.nFileSizeLow;
 
   // convert times as appropriate
-  TRY
+  try
   {
     rStatus.m_ctime = CTime(findFileData.ftCreationTime);
     rStatus.m_has_ctime = true;
   }
-  CATCH_ALL(e)
+  catch (CException*)
   {
     rStatus.m_has_ctime = false;
   }
-  END_CATCH_ALL;
 
-  TRY
+  try
   {
     rStatus.m_atime = CTime(findFileData.ftLastAccessTime);
     rStatus.m_has_atime = true;
   }
-  CATCH_ALL(e)
+  catch (CException*)
   {
     rStatus.m_has_atime = false;
   }
-  END_CATCH_ALL;
 
-  TRY
+  try
   {
     rStatus.m_mtime = CTime(findFileData.ftLastWriteTime);
     rStatus.m_has_mtime = true;
   }
-  CATCH_ALL(e)
+  catch (CException*)
   {
     rStatus.m_has_mtime = false;
   }
-  END_CATCH_ALL;
 
   if (!rStatus.m_has_ctime || rStatus.m_ctime.GetTime() == 0)
   {

+ 4 - 6
source/filezilla/TransferSocket.cpp

@@ -243,7 +243,7 @@ void CTransferSocket::OnReceive(int nErrorCode)
 
     int written = 0;
     m_LastActiveTime = CTime::GetCurrentTime();
-    TRY
+    try
     {
 #ifndef MPEXT_NO_ZLIB
       if (m_useZlib)
@@ -283,7 +283,7 @@ void CTransferSocket::OnReceive(int nErrorCode)
         written = numread;
       }
     }
-    CATCH(CFileException,e)
+    catch (CFileException * e)
     {
       LPTSTR msg = new TCHAR[BUFSIZE];
       if (e->GetErrorMessage(msg, BUFSIZE))
@@ -292,7 +292,6 @@ void CTransferSocket::OnReceive(int nErrorCode)
       CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
       return;
     }
-    END_CATCH;
     m_transferdata.transferleft -= written;
 
     UpdateStatusBar(false);
@@ -1136,7 +1135,7 @@ int CTransferSocket::ReadData(char * buffer, int len)
 
 int CTransferSocket::ReadDataFromFile(char *buffer, int len)
 {
-  TRY
+  try
   {
     // Comparing to Filezilla 2, we do not do any translation locally,
     // leaving it onto the server (what Filezilla 3 seems to do too)
@@ -1156,7 +1155,7 @@ int CTransferSocket::ReadDataFromFile(char *buffer, int len)
     }
     return read;
   }
-  CATCH_ALL(e)
+  catch (CException* e)
   {
     TCHAR error[BUFSIZE];
     if (e->GetErrorMessage(error, BUFSIZE))
@@ -1164,7 +1163,6 @@ int CTransferSocket::ReadDataFromFile(char *buffer, int len)
     CloseOnShutDownOrError(CSMODE_TRANSFERERROR);
     return -1;
   }
-  END_CATCH_ALL;
 }
 
 void CTransferSocket::LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg)

+ 0 - 414
source/filezilla/stdafx.h

@@ -59,420 +59,6 @@ typedef struct
   BOOL bFileTransfer;
 } t_ffam_transferstatus;
 //---------------------------------------------------------------------------
-struct CStringDataA
-{
-  long nRefs;             // reference count
-  int nDataLength;        // length of data (including terminator)
-  int nAllocLength;       // length of allocation
-  // char data[nAllocLength];
-
-  CHAR * data()           // CHAR* to managed data
-  {
-    return (CHAR *)(this+1);
-  }
-};
-//---------------------------------------------------------------------------
-extern LPCSTR _afxPchNilA;
-extern CStringDataA* _afxDataNilA;
-#define afxEmptyStringA ((CStringA&)*(CStringA*)&_afxPchNilA)
-//---------------------------------------------------------------------------
-class CStringA
-{
-public:
-  CStringA()
-  {
-    m_pchData = afxEmptyStringA.m_pchData;
-  }
-
-  CStringA(const CStringA& stringSrc)
-  {
-    DebugAssert(stringSrc.GetData()->nRefs != 0);
-    if (stringSrc.GetData()->nRefs >= 0)
-    {
-      DebugAssert(stringSrc.GetData() != _afxDataNilA);
-      m_pchData = stringSrc.m_pchData;
-      InterlockedIncrement(&GetData()->nRefs);
-    }
-    else
-    {
-      Init();
-      *this = stringSrc.m_pchData;
-    }
-  }
-
-  CStringA(LPCSTR lpsz)
-  {
-    Init();
-    if (lpsz != NULL && HIWORD(lpsz) == NULL)
-    {
-      DebugFail();
-    }
-    else
-    {
-      int nLen = SafeStrlen(lpsz);
-      if (nLen != 0)
-      {
-        AllocBuffer(nLen);
-        memcpy(m_pchData, lpsz, nLen*sizeof(char));
-      }
-    }
-  }
-
-  ~CStringA()
-  {
-    if (GetData() != _afxDataNilA)
-    {
-      if (InterlockedDecrement(&GetData()->nRefs) <= 0)
-      {
-        FreeData(GetData());
-      }
-    }
-  }
-
-  int GetLength() const
-  {
-    return GetData()->nDataLength;
-  }
-
-  char operator[](int nIndex) const
-  {
-    // same as GetAt
-    DebugAssert(nIndex >= 0);
-    DebugAssert(nIndex < GetData()->nDataLength);
-    return m_pchData[nIndex];
-  }
-
-  // ref-counted copy from another CString
-  CStringA& operator=(const CStringA& stringSrc)
-  {
-    if (m_pchData != stringSrc.m_pchData)
-    {
-      if ((GetData()->nRefs < 0 && GetData() != _afxDataNilA) ||
-          stringSrc.GetData()->nRefs < 0)
-      {
-        // actual copy necessary since one of the strings is locked
-        AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
-      }
-      else
-      {
-        // can just copy references around
-        Release();
-        DebugAssert(stringSrc.GetData() != _afxDataNilA);
-        m_pchData = stringSrc.m_pchData;
-        InterlockedIncrement(&GetData()->nRefs);
-      }
-    }
-    return *this;
-  }
-
-  const CStringA & operator=(LPCSTR lpsz)
-  {
-    AssignCopy(SafeStrlen(lpsz), lpsz);
-    return *this;
-  }
-
-  const CStringA & operator+=(char ch)
-  {
-    ConcatInPlace(1, &ch);
-    return *this;
-  }
-
-  friend CStringA AFXAPI operator+(const CStringA & string, char ch);
-
-  operator LPCSTR() const
-  {
-    return m_pchData;
-  }
-
-  int Compare(LPCSTR lpsz) const
-  {
-    return strcmp(m_pchData, lpsz);
-  }
-
-  CStringA 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 > GetData()->nDataLength)
-    {
-      nCount = GetData()->nDataLength - nFirst;
-    }
-    if (nFirst > GetData()->nDataLength)
-    {
-      nCount = 0;
-    }
-
-    DebugAssert(nFirst >= 0);
-    DebugAssert(nFirst + nCount <= GetData()->nDataLength);
-
-    // optimize case of returning entire string
-    if (nFirst == 0 && nFirst + nCount == GetData()->nDataLength)
-    {
-      return *this;
-    }
-
-    CStringA dest;
-    AllocCopy(dest, nCount, nFirst, 0);
-    return dest;
-  }
-
-  CStringA Left(int nCount) const
-  {
-    if (nCount < 0)
-    {
-      nCount = 0;
-    }
-    if (nCount >= GetData()->nDataLength)
-    {
-      return *this;
-    }
-
-    CStringA dest;
-    AllocCopy(dest, nCount, 0, 0);
-    return dest;
-  }
-
-  int Find(char ch) const
-  {
-    return Find(ch, 0);
-  }
-
-  int Find(char ch, int nStart) const
-  {
-    int nLength = GetData()->nDataLength;
-    if (nStart >= nLength)
-    {
-      return -1;
-    }
-
-    // find first single character
-    LPSTR lpsz = strchr(m_pchData + nStart, (unsigned char)ch);
-
-    // return -1 if not found and index otherwise
-    return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
-  }
-
-  // find a sub-string (like strstr)
-  int Find(LPCSTR lpszSub) const
-  {
-    return Find(lpszSub, 0);
-  }
-
-  int Find(LPCSTR lpszSub, int nStart) const
-  {
-    int nLength = GetData()->nDataLength;
-    if (nStart > nLength)
-    {
-      return -1;
-    }
-
-    // find first matching substring
-    LPSTR lpsz = strstr(m_pchData + nStart, lpszSub);
-
-    // return -1 for not found, distance from beginning otherwise
-    return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
-  }
-
-  void MakeUpper()
-  {
-    CopyBeforeWrite();
-    strupr(m_pchData);
-  }
-
-protected:
-  LPSTR m_pchData;   // pointer to ref counted string data
-
-  CStringDataA * GetData() const
-  {
-    DebugAssert(m_pchData != NULL); return ((CStringDataA*)m_pchData)-1;
-  }
-
-  void Init()
-  {
-    m_pchData = afxEmptyStringA.m_pchData;
-  }
-
-  void AllocCopy(CStringA & dest, int nCopyLen, int nCopyIndex, int nExtraLen) const
-  {
-    // will clone the data attached to this string
-    // allocating 'nExtraLen' characters
-    // Places results in uninitialized string 'dest'
-    // Will copy the part or all of original data to start of new string
-
-    int nNewLen = nCopyLen + nExtraLen;
-    if (nNewLen == 0)
-    {
-      dest.Init();
-    }
-    else
-    {
-      dest.AllocBuffer(nNewLen);
-      memcpy(dest.m_pchData, m_pchData+nCopyIndex, nCopyLen*sizeof(char));
-    }
-  }
-
-  void AllocBuffer(int nLen)
-  // always allocate one extra character for '\0' termination
-  // assumes [optimistically] that data length will equal allocation length
-  {
-    DebugAssert(nLen >= 0);
-    DebugAssert(nLen <= INT_MAX-1);    // max size (enough room for 1 extra)
-
-    if (nLen == 0)
-    {
-      Init();
-    }
-    else
-    {
-      CStringDataA* pData;
-      {
-        pData = (CStringDataA*)
-          new BYTE[sizeof(CStringDataA) + (nLen+1)*sizeof(char)];
-        pData->nAllocLength = nLen;
-      }
-      pData->nRefs = 1;
-      pData->data()[nLen] = '\0';
-      pData->nDataLength = nLen;
-      m_pchData = pData->data();
-    }
-  }
-
-  void AssignCopy(int nSrcLen, LPCSTR lpszSrcData)
-  {
-    AllocBeforeWrite(nSrcLen);
-    memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(char));
-    GetData()->nDataLength = nSrcLen;
-    m_pchData[nSrcLen] = '\0';
-  }
-
-  void FASTCALL FreeData(CStringDataA * pData)
-  {
-    delete[] (BYTE*)pData;
-  }
-
-  void PASCAL Release(CStringDataA * pData)
-  {
-    if (pData != _afxDataNilA)
-    {
-      DebugAssert(pData->nRefs != 0);
-      if (InterlockedDecrement(&pData->nRefs) <= 0)
-      {
-        FreeData(pData);
-      }
-    }
-  }
-
-  void Release()
-  {
-    if (GetData() != _afxDataNilA)
-    {
-      DebugAssert(GetData()->nRefs != 0);
-      if (InterlockedDecrement(&GetData()->nRefs) <= 0)
-      {
-        FreeData(GetData());
-      }
-      Init();
-    }
-  }
-
-  void ConcatCopy(int nSrc1Len, LPCSTR lpszSrc1Data, int nSrc2Len, LPCSTR lpszSrc2Data)
-  {
-    // -- master concatenation routine
-    // Concatenate two sources
-    // -- assume that 'this' is a new CString object
-
-    int nNewLen = nSrc1Len + nSrc2Len;
-    if (nNewLen != 0)
-    {
-      AllocBuffer(nNewLen);
-      memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(char));
-      memcpy(m_pchData+nSrc1Len, lpszSrc2Data, nSrc2Len*sizeof(char));
-    }
-  }
-
-  void ConcatInPlace(int nSrcLen, LPCSTR lpszSrcData)
-  {
-    //  -- the main routine for += operators
-
-    // concatenating an empty string is a no-op!
-    if (nSrcLen == 0)
-    {
-      return;
-    }
-
-    // if the buffer is too small, or we have a width mis-match, just
-    //   allocate a new buffer (slow but sure)
-    if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength)
-    {
-      // we have to grow the buffer, use the ConcatCopy routine
-      CStringDataA* pOldData = GetData();
-      ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData);
-      DebugAssert(pOldData != NULL);
-      CStringA::Release(pOldData);
-    }
-    else
-    {
-      // fast concatenation when buffer big enough
-      memcpy(m_pchData+GetData()->nDataLength, lpszSrcData, nSrcLen*sizeof(char));
-      GetData()->nDataLength += nSrcLen;
-      DebugAssert(GetData()->nDataLength <= GetData()->nAllocLength);
-      m_pchData[GetData()->nDataLength] = '\0';
-    }
-  }
-
-  void CopyBeforeWrite()
-  {
-    if (GetData()->nRefs > 1)
-    {
-      CStringDataA* pData = GetData();
-      Release();
-      AllocBuffer(pData->nDataLength);
-      memcpy(m_pchData, pData->data(), (pData->nDataLength+1)*sizeof(char));
-    }
-    DebugAssert(GetData()->nRefs <= 1);
-  }
-
-  void AllocBeforeWrite(int nLen)
-  {
-    if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
-    {
-      Release();
-      AllocBuffer(nLen);
-    }
-    DebugAssert(GetData()->nRefs <= 1);
-  }
-
-  static int PASCAL SafeStrlen(LPCSTR lpsz)
-  {
-    return (lpsz == NULL) ? 0 : strlen(lpsz);
-  }
-};
-//---------------------------------------------------------------------------
-inline bool AFXAPI operator==(const CStringA & s1, LPCSTR s2)
-{
-  return s1.Compare(s2) == 0;
-}
-//---------------------------------------------------------------------------
-inline bool AFXAPI operator!=(const CStringA & s1, LPCSTR s2)
-{
-  return s1.Compare(s2) != 0;
-}
-//---------------------------------------------------------------------------
-inline CStringA AFXAPI operator+(const CStringA & string1, char ch)
-{
-  CStringA s;
-  s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, 1, &ch);
-  return s;
-}
-//---------------------------------------------------------------------------
 #include <FileZillaApi.h>
 #include <FileZillaOpt.h>
 //---------------------------------------------------------------------------

+ 0 - 5
source/filezilla/structures.cpp

@@ -1,11 +1,6 @@
 //---------------------------------------------------------------------------
 #include "stdafx.h"
 
-
-AFX_COMDAT int _afxInitDataA[] = { -1, 0, 0, 0 };
-AFX_COMDAT CStringDataA* _afxDataNilA = (CStringDataA*)&_afxInitDataA;
-AFX_COMDAT LPCSTR _afxPchNilA = (LPCSTR)(((BYTE*)&_afxInitDataA)+sizeof(CStringDataA));
-
 t_directory::t_directory()
 {
   direntry=0;