0027838: Foundation Classes - support wchar_t* input within TCollection_AsciiString...
[occt.git] / src / OSD / OSD_DirectoryIterator.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_Directory.hxx>
19 #include <OSD_DirectoryIterator.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
29 OSD_DirectoryIterator::OSD_DirectoryIterator() 
30 : myFlag(false),
31   myDescr(0),
32   myEntry(0),
33   myInit(0)
34 {
35 }
36
37 OSD_DirectoryIterator::OSD_DirectoryIterator(const OSD_Path& where,
38                                              const TCollection_AsciiString& Mask)
39 : myFlag(false),
40   myDescr(0),
41   myEntry(0),
42   myInit(0)
43 {
44  Initialize(where, Mask) ;
45 }
46
47 // For Windows NT compatibility -----------
48 void OSD_DirectoryIterator :: Destroy () {}
49 //-----------------------------------------
50
51 void OSD_DirectoryIterator::Initialize(const OSD_Path& where,
52                                    const TCollection_AsciiString& Mask){
53
54  myFlag = Standard_False;
55  where.SystemName(myPlace);
56  if (myPlace.Length()==0) myPlace = ".";
57  myMask = Mask;
58  if (myDescr) {
59    closedir((DIR *)myDescr) ;
60    myDescr = NULL ;
61  }
62  myInit = 1 ;
63 }
64
65 // Is there another directory entry ?
66
67 Standard_Boolean OSD_DirectoryIterator::More(){
68  if (myInit) {
69    myInit = 0 ;
70    myDescr = (Standard_Address) opendir(myPlace.ToCString()); 
71    if (myDescr) {            // LD : Si repertoire inaccessible retourner False
72      myFlag = Standard_True;
73      myInit = 0 ;
74      Next();          // Now find first entry
75    }
76  }
77  return myFlag;
78 }
79
80 // Private :  See if directory name matches with a mask (like "*.c")
81 // LD : reecrit (original dans OSD_FileIterator.cxx)
82
83
84 static int strcmp_joker(const char *Mask,const char *Name)
85 {
86   const char *p, *s ;
87
88   for(p = Mask,s = Name ; *p && *p != '*' ; p++,s++)
89     if (*p != *s) return 0 ;
90   if (!*p) return !(*s) ;
91   while (*p == '*') p++ ;
92   if (!*p) return 1 ;
93   for (;*s; s++)
94     if (strcmp_joker(p,s)) return 1 ;
95   return 0 ;
96 }
97
98 // Find next directory entry in current directory
99
100 void OSD_DirectoryIterator::Next(){
101 int again = 1;
102 struct stat stat_buf;
103 char full_name[255];
104
105  myFlag = false;   // Initialize to nothing found
106
107  do{
108     myEntry = readdir((DIR *)myDescr);
109    
110     if (!myEntry){   // No file found
111      myEntry = NULL;              // Keep pointer clean
112      myFlag = Standard_False;   // No more files/directory
113      closedir((DIR *)myDescr) ;       // so close directory
114      myDescr = NULL;
115      again = 0;
116     }
117     else {
118 //     if (!strcmp(entry->d_name,".")) continue;     LD : on prend ces 
119 //     if (!strcmp(entry->d_name,"..")) continue;         2 directories.
120
121      // Is it a directory ?
122
123      sprintf(full_name,"%s/%s",myPlace.ToCString(),
124              ((struct dirent *)myEntry)->d_name);                // LD debug
125      stat(full_name, &stat_buf);
126      if (S_ISDIR(stat_buf.st_mode))   // Ensure me it's not a file
127       if (strcmp_joker(myMask.ToCString(), ((struct dirent *)myEntry)->d_name)){
128                                                          // Does it follow mask ?
129        myFlag = Standard_True;
130        again = 0;
131      }
132     }
133
134  } while (again);
135
136 }
137
138
139 // Get Name of selected directory
140
141 OSD_Directory OSD_DirectoryIterator::Values(){
142 OSD_Path thisvalue;
143 TCollection_AsciiString Name;
144 TCollection_AsciiString Ext;
145 Standard_Integer position;
146
147  if (myEntry) Name = ((struct dirent *)myEntry)->d_name ;
148
149  position = Name.Search(".");
150
151  if (position != -1){
152   Ext = Name.Split(position - 1) ;   // Debug LD
153 //  Ext.Remove(1,position);
154 //  Name.Remove( position,Ext.Length()+1);
155  }
156
157  thisvalue.SetValues("", "", "", "", "", Name,Ext);
158  TheIterator.SetPath (thisvalue);
159
160  return (TheIterator);
161 }
162
163
164 void OSD_DirectoryIterator::Reset(){
165  myError.Reset();
166 }
167
168 Standard_Boolean OSD_DirectoryIterator::Failed()const{
169  return( myError.Failed());
170 }
171
172 void OSD_DirectoryIterator::Perror() {
173  myError.Perror();
174 }
175
176
177 Standard_Integer OSD_DirectoryIterator::Error()const{
178  return( myError.Error());
179 }
180
181 #else
182
183 //------------------------------------------------------------------------
184 //-------------------  Windows NT sources for OSD_DirectoryIterator ------
185 //------------------------------------------------------------------------
186
187
188 #define STRICT
189 #include <windows.h>
190
191
192 #include <OSD_Directory.hxx>
193 #include <OSD_DirectoryIterator.hxx>
194 #include <OSD_OSDError.hxx>
195 #include <OSD_Path.hxx>
196 #include <TCollection_AsciiString.hxx>
197 #include <TCollection_ExtendedString.hxx>
198
199 #define _FD (  ( PWIN32_FIND_DATAW )myData  )
200
201 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
202
203 OSD_DirectoryIterator :: OSD_DirectoryIterator (
204                           const OSD_Path&                where,
205                           const TCollection_AsciiString& Mask
206                          ) {
207
208  myFlag   = Standard_False;
209  myHandle = INVALID_HANDLE_VALUE;
210
211  where.SystemName ( myPlace );
212
213  if (  myPlace.Length () == 0  ) myPlace = ".";
214
215  myMask = Mask;
216  myData = NULL;
217
218 }  // end constructor
219
220 void OSD_DirectoryIterator :: Destroy () {
221
222  if ( myData != NULL ) HeapFree (  GetProcessHeap (), 0, myData  );
223
224  if (  myHandle != INVALID_HANDLE_VALUE  )
225
226   FindClose (  ( HANDLE )myHandle  );
227
228 }  // end  OSD_DirectoryIterator :: Destroy
229
230 Standard_Boolean OSD_DirectoryIterator :: More () {
231
232  if (  myHandle == INVALID_HANDLE_VALUE  ) {
233  
234   TCollection_AsciiString wc = myPlace + "/" + myMask;
235
236   myData = HeapAlloc (
237             GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS, sizeof ( WIN32_FIND_DATAW )
238            );
239
240   // make wchar_t string from UTF-8
241   TCollection_ExtendedString wcW(wc);
242   myHandle = FindFirstFileExW (wcW.ToWideString(), FindExInfoStandard, (PWIN32_FIND_DATAW)myData, FindExSearchNameMatch, NULL, 0);
243
244   if ( myHandle == INVALID_HANDLE_VALUE )
245
246     _osd_wnt_set_error ( myError, OSD_WDirectoryIterator );
247   
248   else {
249   
250    myFlag      = Standard_True;
251    myFirstCall = Standard_True;
252
253    Next ();
254
255   }  // end else
256   
257  } else if ( !myFlag ) {
258  
259   FindClose (  ( HANDLE )myHandle  );
260   myHandle = INVALID_HANDLE_VALUE;
261  
262  }  // end if
263
264  return myFlag;
265
266 }  // end OSD_DirectoryIterator :: More
267
268 void OSD_DirectoryIterator :: Next () {
269
270  if ( ! myFirstCall || ! ( _FD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) {
271  
272   do {
273   
274    if (   !FindNextFileW (  ( HANDLE )myHandle, _FD  )   ) {
275    
276     myFlag = Standard_False;
277
278     break;
279    
280    }  // end if
281   
282   } while (  !( _FD -> dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )  );
283  
284  }  // end if
285  
286  myFirstCall = Standard_False;
287
288 }  // end  OSD_DirectoryIterator :: Next
289
290 OSD_Directory OSD_DirectoryIterator :: Values () {
291
292  // make UTF-8 string
293  TCollection_AsciiString aFileName
294    (TCollection_ExtendedString( (Standard_ExtString) _FD -> cFileName) );
295  TheIterator.SetPath (   OSD_Path ( aFileName )   );
296
297  return TheIterator;
298
299 }  // end  OSD_DirectoryIterator :: Values
300
301 Standard_Boolean OSD_DirectoryIterator :: Failed () const {
302
303  return myError.Failed ();
304
305 }  // end OSD_DirectoryIterator :: Failed
306
307 void OSD_DirectoryIterator :: Reset () {
308
309  myError.Reset ();
310
311 }  // end OSD_DirectoryIterator :: Reset
312
313 void OSD_DirectoryIterator :: Perror () {
314
315  myError.Perror ();
316
317 }  // end OSD_DirectoryIterator :: Perror
318
319 Standard_Integer OSD_DirectoryIterator :: Error () const {
320
321  return myError.Error ();
322
323 }  // end OSD_DirectoryIterator :: Error
324
325 // For compatibility with UNIX version
326 OSD_DirectoryIterator::OSD_DirectoryIterator() {}
327
328 void OSD_DirectoryIterator::Initialize(
329                              const OSD_Path&,
330                              const TCollection_AsciiString&){}
331
332 #endif