Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

gdcmDirList.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002                                                                                 
00003   Program:   gdcm
00004   Module:    $RCSfile: gdcmDirList.cxx,v $
00005   Language:  C++
00006   Date:      $Date: 2006/01/10 15:54:03 $
00007   Version:   $Revision: 1.58 $
00008                                                                                 
00009   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
00010   l'Image). All rights reserved. See Doc/License.txt or
00011   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
00012                                                                                 
00013      This software is distributed WITHOUT ANY WARRANTY; without even
00014      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00015      PURPOSE.  See the above copyright notices for more information.
00016                                                                                 
00017 =========================================================================*/
00018 
00019 #include "gdcmDirList.h"
00020 #include "gdcmUtil.h"
00021 #include "gdcmDebug.h"
00022 
00023 #include <iterator>
00024 #include <assert.h>
00025 #include <errno.h>
00026 #include <sys/stat.h>  //stat function
00027 
00028 #ifdef _MSC_VER
00029    #include <windows.h> 
00030    #include <direct.h>
00031 #else
00032    #include <dirent.h>   
00033    #include <sys/types.h>
00034 #endif
00035 
00036 namespace gdcm
00037 {
00038 //-----------------------------------------------------------------------------
00039 // Constructor / Destructor
00045 DirList::DirList(std::string const &dirName, bool recursive)
00046 {
00047    DirName = dirName;
00048    Explore(dirName, recursive);
00049 }
00050 
00054 DirList::~DirList()
00055 {
00056 }
00057 
00058 //-----------------------------------------------------------------------------
00059 // Public
00065 bool DirList::IsDirectory(std::string const &dirName)
00066 {
00067    struct stat fs;
00068    // std::cout << "dirName[dirName.size()-1] [" << dirName[dirName.size()-1] << "]"
00069    //           << std::endl;
00070    //assert( dirName[dirName.size()-1] != GDCM_FILESEPARATOR );
00071    if ( stat(dirName.c_str(), &fs) == 0 )
00072    {
00073 #if _WIN32
00074       return ((fs.st_mode & _S_IFDIR) != 0);
00075 #else
00076       return S_ISDIR(fs.st_mode);
00077 #endif
00078    }
00079    else
00080    {
00081       const char *str = strerror(errno);
00082       gdcmStaticErrorMacro( str );
00083       return false;
00084    }
00085 }
00086 
00087 //-----------------------------------------------------------------------------
00088 // Protected
00089 
00090 //-----------------------------------------------------------------------------
00091 // Private
00098 int DirList::Explore(std::string const &dirpath, bool recursive)
00099 {
00100    int numberOfFiles = 0;
00101    std::string fileName;
00102    std::string dirName = Util::NormalizePath(dirpath);
00103 #ifdef _MSC_VER
00104    WIN32_FIND_DATA fileData;
00105    //assert( dirName[dirName.size()-1] == '' );
00106    HANDLE hFile = FindFirstFile((dirName+"*").c_str(), &fileData);
00107 
00108    for(BOOL b = (hFile != INVALID_HANDLE_VALUE); b;
00109        b = FindNextFile(hFile, &fileData))
00110    {
00111       fileName = fileData.cFileName;
00112       if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
00113       {
00114          // Need to check for . and .. to avoid infinite loop
00115          if ( fileName != "." && fileName != ".." && recursive )
00116          {
00117             numberOfFiles += Explore(dirName+fileName,recursive);
00118          }
00119       }
00120       else
00121       {
00122          Filenames.push_back(dirName+fileName);
00123          numberOfFiles++;
00124       }
00125    }
00126    DWORD dwError = GetLastError();
00127    if (hFile != INVALID_HANDLE_VALUE) 
00128       FindClose(hFile);
00129    if (dwError != ERROR_NO_MORE_FILES) 
00130    {
00131       LPVOID lpMsgBuf;
00132       FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
00133                     FORMAT_MESSAGE_FROM_SYSTEM|
00134                     FORMAT_MESSAGE_IGNORE_INSERTS,
00135                     NULL,GetLastError(),
00136                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
00137                     (LPTSTR) &lpMsgBuf,0,NULL);
00138 
00139       gdcmErrorMacro("FindNextFile error. Error is " << (char *)lpMsgBuf
00140                    <<" for the directory : "<<dirName);
00141       return -1;
00142    }
00143 
00144 #else
00145   // Real POSIX implementation: scandir is a BSD extension only, and doesn't 
00146   // work on debian for example
00147 
00148    DIR* dir = opendir(dirName.c_str());
00149    if (!dir)
00150    {
00151       return 0;
00152    }
00153 
00154    // According to POSIX, the dirent structure contains a field char d_name[]
00155    // of unspecified size, with at most NAME_MAX characters preceeding the
00156    // terminating null character. Use of other fields will harm the  porta-
00157    // bility of your programs.
00158 
00159    struct stat buf;
00160    dirent *d;
00161    for (d = readdir(dir); d; d = readdir(dir))
00162    {
00163       fileName = dirName + d->d_name;
00164       if( stat(fileName.c_str(), &buf) != 0 )
00165       {
00166          const char *str = strerror(errno);
00167          gdcmErrorMacro( str );
00168       }
00169       if ( S_ISREG(buf.st_mode) )    //is it a regular file?
00170       {
00171          Filenames.push_back( fileName );
00172          numberOfFiles++;
00173       }
00174       else if ( S_ISDIR(buf.st_mode) ) //directory?
00175       {
00176          if ( d->d_name[0] != '.' && recursive ) //we also skip hidden files
00177          {
00178             numberOfFiles += Explore( fileName, recursive);
00179          }
00180       }
00181       else
00182       {
00183          gdcmErrorMacro( "Unexpected error" );
00184          return -1;
00185       }
00186    }
00187    if( closedir(dir) != 0 )
00188    {
00189       const char *str = strerror(errno);
00190       gdcmErrorMacro( str );
00191    }
00192 #endif
00193 
00194   return numberOfFiles;
00195 }
00196 
00197 //-----------------------------------------------------------------------------
00198 // Print
00203 void DirList::Print(std::ostream &os, std::string const &)
00204 {
00205    std::copy(Filenames.begin(), Filenames.end(), 
00206              std::ostream_iterator<std::string>(os, "\n"));
00207 }
00208 
00209 //-----------------------------------------------------------------------------
00210 } // end namespace gdcm

Generated on Fri Jan 20 10:14:24 2006 for gdcm by  doxygen 1.4.4