Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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 std::vector<String> dir_list;
00073 String p = translatePath(subdir_name).right(-path().length()-1);
00074 ref<DiskDirectory> dir = const_cast<DiskDirectory*>(this);
00075 dir->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 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 #ifdef _WIN32
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 #ifdef _WIN32
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
00163
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
00181 (path()+'/'+name).toUTF8( utf8, false );
00182 DIR* is_dir = opendir((char*)&utf8[0]);
00183 if (is_dir)
00184 closedir(is_dir);
00185
00186
00187
00188
00189
00190 if (is_dir)
00191 dirs.push_back( path() + '/' + name );
00192 }
00193 closedir(dp);
00194 }
00195 else
00196 Log::error( Say("Cannot open directory '%s' for directory listing.\n") << path() );
00197 #endif
00198 }
00199
00200 void DiskDirectory::listFiles(std::vector< ref<DiskFile> >& file_list, bool append) const
00201 {
00202
00203 if (!append)
00204 file_list.clear();
00205 std::vector<String> file_names;
00206 listFiles(file_names,false);
00207 for(unsigned i=0; i<file_names.size(); ++i)
00208 {
00209 ref<DiskFile> file = new DiskFile;
00210
00211 file->setPath( file_names[i] );
00212 file_list.push_back(file);
00213 }
00214 }
00215
00216 void DiskDirectory::listFiles(std::vector<String>& files, bool append) const
00217 {
00218 if (!append)
00219 files.clear();
00220 if (path().empty())
00221 {
00222 Log::error( "VirtualDirectory::path() must not be empty!\n" );
00223 return;
00224 }
00225 #ifdef _WIN32
00226 WIN32_FIND_DATA FindFileData;
00227 memset( &FindFileData, 0, sizeof(FindFileData) );
00228 String wild = path() + "/*";
00229 HANDLE hFind = FindFirstFile( (wchar_t*)wild.ptr(), &FindFileData );
00230 if( hFind == INVALID_HANDLE_VALUE )
00231 {
00232 Log::error( Say("Cannot open directory '%s' for file listing.\n") << path() );
00233 }
00234 else
00235 {
00236 do
00237 {
00238 if ( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 )
00239 {
00240 String name;
00241 name = FindFileData.cFileName;
00242
00243 files.push_back( path() + '/' + name );
00244 }
00245 } while( FindNextFile(hFind, &FindFileData) != 0 );
00246
00247 DWORD dwError = GetLastError();
00248 FindClose(hFind);
00249 if (dwError != ERROR_NO_MORE_FILES)
00250 {
00251
00252
00253 }
00254 }
00255 #elif defined(__GNUG__)
00256 std::vector<unsigned char> utf8;
00257 path().toUTF8( utf8, false );
00258 struct dirent64 dirp;
00259 struct dirent64* dirp2;
00260 DIR* dp = opendir((char*)&utf8[0]);
00261 if(dp != NULL)
00262 {
00263 while(readdir64_r(dp, &dirp, &dirp2) == 0 && dirp2 != NULL)
00264 {
00265 String name = dirp.d_name;
00266 if (name == ".." || name == ".")
00267 continue;
00268
00269
00270 (path()+'/'+name).toUTF8( utf8, false );
00271 DIR* is_dir = opendir((char*)&utf8[0]);
00272 if (is_dir)
00273 closedir(is_dir);
00274
00275
00276
00277
00278
00279 if (!is_dir)
00280 files.push_back( name );
00281 }
00282 closedir(dp);
00283 }
00284 else
00285 Log::error( Say("Cannot open directory '%s' for file listing.\n") << path() );
00286 #endif
00287 }
00288
00289 ref<VirtualFile> DiskDirectory::file(const String& name) const
00290 {
00291 return diskFile(name);
00292 }
00293
00294 ref<DiskFile> DiskDirectory::diskFile(const String& name) const
00295 {
00296 String p = translatePath(name);
00297 ref<DiskFile> file = new DiskFile(p);
00298 if (file->exists())
00299 return file;
00300 else
00301 return NULL;
00302 }
00303
00304 void DiskDirectory::listFilesRecursive_internal(std::vector<String>& file_list) const
00305 {
00306
00307 listFiles(file_list, true);
00308
00309 std::vector<String> dir_list;
00310 listSubDirs(dir_list);
00311 for(unsigned i=0; i<dir_list.size(); ++i)
00312 {
00313 VL_CHECK(dir_list[i] != ".")
00314 VL_CHECK(dir_list[i] != "..")
00315
00316 DiskDirectory sub_dir( dir_list[i] );
00317 sub_dir.listFilesRecursive_internal(file_list);
00318 }
00319 }
00320