]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/dir.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxDir implementation for Unix/POSIX systems 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 1999 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" 
  33 #include "wx/filefn.h"          // for wxMatchWild 
  35 #include <sys/types.h> 
  41 // ---------------------------------------------------------------------------- 
  43 // ---------------------------------------------------------------------------- 
  45 #define M_DIR       ((wxDirData *)m_data) 
  47 // ---------------------------------------------------------------------------- 
  49 // ---------------------------------------------------------------------------- 
  51 // this class stores everything we need to enumerate the files 
  55     wxDirData(const wxString
& dirname
); 
  58     bool IsOk() const { return m_dir 
!= NULL
; } 
  60     void SetFileSpec(const wxString
& filespec
) { m_filespec 
= filespec
; } 
  61     void SetFlags(int flags
) { m_flags 
= flags
; } 
  63     void Rewind() { rewinddir(m_dir
); } 
  64     bool Read(wxString 
*filename
); 
  66     const wxString
& GetName() const { return m_dirname
; } 
  77 // ============================================================================ 
  79 // ============================================================================ 
  81 // ---------------------------------------------------------------------------- 
  83 // ---------------------------------------------------------------------------- 
  85 #if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 ) 
  87 wxDirData::wxDirData(const wxString
& dirname
) 
  92     // throw away the trailing slashes 
  93     size_t n 
= m_dirname
.length(); 
  94     wxCHECK_RET( n
, _T("empty dir name in wxDir") ); 
  96     while ( n 
> 0 && m_dirname
[--n
] == '/' ) 
  99     m_dirname
.Truncate(n 
+ 1); 
 102     m_dir 
= opendir(m_dirname
.fn_str()); 
 105 wxDirData::~wxDirData() 
 109         if ( closedir(m_dir
) != 0 ) 
 111             wxLogLastError(_T("closedir")); 
 116 bool wxDirData::Read(wxString 
*filename
) 
 118     dirent 
*de 
= (dirent 
*)NULL
;    // just to silence compiler warnings 
 119     bool matches 
= false; 
 121     // speed up string concatenation in the loop a bit 
 122     wxString path 
= m_dirname
; 
 124     path
.reserve(path
.length() + 255); 
 135         de_d_name 
= wxString(de
->d_name
, *wxConvFileName
); 
 137         de_d_name 
= de
->d_name
; 
 140         // don't return "." and ".." unless asked for 
 141         if ( de
->d_name
[0] == '.' && 
 142              ((de
->d_name
[1] == '.' && de
->d_name
[2] == '\0') || 
 143               (de
->d_name
[1] == '\0')) ) 
 145             if ( !(m_flags 
& wxDIR_DOTDOT
) ) 
 148             // we found a valid match 
 152         // check the type now 
 153         if ( !(m_flags 
& wxDIR_FILES
) && !wxDir::Exists(path 
+ de_d_name
) ) 
 155             // it's a file, but we don't want them 
 158         else if ( !(m_flags 
& wxDIR_DIRS
) && wxDir::Exists(path 
+ de_d_name
) ) 
 160             // it's a dir, and we don't want it 
 164         // finally, check the name 
 165         if ( m_filespec
.empty() ) 
 167             matches 
= m_flags 
& wxDIR_HIDDEN 
? true : de
->d_name
[0] != '.'; 
 171             // test against the pattern 
 172             matches 
= wxMatchWild(m_filespec
, de_d_name
, 
 173                                   !(m_flags 
& wxDIR_HIDDEN
)); 
 177     *filename 
= de_d_name
; 
 182 #else // old VMS (TODO) 
 184 wxDirData::wxDirData(const wxString
& WXUNUSED(dirname
)) 
 186     wxFAIL_MSG(_T("not implemented")); 
 189 wxDirData::~wxDirData() 
 193 bool wxDirData::Read(wxString 
* WXUNUSED(filename
)) 
 198 #endif // not or new VMS/old VMS 
 200 // ---------------------------------------------------------------------------- 
 202 // ---------------------------------------------------------------------------- 
 205 bool wxDir::Exists(const wxString
& dir
) 
 207     return wxDirExists(dir
); 
 210 // ---------------------------------------------------------------------------- 
 211 // wxDir construction/destruction 
 212 // ---------------------------------------------------------------------------- 
 214 wxDir::wxDir(const wxString
& dirname
) 
 221 bool wxDir::Open(const wxString
& dirname
) 
 224     m_data 
= new wxDirData(dirname
); 
 226     if ( !M_DIR
->IsOk() ) 
 228         wxLogSysError(_("Can not enumerate files in directory '%s'"), 
 240 bool wxDir::IsOpened() const 
 242     return m_data 
!= NULL
; 
 245 wxString 
wxDir::GetName() const 
 250         name 
= M_DIR
->GetName(); 
 251         if ( !name
.empty() && (name
.Last() == _T('/')) ) 
 253             // chop off the last (back)slash 
 254             name
.Truncate(name
.length() - 1); 
 266 // ---------------------------------------------------------------------------- 
 268 // ---------------------------------------------------------------------------- 
 270 bool wxDir::GetFirst(wxString 
*filename
, 
 271                      const wxString
& filespec
, 
 274     wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") ); 
 278     M_DIR
->SetFileSpec(filespec
); 
 279     M_DIR
->SetFlags(flags
); 
 281     return GetNext(filename
); 
 284 bool wxDir::GetNext(wxString 
*filename
) const 
 286     wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") ); 
 288     wxCHECK_MSG( filename
, false, _T("bad pointer in wxDir::GetNext()") ); 
 290     return M_DIR
->Read(filename
); 
 293 bool wxDir::HasSubDirs(const wxString
& spec
) 
 295     wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") ); 
 299         // faster check for presence of any subdirectory: normally each subdir 
 300         // has a hard link to the parent directory and so, knowing that there 
 301         // are at least "." and "..", we have a subdirectory if and only if 
 302         // links number is > 2 - this is just a guess but it works fairly well 
 305         // note that we may guess wrongly in one direction only: i.e. we may 
 306         // return true when there are no subdirectories but this is ok as the 
 307         // caller will learn it soon enough when it calls GetFirst(wxDIR) 
 310         if ( wxStat(M_DIR
->GetName().c_str(), &stBuf
) == 0 ) 
 312             switch ( stBuf
.st_nlink 
) 
 320                     // weird filesystem, don't try to guess for it, use dumb 
 325                     // assume we have subdirs - may turn out to be wrong if we 
 326                     // have other hard links to this directory but it's not 
 327                     // that bad as explained above 
 333     // just try to find first directory 
 335     return GetFirst(&s
, spec
, wxDIR_DIRS 
| wxDIR_HIDDEN
);