SNAP Library 2.2, Developer Reference  2014-03-11 19:15:55
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         if (ErrCd == 0) {
00183           Assert(ErrCd==0); // !bn: assert-with-exception [pa se drugje po tej funkciji]
00184         }
00185 
00186         if (S_ISREG(Stat.st_mode)) {
00187           if ((FBase!=".")&&(FBase!="..")){
00188             TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
00189             if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
00190              ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
00191               CurFNm=FNm; CurFNmN++; return true;}
00192           }
00193         } else if (S_ISDIR(Stat.st_mode) && RecurseP) {
00194           if ((FBase!=".")&&(FBase!="..")){
00195             TStr SubFPath=FPathV[FPathN]+FBase;
00196             TStrV SubFPathV; SubFPathV.Add(SubFPath);
00197             SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
00198             if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
00199             else {SubFFile=NULL;}
00200           }
00201         }
00202       } else {
00203         // end of directory; clean up (ignore DirEnt, it's allocated within FDesc), pass control to outer loop
00204         FFileDesc->DirEnt = NULL;
00205         int ErrCd = closedir(FFileDesc->FDesc);
00206         FFileDesc->FDesc = NULL;
00207         if (ErrCd == 0) {
00208           Assert(ErrCd==0);
00209         }
00210         break;
00211       }
00212     }
00213   }
00214   // not found
00215   CurFNm=""; CurFNmN=-1; return false;
00216 }
00217 #endif
00218 
00219 void TFFile::GetFNmV(
00220  const TStr& FPath, const TStrV& FExtV, const bool& RecurseP, TStrV& FNmV){
00221   // prepare file-directory traversal
00222   TStrV FPathV; FPathV.Add(FPath);
00223   TFFile FFile(FPathV, FExtV, "", RecurseP); TStr FNm;
00224   // traverse directory
00225   FNmV.Clr();
00226   while (FFile.Next(FNm)){
00227     FNmV.Add(FNm);
00228   }
00229 }
00230 
00232 // Directories
00233 TStr TDir::GetCurDir(){
00234   const int MxBfL=1000;
00235   char Bf[MxBfL];
00236   int BfL=GetCurrentDirectory(MxBfL, Bf);
00237   IAssert((BfL!=0)&&(BfL<MxBfL));
00238   return TStr::GetNrFPath(TStr(Bf));
00239 }
00240 
00241 TStr TDir::GetExeDir(){
00242   const int MxBfL=1000;
00243   char Bf[MxBfL];
00244   int BfL=GetModuleFileName(NULL, Bf, MxBfL);
00245   IAssert((BfL!=0)&&(BfL<MxBfL));
00246   return TStr::GetNrFPath(TStr(Bf).GetFPath());
00247 }
00248 
00249 bool TDir::GenDir(const TStr& FPathFNm){
00250   return CreateDirectory(FPathFNm.CStr(), NULL)!=0;
00251 }
00252 
00253 bool TDir::DelDir(const TStr& FPathFNm){
00254   return RemoveDirectory(FPathFNm.CStr())!=0;
00255 }
00256 
00258 // File-Log
00259 void TFPathNotify::UpdateSOut(const TTm& Tm) {
00260         if (!LogSOut.Empty()) { LogSOut->Flush(); LogSOut.Clr(); }
00261         TStr FNm = TStr::Fmt("%s-Y%04d-M%02d-D%02d-H%02d.log", PrefixFNm.CStr(),
00262                 Tm.GetYear(), Tm.GetMonth(), Tm.GetDay(), Tm.GetHour());
00263         LogSOut = TFOut::New(LogFPath + FNm, true);
00264 }
00265 
00266 TFPathNotify::TFPathNotify(const TStr& _LogFPath, const TStr& _PrefixFNm,
00267                 const bool& _FlushP): LogFPath(_LogFPath), PrefixFNm(_PrefixFNm),
00268                         FlushP(_FlushP) { 
00269 
00270         LastTm = TTm::GetCurUniTm();
00271         UpdateSOut(LastTm);
00272 }
00273 
00274 void TFPathNotify::OnStatus(const TStr& MsgStr) {
00275         // check if new hour so we switch to new log file
00276         TTm NowTm = TTm::GetCurUniTm();
00277         if (NowTm.GetHour() != LastTm.GetHour()) { 
00278                 LastTm = NowTm; UpdateSOut(LastTm);
00279         }
00280         // write log line
00281         LogSOut->PutStrLn(MsgStr); 
00282         // we flush for each line when in debug mode
00283         if (FlushP) { LogSOut->Flush(); }
00284 }