Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://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 //-----------------------------------------------------------------------------