SNAP Library 2.0, User Reference  2013-05-13 16:33:57
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
xfl.cpp
Go to the documentation of this file.
00001 
00002 // Find-File-Descriptor
00003 #ifdef GLib_WIN
00004 TFFileDesc::TFFileDesc(): FFileH(INVALID_HANDLE_VALUE) {}
00005 
00006 bool TFFileDesc::IsDir() const {
00007   return (FDesc.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=0;
00008 }
00009 
00010 TStr TFFileDesc::GetFBase() const {
00011   return TStr(FDesc.cFileName);
00012 }
00013 
00014 TFFileDesc::~TFFileDesc() {}
00015 
00016 #elif defined(GLib_UNIX)
00017 
00018 TFFileDesc::TFFileDesc(): FDesc(NULL), DirEnt(NULL) {}
00019 
00020 bool TFFileDesc::IsDir() const {
00021   Fail;   // !bn: function not needed; besides we do not have full path to the entry
00022   return false;
00023 }
00024 
00025 TStr TFFileDesc::GetFBase() const {
00026   Assert(DirEnt != NULL);
00027   return TStr(DirEnt->d_name);
00028 }
00029 
00030 TFFileDesc::~TFFileDesc() {
00031   if (FDesc) closedir(FDesc);
00032 }
00033 #endif
00034 
00036 // Find-File
00037 TFFile::TFFile(const TStr& FNmWc, const bool& _RecurseP):
00038   FPathV(), FExtV(), FBaseWc(),
00039   CsImpP(false), RecurseP(_RecurseP), FPathN(0-1),
00040   FFileDesc(TFFileDesc::New()), SubFFile(), CurFNm(), CurFNmN(0-1){
00041   // prepare file-base-name wild-card
00042   FBaseWc=FNmWc.GetFBase(); if (!CsImpP){FBaseWc.ToUc();}
00043   // get & assign file-name
00044   TStr FPath=FNmWc.GetFPath();
00045   FPathV.Add(TStr::GetNrFPath(FPath));
00046 }
00047 
00048 TFFile::TFFile(const TStr& _FPath, const TStr& _FExt, const bool& _RecurseP):
00049   FPathV(), FExtV(), FBaseWc(),
00050   CsImpP(false), RecurseP(_RecurseP), FPathN(0-1),
00051   FFileDesc(TFFileDesc::New()), SubFFile(), CurFNm(), CurFNmN(0-1){
00052   FPathV.Add(TStr::GetNrFPath(_FPath));
00053   if (!_FExt.Empty()){
00054     FExtV.Add(TStr::GetNrFExt(_FExt));
00055     if (!CsImpP){FExtV.Last().ToUc();}
00056   }
00057 }
00058 
00059 TFFile::TFFile(const TStrV& _FPathV, const TStrV& _FExtV, const TStr& _FBaseWc,
00060  const bool& _RecurseP):
00061   FPathV(_FPathV), FExtV(_FExtV), FBaseWc(_FBaseWc),
00062   CsImpP(false), RecurseP(_RecurseP), FPathN(0-1),
00063   FFileDesc(TFFileDesc::New()), SubFFile(), CurFNm(), CurFNmN(0-1){
00064   // prepare file-paths
00065   for (int FPathN=0; FPathN<FPathV.Len(); FPathN++){
00066     FPathV[FPathN]=TStr::GetNrFPath(FPathV[FPathN]);}
00067   // prepare file-extensions
00068   for (int FExtN=0; FExtN<FExtV.Len(); FExtN++){
00069     FExtV[FExtN]=TStr::GetNrFExt(FExtV[FExtN]);
00070     if (!CsImpP){FExtV[FExtN].ToUc();}
00071   }
00072   // prepare file-base wild-card
00073   if (!CsImpP){FBaseWc.ToUc();}
00074 }
00075 
00076 #ifdef GLib_WIN
00077 TFFile::~TFFile(){
00078   if (FFileDesc->FFileH!=INVALID_HANDLE_VALUE){
00079     IAssert(FindClose(FFileDesc->FFileH));}
00080 }
00081 
00082 bool TFFile::Next(TStr& FNm){
00083   // if need to recurse
00084   if (!SubFFile.Empty()){
00085     if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
00086     else {SubFFile=NULL;}
00087   }
00088   // for all required file-paths
00089   while (FPathN<FPathV.Len()){
00090     if ((FPathN!=-1)&&(FindNextFile(FFileDesc->FFileH, &FFileDesc->FDesc))){
00091       // next file-name available on the current file-path
00092       TStr FBase=FFileDesc->GetFBase();
00093       if ((RecurseP)&&(FFileDesc->IsDir())){
00094         // file-name is directory and recursion is required
00095         if ((FBase!=".")&&(FBase!="..")){
00096           // directory is non-trivial - prepare sub-file-find for recursion
00097           TStr SubFPath=FPathV[FPathN]+FBase;
00098           TStrV SubFPathV; SubFPathV.Add(SubFPath);
00099           SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
00100           if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
00101           else {SubFFile=NULL;}
00102         }
00103       } else {
00104         // return file-name if fits
00105         if ((FBase!=".")&&(FBase!="..")){
00106           FNm=FPathV[FPathN]+FBase;
00107           TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
00108           if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
00109            ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
00110             CurFNm=FNm; CurFNmN++; return true;}
00111         }
00112       }
00113     } else {
00114       // close file-find descriptor if needed
00115       if (FPathN!=-1){
00116         IAssert(FindClose(FFileDesc->FFileH));
00117         FFileDesc->FFileH=INVALID_HANDLE_VALUE;
00118       }
00119       // find next file existing path from the input list
00120       while ((++FPathN<FPathV.Len())&&
00121        ((FFileDesc->FFileH=FindFirstFile((FPathV[FPathN]+"*.*").CStr(),
00122        &FFileDesc->FDesc))==INVALID_HANDLE_VALUE)){}
00123       if ((FPathN<FPathV.Len())&&(RecurseP)&&(FFileDesc->IsDir())){
00124         // file-path found, file-name is directory and recursion is required
00125         TStr FBase=FFileDesc->GetFBase();
00126         if ((FBase!=".")&&(FBase!="..")){
00127           TStr SubFPath=FPathV[FPathN]+FBase;
00128           TStrV SubFPathV; SubFPathV.Add(SubFPath);
00129           SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
00130           if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
00131           else {SubFFile=NULL;}
00132         }
00133       } else {
00134         // return file-name if fits
00135         if (FPathN<FPathV.Len()){
00136           TStr FBase=FFileDesc->GetFBase();
00137           if ((FBase!=".")&&(FBase!="..")){
00138             FNm=FPathV[FPathN]+FBase;
00139             TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
00140             if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
00141              ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
00142               CurFNm=FNm; CurFNmN++; return true;
00143             }
00144           }
00145         }
00146       }
00147     }
00148   }
00149   // not found
00150   CurFNm=""; CurFNmN=-1; return false;
00151 }
00152 #elif defined(GLib_UNIX)
00153 TFFile::~TFFile(){}
00154 
00155 bool TFFile::Next(TStr& FNm){
00156   // if need to recurse
00157   if (!SubFFile.Empty()){
00158     if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
00159     else {SubFFile=NULL;}
00160   }
00161   // for all required file-paths
00162   while (FPathN<FPathV.Len()){
00163     // try to find anything within FPathV[FPathN] directory
00164     while (true) {
00165       // if directory not open -> open next first
00166       if (!FFileDesc->FDesc) {
00167         if ((++FPathN)<FPathV.Len()) {
00168           FFileDesc->FDesc = opendir(FPathV[FPathN].CStr());
00169         } else break;
00170         if (!FFileDesc->FDesc) break;   // failed to open this one; pass control to outer loop
00171       }
00172 
00173       FFileDesc->DirEnt = readdir(FFileDesc->FDesc);
00174 
00175       if (FFileDesc->DirEnt) {
00176         // found something
00177         TStr FBase = FFileDesc->GetFBase();
00178         FNm = FPathV[FPathN]+FBase;
00179 
00180         struct stat Stat;
00181         int ErrCd = stat(FNm.CStr(), &Stat);
00182         Assert(ErrCd==0); // !bn: assert-with-exception [pa se drugje po tej funkciji]
00183 
00184         if (S_ISREG(Stat.st_mode)) {
00185           if ((FBase!=".")&&(FBase!="..")){
00186             TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
00187             if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
00188              ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
00189               CurFNm=FNm; CurFNmN++; return true;}
00190           }
00191         } else if (S_ISDIR(Stat.st_mode) && RecurseP) {
00192           if ((FBase!=".")&&(FBase!="..")){
00193             TStr SubFPath=FPathV[FPathN]+FBase;
00194             TStrV SubFPathV; SubFPathV.Add(SubFPath);
00195             SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
00196             if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
00197             else {SubFFile=NULL;}
00198           }
00199         }
00200       } else {
00201         // end of directory; clean up (ignore DirEnt, it's allocated within FDesc), pass control to outer loop
00202         FFileDesc->DirEnt = NULL;
00203         int ErrCd = closedir(FFileDesc->FDesc);
00204         FFileDesc->FDesc = NULL;
00205         Assert(ErrCd==0);
00206         break;
00207       }
00208     }
00209   }
00210   // not found
00211   CurFNm=""; CurFNmN=-1; return false;
00212 }
00213 #endif
00214 
00215 void TFFile::GetFNmV(
00216  const TStr& FPath, const TStrV& FExtV, const bool& RecurseP, TStrV& FNmV){
00217   // prepare file-directory traversal
00218   TStrV FPathV; FPathV.Add(FPath);
00219   TFFile FFile(FPathV, FExtV, "", RecurseP); TStr FNm;
00220   // traverse directory
00221   FNmV.Clr();
00222   while (FFile.Next(FNm)){
00223     FNmV.Add(FNm);
00224   }
00225 }
00226 
00228 // Directories
00229 TStr TDir::GetCurDir(){
00230   const int MxBfL=1000;
00231   char Bf[MxBfL];
00232   int BfL=GetCurrentDirectory(MxBfL, Bf);
00233   IAssert((BfL!=0)&&(BfL<MxBfL));
00234   return TStr::GetNrFPath(TStr(Bf));
00235 }
00236 
00237 TStr TDir::GetExeDir(){
00238   const int MxBfL=1000;
00239   char Bf[MxBfL];
00240   int BfL=GetModuleFileName(NULL, Bf, MxBfL);
00241   IAssert((BfL!=0)&&(BfL<MxBfL));
00242   return TStr::GetNrFPath(TStr(Bf).GetFPath());
00243 }
00244 
00245 bool TDir::GenDir(const TStr& FPathFNm){
00246   return CreateDirectory(FPathFNm.CStr(), NULL)!=0;
00247 }
00248 
00249 bool TDir::DelDir(const TStr& FPathFNm){
00250   return RemoveDirectory(FPathFNm.CStr())!=0;
00251 }
00252 
00254 // File-Log
00255 void TFPathNotify::UpdateSOut(const TTm& Tm) {
00256         if (!LogSOut.Empty()) { LogSOut->Flush(); LogSOut.Clr(); }
00257         TStr FNm = TStr::Fmt("%s-Y%04d-M%02d-D%02d-H%02d.log", PrefixFNm.CStr(),
00258                 Tm.GetYear(), Tm.GetMonth(), Tm.GetDay(), Tm.GetHour());
00259         LogSOut = TFOut::New(LogFPath + FNm, true);
00260 }
00261 
00262 TFPathNotify::TFPathNotify(const TStr& _LogFPath, const TStr& _PrefixFNm,
00263                 const bool& _FlushP): LogFPath(_LogFPath), PrefixFNm(_PrefixFNm),
00264                         FlushP(_FlushP) { 
00265 
00266         LastTm = TTm::GetCurUniTm();
00267         UpdateSOut(LastTm);
00268 }
00269 
00270 void TFPathNotify::OnStatus(const TStr& MsgStr) {
00271         // check if new hour so we switch to new log file
00272         TTm NowTm = TTm::GetCurUniTm();
00273         if (NowTm.GetHour() != LastTm.GetHour()) { 
00274                 LastTm = NowTm; UpdateSOut(LastTm);
00275         }
00276         // write log line
00277         LogSOut->PutStrLn(MsgStr); 
00278         // we flush for each line when in debug mode
00279         if (FlushP) { LogSOut->Flush(); }
00280 }