SNAP Library, User Reference  2012-10-15 15:06:59
SNAP, a general purpose network analysis and graph mining library
 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 }