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