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