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 // License:     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 // ---------------------------------------------------------------------------- 
  77 // ---------------------------------------------------------------------------- 
  79 size_t wxDir::Traverse(wxDirTraverser
& sink
, 
  80                        const wxString
& filespec
, 
  83     wxCHECK_MSG( IsOpened(), (size_t)-1, 
  84                  wxT("dir must be opened before traversing it") ); 
  86     // the total number of files found 
  89     // the name of this dir with path delimiter at the end 
  90     wxString prefix 
= GetName(); 
  91     prefix 
+= wxFILE_SEP_PATH
; 
  93     // first, recurse into subdirs 
  94     if ( flags 
& wxDIR_DIRS 
) 
  97         for ( bool cont 
= GetFirst(&dirname
, wxEmptyString
, wxDIR_DIRS 
| (flags 
& wxDIR_HIDDEN
) ); 
  99               cont 
= cont 
&& GetNext(&dirname
) ) 
 101             const wxString fulldirname 
= prefix 
+ dirname
; 
 103             switch ( sink
.OnDir(fulldirname
) ) 
 106                     wxFAIL_MSG(wxT("unexpected OnDir() return value") ); 
 117                         // don't give the error messages for the directories 
 118                         // which we can't open: there can be all sorts of good 
 119                         // reason for this (e.g. insufficient privileges) and 
 120                         // this shouldn't be treated as an error -- instead 
 121                         // let the user code decide what to do 
 126                             ok 
= subdir
.Open(fulldirname
); 
 129                                 // ask the user code what to do 
 131                                 switch ( sink
.OnOpenError(fulldirname
) ) 
 134                                         wxFAIL_MSG(wxT("unexpected OnOpenError() return value") ); 
 157                             nFiles 
+= subdir
.Traverse(sink
, filespec
, flags
); 
 169     // now enum our own files 
 170     if ( flags 
& wxDIR_FILES 
) 
 172         flags 
&= ~wxDIR_DIRS
; 
 175         bool cont 
= GetFirst(&filename
, filespec
, flags
); 
 178             wxDirTraverseResult res 
= sink
.OnFile(prefix 
+ filename
); 
 179             if ( res 
== wxDIR_STOP 
) 
 182             wxASSERT_MSG( res 
== wxDIR_CONTINUE
, 
 183                           wxT("unexpected OnFile() return value") ); 
 187             cont 
= GetNext(&filename
); 
 194 // ---------------------------------------------------------------------------- 
 195 // wxDir::GetAllFiles() 
 196 // ---------------------------------------------------------------------------- 
 198 class wxDirTraverserSimple 
: public wxDirTraverser
 
 201     wxDirTraverserSimple(wxArrayString
& files
) : m_files(files
) { } 
 203     virtual wxDirTraverseResult 
OnFile(const wxString
& filename
) 
 205         m_files
.push_back(filename
); 
 206         return wxDIR_CONTINUE
; 
 209     virtual wxDirTraverseResult 
OnDir(const wxString
& WXUNUSED(dirname
)) 
 211         return wxDIR_CONTINUE
; 
 215     wxArrayString
& m_files
; 
 217     wxDECLARE_NO_COPY_CLASS(wxDirTraverserSimple
); 
 221 size_t wxDir::GetAllFiles(const wxString
& dirname
, 
 222                           wxArrayString 
*files
, 
 223                           const wxString
& filespec
, 
 226     wxCHECK_MSG( files
, (size_t)-1, wxT("NULL pointer in wxDir::GetAllFiles") ); 
 231     if ( dir
.IsOpened() ) 
 233         wxDirTraverserSimple 
traverser(*files
); 
 235         nFiles 
+= dir
.Traverse(traverser
, filespec
, flags
); 
 241 // ---------------------------------------------------------------------------- 
 242 // wxDir::FindFirst() 
 243 // ---------------------------------------------------------------------------- 
 245 class wxDirTraverserFindFirst 
: public wxDirTraverser
 
 248     wxDirTraverserFindFirst() { } 
 250     virtual wxDirTraverseResult 
OnFile(const wxString
& filename
) 
 256     virtual wxDirTraverseResult 
OnDir(const wxString
& WXUNUSED(dirname
)) 
 258         return wxDIR_CONTINUE
; 
 261     const wxString
& GetFile() const 
 269     wxDECLARE_NO_COPY_CLASS(wxDirTraverserFindFirst
); 
 273 wxString 
wxDir::FindFirst(const wxString
& dirname
, 
 274                           const wxString
& filespec
, 
 278     if ( dir
.IsOpened() ) 
 280         wxDirTraverserFindFirst traverser
; 
 282         dir
.Traverse(traverser
, filespec
, flags 
| wxDIR_FILES
); 
 283         return traverser
.GetFile(); 
 286     return wxEmptyString
; 
 290 // ---------------------------------------------------------------------------- 
 291 // wxDir::GetTotalSize() 
 292 // ---------------------------------------------------------------------------- 
 296 class wxDirTraverserSumSize 
: public wxDirTraverser
 
 299     wxDirTraverserSumSize() { } 
 301     virtual wxDirTraverseResult 
OnFile(const wxString
& filename
) 
 303         wxULongLong sz 
= wxFileName::GetSize(filename
); 
 305         // wxFileName::GetSize won't use this class again as 
 306         // we're passing it a file and not a directory; 
 307         // thus we are sure to avoid an endless loop 
 308         if (sz 
== wxInvalidSize
) 
 310             // if the GetSize() failed (this can happen because e.g. a 
 311             // file is locked by another process), we can proceed but 
 312             // we need to at least warn the user that the resulting 
 313             // final size could be not reliable (if e.g. the locked 
 314             // file is very big). 
 315             m_skippedFiles
.Add(filename
); 
 316             return wxDIR_CONTINUE
; 
 320         return wxDIR_CONTINUE
; 
 323     virtual wxDirTraverseResult 
OnDir(const wxString
& WXUNUSED(dirname
)) 
 325         return wxDIR_CONTINUE
; 
 328     wxULongLong 
GetTotalSize() const 
 330     wxArrayString 
&FilesSkipped() 
 331         { return m_skippedFiles
; } 
 335     wxArrayString m_skippedFiles
; 
 338 wxULongLong 
wxDir::GetTotalSize(const wxString 
&dirname
, wxArrayString 
*filesSkipped
) 
 340     if (!wxDirExists(dirname
)) 
 341         return wxInvalidSize
; 
 343     // to get the size of this directory and its contents we need 
 344     // to recursively walk it... 
 346     if ( !dir
.IsOpened() ) 
 347         return wxInvalidSize
; 
 349     wxDirTraverserSumSize traverser
; 
 350     if (dir
.Traverse(traverser
) == (size_t)-1 || 
 351         traverser
.GetTotalSize() == 0) 
 352         return wxInvalidSize
; 
 355         *filesSkipped 
= traverser
.FilesSkipped(); 
 357     return traverser
.GetTotalSize(); 
 360 #endif // wxUSE_LONGLONG