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
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
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 name = path() + name + '/';
00181
00182 name.toUTF8( utf8, false );
00183 DIR* is_dir = opendir((char*)&utf8[0]);
00184 if (is_dir)
00185 closedir(is_dir);
00186
00187
00188
00189
00190
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
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
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
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
00253
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
00272 name.toUTF8( utf8, false );
00273 DIR* is_dir = opendir((char*)&utf8[0]);
00274 if (is_dir)
00275 closedir(is_dir);
00276
00277
00278
00279
00280
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
00309 listFiles(file_list, true);
00310
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