X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f6bcfd974ef26faf6f91a62cac09827e09463fd1..ef3a5e0aae003c29941c7d41ed6becea4287752d:/src/os2/dir.cpp diff --git a/src/os2/dir.cpp b/src/os2/dir.cpp index 2915cf69b6..c7844fb1f4 100644 --- a/src/os2/dir.cpp +++ b/src/os2/dir.cpp @@ -34,10 +34,113 @@ #include +#define INCL_DOSFILEMGR +#define INCL_DOSERRORS +#include + #ifdef __EMX__ #include #endif +// ---------------------------------------------------------------------------- +// define the types and functions used for file searching +// ---------------------------------------------------------------------------- + +typedef FILEFINDBUF3 FIND_STRUCT; +typedef HDIR FIND_DATA; +typedef ULONG FIND_ATTR; + +static inline FIND_DATA InitFindData() { return ERROR_INVALID_HANDLE; } + +static inline bool IsFindDataOk( + FIND_DATA vFd +) +{ + return vFd != ERROR_INVALID_HANDLE; +} + +static inline void FreeFindData( + FIND_DATA vFd +) +{ + if (!::DosFindClose(vFd)) + { + wxLogLastError(_T("DosFindClose")); + } +} + +static inline FIND_DATA FindFirst( + const wxString& rsSpec +, FIND_STRUCT* pFinddata +) +{ + ULONG ulFindCount = 1; + FIND_DATA hDir; + FIND_ATTR rc; + + rc = ::DosFindFirst( rsSpec.c_str() + ,&hDir + ,FILE_NORMAL + ,pFinddata + ,sizeof(FILEFINDBUF3) + ,&ulFindCount + ,FIL_STANDARD + ); + if (rc != 0) + return 0; + return hDir; +} + +static inline bool FindNext( + FIND_DATA vFd +, FIND_STRUCT* pFinddata +) +{ + ULONG ulFindCount = 1; + + return ::DosFindNext( vFd + ,pFinddata + ,sizeof(FILEFINDBUF3) + ,&ulFindCount + ) != 0; +} + +static const wxChar* GetNameFromFindData( + FIND_STRUCT* pFinddata +) +{ + return pFinddata->achName; +} + +static const FIND_ATTR GetAttrFromFindData( + FIND_STRUCT* pFinddata +) +{ + return pFinddata->attrFile; +} + +static inline bool IsDir( + FIND_ATTR vAttr +) +{ + return (vAttr & FILE_DIRECTORY) != 0; +} + +static inline bool IsHidden( + FIND_ATTR vAttr +) +{ + return (vAttr & (FILE_HIDDEN | FILE_SYSTEM)) != 0; +} + +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +#ifndef MAX_PATH + #define MAX_PATH 260 // from PM++ headers +#endif + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -52,25 +155,23 @@ class wxDirData { public: - wxDirData(const wxString& dirname); + wxDirData(const wxString& rsDirname); ~wxDirData(); - bool IsOk() const { return m_dir != NULL; } + void SetFileSpec(const wxString& rsFilespec) { m_sFilespec = rsFilespec; } + void SetFlags(int nFlags) { m_nFlags = nFlags; } - void SetFileSpec(const wxString& filespec) { m_filespec = filespec; } - void SetFlags(int flags) { m_flags = flags; } - - void Rewind() { rewinddir(m_dir); } - bool Read(wxString *filename); + const wxString& GetName() const { return m_sDirname; } + void Close(); + void Rewind(); + bool Read(wxString* rsFilename); private: - DIR *m_dir; - - wxString m_dirname; - wxString m_filespec; - - int m_flags; -}; + FIND_DATA m_vFinddata; + wxString m_sDirname; + wxString m_sFilespec; + int m_nFlags; +}; // end of CLASS wxDirData // ============================================================================ // implementation @@ -80,160 +181,225 @@ private: // wxDirData // ---------------------------------------------------------------------------- -wxDirData::wxDirData(const wxString& dirname) - : m_dirname(dirname) +wxDirData::wxDirData( + const wxString& rsDirname +) +: m_sDirname(rsDirname) { - m_dir = NULL; + m_vFinddata = InitFindData(); +} // end of wxDirData::wxDirData - // throw away the trailing slashes - size_t n = m_dirname.length(); - wxCHECK_RET( n, _T("empty dir name in wxDir") ); - - while ( n > 0 && m_dirname[--n] == '/' ) - ; +wxDirData::~wxDirData() +{ + Close(); +} // end of wxDirData::~wxDirData - m_dirname.Truncate(n + 1); +void wxDirData::Close() +{ + if ( IsFindDataOk(m_vFinddata) ) + { + FreeFindData(m_vFinddata); + m_vFinddata = InitFindData(); + } +} // end of wxDirData::Close - // do open the dir - m_dir = opendir(m_dirname.fn_str()); -} +void wxDirData::Rewind() +{ + Close(); +} // end of wxDirData::Rewind -wxDirData::~wxDirData() +bool wxDirData::Read( + wxString* psFilename +) { - if ( m_dir ) + bool bFirst = FALSE; + + FILEFINDBUF3 vFinddata; + #define PTR_TO_FINDDATA (&vFinddata) + + if (!IsFindDataOk(m_vFinddata)) { - if ( closedir(m_dir) != 0 ) + // + // Open first + // + wxString sFilespec = m_sDirname; + + if ( !wxEndsWithPathSeparator(sFilespec) ) { - wxLogLastError(_T("closedir")); + sFilespec += _T('\\'); } + sFilespec += (!m_sFilespec ? _T("*.*") : m_sFilespec.c_str()); + + m_vFinddata = FindFirst( sFilespec + ,PTR_TO_FINDDATA + ); + bFirst = TRUE; } -} -bool wxDirData::Read(wxString *filename) -{ - dirent *de; - bool matches = FALSE; + if ( !IsFindDataOk(m_vFinddata) ) + { + return FALSE; + } + + const wxChar* zName; + FIND_ATTR vAttr; - while ( !matches ) + for ( ;; ) { - de = readdir(m_dir); - if ( !de ) - return FALSE; - - // don't return "." and ".." unless asked for - if ( de->d_name[0] == '.' && - ((de->d_name[1] == '.' && de->d_name[2] == '\0') || - (de->d_name[1] == '\0')) ) + if (bFirst) + { + bFirst = FALSE; + } + else { - if ( !(m_flags & wxDIR_DOTDOT) ) + if (!FindNext( m_vFinddata + ,PTR_TO_FINDDATA + )) + { + return FALSE; + } + } + + zName = GetNameFromFindData(PTR_TO_FINDDATA); + vAttr = GetAttrFromFindData(PTR_TO_FINDDATA); + + // + // Don't return "." and ".." unless asked for + // + if ( zName[0] == _T('.') && + ((zName[1] == _T('.') && zName[2] == _T('\0')) || + (zName[1] == _T('\0'))) ) + { + if (!(m_nFlags & wxDIR_DOTDOT)) continue; } - // check the type now - if ( !(m_flags & wxDIR_FILES) && - !wxDir::Exists(m_dirname + _T('/') + de->d_name) ) + // + // Check the type now + // + if (!(m_nFlags & wxDIR_FILES) && !IsDir(vAttr)) { - // it's a file, but we don't want them + // + // It's a file, but we don't want them + // continue; } - else if ( !(m_flags & wxDIR_DIRS) && - wxDir::Exists(m_dirname + _T('/') + de->d_name) ) + else if (!(m_nFlags & wxDIR_DIRS) && IsDir(vAttr) ) { - // it's a dir, and we don't want it + // + // It's a dir, and we don't want it + // continue; } - // finally, check the name - if ( !m_filespec ) - { - matches = m_flags & wxDIR_HIDDEN ? TRUE : de->d_name[0] != '.'; - } - else + // + // Finally, check whether it's a hidden file + // + if (!(m_nFlags & wxDIR_HIDDEN)) { - // test against the pattern - matches = wxMatchWild(m_filespec, de->d_name, - !(m_flags & wxDIR_HIDDEN)); + if (IsHidden(vAttr)) + { + // + // It's a hidden file, skip it + // + continue; + } } + *psFilename = zName; + break; } - - *filename = de->d_name; - return TRUE; -} +} // end of wxDirData::Read // ---------------------------------------------------------------------------- // wxDir helpers // ---------------------------------------------------------------------------- /* static */ -bool wxDir::Exists(const wxString& dir) +bool wxDir::Exists( + const wxString& rsDir +) { - return wxPathExists(dir); -} + return wxPathExists(rsDir); +} // end of wxDir::Exists // ---------------------------------------------------------------------------- // wxDir construction/destruction // ---------------------------------------------------------------------------- -wxDir::wxDir(const wxString& dirname) +wxDir::wxDir( + const wxString& rsDirname +) { m_data = NULL; - (void)Open(dirname); -} + (void)Open(rsDirname); +} // end of wxDir::wxDir -bool wxDir::Open(const wxString& dirname) +bool wxDir::Open( + const wxString& rsDirname +) { delete M_DIR; - m_data = new wxDirData(dirname); - - if ( !M_DIR->IsOk() ) - { - wxLogSysError(_("Can not enumerate files in directory '%s'"), - dirname.c_str()); - - delete M_DIR; - m_data = NULL; - - return FALSE; - } - + m_data = new wxDirData(rsDirname); return TRUE; -} +} // end of wxDir::Open bool wxDir::IsOpened() const { return m_data != NULL; +} // end of wxDir::IsOpen + +wxString wxDir::GetName() const +{ + wxString name; + if ( m_data ) + { + name = M_DIR->GetName(); + if ( !name.empty() ) + { + // bring to canonical Windows form + name.Replace(_T("/"), _T("\\")); + + if ( name.Last() == _T('\\') ) + { + // chop off the last (back)slash + name.Truncate(name.length() - 1); + } + } + } + + return name; } wxDir::~wxDir() { delete M_DIR; -} +} // end of wxDir::~wxDir // ---------------------------------------------------------------------------- // wxDir enumerating // ---------------------------------------------------------------------------- -bool wxDir::GetFirst(wxString *filename, - const wxString& filespec, - int flags) const +bool wxDir::GetFirst( + wxString* psFilename +, const wxString& rsFilespec +, int nFlags +) const { wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") ); - M_DIR->Rewind(); - - M_DIR->SetFileSpec(filespec); - M_DIR->SetFlags(flags); - - return GetNext(filename); -} - -bool wxDir::GetNext(wxString *filename) const + M_DIR->SetFileSpec(rsFilespec); + M_DIR->SetFlags(nFlags); + return GetNext(psFilename); +} // end of wxDir::GetFirst + +bool wxDir::GetNext( + wxString* psFilename +) const { wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") ); + wxCHECK_MSG( psFilename, FALSE, _T("bad pointer in wxDir::GetNext()") ); + return M_DIR->Read(psFilename); +} // end of wxDir::GetNext - wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") ); - - return M_DIR->Read(filename); -}