1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/dircmn.cpp
3 // Purpose: wxDir methods common to all implementations
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
27 #include "wx/string.h"
30 #include "wx/filefn.h"
31 #include "wx/arrstr.h"
35 #include "wx/filename.h"
37 // ============================================================================
39 // ============================================================================
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
46 wxDirTraverser::OnOpenError(const wxString
& WXUNUSED(dirname
))
51 // ----------------------------------------------------------------------------
52 // wxDir::HasFiles() and HasSubDirs()
53 // ----------------------------------------------------------------------------
55 // dumb generic implementation
57 bool wxDir::HasFiles(const wxString
& spec
) const
60 return GetFirst(&s
, spec
, wxDIR_FILES
| wxDIR_HIDDEN
);
63 // we have a (much) faster version for Unix
64 #if (defined(__CYGWIN__) && defined(__WINDOWS__)) || !defined(__UNIX_LIKE__) || defined(__EMX__) || defined(__WINE__)
66 bool wxDir::HasSubDirs(const wxString
& spec
) const
69 return GetFirst(&s
, spec
, wxDIR_DIRS
| wxDIR_HIDDEN
);
74 // ----------------------------------------------------------------------------
75 // wxDir::GetNameWithSep()
76 // ----------------------------------------------------------------------------
78 wxString
wxDir::GetNameWithSep() const
80 // Note that for historical reasons (i.e. because GetName() was there
81 // first) we implement this one in terms of GetName() even though it might
82 // actually make more sense to reverse this logic.
84 wxString name
= GetName();
87 // Notice that even though GetName() isn't supposed to return the
88 // separator, it can still be present for the root directory name.
89 if ( name
.Last() != wxFILE_SEP_PATH
)
90 name
+= wxFILE_SEP_PATH
;
96 // ----------------------------------------------------------------------------
98 // ----------------------------------------------------------------------------
100 size_t wxDir::Traverse(wxDirTraverser
& sink
,
101 const wxString
& filespec
,
104 wxCHECK_MSG( IsOpened(), (size_t)-1,
105 wxT("dir must be opened before traversing it") );
107 // the total number of files found
110 // the name of this dir with path delimiter at the end
111 const wxString prefix
= GetNameWithSep();
113 // first, recurse into subdirs
114 if ( flags
& wxDIR_DIRS
)
117 for ( bool cont
= GetFirst(&dirname
, wxEmptyString
,
118 (flags
& ~(wxDIR_FILES
| wxDIR_DOTDOT
))
121 cont
= cont
&& GetNext(&dirname
) )
123 const wxString fulldirname
= prefix
+ dirname
;
125 switch ( sink
.OnDir(fulldirname
) )
128 wxFAIL_MSG(wxT("unexpected OnDir() return value") );
139 // don't give the error messages for the directories
140 // which we can't open: there can be all sorts of good
141 // reason for this (e.g. insufficient privileges) and
142 // this shouldn't be treated as an error -- instead
143 // let the user code decide what to do
148 ok
= subdir
.Open(fulldirname
);
151 // ask the user code what to do
153 switch ( sink
.OnOpenError(fulldirname
) )
156 wxFAIL_MSG(wxT("unexpected OnOpenError() return value") );
179 nFiles
+= subdir
.Traverse(sink
, filespec
, flags
);
191 // now enum our own files
192 if ( flags
& wxDIR_FILES
)
194 flags
&= ~wxDIR_DIRS
;
197 bool cont
= GetFirst(&filename
, filespec
, flags
);
200 wxDirTraverseResult res
= sink
.OnFile(prefix
+ filename
);
201 if ( res
== wxDIR_STOP
)
204 wxASSERT_MSG( res
== wxDIR_CONTINUE
,
205 wxT("unexpected OnFile() return value") );
209 cont
= GetNext(&filename
);
216 // ----------------------------------------------------------------------------
217 // wxDir::GetAllFiles()
218 // ----------------------------------------------------------------------------
220 class wxDirTraverserSimple
: public wxDirTraverser
223 wxDirTraverserSimple(wxArrayString
& files
) : m_files(files
) { }
225 virtual wxDirTraverseResult
OnFile(const wxString
& filename
)
227 m_files
.push_back(filename
);
228 return wxDIR_CONTINUE
;
231 virtual wxDirTraverseResult
OnDir(const wxString
& WXUNUSED(dirname
))
233 return wxDIR_CONTINUE
;
237 wxArrayString
& m_files
;
239 wxDECLARE_NO_COPY_CLASS(wxDirTraverserSimple
);
243 size_t wxDir::GetAllFiles(const wxString
& dirname
,
244 wxArrayString
*files
,
245 const wxString
& filespec
,
248 wxCHECK_MSG( files
, (size_t)-1, wxT("NULL pointer in wxDir::GetAllFiles") );
253 if ( dir
.IsOpened() )
255 wxDirTraverserSimple
traverser(*files
);
257 nFiles
+= dir
.Traverse(traverser
, filespec
, flags
);
263 // ----------------------------------------------------------------------------
264 // wxDir::FindFirst()
265 // ----------------------------------------------------------------------------
267 class wxDirTraverserFindFirst
: public wxDirTraverser
270 wxDirTraverserFindFirst() { }
272 virtual wxDirTraverseResult
OnFile(const wxString
& filename
)
278 virtual wxDirTraverseResult
OnDir(const wxString
& WXUNUSED(dirname
))
280 return wxDIR_CONTINUE
;
283 const wxString
& GetFile() const
291 wxDECLARE_NO_COPY_CLASS(wxDirTraverserFindFirst
);
295 wxString
wxDir::FindFirst(const wxString
& dirname
,
296 const wxString
& filespec
,
300 if ( dir
.IsOpened() )
302 wxDirTraverserFindFirst traverser
;
304 dir
.Traverse(traverser
, filespec
, flags
| wxDIR_FILES
);
305 return traverser
.GetFile();
308 return wxEmptyString
;
312 // ----------------------------------------------------------------------------
313 // wxDir::GetTotalSize()
314 // ----------------------------------------------------------------------------
318 class wxDirTraverserSumSize
: public wxDirTraverser
321 wxDirTraverserSumSize() { }
323 virtual wxDirTraverseResult
OnFile(const wxString
& filename
)
325 // wxFileName::GetSize won't use this class again as
326 // we're passing it a file and not a directory;
327 // thus we are sure to avoid an endless loop
328 wxULongLong sz
= wxFileName::GetSize(filename
);
330 if (sz
== wxInvalidSize
)
332 // if the GetSize() failed (this can happen because e.g. a
333 // file is locked by another process), we can proceed but
334 // we need to at least warn the user that the resulting
335 // final size could be not reliable (if e.g. the locked
336 // file is very big).
337 m_skippedFiles
.Add(filename
);
338 return wxDIR_CONTINUE
;
342 return wxDIR_CONTINUE
;
345 virtual wxDirTraverseResult
OnDir(const wxString
& WXUNUSED(dirname
))
347 return wxDIR_CONTINUE
;
350 wxULongLong
GetTotalSize() const
352 const wxArrayString
& GetSkippedFiles() const
353 { return m_skippedFiles
; }
357 wxArrayString m_skippedFiles
;
360 wxULongLong
wxDir::GetTotalSize(const wxString
&dirname
, wxArrayString
*filesSkipped
)
362 if (!wxDirExists(dirname
))
363 return wxInvalidSize
;
365 // to get the size of this directory and its contents we need
366 // to recursively walk it...
368 if ( !dir
.IsOpened() )
369 return wxInvalidSize
;
371 wxDirTraverserSumSize traverser
;
372 if (dir
.Traverse(traverser
) == (size_t)-1 )
373 return wxInvalidSize
;
376 *filesSkipped
= traverser
.GetSkippedFiles();
378 return traverser
.GetTotalSize();
381 #endif // wxUSE_LONGLONG
383 // ----------------------------------------------------------------------------
385 // ----------------------------------------------------------------------------
388 bool wxDir::Exists(const wxString
& dir
)
390 return wxFileName::DirExists(dir
);
394 bool wxDir::Make(const wxString
&dir
, int perm
, int flags
)
396 return wxFileName::Mkdir(dir
, perm
, flags
);
400 bool wxDir::Remove(const wxString
&dir
, int flags
)
402 return wxFileName::Rmdir(dir
, flags
);