0027350: Support for Universal Windows Platform
[occt.git] / src / OSD / OSD_FileIterator.cxx
CommitLineData
b311480e 1// Copyright (c) 1998-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
57c28b61 15#ifndef _WIN32
7fd59977 16
42cf5bc1 17
18#include <OSD_File.hxx>
19#include <OSD_FileIterator.hxx>
20#include <OSD_OSDError.hxx>
21#include <OSD_Path.hxx>
7fd59977 22#include <OSD_WhoAmI.hxx>
42cf5bc1 23#include <TCollection_AsciiString.hxx>
7fd59977 24
42cf5bc1 25#include <dirent.h>
7fd59977 26#include <stdio.h>
7fd59977 27#include <sys/stat.h>
42cf5bc1 28#include <sys/types.h>
7fd59977 29# define NAMLEN(dirent) strlen((dirent)->d_name)
30# ifdef VMS
31extern char *vmsify PARAMS ((char *name, int type));
32# endif
7fd59977 33
34/* In GNU systems, <dirent.h> defines this macro for us. */
35#ifdef _D_NAMLEN
36# undef NAMLEN
37# define NAMLEN(d) _D_NAMLEN(d)
38#endif
39
40#if (defined (POSIX) || defined (VMS) || defined (WINDOWS32)) && !defined (__GNU_LIBRARY__)
41/* Posix does not require that the d_ino field be present, and some
42 systems do not provide it. */
43# define REAL_DIR_ENTRY(dp) 1
44# define FAKE_DIR_ENTRY(dp)
45#else
46# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
47# define FAKE_DIR_ENTRY(dp) (dp->d_ino = 1)
48#endif /* POSIX */
49
50//const OSD_WhoAmI Iam = OSD_WFileIterator;
51
52
d48df25d 53OSD_FileIterator::OSD_FileIterator()
54: myFlag(0),
55 myDescr(0),
56 myEntry(0),
57 myInit(0)
58{
7fd59977 59}
60
61OSD_FileIterator::OSD_FileIterator(const OSD_Path& where,
d48df25d 62 const TCollection_AsciiString& Mask)
63: myFlag(0),
64 myDescr(0),
65 myEntry(0),
66 myInit(0)
67{
7fd59977 68 Initialize(where, Mask) ;
69}
70
71// For Windows NT compatibility
72void OSD_FileIterator :: Destroy () {}
73
74void OSD_FileIterator::Initialize(const OSD_Path& where,
75 const TCollection_AsciiString& Mask){
76 myFlag = Standard_False;
77 where.SystemName(myPlace);
78 if (myPlace.Length()==0) myPlace = ".";
79 myMask = Mask;
80 if (myDescr) {
81 closedir((DIR *)myDescr) ;
82 myDescr = NULL ;
83 }
84 myInit = 1 ;
85}
86
87// Is there another file entry ?
88
89Standard_Boolean OSD_FileIterator::More(){
90 if (myInit) {
91 myInit = 0 ;
92 myDescr = (Standard_Address) opendir(myPlace.ToCString());
93 if (myDescr) { // LD : Si repertoire inaccessible retourner False
94 myFlag = Standard_True;
95 myInit = 0 ;
96 Next(); // Now find first entry
97 }
98 }
99 return (myFlag);
100}
101
102// Private : See if file name matches with a mask (like "*.c")
103
104static int strcmp_joker(const char *Mask,const char *Name)
105{
106 const char *p, *s ;
107
108 for(p = Mask,s = Name ; *p && *p != '*' ; p++,s++)
109 if (*p != *s) return 0 ;
110
111 if (!*p) return !(*s) ;
112 while (*p == '*') p++ ;
113 if (!*p) return 1 ;
114 for (;*s; s++)
115 if (strcmp_joker(p,s)) return 1 ;
116 return 0 ;
117}
118
119#if 0
120 // LD : ancienne version.
121
122#define TRUE 1
123#define FALSE 0
124#define NO_MASK '*'
125
126static int strcmp_joker(char *fileMask,char *fileName)
127{
128 char *sauve_fileMask,*sauve_fileName;
129 int compare_result;
130 int beginning = 1; // 0 if first character is a joker, otherwise 1
131
132 while (*fileName) { // Test end of AsciiString
133
134 if (*fileMask == NO_MASK) {
135 beginning = 0;
136
137 while(*fileMask == NO_MASK) fileMask++;
138
139 if (*fileMask) {
140 while(*fileName &&
141 *fileName != *fileMask)
142 fileName++;
143
144 sauve_fileMask = fileMask; // Save strings
145 sauve_fileName = fileName;
146 }
147 else return(0); // fileMask ends with a joker
148
149 }
150 else { // Compare two characters
151 compare_result = *fileMask++ - *fileName++;
152
153 if (compare_result != 0)
154 if (beginning)
155 return (compare_result); /* 1ere chaine pas de joker au debut */
156 else { // Look ahead for same string
157 fileMask = sauve_fileMask;
158 fileName = ++sauve_fileName;
159 while(*fileName &&
160 *fileName != *fileMask)
161 fileName++;
162 sauve_fileName = fileName;
163 }
164
165 }
166
167 }
168
169 while(*fileMask == NO_MASK) fileMask++;
170 return(*fileMask - *fileName);
171}
172#endif
173
174// Find next file entry in current directory
175
176void OSD_FileIterator::Next(){
177int again = 1;
178struct stat stat_buf;
179char full_name[255];
180
181 myFlag = 0; // Initialize to nothing found
182
183 do {
184 myEntry = readdir((DIR *)myDescr);
185
186 if (!myEntry){ // No file found
187 myEntry = NULL; // Keep pointer clean
188 myFlag = Standard_False; // No more files/directory
189 closedir((DIR *)myDescr) ; // so close directory
190 myDescr = NULL;
191 again = 0;
192 }
193 else {
194 if (!strcmp(((struct dirent *)myEntry)->d_name,".")) continue;
195 if (!strcmp(((struct dirent *)myEntry)->d_name,"..")) continue;
196
197 // Is it a file ?
198
199 sprintf(full_name,"%s/%s",myPlace.ToCString(),
200 ((struct dirent *)myEntry)->d_name); // LD debug
0797d9d3 201#ifdef OCCT_DEBUG
7fd59977 202 cout << "Place : " << myPlace << endl;
203 cout << "FName : " << full_name << endl;
204#endif
205 stat(full_name, &stat_buf);
206 if (S_ISREG(stat_buf.st_mode)) // LD : Ensure me it's a regular file
207 if (strcmp_joker(myMask.ToCString(), ((struct dirent *)myEntry)->d_name)){
208 // Does it follow mask ?
209 myFlag = Standard_True;
210 again = 0;
211 }
212 }
213
214 } while (again);
215
216}
217
218// Get Name of selected file
219
220OSD_File OSD_FileIterator::Values(){
221OSD_Path thisvalue;
222TCollection_AsciiString Name;
223TCollection_AsciiString Ext;
224Standard_Integer position;
225
226 if (myEntry) Name = ((struct dirent *)myEntry)->d_name ;
227
228 position = Name.Search(".");
229
230 if (position != -1){
231 Ext = Name;
232 Ext.Remove(1,position-1);
233 Name.Remove( position,Ext.Length());
234 }
235
236 thisvalue.SetValues("", "", "", "", "", Name,Ext);
237 TheIterator.SetPath (thisvalue);
238
239 return (TheIterator);
240}
241
242
243void OSD_FileIterator::Reset(){
244 myError.Reset();
245}
246
247Standard_Boolean OSD_FileIterator::Failed()const{
248 return( myError.Failed());
249}
250
251void OSD_FileIterator::Perror() {
252 myError.Perror();
253}
254
255
256Standard_Integer OSD_FileIterator::Error()const{
257 return( myError.Error());
258}
259
260#else
261
262//------------------------------------------------------------------------
263//------------------- Windows NT sources for OSD_FileIterator -----------
264//------------------------------------------------------------------------
265
266#define STRICT
267#include <windows.h>
268
42cf5bc1 269
270#include <OSD_File.hxx>
271#include <OSD_FileIterator.hxx>
272#include <OSD_OSDError.hxx>
273#include <OSD_Path.hxx>
274#include <TCollection_AsciiString.hxx>
d9ff84e8 275#include <TCollection_ExtendedString.hxx>
7fd59977 276
d9ff84e8 277#define _FD ( ( PWIN32_FIND_DATAW )myData )
7fd59977 278
279void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
280
281OSD_FileIterator :: OSD_FileIterator (
282 const OSD_Path& where,
283 const TCollection_AsciiString& Mask
284 ) {
285
286 myFlag = Standard_False;
7dc9e047 287 myHandle = INVALID_HANDLE_VALUE;
7fd59977 288
289 where.SystemName ( myPlace );
290
d9ff84e8 291 if ( myPlace.Length () == 0 ) myPlace = ".";
7fd59977 292
293 myMask = Mask;
294 myData = NULL;
295
296} // end constructor
297
298void OSD_FileIterator :: Destroy () {
299
300 if ( myData != NULL ) HeapFree ( GetProcessHeap (), 0, myData );
301
7dc9e047 302 if ( myHandle != INVALID_HANDLE_VALUE )
7fd59977 303
304 FindClose ( ( HANDLE )myHandle );
305
306} // end OSD_DirectoryIterator :: Destroy
307
308Standard_Boolean OSD_FileIterator :: More () {
309
7dc9e047 310 if ( myHandle == INVALID_HANDLE_VALUE ) {
7fd59977 311
d9ff84e8 312 TCollection_AsciiString wc = myPlace + "/" + myMask;
7fd59977 313
314 myData = HeapAlloc (
d9ff84e8 315 GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS, sizeof ( WIN32_FIND_DATAW )
7fd59977 316 );
317
d9ff84e8 318 // make wchar_t string from UTF-8
319 TCollection_ExtendedString wcW(wc);
742cc8b0 320 myHandle = FindFirstFileExW((const wchar_t*)wcW.ToExtString(), FindExInfoStandard, (PWIN32_FIND_DATAW)myData, FindExSearchNameMatch, NULL, 0);
7fd59977 321
7dc9e047 322 if ( myHandle == INVALID_HANDLE_VALUE )
7fd59977 323
324 _osd_wnt_set_error ( myError, OSD_WDirectoryIterator );
325
326 else {
327
328 myFlag = Standard_True;
329 myFirstCall = Standard_True;
330
331 Next ();
332
333 } // end else
334
335 } else if ( !myFlag ) {
336
337 FindClose ( ( HANDLE )myHandle );
7dc9e047 338 myHandle = INVALID_HANDLE_VALUE;
7fd59977 339
340 } // end if
341
342 return myFlag;
343
344} // end OSD_FileIterator :: More
345
346void OSD_FileIterator :: Next () {
347
7c65581d 348 if ( ! myFirstCall || ( _FD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) {
7fd59977 349
350 do {
351
d9ff84e8 352 if ( !FindNextFileW ( ( HANDLE )myHandle, _FD ) ) {
7fd59977 353
354 myFlag = Standard_False;
355
356 break;
357
358 } // end if
359
360 } while ( ( _FD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) );
361
362 } // end if
363
364 myFirstCall = Standard_False;
365
366} // end OSD_FileIterator :: Next
367
368OSD_File OSD_FileIterator :: Values () {
369
d9ff84e8 370 // make UTF-8 string
371 TCollection_AsciiString aFileName
372 (TCollection_ExtendedString( (Standard_ExtString) _FD -> cFileName) );
373 TheIterator.SetPath ( OSD_Path ( aFileName ) );
7fd59977 374
375 return TheIterator;
376
377} // end OSD_FileIterator :: Values
378
379Standard_Boolean OSD_FileIterator :: Failed () const {
380
381 return myError.Failed ();
382
383} // end OSD_FileIterator :: Failed
384
385void OSD_FileIterator :: Reset () {
386
387 myError.Reset ();
388
389} // end OSD_FileIterator :: Reset
390
391void OSD_FileIterator :: Perror () {
392
393 myError.Perror ();
394
395} // end OSD_FileIterator :: Perror
396
397Standard_Integer OSD_FileIterator :: Error () const {
398
399 return myError.Error ();
400
401} // end OSD_FileIterator :: Error
402
403// For compatibility with UNIX version
404OSD_FileIterator::OSD_FileIterator() {}
405
406void OSD_FileIterator::Initialize(
35e08fe8 407 const OSD_Path&,
408 const TCollection_AsciiString&){}
7fd59977 409
410#endif