1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/dircmn.cpp
3 // Purpose: wxDir methods common to all implementations
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
28 #include "wx/string.h"
31 #include "wx/filefn.h"
32 #include "wx/arrstr.h"
36 #include "wx/filename.h"
38 // ============================================================================
40 // ============================================================================
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
47 wxDirTraverser::OnOpenError(const wxString
& WXUNUSED(dirname
))
52 // ----------------------------------------------------------------------------
53 // wxDir::HasFiles() and HasSubDirs()
54 // ----------------------------------------------------------------------------
56 // dumb generic implementation
58 bool wxDir::HasFiles(const wxString
& spec
) const
61 return GetFirst(&s
, spec
, wxDIR_FILES
| wxDIR_HIDDEN
);
64 // we have a (much) faster version for Unix
65 #if (defined(__CYGWIN__) && defined(__WINDOWS__)) || !defined(__UNIX_LIKE__) || defined(__EMX__) || defined(__WINE__)
67 bool wxDir::HasSubDirs(const wxString
& spec
) const
70 return GetFirst(&s
, spec
, wxDIR_DIRS
| wxDIR_HIDDEN
);
75 // ----------------------------------------------------------------------------
76 // wxDir::GetNameWithSep()
77 // ----------------------------------------------------------------------------
79 wxString
wxDir::GetNameWithSep() const
81 // Note that for historical reasons (i.e. because GetName() was there
82 // first) we implement this one in terms of GetName() even though it might
83 // actually make more sense to reverse this logic.
85 wxString name
= GetName();
88 // Notice that even though GetName() isn't supposed to return the
89 // separator, it can still be present for the root directory name.
90 if ( name
.Last() != wxFILE_SEP_PATH
)
91 name
+= wxFILE_SEP_PATH
;
97 // ----------------------------------------------------------------------------
99 // ----------------------------------------------------------------------------
101 size_t wxDir::Traverse(wxDirTraverser
& sink
,
102 const wxString
& filespec
,
105 wxCHECK_MSG( IsOpened(), (size_t)-1,
106 wxT("dir must be opened before traversing it") );
108 // the total number of files found
111 // the name of this dir with path delimiter at the end
112 const wxString prefix
= GetNameWithSep();
114 // first, recurse into subdirs
115 if ( flags
& wxDIR_DIRS
)
118 for ( bool cont
= GetFirst(&dirname
, wxEmptyString
,
119 (flags
& ~(wxDIR_FILES
| wxDIR_DOTDOT
))
122 cont
= cont
&& GetNext(&dirname
) )
124 const wxString fulldirname
= prefix
+ dirname
;
126 switch ( sink
.OnDir(fulldirname
) )
129 wxFAIL_MSG(wxT("unexpected OnDir() return value") );
140 // don't give the error messages for the directories
141 // which we can't open: there can be all sorts of good
142 // reason for this (e.g. insufficient privileges) and
143 // this shouldn't be treated as an error -- instead
144 // let the user code decide what to do
149 ok
= subdir
.Open(fulldirname
);
152 // ask the user code what to do
154 switch ( sink
.OnOpenError(fulldirname
) )
157 wxFAIL_MSG(wxT("unexpected OnOpenError() return value") );
180 nFiles
+= subdir
.Traverse(sink
, filespec
, flags
);
192 // now enum our own files
193 if ( flags
& wxDIR_FILES
)
195 flags
&= ~wxDIR_DIRS
;
198 bool cont
= GetFirst(&filename
, filespec
, flags
);
201 wxDirTraverseResult res
= sink
.OnFile(prefix
+ filename
);
202 if ( res
== wxDIR_STOP
)
205 wxASSERT_MSG( res
== wxDIR_CONTINUE
,
206 wxT("unexpected OnFile() return value") );
210 cont
= GetNext(&filename
);
217 // ----------------------------------------------------------------------------
218 // wxDir::GetAllFiles()
219 // ----------------------------------------------------------------------------
221 class wxDirTraverserSimple
: public wxDirTraverser
224 wxDirTraverserSimple(wxArrayString
& files
) : m_files(files
) { }
226 virtual wxDirTraverseResult
OnFile(const wxString
& filename
)
228 m_files
.push_back(filename
);
229 return wxDIR_CONTINUE
;
232 virtual wxDirTraverseResult
OnDir(const wxString
& WXUNUSED(dirname
))
234 return wxDIR_CONTINUE
;
238 wxArrayString
& m_files
;
240 wxDECLARE_NO_COPY_CLASS(wxDirTraverserSimple
);
244 size_t wxDir::GetAllFiles(const wxString
& dirname
,
245 wxArrayString
*files
,
246 const wxString
& filespec
,
249 wxCHECK_MSG( files
, (size_t)-1, wxT("NULL pointer in wxDir::GetAllFiles") );
254 if ( dir
.IsOpened() )
256 wxDirTraverserSimple
traverser(*files
);
258 nFiles
+= dir
.Traverse(traverser
, filespec
, flags
);
264 // ----------------------------------------------------------------------------
265 // wxDir::FindFirst()
266 // ----------------------------------------------------------------------------
268 class wxDirTraverserFindFirst
: public wxDirTraverser
271 wxDirTraverserFindFirst() { }
273 virtual wxDirTraverseResult
OnFile(const wxString
& filename
)
279 virtual wxDirTraverseResult
OnDir(const wxString
& WXUNUSED(dirname
))
281 return wxDIR_CONTINUE
;
284 const wxString
& GetFile() const
292 wxDECLARE_NO_COPY_CLASS(wxDirTraverserFindFirst
);
296 wxString
wxDir::FindFirst(const wxString
& dirname
,
297 const wxString
& filespec
,
301 if ( dir
.IsOpened() )
303 wxDirTraverserFindFirst traverser
;
305 dir
.Traverse(traverser
, filespec
, flags
| wxDIR_FILES
);
306 return traverser
.GetFile();
309 return wxEmptyString
;
313 // ----------------------------------------------------------------------------
314 // wxDir::GetTotalSize()
315 // ----------------------------------------------------------------------------
319 class wxDirTraverserSumSize
: public wxDirTraverser
322 wxDirTraverserSumSize() { }
324 virtual wxDirTraverseResult
OnFile(const wxString
& filename
)
326 // wxFileName::GetSize won't use this class again as
327 // we're passing it a file and not a directory;
328 // thus we are sure to avoid an endless loop
329 wxULongLong sz
= wxFileName::GetSize(filename
);
331 if (sz
== wxInvalidSize
)
333 // if the GetSize() failed (this can happen because e.g. a
334 // file is locked by another process), we can proceed but
335 // we need to at least warn the user that the resulting
336 // final size could be not reliable (if e.g. the locked
337 // file is very big).
338 m_skippedFiles
.Add(filename
);
339 return wxDIR_CONTINUE
;
343 return wxDIR_CONTINUE
;
346 virtual wxDirTraverseResult
OnDir(const wxString
& WXUNUSED(dirname
))
348 return wxDIR_CONTINUE
;
351 wxULongLong
GetTotalSize() const
353 const wxArrayString
& GetSkippedFiles() const
354 { return m_skippedFiles
; }
358 wxArrayString m_skippedFiles
;
361 wxULongLong
wxDir::GetTotalSize(const wxString
&dirname
, wxArrayString
*filesSkipped
)
363 if (!wxDirExists(dirname
))
364 return wxInvalidSize
;
366 // to get the size of this directory and its contents we need
367 // to recursively walk it...
369 if ( !dir
.IsOpened() )
370 return wxInvalidSize
;
372 wxDirTraverserSumSize traverser
;
373 if (dir
.Traverse(traverser
) == (size_t)-1 )
374 return wxInvalidSize
;
377 *filesSkipped
= traverser
.GetSkippedFiles();
379 return traverser
.GetTotalSize();
382 #endif // wxUSE_LONGLONG
384 // ----------------------------------------------------------------------------
386 // ----------------------------------------------------------------------------
389 bool wxDir::Exists(const wxString
& dir
)
391 return wxFileName::DirExists(dir
);
395 bool wxDir::Make(const wxString
&dir
, int perm
, int flags
)
397 return wxFileName::Mkdir(dir
, perm
, flags
);
401 bool wxDir::Remove(const wxString
&dir
, int flags
)
403 return wxFileName::Rmdir(dir
, flags
);