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