Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/DiskDirectory.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlCore/DiskDirectory.hpp>
00033 #include <vlCore/DiskFile.hpp>
00034 #include <algorithm>
00035 
00036 #if defined(__GNUG__)
00037   #include <sys/types.h>
00038   #include <dirent.h>
00039   #if defined(__APPLE__) || (__FreeBSD__)
00040     #define dirent64 dirent
00041     #define readdir64_r readdir_r
00042   #endif
00043 #endif
00044 
00045 using namespace vl;
00046 
00047 //-----------------------------------------------------------------------------
00048 // DiskDirectory
00049 //-----------------------------------------------------------------------------
00050 DiskDirectory::DiskDirectory( const String& name )
00051 {
00052   setPath(name);
00053 }
00054 //-----------------------------------------------------------------------------
00055 DiskDirectory::DiskDirectory()
00056 {
00057 }
00058 //-----------------------------------------------------------------------------
00059 void DiskDirectory::listFilesRecursive(std::vector<String>& file_list) const
00060 {
00061   file_list.clear();
00062   listFilesRecursive_internal(file_list);
00063 }
00064 //-----------------------------------------------------------------------------
00065 ref<DiskDirectory> DiskDirectory::diskSubDir(const String& subdir_name) const
00066 {
00067   if (path().empty())
00068   {
00069     Log::error( "VirtualDirectory::path() must not be empty!\n" );
00070     return NULL;
00071   }
00072 
00073   std::vector<String> dir_list;
00074   String p = translatePath(subdir_name).right(-path().length()-1);
00075   this->listSubDirs(dir_list);
00076   String cur_p = path();
00077   for(int i=0; i<(int)dir_list.size(); ++i)
00078   {
00079     dir_list[i] = dir_list[i].right(-cur_p.length()-1);
00080     if (p.startsWith(dir_list[i]+'/') || p == dir_list[i])
00081     {
00082       ref<DiskDirectory> dir = new DiskDirectory(cur_p + '/' + dir_list[i]);
00083       if (!dir)
00084         return NULL;
00085       cur_p = cur_p + '/' + dir_list[i];
00086       p = p.right(-dir_list[i].length()-1);
00087       dir->listSubDirs(dir_list);
00088       i=-1;
00089       if (p.empty())
00090         return dir;
00091     }
00092   }
00093   return NULL;
00094 }
00095 //-----------------------------------------------------------------------------
00096 bool DiskDirectory::exists() const
00097 {
00098   if (path().empty())
00099   {
00100     Log::error( "VirtualDirectory::path() must not be empty!\n" );
00101     return false;
00102   }
00103   #if defined(VL_PLATFORM_WINDOWS)
00104     WIN32_FIND_DATA FindFileData;
00105     memset( &FindFileData, 0, sizeof(FindFileData) );
00106     String wild = path() + "*";
00107     HANDLE hFind = FindFirstFile( (wchar_t*)wild.ptr(), &FindFileData );
00108     if( hFind == INVALID_HANDLE_VALUE )
00109       return false;
00110     else
00111     {
00112       FindClose(hFind);
00113       return true;
00114     }
00115   #elif defined(__GNUG__)
00116     std::vector<unsigned char> utf8;
00117     path().toUTF8( utf8, false );
00118     DIR* dp = opendir((char*)&utf8[0]);
00119     if(dp == NULL)
00120       return false;
00121     else
00122     {
00123       closedir(dp);
00124       return true;
00125     }
00126   #endif
00127 }
00128 //-----------------------------------------------------------------------------
00129 void DiskDirectory::listSubDirs(std::vector<String>& dirs, bool append) const
00130 {
00131   if (!append)
00132     dirs.clear();
00133   if (path().empty())
00134   {
00135     Log::error( "VirtualDirectory::path() must not be empty!\n" );
00136     return;
00137   }
00138   #if defined(VL_PLATFORM_WINDOWS)
00139     WIN32_FIND_DATA FindFileData;
00140     memset( &FindFileData, 0, sizeof(FindFileData) );
00141     String wild = path() + "*";
00142     HANDLE hFind = FindFirstFile( (wchar_t*)wild.ptr(), &FindFileData );
00143     if( hFind == INVALID_HANDLE_VALUE )
00144       Log::error( Say("Cannot open directory '%s' for directory listing.\n") << path() );
00145     else
00146     {
00147       do
00148       {
00149         if ( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
00150         {
00151           String name;
00152           name = FindFileData.cFileName;
00153           if (name != L"." && name != L"..")
00154             dirs.push_back( path() + name + '/' );
00155         }
00156       } while( FindNextFile(hFind, &FindFileData) != 0 );
00157 
00158       DWORD dwError = GetLastError();
00159       FindClose(hFind);
00160       if (dwError != ERROR_NO_MORE_FILES)
00161       {
00162         // do nothing
00163         // printf ("FindNextFile error. Error code is %u\n", dwError);
00164       }
00165     }
00166   #elif defined(__GNUG__)
00167     std::vector<unsigned char> utf8;
00168     path().toUTF8( utf8, false );
00169     struct dirent64 dirp;
00170     struct dirent64* dirp2;
00171     DIR* dp = opendir((char*)&utf8[0]);
00172     if(dp != NULL)
00173     {
00174       while(readdir64_r(dp, &dirp, &dirp2) == 0 && dirp2 != NULL)
00175       {
00176         String name = dirp.d_name;
00177         if (name == ".." || name == ".")
00178           continue;
00179 
00180         name = path() + name + '/';
00181         // To discover the linked directories we try to open them instead of reading 'dirp.d_type'
00182         name.toUTF8( utf8, false );
00183         DIR* is_dir = opendir((char*)&utf8[0]);
00184         if (is_dir)
00185           closedir(is_dir);
00186         // 4  = directory
00187         // 8  = file
00188         // 10 = file or directory link
00189         // to discover directory links you can try to open them with opendir()
00190         // if (dirp.d_type == 4 )
00191         if (is_dir)
00192           dirs.push_back( name );
00193       }
00194       closedir(dp);
00195     }
00196     else
00197       Log::error( Say("Cannot open directory '%s' for directory listing.\n") << path() );
00198   #endif
00199 }
00200 //-----------------------------------------------------------------------------
00201 void DiskDirectory::listFiles(std::vector< ref<DiskFile> >& file_list, bool append) const
00202 {
00203   // fixme: test
00204   if (!append)
00205     file_list.clear();
00206   std::vector<String> file_names;
00207   listFiles(file_names,false);
00208   for(unsigned i=0; i<file_names.size(); ++i)
00209   {
00210     ref<DiskFile> file = new DiskFile;
00211     // file->setPath( path() + file_names[i] );
00212     file->setPath( file_names[i] );
00213     file_list.push_back(file);
00214   }
00215 }
00216 //-----------------------------------------------------------------------------
00217 void DiskDirectory::listFiles(std::vector<String>& files, bool append) const
00218 {
00219   if (!append)
00220     files.clear();
00221   if (path().empty())
00222   {
00223     Log::error( "VirtualDirectory::path() must not be empty!\n" );
00224     return;
00225   }
00226   #if defined(VL_PLATFORM_WINDOWS)
00227     WIN32_FIND_DATA FindFileData;
00228     memset( &FindFileData, 0, sizeof(FindFileData) );
00229     String wild = path() + "/*";
00230     HANDLE hFind = FindFirstFile( (wchar_t*)wild.ptr(), &FindFileData );
00231     if( hFind == INVALID_HANDLE_VALUE )
00232     {
00233       Log::error( Say("Cannot open directory '%s' for file listing.\n") << path() );
00234     }
00235     else
00236     {
00237       do
00238       {
00239         if ( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 )
00240         {
00241           String name;
00242           name = FindFileData.cFileName;
00243           // the paths are relative
00244           files.push_back( path() + name );
00245         }
00246       } while( FindNextFile(hFind, &FindFileData) != 0 );
00247 
00248       DWORD dwError = GetLastError();
00249       FindClose(hFind);
00250       if (dwError != ERROR_NO_MORE_FILES)
00251       {
00252         // do nothing
00253         // printf ("FindNextFile error. Error is %u\n", dwError);
00254       }
00255     }
00256   #elif defined(__GNUG__)
00257     std::vector<unsigned char> utf8;
00258     path().toUTF8( utf8, false );
00259     struct dirent64 dirp;
00260     struct dirent64* dirp2;
00261     DIR* dp = opendir((char*)&utf8[0]);
00262     if(dp != NULL)
00263     {
00264       while(readdir64_r(dp, &dirp, &dirp2) == 0 && dirp2 != NULL)
00265       {
00266         String name = dirp.d_name;
00267         if (name == ".." || name == ".")
00268           continue;
00269 
00270         name = path() + name;
00271         // whatever is not a directory is a file for us
00272         name.toUTF8( utf8, false );
00273         DIR* is_dir = opendir((char*)&utf8[0]);
00274         if (is_dir)
00275           closedir(is_dir);
00276         // 4  = directory
00277         // 8  = file
00278         // 10 = file or directory link
00279         // to discover directory links you can try to open them with opendir()
00280         // if (dirp.d_type == 4 )
00281         if (!is_dir)
00282           files.push_back( name );
00283       }
00284       closedir(dp);
00285     }
00286     else
00287       Log::error( Say("Cannot open directory '%s' for file listing.\n") << path() );
00288   #endif
00289 }
00290 //-----------------------------------------------------------------------------
00291 ref<VirtualFile> DiskDirectory::file(const String& name) const
00292 {
00293   return diskFile(name);
00294 }
00295 //-----------------------------------------------------------------------------
00296 ref<DiskFile> DiskDirectory::diskFile(const String& name) const
00297 {
00298   String p = translatePath(name);
00299   ref<DiskFile> file = new DiskFile(p);
00300   if (file->exists())
00301     return file;
00302   else
00303     return NULL;
00304 }
00305 //-----------------------------------------------------------------------------
00306 void DiskDirectory::listFilesRecursive_internal(std::vector<String>& file_list) const
00307 {
00308   // add local child
00309   listFiles(file_list, true);
00310   // descend recursively
00311   std::vector<String> dir_list;
00312   listSubDirs(dir_list);
00313   for(unsigned i=0; i<dir_list.size(); ++i)
00314   {
00315     VL_CHECK(dir_list[i] != ".")
00316     VL_CHECK(dir_list[i] != "..")
00317 
00318     DiskDirectory sub_dir( dir_list[i] );
00319     sub_dir.listFilesRecursive_internal(file_list);
00320   }
00321 }
00322 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:28.
Permission is granted to use this page to write and publish articles regarding Visualization Library.