]> Creatis software - crea.git/blob - src/creaFilesFromDirectory.cxx
BUG Files Directory
[crea.git] / src / creaFilesFromDirectory.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   crea
4   Module:    $RCSfile: creaFilesFromDirectory.cxx,v $
5   Language:  C++
6   Date:      $Date: 2009/03/25 16:29:33 $
7   Version:   $Revision: 1.4 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/crea/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18
19
20 /**
21  *  \file 
22  *  \brief  class Exception:generic class for throwing any exception (header) 
23  *
24  *    Long description:
25  */
26 #ifdef _MSC_VER
27    #include <windows.h>
28    #include <direct.h>
29 #else
30    #include <dirent.h>   
31    #include <sys/types.h>
32 #endif
33
34 #include <sys/stat.h>  //stat function
35
36  #include "creaFilesFromDirectory.h"
37  #include "creaMessageManager.h"
38
39 namespace crea
40
41
42 /**
43  * \brief   Add a SEPARATOR to the end of the name if necessary
44  * @param   pathname file/directory name to normalize 
45  */
46 std::string DirList::NormalizePath(std::string const &pathname)
47 {
48
49
50 #ifdef _WIN32
51    const char FILESEPARATOR = '\\';
52 #else
53    const char FILESEPARATOR = '/';
54 #endif
55
56         
57    std::string name = pathname;
58    int size = name.size();
59
60 //   if ( name[size-1] != SEPARATOR_X && name[size-1] != SEPARATOR_WIN )
61    if ( name[size-1] != FILESEPARATOR )
62    {
63       name += FILESEPARATOR;
64    }
65    return name;
66 }  
67 /**
68  * \brief   Explore a directory with possibility of recursion
69  *          return number of files read
70  * @param  dirpath   directory to explore
71  * @param  recursive whether we want recursion or not
72  */
73 int DirList::Explore(std::string const &dirpath, bool recursive)
74 {
75    int numberOfFiles = 0;
76    std::string fileName;
77    std::string dirName = NormalizePath(dirpath);
78 #ifdef _MSC_VER
79    WIN32_FIND_DATA fileData;
80    //assert( dirName[dirName.size()-1] == '' );
81    HANDLE hFile = FindFirstFile((dirName+"*").c_str(), &fileData);
82
83    for(BOOL b = (hFile != INVALID_HANDLE_VALUE); b;
84        b = FindNextFile(hFile, &fileData))
85    {
86       fileName = fileData.cFileName;
87       if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
88       {
89          // Need to check for . and .. to avoid infinite loop
90          if ( fileName != "." && fileName != ".." && recursive )
91          {
92             numberOfFiles += Explore(dirName+fileName,recursive);
93          }
94       }
95       else
96       {
97          Filenames.push_back(dirName+fileName);
98          numberOfFiles++;
99       }
100    }
101    DWORD dwError = GetLastError();
102    if (hFile != INVALID_HANDLE_VALUE) 
103       FindClose(hFile);
104    if (dwError != ERROR_NO_MORE_FILES) 
105    {
106       LPVOID lpMsgBuf;
107       FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
108                     FORMAT_MESSAGE_FROM_SYSTEM|
109                     FORMAT_MESSAGE_IGNORE_INSERTS,
110                     NULL,GetLastError(),
111                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
112                     (LPTSTR) &lpMsgBuf,0,NULL);
113
114       creaError("FindNextFile error. Error is " << (char *)lpMsgBuf
115                    <<" for the directory : "<<dirName);
116       return -1;
117    }
118
119 #else
120   // Real POSIX implementation: scandir is a BSD extension only, and doesn't 
121   // work on debian for example
122
123    DIR* dir = opendir(dirName.c_str());
124    if (!dir)
125    {
126       return 0;
127    }
128
129    // According to POSIX, the dirent structure contains a field char d_name[]
130    // of unspecified size, with at most NAME_MAX characters preceeding the
131    // terminating null character. Use of other fields will harm the  porta-
132    // bility of your programs.
133
134    struct stat buf;
135    dirent *d;
136    for (d = readdir(dir); d; d = readdir(dir))
137    {
138            
139       fileName = dirName + d->d_name;
140       if( stat(fileName.c_str(), &buf) != 0 )
141       {
142          //gdcmErrorMacro( strerror(errno) );
143       }
144       if ( S_ISREG(buf.st_mode) )    //is it a regular file?
145       {
146                   printf("EED DirList::Explore [%s]\n" , d->d_name );
147                   if ( d->d_name[0]!='.')
148                   {     
149                  Filenames.push_back( fileName );
150                  numberOfFiles++;
151                   }
152       }
153       else if ( S_ISDIR(buf.st_mode) ) //directory?
154       {
155          if ( d->d_name[0] != '.' && recursive ) //we also skip hidden files
156          {
157             numberOfFiles += Explore( fileName, recursive);
158          }
159       }
160       else
161       {
162          //gdcmErrorMacro( "Unexpected error" );
163          return -1;
164       }
165    }
166    if( closedir(dir) != 0 )
167    {
168       //gdcmErrorMacro( strerror(errno) );
169    }
170 #endif
171
172   return numberOfFiles;
173 }
174
175 }