home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / os2 / dir.cpp < prev    next >
C/C++ Source or Header  |  2002-01-20  |  11KB  |  407 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        os2/dir.cpp
  3. // Purpose:     wxDir implementation for OS/2
  4. // Author:      Vadim Zeitlin
  5. // Modified by: Stefan Neis
  6. // Created:     08.12.99
  7. // RCS-ID:      $Id: DIR.CPP,v 1.6 2002/01/20 22:02:00 SN Exp $
  8. // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. #ifdef __GNUG__
  21.     #pragma implementation "dir.h"
  22. #endif
  23.  
  24. // For compilers that support precompilation, includes "wx.h".
  25. #include "wx/wxprec.h"
  26.  
  27. #ifndef WX_PRECOMP
  28.     #include "wx/os2/private.h"
  29.     #include "wx/intl.h"
  30.     #include "wx/log.h"
  31. #endif // PCH
  32.  
  33. #include "wx/dir.h"
  34. #include "wx/filefn.h"          // for wxMatchWild
  35.  
  36. #include <sys/types.h>
  37.  
  38. #define INCL_DOSFILEMGR
  39. #define INCL_DOSERRORS
  40. #include <os2.h>
  41.  
  42. #ifdef __EMX__
  43. #include <dirent.h>
  44. #endif
  45.  
  46. // ----------------------------------------------------------------------------
  47. // define the types and functions used for file searching
  48. // ----------------------------------------------------------------------------
  49.  
  50. typedef FILEFINDBUF3                FIND_STRUCT;
  51. typedef HDIR                        FIND_DATA;
  52. typedef ULONG                       FIND_ATTR;
  53.  
  54. static inline FIND_DATA InitFindData() { return ERROR_INVALID_HANDLE; }
  55.  
  56. static inline bool IsFindDataOk(
  57.   FIND_DATA                     vFd
  58. )
  59. {
  60.     return vFd != ERROR_INVALID_HANDLE;
  61. }
  62.  
  63. static inline void FreeFindData(
  64.   FIND_DATA                     vFd
  65. )
  66. {
  67.     if (!::DosFindClose(vFd))
  68.     {
  69.         wxLogLastError(_T("DosFindClose"));
  70.     }
  71. }
  72.  
  73. static inline FIND_DATA FindFirst(
  74.   const wxString&               rsSpec
  75. , FIND_STRUCT*                  pFinddata
  76. )
  77. {
  78.     ULONG                       ulFindCount = 1;
  79.     FIND_DATA                   hDir;
  80.     FIND_ATTR                   rc;
  81.  
  82.     rc = ::DosFindFirst( rsSpec.c_str()
  83.                         ,&hDir
  84.                         ,FILE_NORMAL
  85.                         ,pFinddata
  86.                         ,sizeof(FILEFINDBUF3)
  87.                         ,&ulFindCount
  88.                         ,FIL_STANDARD
  89.                        );
  90.     if (rc != 0)
  91.         return 0;
  92.     return hDir;
  93. }
  94.  
  95. static inline bool FindNext(
  96.   FIND_DATA                         vFd
  97. , FIND_STRUCT*                      pFinddata
  98. )
  99. {
  100.     ULONG                           ulFindCount = 1;
  101.  
  102.     return ::DosFindNext( vFd
  103.                          ,pFinddata
  104.                          ,sizeof(FILEFINDBUF3)
  105.                          ,&ulFindCount
  106.                          ) != 0;
  107. }
  108.  
  109. static const wxChar* GetNameFromFindData(
  110.   FIND_STRUCT*                      pFinddata
  111. )
  112. {
  113.     return pFinddata->achName;
  114. }
  115.  
  116. static const FIND_ATTR GetAttrFromFindData(
  117.   FIND_STRUCT*                      pFinddata
  118. )
  119. {
  120.     return pFinddata->attrFile;
  121. }
  122.  
  123. static inline bool IsDir(
  124.   FIND_ATTR                         vAttr
  125. )
  126. {
  127.     return (vAttr & FILE_DIRECTORY) != 0;
  128. }
  129.  
  130. static inline bool IsHidden(
  131.   FIND_ATTR                         vAttr
  132. )
  133. {
  134.     return (vAttr & (FILE_HIDDEN | FILE_SYSTEM)) != 0;
  135. }
  136.  
  137. // ----------------------------------------------------------------------------
  138. // constants
  139. // ----------------------------------------------------------------------------
  140.  
  141. #ifndef MAX_PATH
  142.     #define MAX_PATH 260        // from PM++ headers
  143. #endif
  144.  
  145. // ----------------------------------------------------------------------------
  146. // macros
  147. // ----------------------------------------------------------------------------
  148.  
  149. #define M_DIR       ((wxDirData *)m_data)
  150.  
  151. // ----------------------------------------------------------------------------
  152. // private classes
  153. // ----------------------------------------------------------------------------
  154.  
  155. // this class stores everything we need to enumerate the files
  156. class wxDirData
  157. {
  158. public:
  159.     wxDirData(const wxString& rsDirname);
  160.     ~wxDirData();
  161.  
  162.     void SetFileSpec(const wxString& rsFilespec) { m_sFilespec = rsFilespec; }
  163.     void SetFlags(int nFlags) { m_nFlags = nFlags; }
  164.  
  165.     const wxString& GetName() const { return m_sDirname; }
  166.     void Close();
  167.     void Rewind();
  168.     bool Read(wxString* rsFilename);
  169.  
  170. private:
  171.     FIND_DATA                       m_vFinddata;
  172.     wxString                        m_sDirname;
  173.     wxString                        m_sFilespec;
  174.     int                             m_nFlags;
  175. }; // end of CLASS wxDirData
  176.  
  177. // ============================================================================
  178. // implementation
  179. // ============================================================================
  180.  
  181. // ----------------------------------------------------------------------------
  182. // wxDirData
  183. // ----------------------------------------------------------------------------
  184.  
  185. wxDirData::wxDirData(
  186.   const wxString&                   rsDirname
  187. )
  188. : m_sDirname(rsDirname)
  189. {
  190.     m_vFinddata = InitFindData();
  191. } // end of wxDirData::wxDirData
  192.  
  193. wxDirData::~wxDirData()
  194. {
  195.     Close();
  196. } // end of wxDirData::~wxDirData
  197.  
  198. void wxDirData::Close()
  199. {
  200.     if ( IsFindDataOk(m_vFinddata) )
  201.     {
  202.         FreeFindData(m_vFinddata);
  203.         m_vFinddata = InitFindData();
  204.     }
  205. } // end of wxDirData::Close
  206.  
  207. void wxDirData::Rewind()
  208. {
  209.     Close();
  210. } // end of wxDirData::Rewind
  211.  
  212. bool wxDirData::Read(
  213.   wxString*                         psFilename
  214. )
  215. {
  216.     bool                            bFirst = FALSE;
  217.  
  218.     FILEFINDBUF3                    vFinddata;
  219.     #define PTR_TO_FINDDATA (&vFinddata)
  220.  
  221.     if (!IsFindDataOk(m_vFinddata))
  222.     {
  223.         //
  224.         // Open first
  225.         //
  226.         wxString                    sFilespec = m_sDirname;
  227.  
  228.         if ( !wxEndsWithPathSeparator(sFilespec) )
  229.         {
  230.             sFilespec += _T('\\');
  231.         }
  232.         sFilespec += (!m_sFilespec ? _T("*.*") : m_sFilespec.c_str());
  233.  
  234.         m_vFinddata = FindFirst( sFilespec
  235.                                 ,PTR_TO_FINDDATA
  236.                                );
  237.         bFirst = TRUE;
  238.     }
  239.  
  240.     if ( !IsFindDataOk(m_vFinddata) )
  241.     {
  242.         return FALSE;
  243.     }
  244.  
  245.     const wxChar*                   zName;
  246.     FIND_ATTR                       vAttr;
  247.  
  248.     for ( ;; )
  249.     {
  250.         if (bFirst)
  251.         {
  252.             bFirst = FALSE;
  253.         }
  254.         else
  255.         {
  256.             if (!FindNext( m_vFinddata
  257.                           ,PTR_TO_FINDDATA
  258.                          ))
  259.             {
  260.                 return FALSE;
  261.             }
  262.         }
  263.  
  264.         zName = GetNameFromFindData(PTR_TO_FINDDATA);
  265.         vAttr = GetAttrFromFindData(PTR_TO_FINDDATA);
  266.  
  267.         //
  268.         // Don't return "." and ".." unless asked for
  269.         //
  270.         if ( zName[0] == _T('.') &&
  271.              ((zName[1] == _T('.') && zName[2] == _T('\0')) ||
  272.               (zName[1] == _T('\0'))) )
  273.         {
  274.             if (!(m_nFlags & wxDIR_DOTDOT))
  275.                 continue;
  276.         }
  277.  
  278.         //
  279.         // Check the type now
  280.         //
  281.         if (!(m_nFlags & wxDIR_FILES) && !IsDir(vAttr))
  282.         {
  283.             //
  284.             // It's a file, but we don't want them
  285.             //
  286.             continue;
  287.         }
  288.         else if (!(m_nFlags & wxDIR_DIRS) && IsDir(vAttr) )
  289.         {
  290.             //
  291.             // It's a dir, and we don't want it
  292.             //
  293.             continue;
  294.         }
  295.  
  296.         //
  297.         // Finally, check whether it's a hidden file
  298.         //
  299.         if (!(m_nFlags & wxDIR_HIDDEN))
  300.         {
  301.             if (IsHidden(vAttr))
  302.             {
  303.                 //
  304.                 // It's a hidden file, skip it
  305.                 //
  306.                 continue;
  307.             }
  308.         }
  309.         *psFilename = zName;
  310.         break;
  311.     }
  312.     return TRUE;
  313. } // end of wxDirData::Read
  314.  
  315. // ----------------------------------------------------------------------------
  316. // wxDir helpers
  317. // ----------------------------------------------------------------------------
  318.  
  319. /* static */
  320. bool wxDir::Exists(
  321.   const wxString&                   rsDir
  322. )
  323. {
  324.     return wxPathExists(rsDir);
  325. } // end of wxDir::Exists
  326.  
  327. // ----------------------------------------------------------------------------
  328. // wxDir construction/destruction
  329. // ----------------------------------------------------------------------------
  330.  
  331. wxDir::wxDir(
  332.   const wxString&                   rsDirname
  333. )
  334. {
  335.     m_data = NULL;
  336.  
  337.     (void)Open(rsDirname);
  338. } // end of wxDir::wxDir
  339.  
  340. bool wxDir::Open(
  341.   const wxString&                   rsDirname
  342. )
  343. {
  344.     delete M_DIR;
  345.     m_data = new wxDirData(rsDirname);
  346.     return TRUE;
  347. } // end of wxDir::Open
  348.  
  349. bool wxDir::IsOpened() const
  350. {
  351.     return m_data != NULL;
  352. } // end of wxDir::IsOpen
  353.  
  354. wxString wxDir::GetName() const
  355. {
  356.     wxString name;
  357.     if ( m_data )
  358.     {
  359.         name = M_DIR->GetName();
  360.         if ( !name.empty() )
  361.         {
  362.             // bring to canonical Windows form
  363.             name.Replace(_T("/"), _T("\\"));
  364.  
  365.             if ( name.Last() == _T('\\') )
  366.             {
  367.                 // chop off the last (back)slash
  368.                 name.Truncate(name.length() - 1);
  369.             }
  370.         }
  371.     }
  372.  
  373.     return name;
  374. }
  375.  
  376. wxDir::~wxDir()
  377. {
  378.     delete M_DIR;
  379. } // end of wxDir::~wxDir
  380.  
  381. // ----------------------------------------------------------------------------
  382. // wxDir enumerating
  383. // ----------------------------------------------------------------------------
  384.  
  385. bool wxDir::GetFirst(
  386.   wxString*                         psFilename
  387. , const wxString&                   rsFilespec
  388. , int                               nFlags
  389. ) const
  390. {
  391.     wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
  392.     M_DIR->Rewind();
  393.     M_DIR->SetFileSpec(rsFilespec);
  394.     M_DIR->SetFlags(nFlags);
  395.     return GetNext(psFilename);
  396. } // end of wxDir::GetFirst
  397.  
  398. bool wxDir::GetNext(
  399.   wxString*                         psFilename
  400. ) const
  401. {
  402.     wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
  403.     wxCHECK_MSG( psFilename, FALSE, _T("bad pointer in wxDir::GetNext()") );
  404.     return M_DIR->Read(psFilename);
  405. } // end of wxDir::GetNext
  406.  
  407.