Remove identic implementations of wxDir::Exists from platform-specific files and...
[wxWidgets.git] / src / palmos / dir.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/palmos/dir.cpp
3 // Purpose: wxDir implementation for PalmOS
4 // Author: William Osborne - minimal working wxPalmOS port
5 // Modified by:
6 // Created: 10.13.04
7 // RCS-ID: $Id$
8 // Copyright: (c) William Osborne
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 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #ifndef WX_PRECOMP
28 #include "wx/intl.h"
29 #include "wx/log.h"
30 #endif // PCH
31
32 #include "wx/dir.h"
33
34 #include "pfall.h"
35
36 // ----------------------------------------------------------------------------
37 // define the types and functions used for file searching
38 // ----------------------------------------------------------------------------
39
40 // ----------------------------------------------------------------------------
41 // constants
42 // ----------------------------------------------------------------------------
43
44 #ifndef MAX_PATH
45 #define MAX_PATH 260 // from VC++ headers
46 #endif
47
48 // ----------------------------------------------------------------------------
49 // macros
50 // ----------------------------------------------------------------------------
51
52 #define M_DIR ((wxDirData *)m_data)
53
54 // ----------------------------------------------------------------------------
55 // private classes
56 // ----------------------------------------------------------------------------
57
58 // this class stores everything we need to enumerate the files
59 class wxDirData
60 {
61 public:
62 wxDirData(const wxString& dirname);
63 ~wxDirData();
64
65 bool IsOk() const { return m_dir != NULL; }
66
67 void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
68 void SetFlags(int flags) { m_flags = flags; }
69
70 void Close();
71 bool Read(wxString *filename);
72
73 const wxString& GetName() const { return m_dirname; }
74
75 private:
76 void *m_dir;
77
78 wxString m_dirname;
79 wxString m_filespec;
80
81 int m_flags;
82 };
83
84 // ============================================================================
85 // implementation
86 // ============================================================================
87
88 // ----------------------------------------------------------------------------
89 // wxDirData
90 // ----------------------------------------------------------------------------
91
92 wxDirData::wxDirData(const wxString& dirname)
93 : m_dirname(dirname)
94 {
95 m_dir = NULL;
96
97 // throw away the trailing slashes
98 size_t n = m_dirname.length();
99 wxCHECK_RET( n, wxT("empty dir name in wxDir") );
100
101 while ( n > 0 && m_dirname[--n] == '/' )
102 ;
103
104 m_dirname.Truncate(n + 1);
105
106 // do open the dir
107 //m_dir = opendir(m_dirname.fn_str());
108 }
109
110 wxDirData::~wxDirData()
111 {
112 Close ();
113 }
114
115 void wxDirData::Close()
116 {
117 if ( m_dir )
118 {
119 if ( svfs_dir_endfind (m_dir) != 0 )
120 {
121 wxLogLastError(wxT("svfs_dir_endfind"));
122 }
123 m_dir = NULL;
124 }
125 }
126
127 bool wxDirData::Read(wxString *filename)
128 {
129 //dirent *de = NULL; // just to silence compiler warnings
130 int ret;
131 char tmpbuf[300];
132 bool matches = false;
133 size_t flags_search;
134
135 // speed up string concatenation in the loop a bit
136 wxString path = m_dirname;
137 path += wxT('/');
138 path.reserve(path.length() + 255);
139
140 wxString de_d_name;
141 de_d_name.reserve(500);
142 flags_search = 0;
143 if (wxDIR_DIRS & m_flags) {
144 flags_search |= SDIR_DIRS;
145 }
146 if (wxDIR_FILES & m_flags) {
147 flags_search |= SDIR_FILES;
148 }
149 if (NULL == m_dir) {
150 #ifdef _PACC_VER
151 // walk around the PalmOS pacc compiler bug
152 ret = svfs_dir_findfirst (m_dirname.fn_str().data(), &m_dir, tmpbuf, sizeof (tmpbuf), flags_search);
153 #else
154 ret = svfs_dir_findfirst (m_dirname.fn_str(), &m_dir, tmpbuf, sizeof (tmpbuf), flags_search);
155 #endif
156 } else {
157 ret = svfs_dir_findnext (m_dir, tmpbuf, sizeof (tmpbuf));
158 }
159 for (; ret > 0; ) {
160
161 #if wxUSE_UNICODE
162 de_d_name = wxString(tmpbuf, *wxConvFileName);
163 #else
164 de_d_name = tmpbuf;
165 #endif
166
167 // don't return "." and ".." unless asked for
168 if ( tmpbuf[0] == '.' &&
169 ((tmpbuf[1] == '.' && tmpbuf[2] == '\0') ||
170 (tmpbuf[1] == '\0')) )
171 {
172 if ( !(m_flags & wxDIR_DOTDOT) )
173 continue;
174
175 // we found a valid match
176 break;
177 }
178
179 // check the name
180 if ( m_filespec.empty() )
181 {
182 matches = m_flags & wxDIR_HIDDEN ? true : tmpbuf[0] != '.';
183 }
184 else
185 {
186 // test against the pattern
187 matches = wxMatchWild(m_filespec, de_d_name,
188 !(m_flags & wxDIR_HIDDEN));
189 }
190 if (matches)
191 break;
192 ret = svfs_dir_findnext (m_dir, tmpbuf, sizeof (tmpbuf));
193 }
194
195 *filename = de_d_name;
196
197 return true;
198 }
199
200 // ----------------------------------------------------------------------------
201 // wxDir construction/destruction
202 // ----------------------------------------------------------------------------
203
204 wxDir::wxDir(const wxString& dirname)
205 {
206 m_data = NULL;
207 (void)Open(dirname);
208 }
209
210 bool wxDir::Open(const wxString& dirname)
211 {
212 delete M_DIR;
213 m_data = new wxDirData(dirname);
214
215 return true;
216 }
217
218 bool wxDir::IsOpened() const
219 {
220 return m_data != NULL;
221 }
222
223 wxString wxDir::GetName() const
224 {
225 wxString name;
226 if ( m_data )
227 {
228 name = M_DIR->GetName();
229 if ( !name.empty() && (name.Last() == wxT('/')) )
230 {
231 // chop off the last (back)slash
232 name.Truncate(name.length() - 1);
233 }
234 }
235
236 return name;
237 }
238
239 wxDir::~wxDir()
240 {
241 delete M_DIR;
242 }
243
244 // ----------------------------------------------------------------------------
245 // wxDir enumerating
246 // ----------------------------------------------------------------------------
247
248 bool wxDir::GetFirst(wxString *filename,
249 const wxString& filespec,
250 int flags) const
251 {
252 wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
253 M_DIR->Close();
254 M_DIR->SetFileSpec(filespec);
255 M_DIR->SetFlags(flags);
256 return GetNext(filename);
257 }
258
259 bool wxDir::GetNext(wxString *filename) const
260 {
261 wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
262 wxCHECK_MSG( filename, false, wxT("bad pointer in wxDir::GetNext()") );
263 return M_DIR->Read(filename);
264 }
265