OSDN Git Service

Update of Lithuanian translation (#496)
[winmerge-jp/winmerge-jp.git] / Src / DirTravel.cpp
index 6705665..bc7ba5a 100644 (file)
@@ -4,24 +4,24 @@
  * @brief Implementation file for Directory traversal functions.
  *
  */
-// ID line follows -- this is updated by SVN
-// $Id: DirTravel.cpp 5761 2008-08-08 04:54:52Z marcelgosselin $
 
+#include "pch.h"
 #include "DirTravel.h"
 #include <algorithm>
 #include <Poco/DirectoryIterator.h>
 #include <Poco/Timestamp.h>
 #include <windows.h>
 #include <tchar.h>
-#include <mbstring.h>
+#include "TFile.h"
 #include "UnicodeString.h"
 #include "DirItem.h"
 #include "unicoder.h"
 #include "paths.h"
+#include "Win_VersionHelper.h"
+#include "DebugNew.h"
 
 using Poco::DirectoryIterator;
 using Poco::Timestamp;
-using boost::int64_t;
 
 static void LoadFiles(const String& sDir, DirItemArray * dirs, DirItemArray * files);
 static void Sort(DirItemArray * dirs, bool casesensitive);
@@ -37,16 +37,16 @@ void LoadAndSortFiles(const String& sDir, DirItemArray * dirs, DirItemArray * fi
 }
 
 /**
- * @brief Find files and subfolders from given folder.
- * This function saves all files and subfolders in given folder to arrays.
+ * @brief Find file and sub-folder names from given folder.
+ * This function saves all file and sub-folder names in given folder to arrays.
  * We use 64-bit version of stat() to get times since find doesn't return
  * valid times for very old files (around year 1970). Even stat() seems to
  * give negative time values but we can live with that. Those around 1970
- * times can happen when file is created so that it  doesn't get valid
- * creation or modificatio dates.
+ * times can happen when file is created so that it doesn't get valid
+ * creation or modification dates.
  * @param [in] sDir Base folder for files and subfolders.
- * @param [in, out] dirs Array where subfolders are stored.
- * @param [in, out] files Array where files are stored.
+ * @param [in, out] dirs Array where subfolder names are stored.
+ * @param [in, out] files Array where file names are stored.
  */
 static void LoadFiles(const String& sDir, DirItemArray * dirs, DirItemArray * files)
 {
@@ -71,19 +71,19 @@ static void LoadFiles(const String& sDir, DirItemArray * dirs, DirItemArray * fi
                ent.size = it->getSize();
                ent.path = dir;
                ent.filename = ucr::toTString(it.name());
-#ifdef _WIN32
-               ent.flags.attributes = GetFileAttributes(ucr::toTString(it.name()).c_str());;
-#else
-#endif
-               
+               ent.flags.attributes = GetFileAttributes(ucr::toTString(it.name()).c_str());            
                (bIsDirectory ? dirs : files)->push_back(ent);
        }
 
 #else
-       String sPattern = paths_ConcatPath(sDir, _T("*.*"));
+       String sPattern = paths::ConcatPath(sDir, _T("*.*"));
 
        WIN32_FIND_DATA ff;
-       HANDLE h = FindFirstFile(sPattern.c_str(), &ff);
+       HANDLE h;
+       if (IsWin7_OrGreater()) // (also 'Windows Server 2008 R2' and greater) for FindExInfoBasic and FIND_FIRST_EX_LARGE_FETCH
+               h = FindFirstFileEx(TFile(sPattern).wpath().c_str(), FindExInfoBasic, &ff, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH);
+       else
+               h = FindFirstFile(TFile(sPattern).wpath().c_str(), &ff);
        if (h != INVALID_HANDLE_VALUE)
        {
                do
@@ -106,7 +106,7 @@ static void LoadFiles(const String& sDir, DirItemArray * dirs, DirItemArray * fi
                                ent.mtime = 0;
 
                        if (ff.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                               ent.size = -1;  // No size for directories
+                               ent.size = DirItem::FILE_SIZE_NONE;  // No size for directories
                        else
                        {
                                ent.size = ((int64_t)ff.nFileSizeHigh << 32) + ff.nFileSizeLow;
@@ -124,55 +124,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++)
-       {
-               if (_ismbblead(s1[i]))
-                       i++;
-               else
-                       s1[i] = _totlower(s1[i]);
-       }
-       for (i = 0; i < s2.length(); i++)
+       bool operator()(const DirItem &elem1, const DirItem &elem2)
        {
-               if (_ismbblead(s2[i]))
-                       i++;
-               else
-                       s2[i] = _totlower(s2[i]);
+               return compfunc(elem1.filename.get().c_str(), elem2.filename.get().c_str()) < 0;
        }
-#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
@@ -180,9 +150,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>());
 }
 
 /**