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 #include "PreCompiled.h"
00027
00028 #ifndef _PreComp_
00029 # include <cassert>
00030 # include <cstdio>
00031 # include <cstdlib>
00032 # include <fstream>
00033 # include <climits>
00034 # include <cstring>
00035 # if defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00036 # include <dirent.h>
00037 # include <unistd.h>
00038 # include <sys/stat.h>
00039 # elif defined (FC_OS_WIN32)
00040 # include <direct.h>
00041 # include <io.h>
00042 # include <windows.h>
00043 # endif
00044 #endif
00045
00046
00047 #include "FileInfo.h"
00048 #include "Exception.h"
00049 #include "Stream.h"
00050 #include <sys/types.h>
00051 #include <sys/stat.h>
00052 #include <cstdio>
00053
00054 #define new DEBUG_CLIENTBLOCK
00055
00056 using namespace Base;
00057
00058
00059
00060
00061
00062 #ifdef FC_OS_WIN32
00063 std::string ConvertFromWideString(const std::wstring& string)
00064 {
00065 int neededSize = WideCharToMultiByte(CP_UTF8, 0, string.c_str(), -1, 0, 0,0,0);
00066 char * CharString = new char[neededSize];
00067 WideCharToMultiByte(CP_UTF8, 0, string.c_str(), -1, CharString, neededSize,0,0);
00068 std::string String((char*)CharString);
00069 delete [] CharString;
00070 CharString = NULL;
00071 return String;
00072 }
00073
00074 std::wstring ConvertToWideString(const std::string& string)
00075 {
00076 int neededSize = MultiByteToWideChar(CP_UTF8, 0, string.c_str(), -1, 0, 0);
00077 wchar_t* wideCharString = new wchar_t[neededSize];
00078 MultiByteToWideChar(CP_UTF8, 0, string.c_str(), -1, wideCharString, neededSize);
00079 std::wstring wideString(wideCharString);
00080 delete [] wideCharString;
00081 wideCharString = NULL;
00082 return wideString;
00083 }
00084 #endif
00085
00086
00087
00088
00089
00090
00091 FileInfo::FileInfo (const char* _FileName)
00092 {
00093 setFile(_FileName);
00094 }
00095
00096 FileInfo::FileInfo (const std::string &_FileName)
00097 {
00098 setFile(_FileName.c_str());
00099 }
00100
00101 const std::string &FileInfo::getTempPath(void)
00102 {
00103 static std::string tempPath;
00104
00105 if (tempPath == "") {
00106 #ifdef FC_OS_WIN32
00107 wchar_t buf[MAX_PATH + 2];
00108 GetTempPathW(MAX_PATH + 1,buf);
00109 int neededSize = WideCharToMultiByte(CP_UTF8, 0, buf, -1, 0, 0, 0, 0);
00110 char* dest = new char[neededSize];
00111 WideCharToMultiByte(CP_UTF8, 0, buf, -1,dest, neededSize, 0, 0);
00112 tempPath = dest;
00113 delete [] dest;
00114 #else
00115 const char* tmp = getenv("TMPDIR");
00116 if (tmp && tmp[0] != '\0') {
00117 tempPath = tmp;
00118 FileInfo fi(tempPath);
00119 if (tempPath.empty() || !fi.isDir())
00120 tempPath = "/tmp/";
00121 else if (tempPath.at(tempPath.size()-1)!='/')
00122 tempPath.append("/");
00123 }
00124 else {
00125 tempPath = "/tmp/";
00126 }
00127 #endif
00128 }
00129
00130 return tempPath;
00131 }
00132
00133 std::string FileInfo::getTempFileName(const char* FileName, const char* Path)
00134 {
00135
00136
00137 #ifdef FC_OS_WIN32
00138 wchar_t buf[MAX_PATH + 2];
00139
00140
00141 std::wstring path;
00142 if (Path)
00143 path = ConvertToWideString(std::string(Path));
00144 else
00145 path = ConvertToWideString(getTempPath());
00146
00147
00148 std::wstring file;
00149 if (FileName)
00150 file = ConvertToWideString(std::string(FileName));
00151 else
00152 file = L"FCTempFile";
00153
00154
00155
00156 GetTempFileNameW(path.c_str(),file.c_str(),0,buf);
00157
00158 return std::string(ConvertFromWideString(std::wstring(buf)));
00159 #else
00160 char buf[PATH_MAX+1];
00161
00162
00163 if (Path)
00164 std::strncpy(buf, Path, PATH_MAX);
00165 else
00166 std::strncpy(buf, getTempPath().c_str(), PATH_MAX);
00167
00168 buf[PATH_MAX] = 0;
00169
00170
00171 if (FileName) {
00172 std::strcat(buf, "/");
00173 std::strcat(buf, FileName);
00174 std::strcat(buf, "XXXXXX");
00175 }
00176 else
00177 std::strcat(buf, "/fileXXXXXX");
00178
00179 (void) mkstemp(buf);
00180
00181 return std::string(buf);
00182 #endif
00183 }
00184
00185 void FileInfo::setFile(const char* name)
00186 {
00187 std::string result;
00188 const char *It=name;
00189
00190 while(*It != '\0') {
00191 switch(*It)
00192 {
00193 case '\\':
00194 result += "/";
00195 break;
00196 default:
00197 result += *It;
00198 }
00199 It++;
00200 }
00201
00202 FileName = result;
00203 }
00204
00205 std::string FileInfo::filePath () const
00206 {
00207 return FileName;
00208 }
00209
00210 std::string FileInfo::fileName () const
00211 {
00212 return FileName.substr(FileName.find_last_of('/')+1);
00213 }
00214
00215 std::string FileInfo::dirPath () const
00216 {
00217 return FileName.substr(0,FileName.find_last_of('/'));
00218 }
00219
00220 std::string FileInfo::fileNamePure () const
00221 {
00222 std::string temp = fileName();
00223 std::string::size_type pos = temp.find_last_of('.');
00224
00225 if (pos != std::string::npos)
00226 return temp.substr(0,pos);
00227 else
00228 return temp;
00229 }
00230
00231 std::wstring FileInfo::toStdWString() const
00232 {
00233
00234
00235 #ifdef FC_OS_WIN32
00236 return ConvertToWideString(FileName);
00237 #else
00238
00239
00240
00241
00242
00243 return std::wstring();
00244 #endif
00245 }
00246
00247 std::string FileInfo::extension (bool complete) const
00248 {
00249
00250 assert(complete==false);
00251 std::string::size_type pos = FileName.find_last_of('.');
00252 if (pos == std::string::npos)
00253 return std::string();
00254 return FileName.substr(pos+1);
00255 }
00256
00257 bool FileInfo::hasExtension (const char* Ext) const
00258 {
00259 #if defined (FC_OS_WIN32)
00260 return _stricmp(Ext,extension().c_str()) == 0;
00261 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00262 return strcasecmp(Ext,extension().c_str()) == 0;
00263 #endif
00264 }
00265
00266 bool FileInfo::exists () const
00267 {
00268 #if defined (FC_OS_WIN32)
00269 std::wstring wstr = toStdWString();
00270 return _waccess(wstr.c_str(),0) == 0;
00271 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00272 return access(FileName.c_str(),0) == 0;
00273 #endif
00274 }
00275
00276 bool FileInfo::isReadable () const
00277 {
00278 #if defined (FC_OS_WIN32)
00279 std::wstring wstr = toStdWString();
00280 return _waccess(wstr.c_str(),4) == 0;
00281 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00282 return access(FileName.c_str(),4) == 0;
00283 #endif
00284 }
00285
00286 bool FileInfo::isWritable () const
00287 {
00288 #if defined (FC_OS_WIN32)
00289 std::wstring wstr = toStdWString();
00290 return _waccess(wstr.c_str(),2) == 0;
00291 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00292 return access(FileName.c_str(),2) == 0;
00293 #endif
00294 }
00295
00296 bool FileInfo::isFile () const
00297 {
00298 #ifdef FC_OS_WIN32
00299 if (exists()) {
00300 std::wstring wstr = toStdWString();
00301 FILE* fd = _wfopen(wstr.c_str(), L"rb");
00302 bool ok = (fd != 0);
00303 fclose(fd);
00304 return ok;
00305 }
00306 #else
00307 if (exists()) {
00308
00309
00310 std::ifstream str(FileName.c_str(), std::ios::in | std::ios::binary);
00311 if (!str) return false;
00312 str.close();
00313 return true;
00314 }
00315 #endif
00316
00317
00318 return true;
00319 }
00320
00321 bool FileInfo::isDir () const
00322 {
00323 if (exists()) {
00324
00325
00326 #if defined (FC_OS_WIN32)
00327 std::wstring wstr = toStdWString();
00328 struct _stat st;
00329
00330 if (_wstat(wstr.c_str(), &st) != 0)
00331 return false;
00332 return ((st.st_mode & _S_IFDIR) != 0);
00333
00334 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00335 struct stat st;
00336 if (stat(FileName.c_str(), &st) != 0) {
00337 return false;
00338 }
00339 return S_ISDIR(st.st_mode);
00340 #endif
00341 return false;
00342 }
00343 else
00344 return false;
00345
00346
00347 return true;
00348 }
00349
00350 unsigned int FileInfo::size () const
00351 {
00352
00353 assert(0);
00354 return 0;
00355 }
00356
00357 TimeInfo FileInfo::lastModified() const
00358 {
00359 TimeInfo ti = TimeInfo::null();
00360 if (exists()) {
00361
00362 #if defined (FC_OS_WIN32)
00363 std::wstring wstr = toStdWString();
00364 struct _stat st;
00365 if (_wstat(wstr.c_str(), &st) == 0) {
00366 ti.setTime_t(st.st_mtime);
00367 }
00368
00369 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00370 struct stat st;
00371 if (stat(FileName.c_str(), &st) == 0) {
00372 ti.setTime_t(st.st_mtime);
00373 }
00374 #endif
00375
00376 }
00377 return ti;
00378 }
00379
00380 TimeInfo FileInfo::lastRead() const
00381 {
00382 TimeInfo ti = TimeInfo::null();
00383 if (exists()) {
00384
00385 #if defined (FC_OS_WIN32)
00386 std::wstring wstr = toStdWString();
00387 struct _stat st;
00388 if (_wstat(wstr.c_str(), &st) == 0) {
00389 ti.setTime_t(st.st_atime);
00390 }
00391
00392 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00393 struct stat st;
00394 if (stat(FileName.c_str(), &st) == 0) {
00395 ti.setTime_t(st.st_atime);
00396 }
00397 #endif
00398
00399 }
00400 return ti;
00401 }
00402
00403 bool FileInfo::deleteFile(void) const
00404 {
00405 #if defined (FC_OS_WIN32)
00406 std::wstring wstr = toStdWString();
00407 return ::_wremove(wstr.c_str()) == 0;
00408 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00409 return (::remove(FileName.c_str())==0);
00410 #else
00411 # error "FileInfo::deleteFile() not implemented for this platform!"
00412 #endif
00413 }
00414
00415 bool FileInfo::renameFile(const char* NewName)
00416 {
00417 bool res;
00418 #if defined (FC_OS_WIN32)
00419 std::wstring oldname = toStdWString();
00420 std::wstring newname = ConvertToWideString(NewName);
00421 res = ::_wrename(oldname.c_str(),newname.c_str()) == 0;
00422 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00423 res = ::rename(FileName.c_str(),NewName) == 0;
00424 #else
00425 # error "FileInfo::renameFile() not implemented for this platform!"
00426 #endif
00427 setFile(NewName);
00428
00429 return res;
00430 }
00431
00432 bool FileInfo::copyTo(const char* NewName) const
00433 {
00434 #if defined (FC_OS_WIN32)
00435 std::wstring oldname = toStdWString();
00436 std::wstring newname = ConvertToWideString(NewName);
00437 return CopyFileW(oldname.c_str(),newname.c_str(),true) != 0;
00438 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00439 FileInfo fi1(FileName);
00440 FileInfo fi2(NewName);
00441 Base::ifstream file(fi1, std::ios::in | std::ios::binary);
00442 Base::ofstream copy(fi2, std::ios::out | std::ios::binary);
00443 file >> copy.rdbuf();
00444 return file.is_open() && copy.is_open();
00445 #else
00446 # error "FileInfo::copyTo() not implemented for this platform!"
00447 #endif
00448 }
00449
00450 bool FileInfo::createDirectory(void) const
00451 {
00452 #if defined (FC_OS_WIN32)
00453 std::wstring wstr = toStdWString();
00454 return _wmkdir(wstr.c_str()) == 0;
00455 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00456 return mkdir(FileName.c_str(), 0777) == 0;
00457 #else
00458 # error "FileInfo::createDirectory() not implemented for this platform!"
00459 #endif
00460 }
00461
00462 bool FileInfo::deleteDirectory(void) const
00463 {
00464 if (isDir() == false ) return false;
00465 #if defined (FC_OS_WIN32)
00466 std::wstring wstr = toStdWString();
00467 return _wrmdir(wstr.c_str()) == 0;
00468 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00469 return rmdir(FileName.c_str()) == 0;
00470 #else
00471 # error "FileInfo::createDirectory() not implemented for this platform!"
00472 #endif
00473 }
00474
00475 bool FileInfo::deleteDirectoryRecursive(void) const
00476 {
00477 if (isDir() == false ) return false;
00478 std::vector<Base::FileInfo> List = getDirectoryContent();
00479
00480 for (std::vector<Base::FileInfo>::iterator It = List.begin();It!=List.end();++It) {
00481 if (It->isDir())
00482 It->deleteDirectoryRecursive();
00483 else if(It->isFile())
00484 It->deleteFile();
00485 else
00486 Base::Exception("FileInfo::deleteDirectoryRecursive(): Unknown object Type in directory!");
00487 }
00488 return deleteDirectory();
00489 }
00490
00491 std::vector<Base::FileInfo> FileInfo::getDirectoryContent(void) const
00492 {
00493 std::vector<Base::FileInfo> List;
00494 #if defined (FC_OS_WIN32)
00495 struct _wfinddata_t dentry;
00496 long hFile;
00497
00498
00499 std::wstring wstr = toStdWString();
00500 wstr += L"/*";
00501
00502 if ((hFile = _wfindfirst( wstr.c_str(), &dentry)) == -1L)
00503 return List;
00504
00505 while (_wfindnext(hFile, &dentry) == 0)
00506 if (wcscmp(dentry.name,L"..") != 0)
00507 List.push_back(FileInfo(FileName + "/" +ConvertFromWideString(std::wstring(dentry.name))));
00508
00509 _findclose(hFile);
00510
00511 #elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
00512 DIR* dp(0);
00513 struct dirent* dentry(0);
00514 if ((dp = opendir(FileName.c_str())) == NULL)
00515 {
00516 return List;
00517 }
00518
00519 while ((dentry = readdir(dp)) != NULL)
00520 {
00521 std::string dir = dentry->d_name;
00522 if (dir != "." && dir != "..")
00523 List.push_back(FileInfo(FileName + "/" + dir));
00524 }
00525 closedir(dp);
00526 #else
00527 # error "FileInfo::getDirectoryContent() not implemented for this platform!"
00528 #endif
00529 return List;
00530 }