]> Creatis software - bbtk.git/blob - packages/std/src/bbstdFilesFromDirectory.cxx
*** empty log message ***
[bbtk.git] / packages / std / src / bbstdFilesFromDirectory.cxx
1 #include "bbstdFilesFromDirectory.h"
2 #include "bbstdPackage.h"
3 #include <string>
4
5 #ifdef _MSC_VER
6    #include <windows.h>
7    #include <direct.h>
8 #else
9    #include <dirent.h>   
10    #include <sys/types.h>
11 #endif
12
13 #include <sys/stat.h>  //stat function
14
15 namespace bbstd
16 {
17
18 BBTK_ADD_BLACK_BOX_TO_PACKAGE(std,FilesFromDirectory)
19 BBTK_BLACK_BOX_IMPLEMENTATION(FilesFromDirectory,bbtk::AtomicBlackBox);
20
21 void FilesFromDirectory::Process()
22 {
23    DirName = bbGetInputIn();
24    bool rec = bbGetInputRecursive();
25    /*int nbFiles = */ Explore(DirName, rec);
26    bbSetOutputOut(Filenames);   
27    
28 //  for (int i=0; i<Filenames.size(); i++)
29 //     std::cout << "Filenames [" << i << "] = [" << Filenames[i] << "]" << std::endl;  
30 }
31
32 void FilesFromDirectory::bbUserSetDefaultValues()
33 {
34     bbSetInputIn(".");
35     bbSetInputRecursive(false);  
36 }
37
38 void FilesFromDirectory::bbUserInitializeProcessing() 
39
40 }
41
42 void FilesFromDirectory::bbUserFinalizeProcessing() 
43 {
44 }
45   
46 /**
47  * \brief   Add a SEPARATOR to the end of the name if necessary
48  * @param   pathname file/directory name to normalize 
49  */
50 std::string FilesFromDirectory::NormalizePath(std::string const &pathname)
51 {
52 #ifdef _WIN32
53    const char FILESEPARATOR = '\\';
54 #else
55    const char FILESEPARATOR = '/';
56 #endif
57
58    std::string name = pathname;
59    int size = name.size();
60
61    if ( name[size-1] != FILESEPARATOR )
62    {
63       name += FILESEPARATOR;
64    }
65    return name;
66
67
68 /**
69  * \brief   Explores a directory with possibility of recursion
70  *          return number of files read
71  * @param  dirpath   directory to explore
72  * @param  recursive whether we want recursion or not
73  */
74 int FilesFromDirectory::Explore(std::string const &dirpath, bool recursive)
75 {
76    int numberOfFiles = 0;
77    std::string fileName;
78    std::string dirName = NormalizePath(dirpath);
79 #ifdef _MSC_VER
80    WIN32_FIND_DATA fileData;
81    //assert( dirName[dirName.size()-1] == '' );
82    HANDLE hFile = FindFirstFile((dirName+"*").c_str(), &fileData);
83
84    for(BOOL b = (hFile != INVALID_HANDLE_VALUE); b;
85        b = FindNextFile(hFile, &fileData))
86    {
87       fileName = fileData.cFileName;
88       if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
89       {
90          // Need to check for . and .. to avoid infinite loop
91          if ( fileName != "." && fileName != ".." && recursive )
92          {
93             numberOfFiles += Explore(dirName+fileName, recursive);
94          }
95       }
96       else
97       {
98          std::string temp = "\"" +dirName+fileName + "\"";
99          std::string::size_type spacePosition = temp.find_first_of(' ');
100                  if (spacePosition != std::string::npos) 
101          {
102    std::cout << "=========================================== File name : [" <<temp << 
103               "] contains space(s); Discarted !" << std::endl;
104             temp.insert(spacePosition, "\\");
105    continue;  /// \TODO : fix the trouble (vtk?)
106          }      
107          Filenames.push_back(temp);
108          numberOfFiles++;
109       }
110    }
111    DWORD dwError = GetLastError();
112    if (hFile != INVALID_HANDLE_VALUE) 
113       FindClose(hFile);
114    if (dwError != ERROR_NO_MORE_FILES) 
115    {
116       LPVOID lpMsgBuf;
117       FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
118                     FORMAT_MESSAGE_FROM_SYSTEM|
119                     FORMAT_MESSAGE_IGNORE_INSERTS,
120                     NULL,GetLastError(),
121                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
122                     (LPTSTR) &lpMsgBuf,0,NULL);
123
124       //gdcmErrorMacro("FindNextFile error. Error is " << (char *)lpMsgBuf
125       //             <<" for the directory : "<<dirName);
126       return -1;
127    }
128
129 #else
130   // Real POSIX implementation: scandir is a BSD extension only, and doesn't 
131   // work on debian for example
132
133    DIR* dir = opendir(dirName.c_str());
134    if (!dir)
135    {
136       return 0;
137    }
138
139    // According to POSIX, the dirent structure contains a field char d_name[]
140    // of unspecified size, with at most NAME_MAX characters preceeding the
141    // terminating null character. Use of other fields will harm the  porta-
142    // bility of your programs.
143
144    struct stat buf;
145    dirent *d;
146    for (d = readdir(dir); d; d = readdir(dir))
147    {
148       fileName = dirName + d->d_name;
149       std::string temp = fileName;
150       if( stat(fileName.c_str(), &buf) != 0 )
151       {
152          //gdcmErrorMacro( strerror(errno) );
153       }
154       if ( S_ISREG(buf.st_mode) )    //is it a regular file?
155       {
156          if ( d->d_name[0]!='.')
157          {
158          
159              std::string::size_type /* long int */ spacePosition = temp.find_first_of(' ');
160              if (spacePosition != std::string::npos)
161              {
162    std::cout << "=========================================== File name : [" <<temp << 
163               "] contains space(s); Discarted !" << std::endl;
164                  temp.insert(spacePosition, "\\");
165    continue;   /// \TODO : fix the trouble (vtk?)
166              }
167              Filenames.push_back(temp);  
168              numberOfFiles++;
169          }
170       }
171       else if ( S_ISDIR(buf.st_mode) ) //directory?
172       {
173          if ( d->d_name[0] != '.' && recursive ) //we also skip hidden files
174          {
175             numberOfFiles += Explore( fileName, recursive);
176          }
177       }
178       else
179       {
180          //gdcmErrorMacro( "Unexpected error" );
181          return -1;
182       }
183    }
184    if( closedir(dir) != 0 )
185    {
186       //gdcmErrorMacro( strerror(errno) );
187    }
188 #endif
189
190   return numberOfFiles;
191 }
192
193
194 }
195 // EO namespace bbstd
196
197