]> git.saurik.com Git - wxWidgets.git/blob - src/common/dircmn.cpp
fixed hash collisions in ZIP files (patch 1082026)
[wxWidgets.git] / src / common / dircmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/dircmn.cpp
3 // Purpose: wxDir methods common to all implementations
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 19.05.01
7 // RCS-ID: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 /* this is done in platform-specific files
21 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
22 #pragma implementation "dir.h"
23 #endif
24 */
25
26 // For compilers that support precompilation, includes "wx.h".
27 #include "wx/wxprec.h"
28
29 #ifdef __BORLANDC__
30 #pragma hdrstop
31 #endif
32
33 #ifndef WX_PRECOMP
34 #include "wx/string.h"
35 #include "wx/log.h"
36 #include "wx/intl.h"
37 #include "wx/filefn.h"
38 #endif //WX_PRECOMP
39
40 #include "wx/arrstr.h"
41 #include "wx/dir.h"
42
43 // ============================================================================
44 // implementation
45 // ============================================================================
46
47 // ----------------------------------------------------------------------------
48 // wxDirTraverser
49 // ----------------------------------------------------------------------------
50
51 wxDirTraverseResult
52 wxDirTraverser::OnOpenError(const wxString& WXUNUSED(dirname))
53 {
54 return wxDIR_IGNORE;
55 }
56
57 // ----------------------------------------------------------------------------
58 // wxDir::HasFiles() and HasSubDirs()
59 // ----------------------------------------------------------------------------
60
61 // dumb generic implementation
62
63 bool wxDir::HasFiles(const wxString& spec)
64 {
65 wxString s;
66 return GetFirst(&s, spec, wxDIR_FILES | wxDIR_HIDDEN);
67 }
68
69 // we have a (much) faster version for Unix
70 #if (defined(__CYGWIN__) && defined(__WINDOWS__)) || !defined(__UNIX_LIKE__) || defined(__WXMAC__) || defined(__EMX__)
71
72 bool wxDir::HasSubDirs(const wxString& spec)
73 {
74 wxString s;
75 return GetFirst(&s, spec, wxDIR_DIRS | wxDIR_HIDDEN);
76 }
77
78 #endif // !Unix
79
80 // ----------------------------------------------------------------------------
81 // wxDir::Traverse()
82 // ----------------------------------------------------------------------------
83
84 size_t wxDir::Traverse(wxDirTraverser& sink,
85 const wxString& filespec,
86 int flags) const
87 {
88 wxCHECK_MSG( IsOpened(), (size_t)-1,
89 _T("dir must be opened before traversing it") );
90
91 // the total number of files found
92 size_t nFiles = 0;
93
94 // the name of this dir with path delimiter at the end
95 wxString prefix = GetName();
96 prefix += wxFILE_SEP_PATH;
97
98 // first, recurse into subdirs
99 if ( flags & wxDIR_DIRS )
100 {
101 wxString dirname;
102 for ( bool cont = GetFirst(&dirname, wxEmptyString, wxDIR_DIRS | (flags & wxDIR_HIDDEN) );
103 cont;
104 cont = cont && GetNext(&dirname) )
105 {
106 const wxString fulldirname = prefix + dirname;
107
108 switch ( sink.OnDir(fulldirname) )
109 {
110 default:
111 wxFAIL_MSG(_T("unexpected OnDir() return value") );
112 // fall through
113
114 case wxDIR_STOP:
115 cont = false;
116 break;
117
118 case wxDIR_CONTINUE:
119 {
120 wxDir subdir;
121
122 // don't give the error messages for the directories
123 // which we can't open: there can be all sorts of good
124 // reason for this (e.g. insufficient privileges) and
125 // this shouldn't be treated as an error -- instead
126 // let the user code decide what to do
127 bool ok;
128 do
129 {
130 wxLogNull noLog;
131 ok = subdir.Open(fulldirname);
132 if ( !ok )
133 {
134 // ask the user code what to do
135 bool tryagain;
136 switch ( sink.OnOpenError(fulldirname) )
137 {
138 default:
139 wxFAIL_MSG(_T("unexpected OnOpenError() return value") );
140 // fall through
141
142 case wxDIR_STOP:
143 cont = false;
144 // fall through
145
146 case wxDIR_IGNORE:
147 tryagain = false;
148 break;
149
150 case wxDIR_CONTINUE:
151 tryagain = true;
152 }
153
154 if ( !tryagain )
155 break;
156 }
157 }
158 while ( !ok );
159
160 if ( ok )
161 {
162 nFiles += subdir.Traverse(sink, filespec, flags);
163 }
164 }
165 break;
166
167 case wxDIR_IGNORE:
168 // nothing to do
169 ;
170 }
171 }
172 }
173
174 // now enum our own files
175 if ( flags & wxDIR_FILES )
176 {
177 flags &= ~wxDIR_DIRS;
178
179 wxString filename;
180 bool cont = GetFirst(&filename, filespec, flags);
181 while ( cont )
182 {
183 wxDirTraverseResult res = sink.OnFile(prefix + filename);
184 if ( res == wxDIR_STOP )
185 break;
186
187 wxASSERT_MSG( res == wxDIR_CONTINUE,
188 _T("unexpected OnFile() return value") );
189
190 nFiles++;
191
192 cont = GetNext(&filename);
193 }
194 }
195
196 return nFiles;
197 }
198
199 // ----------------------------------------------------------------------------
200 // wxDir::GetAllFiles()
201 // ----------------------------------------------------------------------------
202
203 class wxDirTraverserSimple : public wxDirTraverser
204 {
205 public:
206 wxDirTraverserSimple(wxArrayString& files) : m_files(files) { }
207
208 virtual wxDirTraverseResult OnFile(const wxString& filename)
209 {
210 m_files.push_back(filename);
211 return wxDIR_CONTINUE;
212 }
213
214 virtual wxDirTraverseResult OnDir(const wxString& WXUNUSED(dirname))
215 {
216 return wxDIR_CONTINUE;
217 }
218
219 private:
220 wxArrayString& m_files;
221
222 DECLARE_NO_COPY_CLASS(wxDirTraverserSimple)
223 };
224
225 /* static */
226 size_t wxDir::GetAllFiles(const wxString& dirname,
227 wxArrayString *files,
228 const wxString& filespec,
229 int flags)
230 {
231 wxCHECK_MSG( files, (size_t)-1, _T("NULL pointer in wxDir::GetAllFiles") );
232
233 size_t nFiles = 0;
234
235 wxDir dir(dirname);
236 if ( dir.IsOpened() )
237 {
238 wxDirTraverserSimple traverser(*files);
239
240 nFiles += dir.Traverse(traverser, filespec, flags);
241 }
242
243 return nFiles;
244 }
245