Sync translations with Transifex
[TortoiseGit.git] / src / Utils / DirFileEnum.h
blob331e0faa911e675a57d3ae114900e8a030813866
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2005 - 2006, 2010-2011, 2013 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 #pragma once
20 /**
21 * \ingroup Utils
22 * Enumerates over a directory tree, non-recursively.
23 * Advantages over CFileFind:
24 * 1) Return values are not broken. An error return from
25 * CFileFind::FindNext() indicates that the *next*
26 * call to CFileFind::FindNext() will fail.
27 * A failure from CSimpleFileFind means *that* call
28 * failed, which is what I'd expect.
29 * 2) Error handling. If you use CFileFind, you are
30 * required to call ::GetLastError() yourself, there
31 * is no abstraction.
32 * 3) Support for ignoring the "." and ".." directories
33 * automatically.
34 * 4) No dynamic memory allocation.
36 class CSimpleFileFind {
37 private:
38 /**
39 * Windows FindFirstFile() handle.
41 HANDLE m_hFindFile;
43 /**
44 * Windows error code - if all is well, ERROR_SUCCESS.
45 * At end of directory, ERROR_NO_MORE_FILES.
47 DWORD m_dError;
49 /**
50 * Flag indicating that FindNextFile() has not yet been
51 * called.
53 BOOL m_bFirst;
55 protected:
56 /**
57 * The prefix for files in this directory.
58 * Ends with a "\", unless it's a drive letter only
59 * ("C:" is different from "C:\", and "C:filename" is
60 * legal anyway.)
62 CString m_sPathPrefix;
64 /**
65 * The file data returned by FindFirstFile()/FindNextFile().
67 WIN32_FIND_DATA m_FindFileData;
69 public:
71 /**
72 * Constructor.
74 * \param sPath The path to search in.
75 * \param pPattern The filename pattern - default all files.
77 CSimpleFileFind(const CString &sPath, LPCTSTR pPattern = _T("*.*"));
78 ~CSimpleFileFind();
80 /**
81 * Advance to the next file.
82 * Note that the state of this object is undefined until
83 * this method is called the first time.
85 * \return TRUE if a file was found, FALSE on error or
86 * end-of-directory (use IsError() and IsPastEnd() to
87 * disambiguate).
89 BOOL FindNextFile();
91 /**
92 * Advance to the next file, ignoring the "." and ".."
93 * pseudo-directories (if seen).
95 * Behaves like FindNextFile(), apart from ignoring "."
96 * and "..".
98 * \return TRUE if a file was found, FALSE on error or
99 * end-of-directory.
101 BOOL FindNextFileNoDots();
104 * Advance to the next file, ignoring all directories.
106 * Behaves like FindNextFile(), apart from ignoring
107 * directories.
109 * \return TRUE if a file was found, FALSE on error or
110 * end-of-directory.
112 BOOL FindNextFileNoDirectories();
115 * Get the Windows error code.
116 * Only useful when IsError() returns true.
118 * \return Windows error code.
120 inline DWORD GetError() const
122 return m_dError;
126 * Check if the current file data is valid.
127 * (I.e. there has not been an error and we are not past
128 * the end of the directory).
130 * \return TRUE iff the current file data is valid.
132 inline BOOL IsValid() const
134 return (m_dError == ERROR_SUCCESS);
138 * Check if we have passed the end of the directory.
140 * \return TRUE iff we have passed the end of the directory.
142 inline BOOL IsPastEnd() const
144 return (m_dError == ERROR_NO_MORE_FILES);
148 * Check if there has been an unexpected error - i.e.
149 * any error other than passing the end of the directory.
151 * \return TRUE iff there has been an unexpected error.
153 inline BOOL IsError() const
155 return (m_dError != ERROR_SUCCESS)
156 && (m_dError != ERROR_NO_MORE_FILES);
160 * Check if the current file is a directory.
162 * \return TRUE iff the current file is a directory.
164 inline bool IsDirectory() const
166 return !!(m_FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
170 * Get the current file name (excluding the path).
172 * \return the current file name.
174 inline CString GetFileName() const
176 return m_FindFileData.cFileName;
180 * Get the current file name, including the path.
182 * \return the current file path.
184 inline CString GetFilePath() const
186 return m_sPathPrefix + m_FindFileData.cFileName;
190 * Returns the last write time of the path
192 FILETIME GetLastWriteTime() const
194 return m_FindFileData.ftLastWriteTime;
196 FILETIME GetCreateTime() const
198 return m_FindFileData.ftCreationTime;
202 * Check if the current file is the "." or ".."
203 * pseudo-directory.
205 * \return TRUE iff the current file is the "." or ".."
206 * pseudo-directory.
208 inline BOOL IsDots() const
210 return IsDirectory()
211 && m_FindFileData.cFileName[0] == _T('.')
212 && ( (m_FindFileData.cFileName[1] == 0)
213 || (m_FindFileData.cFileName[1] == _T('.')
214 && m_FindFileData.cFileName[2] == 0) );
219 * \ingroup Utils
220 * Enumerates over a directory tree, recursively.
222 * \par requirements
223 * win95 or later
224 * winNT4 or later
225 * MFC
227 * \version 1.0
228 * first version
230 * \date 18-Feb-2004
232 * \author Jon Foster
234 * \par license
235 * This code is GPL'd.
237 class CDirFileEnum
239 private:
241 class CDirStackEntry : public CSimpleFileFind {
242 public:
243 CDirStackEntry(CDirStackEntry * seNext, const CString& sDirName);
244 ~CDirStackEntry();
246 CDirStackEntry * m_seNext;
249 CDirStackEntry * m_seStack;
250 BOOL m_bIsNew;
252 inline void PopStack();
253 inline void PushStack(const CString& sDirName);
255 public:
257 * Iterate through the specified directory and all subdirectories.
258 * It does not matter whether or not the specified directory ends
259 * with a slash. Both relative and absolute paths are allowed,
260 * the results of this iterator will be consistent with the style
261 * passed to this constructor.
263 * @param dirName The directory to search in.
265 CDirFileEnum(const CString& dirName);
268 * Destructor. Frees all resources.
270 ~CDirFileEnum();
273 * Get the next file from this iterator.
275 * \param result On successful return, holds the full path to the found
276 * file. (If this function returns FALSE, the value of
277 * result is unspecified).
278 * \param pbIsDirectory Pointer to a bool variable which will hold
279 * TRUE if the \c result path is a directory, FALSE
280 * if it's a file. Pass NULL if you don't need that information.
281 * \param bRecurse if the last result was a directory, specifies whether to
282 * recurse into that directory or skip it.
283 * \return TRUE iff a file was found, false at end of the iteration.
285 BOOL NextFile(CString &result, bool* pbIsDirectory, bool bRecurse = true);