OSDN Git Service

Various optimizations for folder compare
authorsdottaka <sdottaka@sourceforge.net>
Sun, 27 Apr 2014 12:08:09 +0000 (21:08 +0900)
committersdottaka <sdottaka@sourceforge.net>
Sun, 27 Apr 2014 12:08:09 +0000 (21:08 +0900)
--HG--
branch : stable

Src/Common/UnicodeString.cpp
Src/DirScan.cpp
Src/DirTravel.cpp
Src/DirViewColItems.cpp
Src/FileFilterHelper.h
Src/FolderCmp.cpp
Src/FolderCmp.h

index 56b56e6..e434ae5 100644 (file)
@@ -88,15 +88,7 @@ void string_replace(String &target, const String &find, const String &replace)
  */
 int string_compare_nocase(const String &str1, const String &str2)
 {
-       String s1(str1);
-       String s2(str2);
-       String::size_type i = 0;
-       for (i = 0; i < s1.length(); i++)
-               s1[i] = _totlower(s1[i]);
-       for (i = 0; i < s2.length(); i++)
-               s2[i] = _totlower(s2[i]);
-
-       return s1.compare(s2);
+       return _tcsicoll(str1.c_str(), str2.c_str());
 }
 
 /**
index 8ce499e..df6981a 100644 (file)
@@ -557,7 +557,8 @@ int DirScan_CompareItems(DiffFuncStruct *myStruct, UIntPtr parentdiffpos)
 {
        ThreadPool threadPool;
        std::vector<DiffWorkerPtr> workers;
-       size_t nworkers = Environment::processorCount();
+       const int compareMethod = myStruct->context->GetCompareMethod();
+       size_t nworkers = (compareMethod == CMP_CONTENT || compareMethod == CMP_QUICK_CONTENT) ? Environment::processorCount() : 1;
        NotificationQueue queue;
 
        for (size_t i = 0; i < nworkers; ++i)
index f8ee7a0..e46aa98 100644 (file)
@@ -137,55 +137,25 @@ static void LoadFiles(const String& sDir, DirItemArray * dirs, DirItemArray * fi
 #endif
 }
 
-static int collate(const String &str1, const String &str2)
+static inline int collate(const String &str1, const String &str2)
 {
        return _tcscoll(str1.c_str(), str2.c_str());
 }
 
-/**
- * @brief case-sensitive collate function for qsorting an array
- */
-static bool __cdecl cmpstring(const DirItem &elem1, const DirItem &elem2)
+static inline int collate_ignore_case(const String &str1, const String &str2)
 {
-       return collate(elem1.filename, elem2.filename) < 0;
+       return _tcsicoll(str1.c_str(), str2.c_str());
 }
 
-static int collate_ignore_case(const String &str1, const String &str2)
+
+template<int (*compfunc)(const TCHAR *, const TCHAR *)>
+struct StringComparer
 {
-       String s1(str1);
-       String s2(str2);
-    String::size_type i = 0;
-#ifdef _UNICODE
-       for (i = 0; i < s1.length(); i++)
-               s1[i] = _totlower(s1[i]);
-       for (i = 0; i < s2.length(); i++)
-               s2[i] = _totlower(s2[i]);
-#else
-       for (i = 0; i < s1.length(); i++)
+       bool operator()(const DirItem &elem1, const DirItem &elem2)
        {
-               if (_ismbblead(s1[i]))
-                       i++;
-               else
-                       s1[i] = _totlower(s1[i]);
+               return compfunc(elem1.filename.get().c_str(), elem2.filename.get().c_str()) < 0;
        }
-       for (i = 0; i < s2.length(); i++)
-       {
-               if (_ismbblead(s2[i]))
-                       i++;
-               else
-                       s2[i] = _totlower(s2[i]);
-       }
-#endif
-       return _tcscoll(s1.c_str(), s2.c_str());
-}
-
-/**
- * @brief case-insensitive collate function for qsorting an array
- */
-static bool __cdecl cmpistring(const DirItem &elem1, const DirItem &elem2)
-{
-       return collate_ignore_case(elem1.filename, elem2.filename) < 0;
-}
+};
 
 /**
  * @brief sort specified array
@@ -193,9 +163,9 @@ static bool __cdecl cmpistring(const DirItem &elem1, const DirItem &elem2)
 static void Sort(DirItemArray * dirs, bool casesensitive)
 {
        if (casesensitive)
-        std::sort(dirs->begin(), dirs->end(), cmpstring);
+        std::sort(dirs->begin(), dirs->end(), StringComparer<_tcscoll>());
        else
-               std::sort(dirs->begin(), dirs->end(), cmpistring);
+               std::sort(dirs->begin(), dirs->end(), StringComparer<_tcsicoll>());
 }
 
 /**
index 93ce8d0..4ef5b55 100644 (file)
@@ -189,16 +189,17 @@ static String MakeShortSize(__int64 size)
  * @param [in] p Pointer to DIFFITEM.
  * @return String to show in the column.
  */
-static String ColFileNameGet(const CDiffContext *, const void *p) //sfilename
+template<class Type>
+static Type ColFileNameGet(const CDiffContext *, const void *p) //sfilename
 {
-       const DIFFITEM &di = *static_cast<const DIFFITEM*>(p);
-       return
-       (
-               di.diffFileInfo[0].filename.get().empty() ? di.diffFileInfo[1].filename :
-               di.diffFileInfo[1].filename.get().empty() ? di.diffFileInfo[0].filename :
-               di.diffFileInfo[0].filename == di.diffFileInfo[1].filename ? di.diffFileInfo[0].filename :
-               di.diffFileInfo[0].filename.get() + _T("|") + di.diffFileInfo[1].filename.get()
-       );
+       const boost::flyweight<String> &lfilename = static_cast<const DIFFITEM*>(p)->diffFileInfo[0].filename;
+       const boost::flyweight<String> &rfilename = static_cast<const DIFFITEM*>(p)->diffFileInfo[1].filename;
+       if (lfilename.get().empty())
+               return rfilename;
+       else if (rfilename.get().empty() || lfilename == rfilename)
+               return lfilename;
+       else
+               return static_cast<Type>(lfilename.get() + _T("|") + rfilename.get());
 }
 
 /**
@@ -730,7 +731,7 @@ static int ColFileNameSort(const CDiffContext *pCtxt, const void *p, const void
                return -1;
        if (!ldi.diffcode.isDirectory() && rdi.diffcode.isDirectory())
                return 1;
-       return string_compare_nocase(ColFileNameGet(pCtxt, p), ColFileNameGet(pCtxt, q));
+       return string_compare_nocase(ColFileNameGet<boost::flyweight<String> >(pCtxt, p), ColFileNameGet<boost::flyweight<String> >(pCtxt, q));
 }
 
 /**
@@ -922,7 +923,7 @@ static int ColEncodingSort(const CDiffContext *, const void *p, const void *q)
  */
 static DirColInfo f_cols[] =
 {
-       { _T("Name"), IDS_COLHDR_FILENAME, IDS_COLDESC_FILENAME, &ColFileNameGet, &ColFileNameSort, 0, 0, true, LVCFMT_LEFT },
+       { _T("Name"), IDS_COLHDR_FILENAME, IDS_COLDESC_FILENAME, &ColFileNameGet<String>, &ColFileNameSort, 0, 0, true, LVCFMT_LEFT },
        { _T("Path"), IDS_COLHDR_DIR, IDS_COLDESC_DIR, &ColPathGet, &ColPathSort, 0, 1, true, LVCFMT_LEFT },
        { _T("Status"), IDS_COLHDR_RESULT, IDS_COLDESC_RESULT, &ColStatusGet, &ColStatusSort, 0, 2, true, LVCFMT_LEFT },
        { _T("Lmtime"), IDS_COLHDR_LTIMEM, IDS_COLDESC_LTIMEM, &ColTimeGet, &ColTimeSort, FIELD_OFFSET(DIFFITEM, diffFileInfo[0].mtime), 3, false, LVCFMT_LEFT },
@@ -950,7 +951,7 @@ static DirColInfo f_cols[] =
 };
 static DirColInfo f_cols3[] =
 {
-       { _T("Name"), IDS_COLHDR_FILENAME, IDS_COLDESC_FILENAME, &ColFileNameGet, &ColFileNameSort, 0, 0, true, LVCFMT_LEFT },
+       { _T("Name"), IDS_COLHDR_FILENAME, IDS_COLDESC_FILENAME, &ColFileNameGet<String>, &ColFileNameSort, 0, 0, true, LVCFMT_LEFT },
        { _T("Path"), IDS_COLHDR_DIR, IDS_COLDESC_DIR, &ColPathGet, &ColPathSort, 0, 1, true, LVCFMT_LEFT },
        { _T("Status"), IDS_COLHDR_RESULT, IDS_COLDESC_RESULT, &ColStatusGet, &ColStatusSort, 0, 2, true, LVCFMT_LEFT },
        { _T("Lmtime"), IDS_COLHDR_LTIMEM, IDS_COLDESC_LTIMEM, &ColTimeGet, &ColTimeSort, FIELD_OFFSET(DIFFITEM, diffFileInfo[0].mtime), 3, false, LVCFMT_LEFT },
index b2ef89b..6c3c612 100644 (file)
@@ -63,37 +63,43 @@ public:
        virtual bool includeDir(const String& szDirName) = 0;
        bool includeFile(const String& szFileName1, const String& szFileName2)
        {
-               return
-               (
-                       (szFileName1.empty() || includeFile(szFileName1))
-               &&      (szFileName2.empty() || includeFile(szFileName2))
-               );
+               if (!szFileName1.empty())
+                       return includeFile(szFileName1);
+               else if (!szFileName2.empty())
+                       return includeFile(szFileName2);
+               else
+                       return false;
        }
        bool includeFile(const String& szFileName1, const String& szFileName2, const String& szFileName3)
        {
-               return
-               (
-                       (szFileName1.empty() || includeFile(szFileName1))
-               &&      (szFileName2.empty() || includeFile(szFileName2))
-               &&      (szFileName3.empty() || includeFile(szFileName3))
-               );
+               if (!szFileName1.empty())
+                       return includeFile(szFileName1);
+               else if (!szFileName2.empty())
+                       return includeFile(szFileName2);
+               else if (!szFileName3.empty())
+                       return includeFile(szFileName3);
+               else
+                       return false;
        }
        bool includeDir(const String& szDirName1, const String& szDirName2)
        {
-               return
-               (
-                       (szDirName1.empty() || includeDir(szDirName1))
-               &&      (szDirName2.empty() || includeDir(szDirName2))
-               );
+               if (!szDirName1.empty())
+                       return includeDir(szDirName1);
+               else if (!szDirName2.empty())
+                       return includeDir(szDirName2);
+               else
+                       return false;
        }
        bool includeDir(const String& szDirName1, const String& szDirName2, const String& szDirName3)
        {
-               return
-               (
-                       (szDirName1.empty() || includeDir(szDirName1))
-               &&      (szDirName2.empty() || includeDir(szDirName2))
-               &&      (szDirName3.empty() || includeDir(szDirName3))
-               );
+               if (!szDirName1.empty())
+                       return includeDir(szDirName1);
+               else if (!szDirName2.empty())
+                       return includeDir(szDirName2);
+               else if (!szDirName3.empty())
+                       return includeDir(szDirName3);
+               else
+                       return false;
        }
 };
 
index 0a315af..e04361f 100644 (file)
@@ -37,8 +37,6 @@ FolderCmp::FolderCmp()
 , m_pTimeSizeCompare(NULL)
 , m_ndiffs(CDiffContext::DIFFS_UNKNOWN)
 , m_ntrivialdiffs(CDiffContext::DIFFS_UNKNOWN)
-, m_codepage(-1)
-, m_pCtx(NULL)
 {
 }
 
@@ -67,28 +65,28 @@ void FolderCmp::CleanupAfterPlugins(PluginsContext *plugCtxt)
 int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
 {
        int nIndex;
-       int nDirs = pCtxt->GetCompareDirs();
        int nCompMethod = pCtxt->GetCompareMethod();
-       PathContext files;
-       GetComparePaths(pCtxt, di, files);
-       m_pCtx = pCtxt;
-
-       // Reset text stats
-       for (nIndex = 0; nIndex < nDirs; nIndex++)
-               m_diffFileData.m_textStats[nIndex].clear();
 
        unsigned code = DIFFCODE::FILE | DIFFCODE::CMPERR;
 
-       struct change *script = NULL;
-       struct change *script10 = NULL;
-       struct change *script12 = NULL;
-       FolderCmp diffdata10, diffdata12;
-       String filepathUnpacked[3];
-       String filepathTransformed[3];
-
        if (nCompMethod == CMP_CONTENT ||
                nCompMethod == CMP_QUICK_CONTENT)
        {
+               int nDirs = pCtxt->GetCompareDirs();
+
+               // Reset text stats
+               for (nIndex = 0; nIndex < nDirs; nIndex++)
+                       m_diffFileData.m_textStats[nIndex].clear();
+
+               PathContext files;
+               GetComparePaths(pCtxt, di, files);
+               struct change *script = NULL;
+               struct change *script10 = NULL;
+               struct change *script12 = NULL;
+               FolderCmp diffdata10, diffdata12;
+               String filepathUnpacked[3];
+               String filepathTransformed[3];
+
                // For user chosen plugins, define bAutomaticUnpacker as false and use the chosen infoHandler
                // but how can we receive the infoHandler ? DirScan actually only 
                // returns info, but can not use file dependent information.
@@ -142,7 +140,7 @@ int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
                        if (encoding[0].m_unicoding != encoding[nIndex].m_unicoding || encoding[0].m_codepage != encoding[nIndex].m_codepage)
                                bForceUTF8 = true;
                }
-               m_codepage = bForceUTF8 ? CP_UTF8 : (encoding[0].m_unicoding ? CP_UTF8 : encoding[0].m_codepage);
+               int codepage = bForceUTF8 ? CP_UTF8 : (encoding[0].m_unicoding ? CP_UTF8 : encoding[0].m_codepage);
                for (nIndex = 0; nIndex < nDirs; nIndex++)
                {
                // Invoke prediff'ing plugins
@@ -177,218 +175,197 @@ int FolderCmp::prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di)
                        if (!diffdata12.m_diffFileData.OpenFiles(filepathTransformed[1], filepathTransformed[2]))
                                goto exitPrepAndCompare;
                }
-       }
-
-       // If either file is larger than limit compare files by quick contents
-       // This allows us to (faster) compare big binary files
-       if (nCompMethod == CMP_CONTENT && 
-               (di.diffFileInfo[0].size > pCtxt->m_nQuickCompareLimit ||
-               di.diffFileInfo[1].size > pCtxt->m_nQuickCompareLimit))
-       {
-               nCompMethod = CMP_QUICK_CONTENT;
-       }
 
-       if (nCompMethod == CMP_CONTENT)
-       {
-               if (files.GetSize() == 2)
+               // If either file is larger than limit compare files by quick contents
+               // This allows us to (faster) compare big binary files
+               if (nCompMethod == CMP_CONTENT && 
+                       (di.diffFileInfo[0].size > pCtxt->m_nQuickCompareLimit ||
+                       di.diffFileInfo[1].size > pCtxt->m_nQuickCompareLimit))
                {
-                       if (m_pDiffUtilsEngine == NULL)
-                               m_pDiffUtilsEngine.reset(new CompareEngines::DiffUtils());
-                       m_pDiffUtilsEngine->SetCodepage(m_codepage);
-                       bool success = m_pDiffUtilsEngine->SetCompareOptions(
-                                       *m_pCtx->GetCompareOptions(CMP_CONTENT));
-                       if (success)
-                       {
-                               if (m_pCtx->m_pFilterList != NULL)
-                                       m_pDiffUtilsEngine->SetFilterList(m_pCtx->m_pFilterList.get());
-                               else
-                                       m_pDiffUtilsEngine->ClearFilterList();
-                               m_pDiffUtilsEngine->SetFileData(2, m_diffFileData.m_inf);
-                               code = m_pDiffUtilsEngine->diffutils_compare_files();
-                               m_pDiffUtilsEngine->GetDiffCounts(m_ndiffs, m_ntrivialdiffs);
-                               m_pDiffUtilsEngine->GetTextStats(0, &m_diffFileData.m_textStats[0]);
-                               m_pDiffUtilsEngine->GetTextStats(1, &m_diffFileData.m_textStats[1]);
-                       }
-                       else
-                               code = DIFFCODE::FILE | DIFFCODE::TEXT | DIFFCODE::CMPERR;
-
-                       // If unique item, it was being compared to itself to determine encoding
-                       // and the #diffs is invalid
-                       if (di.diffcode.isSideSecondOnly() || di.diffcode.isSideFirstOnly())
-                       {
-                               m_ndiffs = CDiffContext::DIFFS_UNKNOWN;
-                               m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN;
-                       }
+                       nCompMethod = CMP_QUICK_CONTENT;
                }
-               else
+
+               if (nCompMethod == CMP_CONTENT)
                {
-                       if (m_pDiffUtilsEngine == NULL)
-                               m_pDiffUtilsEngine.reset(new CompareEngines::DiffUtils());
-                       m_pDiffUtilsEngine->SetCodepage(m_codepage);
-                       bool success = m_pDiffUtilsEngine->SetCompareOptions(
-                                       *m_pCtx->GetCompareOptions(CMP_CONTENT));
-                       if (success)
+                       if (files.GetSize() == 2)
                        {
-                               if (m_pCtx->m_pFilterList != NULL)
-                                       m_pDiffUtilsEngine->SetFilterList(m_pCtx->m_pFilterList.get());
-                               else
-                                       m_pDiffUtilsEngine->ClearFilterList();
-
-                               bool bRet;
-                               int bin_flag = 0, bin_flag10 = 0, bin_flag12 = 0;
-
-                               m_pDiffUtilsEngine->SetFileData(2, diffdata10.m_diffFileData.m_inf);
-                               bRet = m_pDiffUtilsEngine->Diff2Files(&script10, 0, &bin_flag10, false, NULL);
-                               m_pDiffUtilsEngine->SetFileData(2, diffdata12.m_diffFileData.m_inf);
-                               bRet = m_pDiffUtilsEngine->Diff2Files(&script12, 0, &bin_flag12, false, NULL);
-                               code = DIFFCODE::FILE;
-
-                               CDiffWrapper dw;
-                               DiffList diffList;
-                               DIFFSTATUS status;
-
-                               diffList.Clear();
-                               dw.SetCreateDiffList(&diffList);
-                               dw.LoadWinMergeDiffsFromDiffUtilsScript3(
-                                       script10, script12,
-                                       diffdata10.m_diffFileData.m_inf, diffdata12.m_diffFileData.m_inf);
-                               m_ndiffs = diffList.GetSignificantDiffs(); 
-                               m_ntrivialdiffs = diffList.GetSize() - m_ndiffs;
-                               
-                               if (m_ndiffs > 0)
-                                       code |= DIFFCODE::DIFF;
-                               else
-                                       code |= DIFFCODE::SAME;
-                               if (bin_flag10 || bin_flag12)
-                                       code |= DIFFCODE::BIN;
+                               if (m_pDiffUtilsEngine == NULL)
+                                       m_pDiffUtilsEngine.reset(new CompareEngines::DiffUtils());
+                               m_pDiffUtilsEngine->SetCodepage(codepage);
+                               bool success = m_pDiffUtilsEngine->SetCompareOptions(
+                                               *pCtxt->GetCompareOptions(CMP_CONTENT));
+                               if (success)
+                               {
+                                       if (pCtxt->m_pFilterList != NULL)
+                                               m_pDiffUtilsEngine->SetFilterList(pCtxt->m_pFilterList.get());
+                                       else
+                                               m_pDiffUtilsEngine->ClearFilterList();
+                                       m_pDiffUtilsEngine->SetFileData(2, m_diffFileData.m_inf);
+                                       code = m_pDiffUtilsEngine->diffutils_compare_files();
+                                       m_pDiffUtilsEngine->GetDiffCounts(m_ndiffs, m_ntrivialdiffs);
+                                       m_pDiffUtilsEngine->GetTextStats(0, &m_diffFileData.m_textStats[0]);
+                                       m_pDiffUtilsEngine->GetTextStats(1, &m_diffFileData.m_textStats[1]);
+                               }
                                else
-                                       code |= DIFFCODE::TEXT;
+                                       code = DIFFCODE::FILE | DIFFCODE::TEXT | DIFFCODE::CMPERR;
 
                                // If unique item, it was being compared to itself to determine encoding
                                // and the #diffs is invalid
-                               if (di.diffcode.isSideFirstOnly() || di.diffcode.isSideSecondOnly() || di.diffcode.isSideThirdOnly())
+                               if (di.diffcode.isSideSecondOnly() || di.diffcode.isSideFirstOnly())
                                {
                                        m_ndiffs = CDiffContext::DIFFS_UNKNOWN;
                                        m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN;
                                }
-
-                               dw.FreeDiffUtilsScript3(script10, script12);
                        }
                        else
-                               code = DIFFCODE::FILE | DIFFCODE::CMPERR;
-               }
+                       {
+                               if (m_pDiffUtilsEngine == NULL)
+                                       m_pDiffUtilsEngine.reset(new CompareEngines::DiffUtils());
+                               m_pDiffUtilsEngine->SetCodepage(codepage);
+                               bool success = m_pDiffUtilsEngine->SetCompareOptions(
+                                               *pCtxt->GetCompareOptions(CMP_CONTENT));
+                               if (success)
+                               {
+                                       if (pCtxt->m_pFilterList != NULL)
+                                               m_pDiffUtilsEngine->SetFilterList(pCtxt->m_pFilterList.get());
+                                       else
+                                               m_pDiffUtilsEngine->ClearFilterList();
+
+                                       bool bRet;
+                                       int bin_flag = 0, bin_flag10 = 0, bin_flag12 = 0;
+
+                                       m_pDiffUtilsEngine->SetFileData(2, diffdata10.m_diffFileData.m_inf);
+                                       bRet = m_pDiffUtilsEngine->Diff2Files(&script10, 0, &bin_flag10, false, NULL);
+                                       m_pDiffUtilsEngine->SetFileData(2, diffdata12.m_diffFileData.m_inf);
+                                       bRet = m_pDiffUtilsEngine->Diff2Files(&script12, 0, &bin_flag12, false, NULL);
+                                       code = DIFFCODE::FILE;
+
+                                       CDiffWrapper dw;
+                                       DiffList diffList;
+                                       DIFFSTATUS status;
+
+                                       diffList.Clear();
+                                       dw.SetCreateDiffList(&diffList);
+                                       dw.LoadWinMergeDiffsFromDiffUtilsScript3(
+                                               script10, script12,
+                                               diffdata10.m_diffFileData.m_inf, diffdata12.m_diffFileData.m_inf);
+                                       m_ndiffs = diffList.GetSignificantDiffs(); 
+                                       m_ntrivialdiffs = diffList.GetSize() - m_ndiffs;
+                               
+                                       if (m_ndiffs > 0)
+                                               code |= DIFFCODE::DIFF;
+                                       else
+                                               code |= DIFFCODE::SAME;
+                                       if (bin_flag10 || bin_flag12)
+                                               code |= DIFFCODE::BIN;
+                                       else
+                                               code |= DIFFCODE::TEXT;
+
+                                       // If unique item, it was being compared to itself to determine encoding
+                                       // and the #diffs is invalid
+                                       if (di.diffcode.isSideFirstOnly() || di.diffcode.isSideSecondOnly() || di.diffcode.isSideThirdOnly())
+                                       {
+                                               m_ndiffs = CDiffContext::DIFFS_UNKNOWN;
+                                               m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN;
+                                       }
+
+                                       dw.FreeDiffUtilsScript3(script10, script12);
+                               }
+                               else
+                                       code = DIFFCODE::FILE | DIFFCODE::CMPERR;
+                       }
 
-       }
-       else if (nCompMethod == CMP_QUICK_CONTENT)
-       {
-               // use our own byte-by-byte compare
-               if (files.GetSize() == 2)
+               }
+               else if (nCompMethod == CMP_QUICK_CONTENT)
                {
-                       if (m_pByteCompare == NULL)
-                               m_pByteCompare.reset(new ByteCompare());
-                       bool success = m_pByteCompare->SetCompareOptions(
-                               *m_pCtx->GetCompareOptions(CMP_QUICK_CONTENT));
-       
-                       if (success)
+                       // use our own byte-by-byte compare
+                       if (files.GetSize() == 2)
                        {
-                               m_pByteCompare->SetAdditionalOptions(pCtxt->m_bStopAfterFirstDiff);
-                               m_pByteCompare->SetAbortable(pCtxt->GetAbortable());
-                               m_pByteCompare->SetFileData(2, m_diffFileData.m_inf);
+                               if (m_pByteCompare == NULL)
+                                       m_pByteCompare.reset(new ByteCompare());
+                               bool success = m_pByteCompare->SetCompareOptions(
+                                       *pCtxt->GetCompareOptions(CMP_QUICK_CONTENT));
        
-                               // use our own byte-by-byte compare
-                               code = m_pByteCompare->CompareFiles(m_diffFileData.m_FileLocation);
+                               if (success)
+                               {
+                                       m_pByteCompare->SetAdditionalOptions(pCtxt->m_bStopAfterFirstDiff);
+                                       m_pByteCompare->SetAbortable(pCtxt->GetAbortable());
+                                       m_pByteCompare->SetFileData(2, m_diffFileData.m_inf);
        
-                               m_pByteCompare->GetTextStats(0, &m_diffFileData.m_textStats[0]);
-                               m_pByteCompare->GetTextStats(1, &m_diffFileData.m_textStats[1]);
-                       }
-                       else
-                               code = DIFFCODE::FILE | DIFFCODE::TEXT | DIFFCODE::CMPERR;
+                                       // use our own byte-by-byte compare
+                                       code = m_pByteCompare->CompareFiles(m_diffFileData.m_FileLocation);
        
-                       // Quick contents doesn't know about diff counts
-                       // Set to special value to indicate invalid
-                       m_ndiffs = CDiffContext::DIFFS_UNKNOWN_QUICKCOMPARE;
-                       m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN_QUICKCOMPARE;
-                       di.diffFileInfo[0].m_textStats = m_diffFileData.m_textStats[0];
-                       di.diffFileInfo[1].m_textStats = m_diffFileData.m_textStats[1]; 
-               }
-               else
-               {
-                       int code10, code12;
-                       if (m_pByteCompare == NULL)
-                               m_pByteCompare.reset(new ByteCompare());
-                       bool success = m_pByteCompare->SetCompareOptions(
-                               *m_pCtx->GetCompareOptions(CMP_QUICK_CONTENT));
+                                       m_pByteCompare->GetTextStats(0, &m_diffFileData.m_textStats[0]);
+                                       m_pByteCompare->GetTextStats(1, &m_diffFileData.m_textStats[1]);
+                               }
+                               else
+                                       code = DIFFCODE::FILE | DIFFCODE::TEXT | DIFFCODE::CMPERR;
        
-                       if (success)
+                               // Quick contents doesn't know about diff counts
+                               // Set to special value to indicate invalid
+                               m_ndiffs = CDiffContext::DIFFS_UNKNOWN_QUICKCOMPARE;
+                               m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN_QUICKCOMPARE;
+                               di.diffFileInfo[0].m_textStats = m_diffFileData.m_textStats[0];
+                               di.diffFileInfo[1].m_textStats = m_diffFileData.m_textStats[1]; 
+                       }
+                       else
                        {
-                               /* \93r\92\86 */
-                               m_pByteCompare->SetAdditionalOptions(pCtxt->m_bStopAfterFirstDiff);
-                               m_pByteCompare->SetAbortable(pCtxt->GetAbortable());
+                               int code10, code12;
+                               if (m_pByteCompare == NULL)
+                                       m_pByteCompare.reset(new ByteCompare());
+                               bool success = m_pByteCompare->SetCompareOptions(
+                                       *pCtxt->GetCompareOptions(CMP_QUICK_CONTENT));
+       
+                               if (success)
+                               {
+                                       /* \93r\92\86 */
+                                       m_pByteCompare->SetAdditionalOptions(pCtxt->m_bStopAfterFirstDiff);
+                                       m_pByteCompare->SetAbortable(pCtxt->GetAbortable());
 
-                               // 10
-                               m_pByteCompare->SetFileData(2, diffdata10.m_diffFileData.m_inf);
+                                       // 10
+                                       m_pByteCompare->SetFileData(2, diffdata10.m_diffFileData.m_inf);
        
-                               // use our own byte-by-byte compare
-                               code10 = m_pByteCompare->CompareFiles(diffdata10.m_diffFileData.m_FileLocation);
+                                       // use our own byte-by-byte compare
+                                       code10 = m_pByteCompare->CompareFiles(diffdata10.m_diffFileData.m_FileLocation);
        
-                               m_pByteCompare->GetTextStats(0, &diffdata10.m_diffFileData.m_textStats[0]);
-                               m_pByteCompare->GetTextStats(1, &diffdata10.m_diffFileData.m_textStats[1]);
+                                       m_pByteCompare->GetTextStats(0, &diffdata10.m_diffFileData.m_textStats[0]);
+                                       m_pByteCompare->GetTextStats(1, &diffdata10.m_diffFileData.m_textStats[1]);
 
-                               // 12
-                               m_pByteCompare->SetFileData(2, diffdata12.m_diffFileData.m_inf);
+                                       // 12
+                                       m_pByteCompare->SetFileData(2, diffdata12.m_diffFileData.m_inf);
        
-                               // use our own byte-by-byte compare
-                               code12 = m_pByteCompare->CompareFiles(diffdata12.m_diffFileData.m_FileLocation);
+                                       // use our own byte-by-byte compare
+                                       code12 = m_pByteCompare->CompareFiles(diffdata12.m_diffFileData.m_FileLocation);
        
-                               m_pByteCompare->GetTextStats(0, &diffdata12.m_diffFileData.m_textStats[0]);
-                               m_pByteCompare->GetTextStats(1, &diffdata12.m_diffFileData.m_textStats[1]);
-
-                               code = DIFFCODE::FILE;
-                               if (DIFFCODE::isResultError(code10) || DIFFCODE::isResultError(code12))
-                                       code |= DIFFCODE::CMPERR;
-                               if (code10 & DIFFCODE::DIFF || code12 & DIFFCODE::DIFF)
-                                       code |= DIFFCODE::DIFF;
-                               else
-                                       code |= DIFFCODE::SAME;
-                               if (code10 & DIFFCODE::BIN || code12 & DIFFCODE::BIN)
-                                       code |= DIFFCODE::BIN;
+                                       m_pByteCompare->GetTextStats(0, &diffdata12.m_diffFileData.m_textStats[0]);
+                                       m_pByteCompare->GetTextStats(1, &diffdata12.m_diffFileData.m_textStats[1]);
+
+                                       code = DIFFCODE::FILE;
+                                       if (DIFFCODE::isResultError(code10) || DIFFCODE::isResultError(code12))
+                                               code |= DIFFCODE::CMPERR;
+                                       if (code10 & DIFFCODE::DIFF || code12 & DIFFCODE::DIFF)
+                                               code |= DIFFCODE::DIFF;
+                                       else
+                                               code |= DIFFCODE::SAME;
+                                       if (code10 & DIFFCODE::BIN || code12 & DIFFCODE::BIN)
+                                               code |= DIFFCODE::BIN;
+                                       else
+                                               code |= DIFFCODE::TEXT;
+                               }
                                else
-                                       code |= DIFFCODE::TEXT;
-                       }
-                       else
-                               code = DIFFCODE::FILE | DIFFCODE::TEXT | DIFFCODE::CMPERR;
+                                       code = DIFFCODE::FILE | DIFFCODE::TEXT | DIFFCODE::CMPERR;
        
-                       // Quick contents doesn't know about diff counts
-                       // Set to special value to indicate invalid
-                       m_ndiffs = CDiffContext::DIFFS_UNKNOWN_QUICKCOMPARE;
-                       m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN_QUICKCOMPARE;
-                       // FIXME:
-                       di.diffFileInfo[0].m_textStats = diffdata10.m_diffFileData.m_textStats[1];
-                       di.diffFileInfo[1].m_textStats = diffdata10.m_diffFileData.m_textStats[0];      
-                       di.diffFileInfo[2].m_textStats = diffdata12.m_diffFileData.m_textStats[1];      
+                               // Quick contents doesn't know about diff counts
+                               // Set to special value to indicate invalid
+                               m_ndiffs = CDiffContext::DIFFS_UNKNOWN_QUICKCOMPARE;
+                               m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN_QUICKCOMPARE;
+                               // FIXME:
+                               di.diffFileInfo[0].m_textStats = diffdata10.m_diffFileData.m_textStats[1];
+                               di.diffFileInfo[1].m_textStats = diffdata10.m_diffFileData.m_textStats[0];      
+                               di.diffFileInfo[2].m_textStats = diffdata12.m_diffFileData.m_textStats[1];      
+                       }
                }
-
-       }
-       else if (nCompMethod == CMP_DATE || nCompMethod == CMP_DATE_SIZE || nCompMethod == CMP_SIZE)
-       {
-               if (m_pTimeSizeCompare == NULL)
-                       m_pTimeSizeCompare.reset(new TimeSizeCompare());
-
-               m_pTimeSizeCompare->SetAdditionalOptions(!!pCtxt->m_bIgnoreSmallTimeDiff);
-               code = m_pTimeSizeCompare->CompareFiles(nCompMethod, di);
-
-       }
-       else
-       {
-               // Print error since we should have handled by date compare earlier
-               throw "Invalid compare type, DiffFileData can't handle it";
-               goto exitPrepAndCompare;
-       }
-
-
 exitPrepAndCompare:
-       if (nCompMethod == CMP_CONTENT || nCompMethod == CMP_QUICK_CONTENT)
-       {
                m_diffFileData.Reset();
                diffdata10.m_diffFileData.Reset();
                diffdata12.m_diffFileData.Reset();
@@ -407,6 +384,20 @@ exitPrepAndCompare:
                if (nDirs > 2 && filepathUnpacked[2] != files[2])
                        try { TFile(filepathUnpacked[2]).remove(); } catch (...) { LogErrorString(string_format(_T("DeleteFile(%s) failed"), filepathUnpacked[2].c_str())); }
        }
+       else if (nCompMethod == CMP_DATE || nCompMethod == CMP_DATE_SIZE || nCompMethod == CMP_SIZE)
+       {
+               if (m_pTimeSizeCompare == NULL)
+                       m_pTimeSizeCompare.reset(new TimeSizeCompare());
+
+               m_pTimeSizeCompare->SetAdditionalOptions(!!pCtxt->m_bIgnoreSmallTimeDiff);
+               code = m_pTimeSizeCompare->CompareFiles(nCompMethod, di);
+       }
+       else
+       {
+               // Print error since we should have handled by date compare earlier
+               throw "Invalid compare type, DiffFileData can't handle it";
+       }
+
        return code;
 }
 
@@ -428,14 +419,12 @@ void GetComparePaths(CDiffContext * pCtxt, const DIFFITEM &di, PathContext & fil
        {
                if (di.diffcode.isExists(nIndex))
                {
-                       // Compare file to itself to detect encoding
-                       String path = pCtxt->GetNormalizedPath(nIndex);
-                       path = paths_ConcatPath(path, di.diffFileInfo[nIndex].GetFile());
-                       files.SetPath(nIndex, path);
+                       files.SetPath(nIndex,
+                               paths_ConcatPath(pCtxt->GetPath(nIndex), di.diffFileInfo[nIndex].GetFile()), false);
                }
                else
                {
-                       files.SetPath(nIndex, _T("NUL"));
+                       files.SetPath(nIndex, _T("NUL"), false);
                }
        }
 }
index 0bd54cf..4559ebd 100644 (file)
@@ -46,14 +46,11 @@ public:
        bool RunPlugins(CDiffContext * pCtxt, PluginsContext * plugCtxt, String &errStr);
        void CleanupAfterPlugins(PluginsContext *plugCtxt);
        int prepAndCompareFiles(CDiffContext * pCtxt, DIFFITEM &di);
-       void SetCodepage(int codepage) { m_codepage = codepage; }
 
        int m_ndiffs;
        int m_ntrivialdiffs;
-       int m_codepage;
 
        DiffFileData m_diffFileData;
-       CDiffContext * m_pCtx;
 
 private:
        boost::scoped_ptr<CompareEngines::DiffUtils> m_pDiffUtilsEngine;