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
00033
00034
00035
00036
00037
00038
00039
00040 #include "cxutils/fileio.h"
00041
00042 #ifdef WIN32
00043 #include <windows.h>
00044 #ifndef MINGW
00045 #include <atlbase.h>
00046 #else
00047 #define USES_CONVERSION
00048 #define A2W(x) (x)
00049 #define W2A(x) (x)
00050 #endif
00051 #else
00052 #include <unistd.h>
00053 #include <fcntl.h>
00054 #include <sys/stat.h>
00055 #include <stdlib.h>
00056 #include <string.h>
00057 #include <dirent.h>
00058 #include <fnmatch.h>
00059 #endif
00060
00061 #include <fstream>
00062
00063
00064
00065 using namespace CxUtils;
00066
00078 int FileIO::CreateDir(const std::string& fname)
00079 {
00080 int result = 0;
00081 std::vector<std::string> tokens = CxUtils::FileIO::Tokenize(fname, "/");
00082 if(tokens.size() > 1)
00083 {
00084 std::string total;
00085 for(unsigned int i = 0; i < (unsigned int)tokens.size(); i++)
00086 {
00087 total += tokens[i];
00088 total += "/";
00089 #ifdef WIN32
00090 USES_CONVERSION;
00091 result = ::CreateDirectory(A2W(total.c_str()), 0);
00092 if(result != 1)
00093 result = 0;
00094 #else
00095
00096 result = !::mkdir(total.c_str(), 0755);
00097 #endif
00098
00099 }
00100 }
00101 else
00102 {
00103 #ifdef WIN32
00104 USES_CONVERSION;
00105 result = ::CreateDirectory(A2W(fname.c_str()), 0);
00106 if(result != 1)
00107 result = 0;
00108 #else
00109
00110 result = !::mkdir(fname.c_str(), 0755);
00111 #endif
00112 }
00113 return result;
00114 }
00115
00116
00128 int FileIO::DeleteDir(const std::string& fname)
00129 {
00130 int result = 0;
00131 #ifdef WIN32
00132 USES_CONVERSION;
00133 result = ::RemoveDirectory(A2W(fname.c_str()));
00134 if(result != 1)
00135 result = 0;
00136 #else
00137 result = !::rmdir(fname.c_str());
00138 #endif
00139 return result;
00140 }
00141
00142
00154 int FileIO::DeleteFiles(const std::string& fname)
00155 {
00156 return !remove(fname.c_str());
00157 }
00158
00159
00171 int FileIO::DeleteFiles(const std::vector<std::string>& files)
00172 {
00173 int result = 0;
00174 for(unsigned int i = 0; i < (unsigned int)files.size(); i++)
00175 {
00176 if(!DeleteFiles(files[i]))
00177 result++;
00178 }
00179 return result;
00180 }
00181
00182
00193 int FileIO::GetPath(const std::string& src, std::string& path)
00194 {
00195 path.clear();
00196 if(src.size() > 0 )
00197 {
00198
00199
00200
00201 unsigned int fnamesize = 0;
00202 const char *str = src.c_str();
00203 for(int i = (int)(src.size() - 1); i >= 0; i--)
00204 {
00205 if(str[i] == '\\' || str[i] == '/' )
00206 {
00207 break;
00208 }
00209 fnamesize++;
00210 }
00211
00212 for(unsigned int i = 0; i < (unsigned int)(src.size() - fnamesize); i++)
00213 path += str[i];
00214 }
00215
00216 if(path.size() > 0)
00217 return 1;
00218 return 0;
00219 }
00220
00221
00235 int FileIO::GetFiles(std::vector<std::string>& files,
00236 const std::string& ext,
00237 const std::string& path,
00238 const bool extractPath,
00239 const bool recursive)
00240 {
00241 int result = 0;
00242 files.clear();
00243 std::string dir;
00244 std::string findPattern;
00245
00246 dir = path;
00247 if( dir.empty() )
00248 {
00249 findPattern = ext;
00250 }
00251 else
00252 {
00253
00254
00255 if( dir.c_str()[dir.length() - 1] != '/' &&
00256 dir.c_str()[dir.length() - 1] != '\\' )
00257 {
00258 dir += '/';
00259 }
00260 findPattern = dir + ext;
00261 }
00262
00263
00264
00265 #ifdef WIN32
00266 ::WIN32_FIND_DATA foundFiles;
00267 ::HANDLE hFind;
00268
00269 USES_CONVERSION;
00270
00271 hFind = ::FindFirstFile(A2W(findPattern.c_str()), &foundFiles);
00272
00273 if( hFind != INVALID_HANDLE_VALUE )
00274 {
00275 do
00276 {
00277 if( !(foundFiles.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
00278 {
00279 std::string item;
00280 if( !extractPath )
00281 {
00282 item = dir;
00283 item += W2A(foundFiles.cFileName);
00284 }
00285 else
00286 {
00287 item = W2A(foundFiles.cFileName);
00288 }
00289 files.push_back(item);
00290 result++;
00291 }
00292 }
00293 while( ::FindNextFile(hFind, &foundFiles) );
00294 }
00295 #else
00296 DIR *directory = opendir(path.length() == 0 ? "." : path.c_str());
00297 if (directory)
00298 {
00299 dirent *d = readdir(directory);
00300 while (d)
00301 {
00302 if (!fnmatch(ext.c_str(), d->d_name, 0))
00303 {
00304 if(!extractPath)
00305 {
00306 files.push_back(dir + std::string(d->d_name));
00307 }
00308 else
00309 {
00310 files.push_back(d->d_name);
00311 }
00312 result++;
00313 }
00314 d = readdir(directory);
00315 }
00316 closedir(directory);
00317 }
00318 #endif
00319
00320 if(recursive)
00321 {
00322 std::vector<std::string> directories;
00323 FileIO::GetDirectories(directories, path, false);
00324 for(unsigned int i = 0; i < (unsigned int)directories.size(); i++)
00325 {
00326 std::vector<std::string> rfiles;
00327 if(GetFiles(rfiles, ext, directories[i], false, true))
00328 {
00329 for(unsigned int j = 0; j < (unsigned int)rfiles.size(); j++)
00330 {
00331 if(extractPath)
00332 {
00333 rfiles[j].erase(0, dir.size());
00334 }
00335 files.push_back(rfiles[j]);
00336 }
00337 }
00338 }
00339 }
00340
00341 return (int)files.size();
00342 }
00343
00344
00356 int FileIO::GetDirectories(std::vector<std::string>& dirs,
00357 const std::string& path,
00358 const bool extractPath)
00359 {
00360 int result = 0;
00361 dirs.clear();
00362 std::string findPattern;
00363
00364 findPattern = path;
00365
00366 for(unsigned int i = 0; i < (unsigned int)(findPattern.size()); i++)
00367 {
00368 if(findPattern.c_str()[i] == '\\')
00369 {
00370 ((char *)(findPattern.c_str()))[i] = '/';
00371 }
00372 }
00373
00374 if(findPattern.size() > 0)
00375 {
00376 if(findPattern.c_str()[findPattern.size() - 1] != '\\' &&
00377 findPattern.c_str()[findPattern.size() - 1] != '/')
00378 {
00379 findPattern.push_back('/');
00380 }
00381 }
00382
00383
00384
00385 #ifdef WIN32
00386 ::WIN32_FIND_DATA foundFiles;
00387 ::HANDLE hFind;
00388
00389 USES_CONVERSION;
00390 std::string pattern = findPattern;
00391 pattern += "*.*";
00392 hFind = ::FindFirstFile(A2W(pattern.c_str()), &foundFiles);
00393
00394 if( hFind != INVALID_HANDLE_VALUE )
00395 {
00396 do
00397 {
00398 if( foundFiles.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
00399 {
00400 std::string dir = W2A(foundFiles.cFileName);
00401 if(dir != "." && dir != "..")
00402 {
00403 std::string item;
00404 if( !extractPath )
00405 {
00406 item = findPattern;
00407 item += dir;
00408 }
00409 else
00410 {
00411 item = dir;
00412 }
00413 dirs.push_back(item);
00414 result++;
00415 }
00416 }
00417 }
00418 while( ::FindNextFile(hFind, &foundFiles) );
00419 }
00420 #else
00421 DIR *directory = opendir(path.length() == 0 ? "." : path.c_str());
00422 if (directory)
00423 {
00424 dirent *d = readdir(directory);
00425 while (d)
00426 {
00427 std::string dir = d->d_name;
00428 if(dir != "." && dir != "..")
00429 {
00430 std::string test = findPattern;
00431 test += d->d_name;
00432 DIR* testDir = opendir(test.c_str());
00433
00434 if(testDir)
00435 {
00436 std::string item;
00437 if( !extractPath )
00438 {
00439 item = test;
00440 }
00441 else
00442 {
00443 item = dir;
00444 }
00445 dirs.push_back(item);
00446 result++;
00447 }
00448 }
00449 d = readdir(directory);
00450 }
00451 closedir(directory);
00452 }
00453 #endif
00454
00455 return result;
00456 }
00457
00458
00470 int FileIO::GetFilesAndDirectories(std::vector<std::string>& files,
00471 const std::string& path,
00472 const bool extractPath)
00473 {
00474 int result = 0;
00475 files.clear();
00476 std::string findPattern;
00477
00478 findPattern = path;
00479
00480 for(unsigned int i = 0; i < (unsigned int)(findPattern.size()); i++)
00481 {
00482 if(findPattern.c_str()[i] == '\\')
00483 {
00484 ((char *)(findPattern.c_str()))[i] = '/';
00485 }
00486 }
00487 if(findPattern.size() > 0 && findPattern[findPattern.size() - 1] != '/')
00488 {
00489 findPattern.push_back('/');
00490 }
00491
00492
00493
00494 #ifdef WIN32
00495 ::WIN32_FIND_DATA foundFiles;
00496 ::HANDLE hFind;
00497
00498 USES_CONVERSION;
00499 std::string pattern = findPattern;
00500 pattern += "*.*";
00501 hFind = ::FindFirstFile(A2W(pattern.c_str()), &foundFiles);
00502
00503 if( hFind != INVALID_HANDLE_VALUE )
00504 {
00505 do
00506 {
00507 std::string dir = W2A(foundFiles.cFileName);
00508 if(dir != "." && dir != "..")
00509 {
00510 std::string item;
00511 if( !extractPath )
00512 {
00513 item = findPattern;
00514 item += dir;
00515 }
00516 else
00517 {
00518 item = dir;
00519 }
00520 files.push_back(item);
00521 result++;
00522 }
00523 }
00524 while( ::FindNextFile(hFind, &foundFiles) );
00525 }
00526 #else
00527 DIR *directory = opendir(path.length() == 0 ? "." : path.c_str());
00528 if (directory)
00529 {
00530 dirent *d = readdir(directory);
00531 while (d)
00532 {
00533 std::string dir = d->d_name;
00534 if(dir != "." && dir != "..")
00535 {
00536 std::string test = findPattern;
00537 test += d->d_name;
00538
00539 std::string item;
00540 if( !extractPath )
00541 {
00542 item = test;
00543 }
00544 else
00545 {
00546 item = dir;
00547 }
00548 files.push_back(item);
00549 result++;
00550 }
00551 d = readdir(directory);
00552 }
00553 closedir(directory);
00554 }
00555 #endif
00556
00557 return result;
00558 }
00559
00560
00571 FILE* FileIO::Open(const std::string& name, const std::string& mode)
00572 {
00573 std::vector<std::string> tokens = Tokenize(name, "/");
00574 if(tokens.size() == 0)
00575 {
00576 tokens = Tokenize(name, "\\");
00577 }
00578 if(tokens.size() > 0 && strchr(mode.c_str(), 'w'))
00579 {
00580 std::string dir;
00581 for(int i = 0; i < (int)tokens.size() - 1; i++)
00582 {
00583 dir += tokens[i];
00584 dir += "/";
00585 CreateDir(dir);
00586 }
00587 }
00588 return fopen(name.c_str(), mode.c_str());
00589 }
00590
00591
00601 bool FileIO::IsDir(const std::string& path)
00602 {
00603 #ifdef WIN32
00604 USES_CONVERSION;
00605 DWORD attr = ::GetFileAttributes(A2W(path.c_str()));
00606 if(attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
00607 {
00608 return true;
00609 }
00610 #else
00611 DIR* testDir = opendir(path.c_str());
00612
00613 if(testDir)
00614 {
00615 return true;
00616 }
00617 #endif
00618 return false;
00619 }
00620
00621
00632 int FileIO::RenameFile(const std::string& originalName, const std::string& newName)
00633 {
00634 return !rename(originalName.c_str(), newName.c_str());
00635 }
00636
00637
00638
00649 int FileIO::CopyFileTo(const std::string& existingFile, const std::string& newFile)
00650 {
00651 int result = 0;
00652 #ifdef WIN32
00653 USES_CONVERSION;
00654 if(::CopyFile(A2W(existingFile.c_str()), A2W(newFile.c_str()), false))
00655 {
00656 result = 1;
00657 }
00658 #else
00659 std::ifstream ifs(existingFile.c_str(), std::ios::binary);
00660 std::ofstream ofs(newFile.c_str(), std::ios::binary);
00661 if(ifs.is_open() && ofs.is_open())
00662 {
00663 ofs << ifs.rdbuf();
00664 result = 1;
00665 ifs.close();
00666 ofs.close();
00667 }
00668 #endif
00669 return result;
00670 }
00671
00672
00683 unsigned int FileIO::GetFileSizeBytes(const std::string& filename)
00684 {
00685 std::ifstream ifs(filename.c_str(), std::ios::binary);
00686 if(ifs.is_open())
00687 {
00688 return (unsigned int)ifs.rdbuf()->pubseekoff(0, std::ios::end, std::ios::in);
00689 }
00690 return 0;
00691 }
00692
00693
00711 unsigned int FileIO::ParseDelimitedLine(FILE* fp,
00712 std::vector<std::string>& columns,
00713 const char delimiter,
00714 const char end,
00715 const bool skipBlankEntriesFlag)
00716 {
00717 char ch;
00718 std::string str;
00719
00720 str.reserve(512);
00721 columns.clear();
00722 while(fp && !feof(fp))
00723 {
00724 ch = fgetc(fp);
00725 if(delimiter == ch || end == ch)
00726 {
00727
00728
00729 std::string::iterator c;
00730 c = str.begin();
00731 while( c != str.end() && (*c) == ' ')
00732 {
00733 c = str.erase(c);
00734 }
00735 if(str.size() > 0)
00736 {
00737 columns.push_back(str);
00738 }
00739 else if(!skipBlankEntriesFlag)
00740 {
00741 columns.push_back("");
00742 }
00743 str.clear();
00744 if(end == ch)
00745 {
00746 break;
00747 }
00748 }
00749 else
00750 {
00751 str.push_back(ch);
00752 }
00753 }
00754
00755 return (unsigned int)columns.size();
00756 }
00757
00758
00770 unsigned int FileIO::ReadLine(FILE* fp,
00771 std::string& line)
00772 {
00773 char ch;
00774 line.reserve(512);
00775 line.clear();
00776 while(fp && !feof(fp))
00777 {
00778 ch = fgetc(fp);
00779 if(ch == '\n')
00780 {
00781 break;
00782 }
00783 else
00784 {
00785 line.push_back(ch);
00786 }
00787 }
00788
00789 return (unsigned int)line.size();
00790 }
00791
00792
00804 unsigned int FileIO::ReadLine(std::fstream& str,
00805 std::string& line)
00806 {
00807 char ch;
00808 line.reserve(512);
00809 line.clear();
00810 while(str.eof() == false && str.good())
00811 {
00812 str.get(ch);
00813 if(ch == '\n')
00814 {
00815 break;
00816 }
00817 else
00818 {
00819 line.push_back(ch);
00820 }
00821 }
00822
00823 return (unsigned int)line.size();
00824 }
00825
00826
00827
00838 std::vector<std::string> FileIO::Tokenize(const std::string& str,
00839 const std::string& delimiters)
00840 {
00841 std::string client = str;
00842 std::vector<std::string> result;
00843
00844 while (!client.empty())
00845 {
00846 std::string::size_type dPos = client.find_first_of( delimiters );
00847
00848 if (dPos == std::string::npos)
00849 {
00850 std::string::size_type ePos = 0;
00851 while(client.c_str()[ePos] == ' ')
00852 {
00853 ePos++;
00854 }
00855 result.push_back(client.substr(ePos, std::string::npos));
00856 return result;
00857 }
00858 while(client.substr(dPos).substr(0, delimiters.size()) != delimiters)
00859 {
00860 dPos++;
00861 if(dPos >= client.size())
00862 {
00863 break;
00864 }
00865 }
00866 std::string element = client.substr(0, dPos);
00867 std::string::size_type ePos = 0;
00868 while(element.c_str()[ePos] == ' ')
00869 {
00870 ePos++;
00871 }
00872 element = element.substr(ePos, std::string::npos);
00873 result.push_back(element);
00874 if(dPos + delimiters.length() >= client.size())
00875 {
00876 break;
00877 }
00878 client = client.substr(dPos + delimiters.length());
00879 }
00880 if (client.empty())
00881 {
00882 result.push_back("");
00883 }
00884
00885 return result;
00886 }
00887
00888
00898 bool FileIO::FileExists(const std::string& fname)
00899 {
00900 std::vector<std::string> tokens;
00901 std::string fcopy = fname;
00902 unsigned int last = 0;
00903 for(unsigned int i = 0; i < (unsigned int)fcopy.size(); i++)
00904 {
00905 if(fcopy[i] == '\\')
00906 {
00907 fcopy[i] = '/';
00908 }
00909 if(fcopy[i] == '/')
00910 {
00911 last = i;
00912 }
00913 }
00914
00915 std::string path = fcopy;
00916 if(last > 0 && last + 1 < (unsigned int)fcopy.size())
00917 {
00918 path.resize(last);
00919 }
00920 if(last == 0)
00921 {
00922 path = ".";
00923 }
00924 if(FileIO::GetFiles(tokens,
00925 "*.*",
00926 path,
00927 false,
00928 true))
00929 {
00930 std::vector<std::string>::iterator f;
00931 for(f = tokens.begin();
00932 f != tokens.end();
00933 f++)
00934 {
00935 if(strstr((*f).c_str(), fcopy.c_str()) != 0)
00936 {
00937 return true;
00938 }
00939 }
00940 }
00941
00942 FILE* fp = fopen(fname.c_str(), "r");
00943
00944 if (fp)
00945 {
00946 fclose(fp);
00947 return true;
00948 }
00949
00950 return false;
00951 }
00952