0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[occt.git] / src / OSD / OSD_FileIterator.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _WIN32
16
17
18 #include <OSD_File.hxx>
19 #include <OSD_FileIterator.hxx>
20 #include <OSD_OSDError.hxx>
21 #include <OSD_Path.hxx>
22 #include <OSD_WhoAmI.hxx>
23 #include <TCollection_AsciiString.hxx>
24
25 #include <dirent.h>
26 #include <stdio.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 # define NAMLEN(dirent) strlen((dirent)->d_name)
30 # ifdef VMS
31 extern char *vmsify PARAMS ((char *name, int type));
32 # endif
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
53 OSD_FileIterator::OSD_FileIterator()
54 : myFlag(false),
55   myDescr(0),
56   myEntry(0),
57   myInit(0)
58 {
59 }
60
61 OSD_FileIterator::OSD_FileIterator(const OSD_Path& where,
62                                    const TCollection_AsciiString& Mask)
63 : myFlag(false),
64   myDescr(0),
65   myEntry(0),
66   myInit(0)
67 {
68  Initialize(where, Mask) ;
69 }
70
71 // For Windows NT compatibility
72 void OSD_FileIterator :: Destroy () {}
73
74 void 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
89 Standard_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
104 static 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
126 static 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
176 void OSD_FileIterator::Next(){
177 int again = 1;
178 struct stat stat_buf;
179 char full_name[255];
180
181  myFlag = false;   // 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
201 #ifdef OCCT_DEBUG
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
220 OSD_File OSD_FileIterator::Values(){
221 OSD_Path thisvalue;
222 TCollection_AsciiString Name;
223 TCollection_AsciiString Ext;
224 Standard_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
243 void OSD_FileIterator::Reset(){
244  myError.Reset();
245 }
246
247 Standard_Boolean OSD_FileIterator::Failed()const{
248  return( myError.Failed());
249 }
250
251 void OSD_FileIterator::Perror() {
252  myError.Perror();
253 }
254
255
256 Standard_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
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>
275 #include <TCollection_ExtendedString.hxx>
276
277 #define _FD (  ( PWIN32_FIND_DATAW )myData  )
278
279 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
280
281 OSD_FileIterator :: OSD_FileIterator (
282                      const OSD_Path&                where,
283                      const TCollection_AsciiString& Mask
284                     ) {
285
286  myFlag   = Standard_False;
287  myHandle = INVALID_HANDLE_VALUE;
288
289  where.SystemName ( myPlace );
290
291  if (  myPlace.Length () == 0  ) myPlace = ".";
292
293  myMask = Mask;
294  myData = NULL;
295
296 }  // end constructor
297
298 void OSD_FileIterator :: Destroy () {
299
300  if ( myData != NULL ) HeapFree (  GetProcessHeap (), 0, myData  );
301
302  if (  myHandle != INVALID_HANDLE_VALUE  )
303
304   FindClose (  ( HANDLE )myHandle  );
305
306 }  // end  OSD_DirectoryIterator :: Destroy
307
308 Standard_Boolean OSD_FileIterator :: More () {
309
310  if (  myHandle == INVALID_HANDLE_VALUE  ) {
311  
312   TCollection_AsciiString wc = myPlace + "/" + myMask;
313
314   myData = HeapAlloc (
315             GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS, sizeof ( WIN32_FIND_DATAW )
316            );
317
318   // make wchar_t string from UTF-8
319   TCollection_ExtendedString wcW(wc);
320   myHandle = FindFirstFileExW((const wchar_t*)wcW.ToExtString(), FindExInfoStandard, (PWIN32_FIND_DATAW)myData, FindExSearchNameMatch, NULL, 0);
321
322   if (  myHandle == INVALID_HANDLE_VALUE  )
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  );
338   myHandle = INVALID_HANDLE_VALUE;
339  
340  }  // end if
341
342  return myFlag;
343
344 }  // end OSD_FileIterator :: More
345
346 void OSD_FileIterator :: Next () {
347
348  if ( ! myFirstCall || ( _FD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) {
349  
350   do {
351   
352    if (   !FindNextFileW (  ( HANDLE )myHandle, _FD  )   ) {
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
368 OSD_File OSD_FileIterator :: Values () {
369
370  // make UTF-8 string
371  TCollection_AsciiString aFileName
372    (TCollection_ExtendedString( (Standard_ExtString) _FD -> cFileName) );
373  TheIterator.SetPath (   OSD_Path ( aFileName  )   );
374
375  return TheIterator;
376
377 }  // end OSD_FileIterator :: Values
378
379 Standard_Boolean OSD_FileIterator :: Failed () const {
380
381  return myError.Failed ();
382
383 }  // end OSD_FileIterator :: Failed
384
385 void OSD_FileIterator :: Reset () {
386
387  myError.Reset ();
388
389 }  // end OSD_FileIterator :: Reset
390
391 void OSD_FileIterator :: Perror () {
392
393  myError.Perror ();
394
395 }  // end OSD_FileIterator :: Perror
396
397 Standard_Integer OSD_FileIterator :: Error () const {
398
399  return myError.Error ();
400
401 }  // end  OSD_FileIterator :: Error
402
403 // For compatibility with UNIX version
404 OSD_FileIterator::OSD_FileIterator() {}
405
406 void OSD_FileIterator::Initialize(
407                        const OSD_Path&,
408                        const TCollection_AsciiString&){}
409  
410 #endif