OSDN Git Service

* Reduce memory usage while comparing folders(2)
authorsdottaka <none@none>
Thu, 2 Jan 2014 10:00:20 +0000 (19:00 +0900)
committersdottaka <none@none>
Thu, 2 Jan 2014 10:00:20 +0000 (19:00 +0900)
 (Share the same string data)
* Remove unused variable 'errorDesc' from DIFFITEM

--HG--
branch : stable

16 files changed:
Src/7zCommon.cpp
Src/DiffContext.cpp
Src/DiffItem.cpp
Src/DiffItem.h
Src/DiffThread.cpp
Src/DirActions.cpp
Src/DirDoc.cpp
Src/DirItem.cpp
Src/DirItem.h
Src/DirScan.cpp
Src/DirScan.h
Src/DirTravel.cpp
Src/DirViewColItems.cpp
Src/FolderCmp.cpp
Src/MainFrm.cpp
Testing/FolderCompare/FolderCompare.cpp

index b1f4ae8..1c91e60 100644 (file)
@@ -814,7 +814,7 @@ CDirView::DirItemEnumerator::DirItemEnumerator(CDirView *pView, int nFlags)
                                if (!di.diffcode.isSideFirstOnly())
                                {
                                        // Item is present on right side, i.e. folder is implied
-                                       m_rgImpliedFoldersRight[di.diffFileInfo[1].path] = PVOID(1);
+                                       m_rgImpliedFoldersRight[di.diffFileInfo[1].GetPath()] = PVOID(1);
                                }
                        }
                        else
@@ -823,7 +823,7 @@ CDirView::DirItemEnumerator::DirItemEnumerator(CDirView *pView, int nFlags)
                                if (!di.diffcode.isSideSecondOnly())
                                {
                                        // Item is present on left side, i.e. folder is implied
-                                       m_rgImpliedFoldersLeft[di.diffFileInfo[0].path] = PVOID(1);
+                                       m_rgImpliedFoldersLeft[di.diffFileInfo[0].GetPath()] = PVOID(1);
                                }
                        }
                }
@@ -898,8 +898,8 @@ Merge7z::Envelope *CDirView::DirItemEnumerator::Enum(Item &item)
 
        Envelope *envelope = new Envelope;
 
-       const String &sFilename = m_bRight ? di.diffFileInfo[1].filename : di.diffFileInfo[0].filename;
-       const String &sSubdir = m_bRight ? di.diffFileInfo[1].path : di.diffFileInfo[0].path;
+       const String &sFilename = m_bRight ? di.diffFileInfo[1].GetFileName() : di.diffFileInfo[0].GetFileName();
+       const String &sSubdir = m_bRight ? di.diffFileInfo[1].GetPath() : di.diffFileInfo[0].GetPath();
        envelope->Name = sFilename;
        if (sSubdir.length())
        {
@@ -922,12 +922,12 @@ Merge7z::Envelope *CDirView::DirItemEnumerator::Enum(Item &item)
                        if (isSideFirst)
                        {
                                // Item is missing on right side
-                               PVOID &implied = m_rgImpliedFoldersRight[di.diffFileInfo[0].path.c_str()];
+                               PVOID &implied = m_rgImpliedFoldersRight[di.diffFileInfo[0].GetPath()];
                                if (!implied)
                                {
                                        // Folder is not implied by some other file, and has
                                        // not been enumerated so far, so enumerate it now!
-                                       envelope->Name = di.diffFileInfo[0].path;
+                                       envelope->Name = di.diffFileInfo[0].GetPath();
                                        envelope->FullPath = di.getFilepath(0, pDoc->GetBasePath(0));
                                        implied = PVOID(2); // Don't enumerate same folder twice!
                                        isSideFirst = false;
@@ -941,12 +941,12 @@ Merge7z::Envelope *CDirView::DirItemEnumerator::Enum(Item &item)
                        if (isSideSecond)
                        {
                                // Item is missing on left side
-                               PVOID &implied = m_rgImpliedFoldersLeft[di.diffFileInfo[1].path.c_str()];
+                               PVOID &implied = m_rgImpliedFoldersLeft[di.diffFileInfo[1].GetPath()];
                                if (!implied)
                                {
                                        // Folder is not implied by some other file, and has
                                        // not been enumerated so far, so enumerate it now!
-                                       envelope->Name = di.diffFileInfo[1].path;
+                                       envelope->Name = di.diffFileInfo[1].GetPath();
                                        envelope->FullPath = di.getFilepath(1, pDoc->GetBasePath(1));
                                        implied = PVOID(2); // Don't enumerate same folder twice!
                                        isSideSecond = false;
@@ -1100,7 +1100,7 @@ void CDirView::DirItemEnumerator::CollectFiles(String &strBuffer)
                        cchBuffer +=
                        (
                                m_bRight ? di.getFilepath(1, sLeftRootPath) : di.getFilepath(0, sRightRootPath)
-                       ).length() + (m_bRight ? di.diffFileInfo[1].filename : di.diffFileInfo[0].filename).length() + 2;
+                       ).length() + (m_bRight ? di.diffFileInfo[1].GetFileName() : di.diffFileInfo[0].GetFileName()).length() + 2;
                }
        }
        strBuffer.resize(cchBuffer + 1);
@@ -1115,7 +1115,7 @@ void CDirView::DirItemEnumerator::CollectFiles(String &strBuffer)
                                pchBuffer,
                                _T("%s\\%s"),
                                m_bRight ? di.getFilepath(1, sLeftRootPath).c_str() : di.getFilepath(0, sRightRootPath).c_str(),
-                               m_bRight ? di.diffFileInfo[1].filename.c_str() : di.diffFileInfo[0].filename.c_str()
+                               m_bRight ? di.diffFileInfo[1].GetFileName().c_str() : di.diffFileInfo[0].GetFileName().c_str()
                        ) + 1;
                }
        }
index a52885a..e385957 100644 (file)
@@ -120,7 +120,7 @@ void CDiffContext::UpdateStatusFromDisk(UIntPtr diffpos, bool bLeft, bool bRight
  */
 bool CDiffContext::UpdateInfoFromDiskHalf(DIFFITEM & di, int nIndex)
 {
-       String filepath = paths_ConcatPath(di.getFilepath(nIndex, GetNormalizedPath(nIndex)), di.diffFileInfo[nIndex].filename);
+       String filepath = paths_ConcatPath(di.getFilepath(nIndex, GetNormalizedPath(nIndex)), di.diffFileInfo[nIndex].GetFileName());
        DiffFileInfo & dfi = di.diffFileInfo[nIndex];
        if (!dfi.Update(filepath))
                return false;
@@ -161,8 +161,7 @@ void CDiffContext::UpdateVersion(DIFFITEM & di, int nIndex) const
 {
        DiffFileInfo & dfi = nIndex == 0 ? di.diffFileInfo[0] : di.diffFileInfo[1];
        // Check only binary files
-       dfi.version.Clear();
-       dfi.bVersionChecked = true;
+       dfi.version.SetFileVersionNone();
 
        if (di.diffcode.isDirectory())
                return;
@@ -172,21 +171,21 @@ void CDiffContext::UpdateVersion(DIFFITEM & di, int nIndex) const
        {
                if (di.diffcode.isSideSecondOnly())
                        return;
-               String ext = paths_FindExtension(di.diffFileInfo[0].filename);
+               String ext = paths_FindExtension(di.diffFileInfo[0].GetFileName());
                if (!CheckFileForVersion(ext))
                        return;
                spath = di.getFilepath(0, GetNormalizedLeft());
-               spath = paths_ConcatPath(spath, di.diffFileInfo[0].filename);
+               spath = paths_ConcatPath(spath, di.diffFileInfo[0].GetFileName());
        }
        else
        {
                if (di.diffcode.isSideFirstOnly())
                        return;
-               String ext = paths_FindExtension(di.diffFileInfo[1].filename);
+               String ext = paths_FindExtension(di.diffFileInfo[1].GetFileName());
                if (!CheckFileForVersion(ext))
                        return;
                spath = di.getFilepath(1, GetNormalizedRight());
-               spath = paths_ConcatPath(spath, di.diffFileInfo[1].filename);
+               spath = paths_ConcatPath(spath, di.diffFileInfo[1].GetFileName());
        }
        
        // Get version info if it exists
index 694bde9..48d6175 100644 (file)
@@ -27,7 +27,7 @@ String DIFFITEM::getFilepath(int nIndex, const String &sRoot) const
 {
        if (diffcode.isExists(nIndex))
        {
-               return paths_ConcatPath(sRoot, diffFileInfo[nIndex].path);
+               return paths_ConcatPath(sRoot, diffFileInfo[nIndex].GetPath());
        }
        return _T("");
 }
index 7847f9c..c9bfb24 100644 (file)
@@ -162,7 +162,6 @@ struct DIFFITEM : ListEntry
        DiffFileInfo diffFileInfo[3]; /**< Fileinfo for left/middle/right file */
        int     nsdiffs; /**< Amount of non-ignored differences */
        int nidiffs; /**< Amount of ignored differences */
-       String errorDesc; /**< technical note about error */
        unsigned customFlags1; /**< Custom flags set 1 */
        DIFFCODE diffcode; /**< Compare result */
 
index 6ee4286..f1ca729 100644 (file)
@@ -27,6 +27,7 @@
 #include <climits>
 #include <Poco/Thread.h>
 #include <Poco/Semaphore.h>
+#include <boost/shared_ptr.hpp>
 #include "UnicodeString.h"
 #include "DiffContext.h"
 #include "DirScan.h"
@@ -37,6 +38,7 @@
 
 using Poco::Thread;
 using Poco::Semaphore;
+using boost::shared_ptr;
 
 // Thread functions
 static void DiffThreadCollect(void *lpParam);
@@ -158,7 +160,9 @@ static void DiffThreadCollect(void *pParam)
 
        paths = myStruct->context->GetNormalizedPaths();
 
-       const TCHAR *subdir[3] = {_T(""), _T(""), _T("")}; // blank to start at roots specified in diff context
+       shared_ptr<String> subdir[3]; // blank to start at roots specified in diff context
+       subdir[0].reset(new String(_T("")));
+       subdir[1] = subdir[2] = subdir[0];
 
        // Build results list (except delaying file comparisons until below)
        DirScan_GetItems(paths, subdir, myStruct,
index df1c191..d619c6d 100644 (file)
@@ -274,11 +274,10 @@ void CDirView::DoCopyRightToLeft()
                                // If destination sides's relative path is empty it means we
                                // are copying unique items and need to get the real relative
                                // path from original side.
-                               if (di.diffFileInfo[0].path.empty())
+                               if (di.diffFileInfo[0].GetPath().empty())
                                {
                                        sDest = GetDocument()->GetLeftBasePath();
-                                       sDest = paths_ConcatPath(sDest, di.diffFileInfo[1].path);
-                                       sDest = paths_ConcatPath(sDest, di.diffFileInfo[1].filename);
+                                       sDest = paths_ConcatPath(sDest, di.diffFileInfo[1].GetFile());
                                }
                        }
 
@@ -335,11 +334,10 @@ void CDirView::DoCopyLeftToRight()
                                // If destination sides's relative path is empty it means we
                                // are copying unique items and need to get the real relative
                                // path from original side.
-                               if (di.diffFileInfo[1].path.empty())
+                               if (di.diffFileInfo[1].GetPath().empty())
                                {
                                        sDest = GetDocument()->GetRightBasePath();
-                                       sDest = paths_ConcatPath(sDest, di.diffFileInfo[0].path);
-                                       sDest = paths_ConcatPath(sDest, di.diffFileInfo[0].filename);
+                                       sDest = paths_ConcatPath(sDest, di.diffFileInfo[0].GetFile());
                                }
                        }
 
@@ -621,13 +619,13 @@ void CDirView::DoCopyLeftTo()
 
                        if (GetDocument()->GetRecursive())
                        {
-                               if (!di.diffFileInfo[0].path.empty())
+                               if (!di.diffFileInfo[0].GetPath().empty())
                                {
-                                       sFullDest += di.diffFileInfo[0].path;
+                                       sFullDest += di.diffFileInfo[0].GetPath();
                                        sFullDest += _T("\\");
                                }
                        }
-                       sFullDest += di.diffFileInfo[0].filename;
+                       sFullDest += di.diffFileInfo[0].GetFileName();
                        act.dest = sFullDest;
 
                        act.src = slFile;
@@ -692,13 +690,13 @@ void CDirView::DoCopyRightTo()
 
                        if (GetDocument()->GetRecursive())
                        {
-                               if (!di.diffFileInfo[1].path.empty())
+                               if (!di.diffFileInfo[1].GetPath().empty())
                                {
-                                       sFullDest += di.diffFileInfo[1].path;
+                                       sFullDest += di.diffFileInfo[1].GetPath();
                                        sFullDest += _T("\\");
                                }
                        }
-                       sFullDest += di.diffFileInfo[1].filename;
+                       sFullDest += di.diffFileInfo[1].GetFileName();
                        act.dest = sFullDest;
 
                        act.src = srFile;
@@ -761,13 +759,13 @@ void CDirView::DoMoveLeftTo()
                        actionScript.m_destBase = sFullDest;
                        if (GetDocument()->GetRecursive())
                        {
-                               if (!di.diffFileInfo[0].path.empty())
+                               if (!di.diffFileInfo[0].GetPath().empty())
                                {
-                                       sFullDest += di.diffFileInfo[0].path;
+                                       sFullDest += di.diffFileInfo[0].GetPath();
                                        sFullDest += _T("\\");
                                }
                        }
-                       sFullDest += di.diffFileInfo[0].filename;
+                       sFullDest += di.diffFileInfo[0].GetFileName();
                        act.dest = sFullDest;
 
                        act.src = slFile;
@@ -830,13 +828,13 @@ void CDirView::DoMoveRightTo()
                        actionScript.m_destBase = sFullDest;
                        if (GetDocument()->GetRecursive())
                        {
-                               if (!di.diffFileInfo[1].path.empty())
+                               if (!di.diffFileInfo[1].GetPath().empty())
                                {
-                                       sFullDest += di.diffFileInfo[1].path;
+                                       sFullDest += di.diffFileInfo[1].GetPath();
                                        sFullDest += _T("\\");
                                }
                        }
-                       sFullDest += di.diffFileInfo[1].filename;
+                       sFullDest += di.diffFileInfo[1].GetFileName();
                        act.dest = sFullDest;
 
                        act.src = srFile;
@@ -1261,15 +1259,15 @@ bool CDirView::AreItemsOpenable(const DIFFITEM & di1, const DIFFITEM & di2, cons
        String sLeftBasePath = GetDocument()->GetBasePath(0);
        String sMiddleBasePath = GetDocument()->GetBasePath(1);
        String sRightBasePath = GetDocument()->GetBasePath(2);
-       String sLeftPath1 = paths_ConcatPath(di1.getFilepath(0, sLeftBasePath), di1.diffFileInfo[0].filename);
-       String sLeftPath2 = paths_ConcatPath(di2.getFilepath(0, sLeftBasePath), di2.diffFileInfo[0].filename);
-       String sLeftPath3 = paths_ConcatPath(di3.getFilepath(0, sLeftBasePath), di3.diffFileInfo[0].filename);
-       String sMiddlePath1 = paths_ConcatPath(di1.getFilepath(1, sMiddleBasePath), di1.diffFileInfo[1].filename);
-       String sMiddlePath2 = paths_ConcatPath(di2.getFilepath(1, sMiddleBasePath), di2.diffFileInfo[1].filename);
-       String sMiddlePath3 = paths_ConcatPath(di3.getFilepath(1, sMiddleBasePath), di3.diffFileInfo[1].filename);
-       String sRightPath1 = paths_ConcatPath(di1.getFilepath(2, sRightBasePath), di1.diffFileInfo[2].filename);
-       String sRightPath2 = paths_ConcatPath(di2.getFilepath(2, sRightBasePath), di2.diffFileInfo[2].filename);
-       String sRightPath3 = paths_ConcatPath(di3.getFilepath(2, sRightBasePath), di3.diffFileInfo[2].filename);
+       String sLeftPath1 = paths_ConcatPath(di1.getFilepath(0, sLeftBasePath), di1.diffFileInfo[0].GetFileName());
+       String sLeftPath2 = paths_ConcatPath(di2.getFilepath(0, sLeftBasePath), di2.diffFileInfo[0].GetFileName());
+       String sLeftPath3 = paths_ConcatPath(di3.getFilepath(0, sLeftBasePath), di3.diffFileInfo[0].GetFileName());
+       String sMiddlePath1 = paths_ConcatPath(di1.getFilepath(1, sMiddleBasePath), di1.diffFileInfo[1].GetFileName());
+       String sMiddlePath2 = paths_ConcatPath(di2.getFilepath(1, sMiddleBasePath), di2.diffFileInfo[1].GetFileName());
+       String sMiddlePath3 = paths_ConcatPath(di3.getFilepath(1, sMiddleBasePath), di3.diffFileInfo[1].GetFileName());
+       String sRightPath1 = paths_ConcatPath(di1.getFilepath(2, sRightBasePath), di1.diffFileInfo[2].GetFileName());
+       String sRightPath2 = paths_ConcatPath(di2.getFilepath(2, sRightBasePath), di2.diffFileInfo[2].GetFileName());
+       String sRightPath3 = paths_ConcatPath(di3.getFilepath(2, sRightBasePath), di3.diffFileInfo[2].GetFileName());
        // Must not be binary (unless archive)
        if
        (
@@ -1391,8 +1389,8 @@ void CDirView::GetItemFileNames(int sel, String& strLeft, String& strRight) cons
        else
        {
                const DIFFITEM & di = GetDocument()->GetDiffByKey(diffpos);
-               const String leftrelpath = paths_ConcatPath(di.diffFileInfo[0].path, di.diffFileInfo[0].filename);
-               const String rightrelpath = paths_ConcatPath(di.diffFileInfo[1].path, di.diffFileInfo[1].filename);
+               const String leftrelpath = di.diffFileInfo[0].GetFile();
+               const String rightrelpath = di.diffFileInfo[1].GetFile();
                const String & leftpath = GetDocument()->GetBasePath(0);
                const String & rightpath = GetDocument()->GetBasePath(1);
                strLeft = paths_ConcatPath(leftpath, leftrelpath);
@@ -1418,7 +1416,7 @@ void CDirView::GetItemFileNames(int sel, PathContext * paths) const
                const DIFFITEM & di = GetDocument()->GetDiffByKey(diffpos);
                for (int nIndex = 0; nIndex < GetDocument()->m_nDirs; nIndex++)
                {
-                       const String relpath = paths_ConcatPath(di.diffFileInfo[nIndex].path, di.diffFileInfo[nIndex].filename);
+                       const String relpath = di.diffFileInfo[nIndex].GetFile();
                        const String & path = GetDocument()->GetBasePath(nIndex);
                        paths->SetPath(nIndex, paths_ConcatPath(path, relpath));
                }
@@ -1732,9 +1730,9 @@ bool CDirView::DoItemRename(const String& szNewItemName)
                for (index = 0; index < nDirs; index++)
                {
                        if (bRename[index])
-                               di.diffFileInfo[index].filename = szNewItemName;
+                               di.diffFileInfo[index].SetFileName(szNewItemName);
                        else
-                               di.diffFileInfo[index].filename.erase();
+                               di.diffFileInfo[index].SetFileName(_T(""));
                }
        }
 
@@ -1767,7 +1765,7 @@ void CDirView::DoCopyItemsToClipboard(int flags)
                                path += '\\';
                                // If item is a folder then subfolder (relative to base folder)
                                // is in filename member.
-                               path += di.diffFileInfo[nIndex].filename;
+                               path += di.diffFileInfo[nIndex].GetFileName();
 
                                strPaths += path.c_str();
                                strPaths += '\0';
index 6da416a..6d60571 100644 (file)
@@ -589,10 +589,10 @@ UIntPtr CDirDoc::FindItemFromPaths(const String& pathLeft, const String& pathRig
        while (UIntPtr currentPos = pos) // Save our current pos before getting next
        {
                const DIFFITEM &di = m_pCtxt->GetNextDiffPosition(pos);
-               if (di.diffFileInfo[0].path == path1 &&
-                       di.diffFileInfo[1].path == path2 &&
-                       di.diffFileInfo[0].filename == file1 &&
-                       di.diffFileInfo[1].filename == file2)
+               if (di.diffFileInfo[0].GetPath() == path1 &&
+                       di.diffFileInfo[1].GetPath() == path2 &&
+                       di.diffFileInfo[0].GetFileName() == file1 &&
+                       di.diffFileInfo[1].GetFileName() == file2)
                {
                        return currentPos;
                }
index 5bd0032..ad1c669 100644 (file)
@@ -30,6 +30,8 @@
 #include "paths.h"
 #include "TFile.h"
 
+using boost::shared_ptr;
+
 /**
        * @brief Convert file flags to string presentation.
        * This function converts file flags to a string presentation that can be
@@ -58,10 +60,12 @@ String FileFlags::ToString() const
  */
 void DirItem::SetFile(const String &fullPath)
 {
-       String ext;
-       paths_SplitFilename(fullPath, &path, &filename, &ext);
-       filename += _T(".");
-       filename += ext;
+       String ext, filename2, path2;
+       paths_SplitFilename(fullPath, &path2, &filename2, &ext);
+       filename2 += _T(".");
+       filename2 += ext;
+       SetFileName(filename2);
+       SetPath(path2);
 }
 
 /**
@@ -70,7 +74,7 @@ void DirItem::SetFile(const String &fullPath)
  */
 String DirItem::GetFile() const
 {
-       return paths_ConcatPath(path, filename);
+       return paths_ConcatPath(*path, *filename);
 }
 
 /**
index f95d209..cb833da 100644 (file)
@@ -31,6 +31,7 @@
 #include <Poco/Types.h>
 #include <Poco/File.h>
 #include <Poco/Timestamp.h>
+#include <boost/shared_ptr.hpp>
 
 /**
  * @brief Class for fileflags.
@@ -57,14 +58,18 @@ struct DirItem
        Poco::Timestamp ctime; /**< time of creation */
        Poco::Timestamp mtime; /**< time of last modify */
        Poco::File::FileSize size; /**< file size in bytes, -1 means file does not exist*/
-       String filename; /**< filename for this item */
-       String path; /**< full path (excluding filename) for the item */
+       boost::shared_ptr<const String> filename; /**< filename for this item */
+       boost::shared_ptr<const String> path; /**< full path (excluding filename) for the item */
        FileVersion version; /**< string of fixed file version, eg, 1.2.3.4 */
        FileFlags flags; /**< file attributes */
 
        DirItem() : ctime(0), mtime(0), size(-1) { }
        void SetFile(const String &fullPath);
        String GetFile() const;
+       const String& GetPath() const { return *path; };
+       void SetPath(const String& newpath) { path.reset(new String(newpath)); }
+       const String& GetFileName() const { return *filename; };
+       void SetFileName(const String& newfilename) { filename.reset(new String(newfilename)); }
        bool Update(const String &sFilePath);
        void ClearPartial();
 };
index 6bc9dcb..4ef2d53 100644 (file)
@@ -45,14 +45,15 @@ using Poco::ThreadPool;
 using Poco::Runnable;
 using Poco::Environment;
 using Poco::Stopwatch;
+using boost::shared_ptr;
 
 // Static functions (ie, functions only used locally)
 void CompareDiffItem(DIFFITEM &di, CDiffContext * pCtxt);
 static void StoreDiffData(DIFFITEM &di, CDiffContext * pCtxt,
                const FolderCmp * pCmpData);
-static DIFFITEM *AddToList(const TCHAR * sLeftDir, const TCHAR * sRightDir, const DirItem * lent, const DirItem * rent,
+static DIFFITEM *AddToList(const shared_ptr<String> sLeftDir, const shared_ptr<String> sRightDir, const DirItem * lent, const DirItem * rent,
        unsigned code, DiffFuncStruct *myStruct, DIFFITEM *parent);
-static DIFFITEM *AddToList(const TCHAR * sLeftDir, const TCHAR * sMiddleDir, const TCHAR * sRightDir, const DirItem * lent, const DirItem * ment, const DirItem * rent,
+static DIFFITEM *AddToList(const shared_ptr<String> sLeftDir, const shared_ptr<String> sMiddleDir, const shared_ptr<String> sRightDir, const DirItem * lent, const DirItem * ment, const DirItem * rent,
        unsigned code, DiffFuncStruct *myStruct, DIFFITEM *parent);
 static void UpdateDiffItem(DIFFITEM & di, bool & bExists, CDiffContext *pCtxt);
 static int CompareItems(NotificationQueue& queue, DiffFuncStruct *myStruct, UIntPtr parentdiffpos);
@@ -110,19 +111,6 @@ private:
 typedef boost::shared_ptr<DiffWorker> DiffWorkerPtr;
 
 /**
- * @brief Help minimize memory footprint by sharing CStringData if possible.
- * 
- * Use OPTIMIZE_SHARE_CSTRINGDATA to conditionally include code that is merely
- * intended to minimize memory footprint by having two CStrings share one
- * CStringData if possible. The rule is that semantics must be identical
- * regardless of whether OPTIMIZE_SHARE_CSTRINGDATA(X) expands to X or to
- * nothing. If you suspect some bug to be related to this kind of optimization,
- * then you can simply change OPTIMIZE_SHARE_CSTRINGDATA to expand to nothing,
- * recompile, and see if bug disappears.
- */
-#define OPTIMIZE_SHARE_CSTRINGDATA(X) X
-
-/**
  * @brief Collect file- and folder-names to list.
  * This function walks given folders and adds found subfolders and files into
  * lists. There are two modes, determined by the @p depth:
@@ -145,7 +133,7 @@ typedef boost::shared_ptr<DiffWorker> DiffWorkerPtr;
  * @param [in] bUniques If true, walk into unique folders.
  * @return 1 normally, -1 if compare was aborted
  */
-int DirScan_GetItems(const PathContext &paths, const TCHAR * subdir[],
+int DirScan_GetItems(const PathContext &paths, const shared_ptr<String> subdir[],
                DiffFuncStruct *myStruct,
                bool casesensitive, int depth, DIFFITEM *parent,
                bool bUniques)
@@ -160,19 +148,12 @@ int DirScan_GetItems(const PathContext &paths, const TCHAR * subdir[],
        for (nIndex = 0; nIndex < nDirs; nIndex++)
                sDir[nIndex] = paths.GetPath(nIndex);
 
-       if (subdir[0][0])
+       if (!subdir[0]->empty())
        {
                for (nIndex = 0; nIndex < paths.GetSize(); nIndex++)
-                       sDir[nIndex] = paths_ConcatPath(sDir[nIndex], subdir[nIndex]);
-               subprefix[0] = subdir[0];
-               subprefix[0] += backslash;
-               for (nIndex = 1; nIndex < paths.GetSize(); nIndex++)
                {
-                       // minimize memory footprint by having left/rightsubprefix share CStringData if possible
-                       subprefix[nIndex] = OPTIMIZE_SHARE_CSTRINGDATA
-                       (
-                               _tcsicmp(subdir[0], subdir[nIndex]) == 0 ? subprefix[0] : 
-                       ) String(subdir[nIndex]) + backslash;
+                       sDir[nIndex] = paths_ConcatPath(sDir[nIndex], *subdir[nIndex]);
+                       subprefix[nIndex] = *subdir[nIndex] + backslash;
                }
        }
 
@@ -207,14 +188,14 @@ int DirScan_GetItems(const PathContext &paths, const TCHAR * subdir[],
 #ifdef _DEBUG
 TCHAR buf[1024];
 if (nDirs == 2)
-       wsprintf(buf, _T("%s %s\n"), (i < dirs[0].size()) ? dirs[0][i].filename.c_str() : _T(""), (j < dirs[1].size()) ? dirs[1][j].filename.c_str() : _T(""));
+       wsprintf(buf, _T("%s %s\n"), (i < dirs[0].size()) ? dirs[0][i].GetFileName().c_str() : _T(""), (j < dirs[1].size()) ? dirs[1][j].GetFileName().c_str() : _T(""));
 else
-       wsprintf(buf, _T("%s %s %s\n"), (i < dirs[0].size()) ? dirs[0][i].filename.c_str() : _T(""), (j < dirs[1].size()) ?  dirs[1][j].filename.c_str() : _T(""), (k < dirs[2].size()) ? dirs[2][k].filename.c_str() : _T(""));
+       wsprintf(buf, _T("%s %s %s\n"), (i < dirs[0].size()) ? dirs[0][i].GetFileName().c_str() : _T(""), (j < dirs[1].size()) ?  dirs[1][j].GetFileName().c_str() : _T(""), (k < dirs[2].size()) ? dirs[2][k].GetFileName().c_str() : _T(""));
 OutputDebugString(buf);
 #endif
 
-               if (i<dirs[0].size() && (j==dirs[1].size() || collstr(dirs[0][i].filename, dirs[1][j].filename, casesensitive)<0)
-                       && (nDirs < 3 ||      (k==dirs[2].size() || collstr(dirs[0][i].filename, dirs[2][k].filename, casesensitive)<0) ))
+               if (i<dirs[0].size() && (j==dirs[1].size() || collstr(dirs[0][i].GetFileName(), dirs[1][j].GetFileName(), casesensitive)<0)
+                       && (nDirs < 3 ||      (k==dirs[2].size() || collstr(dirs[0][i].GetFileName(), dirs[2][k].GetFileName(), casesensitive)<0) ))
                {
                        nDiffCode = DIFFCODE::FIRST | DIFFCODE::DIR;
                        if (!bUniques)
@@ -228,8 +209,8 @@ OutputDebugString(buf);
                                continue;
                        }
                }
-               else if (j<dirs[1].size() && (i==dirs[0].size() || collstr(dirs[1][j].filename, dirs[0][i].filename, casesensitive)<0)
-                       && (nDirs < 3 ||      (k==dirs[2].size() || collstr(dirs[1][j].filename, dirs[2][k].filename, casesensitive)<0) ))
+               else if (j<dirs[1].size() && (i==dirs[0].size() || collstr(dirs[1][j].GetFileName(), dirs[0][i].GetFileName(), casesensitive)<0)
+                       && (nDirs < 3 ||      (k==dirs[2].size() || collstr(dirs[1][j].GetFileName(), dirs[2][k].GetFileName(), casesensitive)<0) ))
                {
                        nDiffCode = DIFFCODE::SECOND | DIFFCODE::DIR;
                        if (!bUniques)
@@ -249,8 +230,8 @@ OutputDebugString(buf);
                }
                else
                {
-                       if (k<dirs[2].size() && (i==dirs[0].size() || collstr(dirs[2][k].filename, dirs[0][i].filename, casesensitive)<0)
-                               &&                     (j==dirs[1].size() || collstr(dirs[2][k].filename, dirs[1][j].filename, casesensitive)<0) )
+                       if (k<dirs[2].size() && (i==dirs[0].size() || collstr(dirs[2][k].GetFileName(), dirs[0][i].GetFileName(), casesensitive)<0)
+                               &&                     (j==dirs[1].size() || collstr(dirs[2][k].GetFileName(), dirs[1][j].GetFileName(), casesensitive)<0) )
                        {
                                nDiffCode = DIFFCODE::THIRD | DIFFCODE::DIR;
                                if (!bUniques)
@@ -263,8 +244,8 @@ OutputDebugString(buf);
                                }       
 
                        }
-                       else if ((i<dirs[0].size() && j<dirs[1].size() && collstr(dirs[0][i].filename, dirs[1][j].filename, casesensitive) == 0)
-                               && (k==dirs[2].size() || collstr(dirs[2][k].filename, dirs[0][i].filename, casesensitive) != 0))
+                       else if ((i<dirs[0].size() && j<dirs[1].size() && collstr(dirs[0][i].GetFileName(), dirs[1][j].GetFileName(), casesensitive) == 0)
+                               && (k==dirs[2].size() || collstr(dirs[2][k].GetFileName(), dirs[0][i].GetFileName(), casesensitive) != 0))
                        {
                                nDiffCode = DIFFCODE::FIRST | DIFFCODE::SECOND | DIFFCODE::DIR;
                                if (!bUniques)
@@ -275,8 +256,8 @@ OutputDebugString(buf);
                                        continue;       
                                }
                        }
-                       else if ((i<dirs[0].size() && k<dirs[2].size() && collstr(dirs[0][i].filename, dirs[2][k].filename, casesensitive) == 0)
-                               && (j==dirs[1].size() || collstr(dirs[1][j].filename, dirs[2][k].filename, casesensitive) != 0))
+                       else if ((i<dirs[0].size() && k<dirs[2].size() && collstr(dirs[0][i].GetFileName(), dirs[2][k].GetFileName(), casesensitive) == 0)
+                               && (j==dirs[1].size() || collstr(dirs[1][j].GetFileName(), dirs[2][k].GetFileName(), casesensitive) != 0))
                        {
                                nDiffCode = DIFFCODE::FIRST | DIFFCODE::THIRD | DIFFCODE::DIR;
                                if (!bUniques)
@@ -287,8 +268,8 @@ OutputDebugString(buf);
                                        continue;
                                }
                        }
-                       else if ((j<dirs[1].size() && k<dirs[2].size() && collstr(dirs[1][j].filename, dirs[2][k].filename, casesensitive) == 0)
-                               && (i==dirs[0].size() || collstr(dirs[0][i].filename, dirs[1][j].filename, casesensitive) != 0))
+                       else if ((j<dirs[1].size() && k<dirs[2].size() && collstr(dirs[1][j].GetFileName(), dirs[2][k].GetFileName(), casesensitive) == 0)
+                               && (i==dirs[0].size() || collstr(dirs[0][i].GetFileName(), dirs[1][j].GetFileName(), casesensitive) != 0))
                        {
                                nDiffCode = DIFFCODE::SECOND | DIFFCODE::THIRD | DIFFCODE::DIR;
                                if (!bUniques)
@@ -328,23 +309,23 @@ OutputDebugString(buf);
                        String middlenewsub;
                        if (nDirs < 3)
                        {
-                               leftnewsub  = (nDiffCode & DIFFCODE::FIRST)  ? subprefix[0] + dirs[0][i].filename : subprefix[0] + dirs[1][j].filename;
-                               rightnewsub = (nDiffCode & DIFFCODE::SECOND) ? subprefix[1] + dirs[1][j].filename : subprefix[1] + dirs[0][i].filename;
+                               leftnewsub  = (nDiffCode & DIFFCODE::FIRST)  ? subprefix[0] + dirs[0][i].GetFileName() : subprefix[0] + dirs[1][j].GetFileName();
+                               rightnewsub = (nDiffCode & DIFFCODE::SECOND) ? subprefix[1] + dirs[1][j].GetFileName() : subprefix[1] + dirs[0][i].GetFileName();
                        }
                        else
                        {
                                leftnewsub   = subprefix[0];
-                               if (nDiffCode & DIFFCODE::FIRST)       leftnewsub += dirs[0][i].filename;
-                               else if (nDiffCode & DIFFCODE::SECOND) leftnewsub += dirs[1][j].filename;
-                               else if (nDiffCode & DIFFCODE::THIRD)  leftnewsub += dirs[2][k].filename;
+                               if (nDiffCode & DIFFCODE::FIRST)       leftnewsub += dirs[0][i].GetFileName();
+                               else if (nDiffCode & DIFFCODE::SECOND) leftnewsub += dirs[1][j].GetFileName();
+                               else if (nDiffCode & DIFFCODE::THIRD)  leftnewsub += dirs[2][k].GetFileName();
                                middlenewsub = subprefix[1];
-                               if (nDiffCode & DIFFCODE::SECOND)      middlenewsub += dirs[1][j].filename;
-                               else if (nDiffCode & DIFFCODE::FIRST)  middlenewsub += dirs[0][i].filename;
-                               else if (nDiffCode & DIFFCODE::THIRD)  middlenewsub += dirs[2][k].filename;
+                               if (nDiffCode & DIFFCODE::SECOND)      middlenewsub += dirs[1][j].GetFileName();
+                               else if (nDiffCode & DIFFCODE::FIRST)  middlenewsub += dirs[0][i].GetFileName();
+                               else if (nDiffCode & DIFFCODE::THIRD)  middlenewsub += dirs[2][k].GetFileName();
                                rightnewsub  = subprefix[2];
-                               if (nDiffCode & DIFFCODE::THIRD)       rightnewsub += dirs[2][k].filename;
-                               else if (nDiffCode & DIFFCODE::FIRST)  rightnewsub += dirs[0][i].filename;
-                               else if (nDiffCode & DIFFCODE::SECOND) rightnewsub += dirs[1][j].filename;
+                               if (nDiffCode & DIFFCODE::THIRD)       rightnewsub += dirs[2][k].GetFileName();
+                               else if (nDiffCode & DIFFCODE::FIRST)  rightnewsub += dirs[0][i].GetFileName();
+                               else if (nDiffCode & DIFFCODE::SECOND) rightnewsub += dirs[1][j].GetFileName();
                        }
                        if (nDirs < 3)
                        {
@@ -370,9 +351,12 @@ OutputDebugString(buf);
                                                nDiffCode & DIFFCODE::SECOND ? &dirs[1][j] : NULL,
                                                nDiffCode, myStruct, parent);
                                        // Scan recursively all subdirectories too, we are not adding folders
-                                       const TCHAR * newsubdir[3];
-                                       newsubdir[0] = leftnewsub.c_str();
-                                       newsubdir[1] = rightnewsub.c_str();
+                                       shared_ptr<String> newsubdir[3];
+                                       newsubdir[0].reset(new String(leftnewsub));
+                                       if (leftnewsub == rightnewsub)
+                                               newsubdir[1] = newsubdir[0];
+                                       else
+                                               newsubdir[1].reset(new String(rightnewsub));
                                        int result = DirScan_GetItems(paths, newsubdir, myStruct, casesensitive,
                                                        depth - 1, me, bUniques);
                                        if (result == -1)
@@ -418,10 +402,16 @@ OutputDebugString(buf);
                                                nDiffCode & DIFFCODE::THIRD  ? &dirs[2][k] : NULL,
                                                nDiffCode, myStruct, parent);
                                        // Scan recursively all subdirectories too, we are not adding folders
-                                       const TCHAR * newsubdir[3];
-                                       newsubdir[0] = leftnewsub.c_str();
-                                       newsubdir[1] = middlenewsub.c_str();
-                                       newsubdir[2] = rightnewsub.c_str();
+                                       shared_ptr<String> newsubdir[3];
+                                       newsubdir[0].reset(new String(leftnewsub));
+                                       if (leftnewsub == middlenewsub)
+                                               newsubdir[1] = newsubdir[0];
+                                       else
+                                               newsubdir[1].reset(new String(middlenewsub));
+                                       if (leftnewsub == rightnewsub)
+                                               newsubdir[2] = newsubdir[0];
+                                       else
+                                               newsubdir[2].reset(new String(rightnewsub));
                                        int result = DirScan_GetItems(paths, newsubdir, myStruct, casesensitive,
                                                        depth - 1, me, bUniques);
                                        if (result == -1)
@@ -463,16 +453,16 @@ OutputDebugString(buf);
 #ifdef _DEBUG
 TCHAR buf[1024];
 if (nDirs == 2)
-       wsprintf(buf, _T("%s %s\n"), (i < files[0].size()) ? files[0][i].filename.c_str() : _T(""), (j < files[1].size()) ? files[1][j].filename.c_str() : _T(""));
+       wsprintf(buf, _T("%s %s\n"), (i < files[0].size()) ? files[0][i].GetFileName().c_str() : _T(""), (j < files[1].size()) ? files[1][j].GetFileName().c_str() : _T(""));
 else
-       wsprintf(buf, _T("%s %s %s\n"), (i < files[0].size()) ? files[0][i].filename.c_str() : _T(""), (j < files[1].size()) ?  files[1][j].filename.c_str() : _T(""), 
-(k < files[2].size()) ? files[2][k].filename.c_str() : _T(""));
+       wsprintf(buf, _T("%s %s %s\n"), (i < files[0].size()) ? files[0][i].GetFileName().c_str() : _T(""), (j < files[1].size()) ?  files[1][j].GetFileName().c_str() : _T(""), 
+(k < files[2].size()) ? files[2][k].GetFileName().c_str() : _T(""));
 OutputDebugString(buf);
 #endif
                if (i<files[0].size() && (j==files[1].size() ||
-                               collstr(files[0][i].filename, files[1][j].filename, casesensitive) < 0)
+                               collstr(files[0][i].GetFileName(), files[1][j].GetFileName(), casesensitive) < 0)
                        && (nDirs < 3 || 
-                               (k==files[2].size() || collstr(files[0][i].filename, files[2][k].filename, casesensitive)<0) ))
+                               (k==files[2].size() || collstr(files[0][i].GetFileName(), files[2][k].GetFileName(), casesensitive)<0) ))
                {
                        if (nDirs < 3)
                        {
@@ -489,9 +479,9 @@ OutputDebugString(buf);
                        continue;
                }
                if (j<files[1].size() && (i==files[0].size() ||
-                               collstr(files[0][i].filename, files[1][j].filename, casesensitive) > 0)
+                               collstr(files[0][i].GetFileName(), files[1][j].GetFileName(), casesensitive) > 0)
                        && (nDirs < 3 ||
-                               (k==files[2].size() || collstr(files[1][j].filename, files[2][k].filename, casesensitive)<0) ))
+                               (k==files[2].size() || collstr(files[1][j].GetFileName(), files[2][k].GetFileName(), casesensitive)<0) ))
                {
                        const unsigned nDiffCode = DIFFCODE::SECOND | DIFFCODE::FILE;
                        if (nDirs < 3)
@@ -505,8 +495,8 @@ OutputDebugString(buf);
                if (nDirs == 3)
                {
                        if (k<files[2].size() && (i==files[0].size() ||
-                                       collstr(files[2][k].filename, files[0][i].filename, casesensitive)<0)
-                               && (j==files[1].size() || collstr(files[2][k].filename, files[1][j].filename, casesensitive)<0) )
+                                       collstr(files[2][k].GetFileName(), files[0][i].GetFileName(), casesensitive)<0)
+                               && (j==files[1].size() || collstr(files[2][k].GetFileName(), files[1][j].GetFileName(), casesensitive)<0) )
                        {
                                int nDiffCode = DIFFCODE::THIRD | DIFFCODE::FILE;
                                AddToList(subdir[0], subdir[1], subdir[2], 0, 0, &files[2][k], nDiffCode, myStruct, parent);
@@ -515,8 +505,8 @@ OutputDebugString(buf);
                                continue;
                        }
 
-                       if ((i<files[0].size() && j<files[1].size() && collstr(files[0][i].filename, files[1][j].filename, casesensitive) == 0)
-                           && (k==files[2].size() || collstr(files[0][i].filename, files[2][k].filename, casesensitive) != 0))
+                       if ((i<files[0].size() && j<files[1].size() && collstr(files[0][i].GetFileName(), files[1][j].GetFileName(), casesensitive) == 0)
+                           && (k==files[2].size() || collstr(files[0][i].GetFileName(), files[2][k].GetFileName(), casesensitive) != 0))
                        {
                                int nDiffCode = DIFFCODE::FIRST | DIFFCODE::SECOND | DIFFCODE::FILE;
                                AddToList(subdir[0], subdir[1], subdir[2], &files[0][i], &files[1][j], 0, nDiffCode, myStruct, parent);
@@ -524,8 +514,8 @@ OutputDebugString(buf);
                                ++j;
                                continue;
                        }
-                       else if ((i<files[0].size() && k<files[2].size() && collstr(files[0][i].filename, files[2][k].filename, casesensitive) == 0)
-                           && (j==files[1].size() || collstr(files[1][j].filename, files[2][k].filename, casesensitive) != 0))
+                       else if ((i<files[0].size() && k<files[2].size() && collstr(files[0][i].GetFileName(), files[2][k].GetFileName(), casesensitive) == 0)
+                           && (j==files[1].size() || collstr(files[1][j].GetFileName(), files[2][k].GetFileName(), casesensitive) != 0))
                        {
                                int nDiffCode = DIFFCODE::FIRST | DIFFCODE::THIRD | DIFFCODE::FILE;
                                AddToList(subdir[0], subdir[1], subdir[2], &files[0][i], 0, &files[2][k], nDiffCode, myStruct, parent);
@@ -533,8 +523,8 @@ OutputDebugString(buf);
                                ++k;
                                continue;
                        }
-                       else if ((j<files[1].size() && k<files[2].size() && collstr(files[1][j].filename, files[2][k].filename, casesensitive) == 0)
-                           && (i==files[0].size() || collstr(files[0][i].filename, files[1][j].filename, casesensitive) != 0))
+                       else if ((j<files[1].size() && k<files[2].size() && collstr(files[1][j].GetFileName(), files[2][k].GetFileName(), casesensitive) == 0)
+                           && (i==files[0].size() || collstr(files[0][i].GetFileName(), files[1][j].GetFileName(), casesensitive) != 0))
                        {
                                int nDiffCode = DIFFCODE::SECOND | DIFFCODE::THIRD | DIFFCODE::FILE;
                                AddToList(subdir[0], subdir[1], subdir[2], 0, &files[1][j], &files[2][k], nDiffCode, myStruct, parent);
@@ -790,8 +780,8 @@ void CompareDiffItem(DIFFITEM &di, CDiffContext * pCtxt)
        {
                // 1. Test against filters
                if (!pCtxt->m_piFilterGlobal ||
-                       (nDirs == 2 && pCtxt->m_piFilterGlobal->includeDir(di.diffFileInfo[0].filename, di.diffFileInfo[1].filename)) ||
-                       (nDirs == 3 && pCtxt->m_piFilterGlobal->includeDir(di.diffFileInfo[0].filename, di.diffFileInfo[1].filename, di.diffFileInfo[2].filename))
+                       (nDirs == 2 && pCtxt->m_piFilterGlobal->includeDir(di.diffFileInfo[0].GetFileName(), di.diffFileInfo[1].GetFileName())) ||
+                       (nDirs == 3 && pCtxt->m_piFilterGlobal->includeDir(di.diffFileInfo[0].GetFileName(), di.diffFileInfo[1].GetFileName(), di.diffFileInfo[2].GetFileName()))
                        )
                        di.diffcode.diffcode |= DIFFCODE::INCLUDED;
                else
@@ -804,8 +794,8 @@ void CompareDiffItem(DIFFITEM &di, CDiffContext * pCtxt)
        {
                // 1. Test against filters
                if (!pCtxt->m_piFilterGlobal ||
-                       (nDirs == 2 && pCtxt->m_piFilterGlobal->includeFile(di.diffFileInfo[0].filename, di.diffFileInfo[1].filename)) ||
-                       (nDirs == 3 && pCtxt->m_piFilterGlobal->includeFile(di.diffFileInfo[0].filename, di.diffFileInfo[1].filename, di.diffFileInfo[2].filename))
+                       (nDirs == 2 && pCtxt->m_piFilterGlobal->includeFile(di.diffFileInfo[0].GetFileName(), di.diffFileInfo[1].GetFileName())) ||
+                       (nDirs == 3 && pCtxt->m_piFilterGlobal->includeFile(di.diffFileInfo[0].GetFileName(), di.diffFileInfo[1].GetFileName(), di.diffFileInfo[2].GetFileName()))
                        )
                {
                        di.diffcode.diffcode |= DIFFCODE::INCLUDED;
@@ -892,7 +882,7 @@ static void StoreDiffData(DIFFITEM &di, CDiffContext * pCtxt,
  * @param [in] pCtxt Compare context.
  * @param [in] parent Parent of item to be added
  */
-static DIFFITEM *AddToList(const TCHAR * sLeftDir, const TCHAR * sRightDir,
+static DIFFITEM *AddToList(const shared_ptr<String> sLeftDir, const shared_ptr<String> sRightDir,
        const DirItem * lent, const DirItem * rent,
        unsigned code, DiffFuncStruct *myStruct, DIFFITEM *parent)
 {
@@ -902,7 +892,7 @@ static DIFFITEM *AddToList(const TCHAR * sLeftDir, const TCHAR * sRightDir,
 /**
  * @brief Add one compare item to list.
  */
-static DIFFITEM *AddToList(const TCHAR * sLeftDir, const TCHAR * sMiddleDir, const TCHAR * sRightDir,
+static DIFFITEM *AddToList(const shared_ptr<String> sLeftDir, const shared_ptr<String> sMiddleDir, const shared_ptr<String> sRightDir,
        const DirItem * lent, const DirItem * ment, const DirItem * rent,
        unsigned code, DiffFuncStruct *myStruct, DIFFITEM *parent)
 {
@@ -935,10 +925,8 @@ static DIFFITEM *AddToList(const TCHAR * sLeftDir, const TCHAR * sMiddleDir, con
 
        if (ment)
        {
-               di->diffFileInfo[1].filename = OPTIMIZE_SHARE_CSTRINGDATA
-               (
-                       ment && di->diffFileInfo[0].filename == ment->filename ? di->diffFileInfo[0].filename :
-               ) ment->filename;
+               di->diffFileInfo[1].filename = 
+                       (*di->diffFileInfo[0].filename == *ment->filename) ? di->diffFileInfo[0].filename : ment->filename;
                di->diffFileInfo[1].mtime = ment->mtime;
                di->diffFileInfo[1].ctime = ment->ctime;
                di->diffFileInfo[1].size = ment->size;
@@ -955,10 +943,8 @@ static DIFFITEM *AddToList(const TCHAR * sLeftDir, const TCHAR * sMiddleDir, con
 
        if (rent)
        {
-               di->diffFileInfo[2].filename = OPTIMIZE_SHARE_CSTRINGDATA
-               (
-                       lent && di->diffFileInfo[0].filename == lent->filename ? di->diffFileInfo[0].filename :
-               ) rent->filename;
+               di->diffFileInfo[2].filename = 
+                       (*di->diffFileInfo[0].filename == *rent->filename) ? di->diffFileInfo[0].filename : rent->filename;
                di->diffFileInfo[2].mtime = rent->mtime;
                di->diffFileInfo[2].ctime = rent->ctime;
                di->diffFileInfo[2].size = rent->size;
index 8ca84c1..cbea8e0 100644 (file)
@@ -12,6 +12,7 @@
 #include "UnicodeString.h"
 #define POCO_NO_UNWINDOWS 1
 #include <Poco/Types.h>
+#include <boost/shared_ptr.hpp>
 
 class CDiffContext;
 class DiffItemList;
@@ -20,7 +21,7 @@ class IAbortable;
 struct DIFFITEM;
 struct DiffFuncStruct;
 
-int DirScan_GetItems(const PathContext &paths, const TCHAR *subdir[], DiffFuncStruct *myStruct,
+int DirScan_GetItems(const PathContext &paths, const boost::shared_ptr<String> subdir[], DiffFuncStruct *myStruct,
                bool casesensitive, int depth, DIFFITEM *parent, bool bUniques);
 
 int DirScan_CompareItems(DiffFuncStruct *, Poco::UIntPtr parentdiffpos);
index f9db1cd..e415f37 100644 (file)
@@ -21,6 +21,7 @@
 using Poco::DirectoryIterator;
 using Poco::Timestamp;
 using Poco::Int64;
+using boost::shared_ptr;
 
 static void LoadFiles(const String& sDir, DirItemArray * dirs, DirItemArray * files);
 static void Sort(DirItemArray * dirs, bool casesensitive);
@@ -49,6 +50,7 @@ void LoadAndSortFiles(const String& sDir, DirItemArray * dirs, DirItemArray * fi
  */
 static void LoadFiles(const String& sDir, DirItemArray * dirs, DirItemArray * files)
 {
+       shared_ptr<const String> pdir(new String(sDir));
 #if 0
        DirectoryIterator it(ucr::toUTF8(sDir));
        DirectoryIterator end;
@@ -67,8 +69,8 @@ static void LoadFiles(const String& sDir, DirItemArray * dirs, DirItemArray * fi
                if (ent.mtime < 0)
                        ent.mtime = 0;
                ent.size = it->getSize();
-               ent.path = sDir;
-               ent.filename = ucr::toTString(it.name());
+               ent.path = pdir;
+               ent.filename.reset(new String(ucr::toTString(it.name()));
 #ifdef _WIN32
                ent.flags.attributes = GetFileAttributes(ucr::toTString(it.name()).c_str());;
 #else
@@ -115,8 +117,8 @@ static void LoadFiles(const String& sDir, DirItemArray * dirs, DirItemArray * fi
                                ent.size = ((Int64)ff.nFileSizeHigh << 32) + ff.nFileSizeLow;
                        }
 
-                       ent.path = sDir;
-                       ent.filename = ff.cFileName;
+                       ent.path = pdir;
+                       ent.filename.reset(new String(ff.cFileName));
                        ent.flags.attributes = ff.dwFileAttributes;
                        
                        (bIsDirectory ? dirs : files)->push_back(ent);
@@ -137,7 +139,7 @@ static int collate(const String &str1, const String &str2)
  */
 static bool __cdecl cmpstring(const DirItem &elem1, const DirItem &elem2)
 {
-       return collate(elem1.filename, elem2.filename) < 0;
+       return collate(elem1.GetFileName(), elem2.GetFileName()) < 0;
 }
 
 static int collate_ignore_case(const String &str1, const String &str2)
@@ -174,7 +176,7 @@ static int collate_ignore_case(const String &str1, const String &str2)
  */
 static bool __cdecl cmpistring(const DirItem &elem1, const DirItem &elem2)
 {
-       return collate_ignore_case(elem1.filename, elem2.filename) < 0;
+       return collate_ignore_case(elem1.GetFileName(), elem2.GetFileName()) < 0;
 }
 
 /**
index a7749a2..5571d98 100644 (file)
@@ -195,10 +195,10 @@ static String ColFileNameGet(const CDiffContext *, const void *p) //sfilename
        const DIFFITEM &di = *static_cast<const DIFFITEM*>(p);
        return
        (
-               di.diffFileInfo[0].filename.empty() ? di.diffFileInfo[1].filename :
-               di.diffFileInfo[1].filename.empty() ? di.diffFileInfo[0].filename :
-               di.diffFileInfo[0].filename == di.diffFileInfo[1].filename ? di.diffFileInfo[0].filename :
-               di.diffFileInfo[0].filename + _T("|") + di.diffFileInfo[1].filename
+               di.diffFileInfo[0].GetFileName().empty() ? di.diffFileInfo[1].GetFileName() :
+               di.diffFileInfo[1].GetFileName().empty() ? di.diffFileInfo[0].GetFileName() :
+               di.diffFileInfo[0].GetFileName() == di.diffFileInfo[1].GetFileName() ? di.diffFileInfo[0].GetFileName() :
+               di.diffFileInfo[0].GetFileName() + _T("|") + di.diffFileInfo[1].GetFileName()
        );
 }
 
@@ -213,7 +213,7 @@ static String ColExtGet(const CDiffContext *, const void *p) //sfilename
        // We don't show extension for folder names
        if (di.diffcode.isDirectory())
                return _T("");
-       const String &r = di.diffFileInfo[0].filename;
+       const String &r = di.diffFileInfo[0].GetFileName();
        String s = paths_FindExtension(r);
        return s.c_str() + _tcsspn(s.c_str(), _T("."));
 }
@@ -226,8 +226,8 @@ static String ColExtGet(const CDiffContext *, const void *p) //sfilename
 static String ColPathGet(const CDiffContext *, const void *p)
 {
        const DIFFITEM &di = *static_cast<const DIFFITEM*>(p);
-       String s = di.diffFileInfo[1].path;
-       const String &t = di.diffFileInfo[0].path;
+       String s = di.diffFileInfo[1].GetPath();
+       const String &t = di.diffFileInfo[0].GetPath();
 
        // If we have unique path, just print the existing path name
        if (s.length() == 0 || t.length() == 0)
@@ -491,7 +491,7 @@ static String GetVersion(const CDiffContext * pCtxt, const DIFFITEM * pdi, int n
 {
        DIFFITEM & di = const_cast<DIFFITEM &>(*pdi);
        DiffFileInfo & dfi = di.diffFileInfo[nIndex];
-       if (!dfi.bVersionChecked)
+       if (dfi.version.IsCleared())
        {
                pCtxt->UpdateVersion(di, nIndex);
        }
index 64d6b79..8a4d34d 100644 (file)
@@ -124,11 +124,7 @@ int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
                        if (infoUnpacker && string_compare_nocase(filepathUnpacked[nIndex], _T("\\\\.\\NUL")) != 0)
                        {
                                if (!Unpack(filepathUnpacked[nIndex], filteredFilenames, infoUnpacker))
-                               {
-                                       const TCHAR *pszErrorDesc[] = {_T("Unpack Error Side 1"), _T("Unpack Error Side 2"), _T("Unpack Error Side 3")};
-                                       di.errorDesc = pszErrorDesc[nIndex];
                                        goto exitPrepAndCompare;
-                               }
 
                                // we use the same plugins for both files, so they must be defined before second file
                                assert(infoUnpacker->bToBeScanned == false);
@@ -152,11 +148,7 @@ int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
                {
                // Invoke prediff'ing plugins
                        if (infoPrediffer && !m_diffFileData.Filepath_Transform(bForceUTF8, encoding[nIndex], filepathUnpacked[nIndex], filepathTransformed[nIndex], filteredFilenames, infoPrediffer))
-                       {
-                               const TCHAR *pszErrorDesc[] = {_T("Transform Error Side 1"), _T("Unpack Error Side 2"), _T("Unpack Error Side 3")};
-                               di.errorDesc = pszErrorDesc[nIndex];
                                goto exitPrepAndCompare;
-                       }
                }
 
                // If options are binary equivalent, we could check for filesize
@@ -172,10 +164,7 @@ int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
                        m_diffFileData.SetDisplayFilepaths(files[0], files[1]); // store true names for diff utils patch file
                        // This opens & fstats both files (if it succeeds)
                        if (!m_diffFileData.OpenFiles(filepathTransformed[0], filepathTransformed[1]))
-                       {
-                               di.errorDesc = _T("OpenFiles error");
                                goto exitPrepAndCompare;
-                       }
                }
                else
                {
@@ -184,23 +173,14 @@ int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
                        diffdata12.m_diffFileData.SetDisplayFilepaths(files[1], files[2]); // store true names for diff utils patch file
 
                        if (!diffdata10.m_diffFileData.OpenFiles(filepathTransformed[1], filepathTransformed[0]))
-                       {
-                               di.errorDesc = _T("OpenFiles(10) error");
                                goto exitPrepAndCompare;
-                       }
 
 
                        if (!diffdata12.m_diffFileData.OpenFiles(filepathTransformed[1], filepathTransformed[2]))
-                       {
-                               di.errorDesc = _T("OpenFiles(12) error");
                                goto exitPrepAndCompare;
-                       }
 
                        if (!diffdata02.m_diffFileData.OpenFiles(filepathTransformed[0], filepathTransformed[2]))
-                       {
-                               di.errorDesc = _T("OpenFiles(02) error");
                                goto exitPrepAndCompare;
-                       }
 
                }
        }
@@ -245,8 +225,6 @@ int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
                                m_ndiffs = CDiffContext::DIFFS_UNKNOWN;
                                m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN;
                        }
-                       if (DIFFCODE::isResultError(code))
-                               di.errorDesc = _T("DiffUtils Error");
                }
                else
                {
@@ -301,8 +279,6 @@ int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
                                        m_ndiffs = CDiffContext::DIFFS_UNKNOWN;
                                        m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN;
                                }
-                               if (DIFFCODE::isResultError(code))
-                                       di.errorDesc = _T("DiffUtils Error");
 
                                dw.FreeDiffUtilsScript3(script10, script12, script02);
                        }
@@ -423,7 +399,6 @@ int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
        {
                // Print error since we should have handled by date compare earlier
                throw "Invalid compare type, DiffFileData can't handle it";
-               di.errorDesc = _T("Bad compare type");
                goto exitPrepAndCompare;
        }
 
@@ -473,9 +448,7 @@ void GetComparePaths(CDiffContext * pCtxt, const DIFFITEM &di, PathContext & fil
                {
                        // Compare file to itself to detect encoding
                        String path = pCtxt->GetNormalizedPath(nIndex);
-                       if (!di.diffFileInfo[nIndex].path.empty())
-                               path = paths_ConcatPath(path, di.diffFileInfo[nIndex].path);
-                       path = paths_ConcatPath(path, di.diffFileInfo[nIndex].filename);
+                       path = paths_ConcatPath(path, di.diffFileInfo[nIndex].GetFile());
                        files.SetPath(nIndex, path);
                }
                else
index be65a3b..7095dbb 100644 (file)
@@ -2029,20 +2029,20 @@ void CMainFrame::OnToolsGeneratePatch()
                                // Format full paths to files (leftFile/rightFile)
                                String leftFile = item.getFilepath(0, pDoc->GetBasePath(0));
                                if (!leftFile.empty())
-                                       leftFile = paths_ConcatPath(leftFile, item.diffFileInfo[0].filename);
+                                       leftFile = paths_ConcatPath(leftFile, item.diffFileInfo[0].GetFileName());
                                String rightFile = item.getFilepath(1, pDoc->GetBasePath(1));
                                if (!rightFile.empty())
-                                       rightFile = paths_ConcatPath(rightFile, item.diffFileInfo[1].filename);
+                                       rightFile = paths_ConcatPath(rightFile, item.diffFileInfo[1].GetFileName());
 
                                // Format relative paths to files in folder compare
-                               String leftpatch = item.diffFileInfo[0].path;
+                               String leftpatch = item.diffFileInfo[0].GetPath();
                                if (!leftpatch.empty())
                                        leftpatch += _T("/");
-                               leftpatch += item.diffFileInfo[0].filename;
-                               String rightpatch = item.diffFileInfo[1].path;
+                               leftpatch += item.diffFileInfo[0].GetFileName();
+                               String rightpatch = item.diffFileInfo[1].GetPath();
                                if (!rightpatch.empty())
                                        rightpatch += _T("/");
-                               rightpatch += item.diffFileInfo[1].filename;
+                               rightpatch += item.diffFileInfo[1].GetFileName();
                                patcher.AddFiles(leftFile, leftpatch, rightFile, rightpatch);
                                pView->GetNextSelectedInd(ind);
                        }
index 3fa8a49..573963e 100644 (file)
@@ -17,12 +17,26 @@ int main()
 #endif
        CompareStats cmpstats(2);
 
+       std::wcout << _T("DIFFITEM size = ") << sizeof(DIFFITEM) << std::endl;
+       std::wcout << _T("FileVersion size = ") << sizeof(FileVersion) << std::endl;
+       std::wcout << _T("String size = ") << sizeof(String) << std::endl;
+       std::wcout << _T("Poco::Timestamp size = ") << sizeof(Poco::Timestamp) << std::endl;
+       std::wcout << _T("Poco::File::FileSize size = ") << sizeof(Poco::File::FileSize) << std::endl;
+       std::wcout << _T("DirItem size = ") << sizeof(DirItem) << std::endl;
+       std::wcout << _T("FileTextEncoding size = ") << sizeof(FileTextEncoding) << std::endl;
+       std::wcout << _T("FileFlags size = ") << sizeof(FileFlags) << std::endl;
+       std::wcout << _T("FileTextStats size = ") << sizeof(FileTextStats) << std::endl;
+       std::wcout << _T("DiffFileInfo size = ") << sizeof(DiffFileInfo) << std::endl;
+       std::wcout << _T("shared_ptr size = ") << sizeof(boost::shared_ptr<String>) << std::endl;
+       std::wcout << _T("scoped_ptr size = ") << sizeof(boost::scoped_ptr<String>) << std::endl;
+
        FileFilterHelper filter;
        filter.UseMask(true);
-       filter.SetMask(_T("*.cpp;*.c;*.h;*.vcproj;*.vcxproj"));
+//     filter.SetMask(_T("*.cpp;*.c;*.h;*.vcproj;*.vcxproj"));
+       filter.SetMask(_T("*.*"));
 
        CDiffContext ctx(
-               PathContext(_T("c:/dev/winmerge/winmerge-3pane/winmerge-v2/"), _T("c:/dev/winmerge/winmerge.org/trunk/")),
+               PathContext(_T("c:/windows"), _T("c:/windows")),
                CMP_CONTENT);
 
        DIFFOPTIONS options = {0};
@@ -32,7 +46,8 @@ int main()
        options.bIgnoreCase = false;
        options.bIgnoreEol = false;
 
-       ctx.CreateCompareOptions(CMP_CONTENT, options);
+       //ctx.CreateCompareOptions(CMP_CONTENT, options);
+       ctx.CreateCompareOptions(CMP_DATE, options);
 
        ctx.m_iGuessEncodingType = 0;//(50001 << 16) + 2;
        ctx.m_bIgnoreSmallTimeDiff = true;
@@ -60,7 +75,7 @@ int main()
        while (pos)
        {
                DIFFITEM& di = ctx.GetNextDiffRefPosition(pos);
-               if (ctx.m_piFilterGlobal->includeFile(di.diffFileInfo[0].filename, di.diffFileInfo[1].filename))
+               if (ctx.m_piFilterGlobal->includeFile(di.diffFileInfo[0].GetFileName(), di.diffFileInfo[1].GetFileName()))
                {
                        FolderCmp folderCmp;
                        folderCmp.prepAndCompareFiles(&ctx, di);