1 #include "bbstdFilesFromDirectory.h"
2 #include "bbstdPackage.h"
12 #include <sys/stat.h> //stat function
17 BBTK_ADD_BLACK_BOX_TO_PACKAGE(std,FilesFromDirectory)
18 BBTK_BLACK_BOX_IMPLEMENTATION(FilesFromDirectory,bbtk::AtomicBlackBox);
20 void FilesFromDirectory::Process()
23 DirName = bbGetInputIn();
24 bool rec = bbGetInputRecursive();
25 /*int nbFiles = */ Explore(DirName, rec);
26 bbSetOutputOut(Filenames);
30 void FilesFromDirectory::bbUserConstructor()
34 bbSetInputRecursive(false);
37 void FilesFromDirectory::bbUserCopyConstructor(bbtk::BlackBox::Pointer)
42 void FilesFromDirectory::bbUserDestructor()
49 * \brief Add a SEPARATOR to the end of the name if necessary
50 * @param pathname file/directory name to normalize
52 std::string FilesFromDirectory::NormalizePath(std::string const &pathname)
55 const char FILESEPARATOR = '\\';
57 const char FILESEPARATOR = '/';
60 std::string name = pathname;
61 int size = name.size();
63 if ( name[size-1] != FILESEPARATOR )
65 name += FILESEPARATOR;
71 * \brief Explores a directory with possibility of recursion
72 * return number of files read
73 * @param dirpath directory to explore
74 * @param recursive whether we want recursion or not
76 int FilesFromDirectory::Explore(std::string const &dirpath, bool recursive)
78 int numberOfFiles = 0;
80 std::string dirName = NormalizePath(dirpath);
82 WIN32_FIND_DATA fileData;
83 //assert( dirName[dirName.size()-1] == '' );
84 HANDLE hFile = FindFirstFile((dirName+"*").c_str(), &fileData);
86 for(BOOL b = (hFile != INVALID_HANDLE_VALUE); b;
87 b = FindNextFile(hFile, &fileData))
89 fileName = fileData.cFileName;
90 if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
92 // Need to check for . and .. to avoid infinite loop
93 if ( fileName != "." && fileName != ".." && recursive )
95 numberOfFiles += Explore(dirName+fileName,recursive);
100 Filenames.push_back(dirName+fileName);
104 DWORD dwError = GetLastError();
105 if (hFile != INVALID_HANDLE_VALUE)
107 if (dwError != ERROR_NO_MORE_FILES)
110 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
111 FORMAT_MESSAGE_FROM_SYSTEM|
112 FORMAT_MESSAGE_IGNORE_INSERTS,
114 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
115 (LPTSTR) &lpMsgBuf,0,NULL);
117 //gdcmErrorMacro("FindNextFile error. Error is " << (char *)lpMsgBuf
118 // <<" for the directory : "<<dirName);
123 // Real POSIX implementation: scandir is a BSD extension only, and doesn't
124 // work on debian for example
126 DIR* dir = opendir(dirName.c_str());
132 // According to POSIX, the dirent structure contains a field char d_name[]
133 // of unspecified size, with at most NAME_MAX characters preceeding the
134 // terminating null character. Use of other fields will harm the porta-
135 // bility of your programs.
139 for (d = readdir(dir); d; d = readdir(dir))
141 fileName = dirName + d->d_name;
142 if( stat(fileName.c_str(), &buf) != 0 )
144 //gdcmErrorMacro( strerror(errno) );
146 if ( S_ISREG(buf.st_mode) ) //is it a regular file?
148 Filenames.push_back( fileName );
151 else if ( S_ISDIR(buf.st_mode) ) //directory?
153 if ( d->d_name[0] != '.' && recursive ) //we also skip hidden files
155 numberOfFiles += Explore( fileName, recursive);
160 //gdcmErrorMacro( "Unexpected error" );
164 if( closedir(dir) != 0 )
166 //gdcmErrorMacro( strerror(errno) );
170 return numberOfFiles;
175 // EO namespace bbstd