SNAP Library 6.0, Developer Reference  2020-12-09 16:24:20
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
xfl.cpp
Go to the documentation of this file.
1 // Find-File-Descriptor
3 #ifdef GLib_WIN
4 TFFileDesc::TFFileDesc(): FFileH(INVALID_HANDLE_VALUE) {}
5 
6 bool TFFileDesc::IsDir() const {
7  return (FDesc.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=0;
8 }
9 
10 TStr TFFileDesc::GetFBase() const {
11  return TStr(FDesc.cFileName);
12 }
13 
15 
16 #elif defined(GLib_UNIX)
17 
18 TFFileDesc::TFFileDesc(): FDesc(NULL), DirEnt(NULL) {}
19 
20 bool TFFileDesc::IsDir() const {
21  Fail; // !bn: function not needed; besides we do not have full path to the entry
22  return false;
23 }
24 
25 TStr TFFileDesc::GetFBase() const {
26  Assert(DirEnt != NULL);
27  return TStr(DirEnt->d_name);
28 }
29 
31  if (FDesc) closedir(FDesc);
32 }
33 #endif
34 
36 // Find-File
37 TFFile::TFFile(const TStr& FNmWc, const bool& _RecurseP):
38  FPathV(), FExtV(), FBaseWc(),
39  CsImpP(false), RecurseP(_RecurseP), FPathN(0-1),
40  FFileDesc(TFFileDesc::New()), SubFFile(), CurFNm(), CurFNmN(0-1){
41  // prepare file-base-name wild-card
42  FBaseWc=FNmWc.GetFBase(); if (!CsImpP){FBaseWc.ToUc();}
43  // get & assign file-name
44  TStr FPath=FNmWc.GetFPath();
45  FPathV.Add(TStr::GetNrFPath(FPath));
46 }
47 
48 TFFile::TFFile(const TStr& _FPath, const TStr& _FExt, const bool& _RecurseP):
49  FPathV(), FExtV(), FBaseWc(),
50  CsImpP(false), RecurseP(_RecurseP), FPathN(0-1),
51  FFileDesc(TFFileDesc::New()), SubFFile(), CurFNm(), CurFNmN(0-1){
52  FPathV.Add(TStr::GetNrFPath(_FPath));
53  if (!_FExt.Empty()){
54  FExtV.Add(TStr::GetNrFExt(_FExt));
55  if (!CsImpP){FExtV.Last().ToUc();}
56  }
57 }
58 
59 TFFile::TFFile(const TStrV& _FPathV, const TStrV& _FExtV, const TStr& _FBaseWc,
60  const bool& _RecurseP):
61  FPathV(_FPathV), FExtV(_FExtV), FBaseWc(_FBaseWc),
62  CsImpP(false), RecurseP(_RecurseP), FPathN(0-1),
63  FFileDesc(TFFileDesc::New()), SubFFile(), CurFNm(), CurFNmN(0-1){
64  // prepare file-paths
65  for (int FPathN=0; FPathN<FPathV.Len(); FPathN++){
67  // prepare file-extensions
68  for (int FExtN=0; FExtN<FExtV.Len(); FExtN++){
69  FExtV[FExtN]=TStr::GetNrFExt(FExtV[FExtN]);
70  if (!CsImpP){FExtV[FExtN].ToUc();}
71  }
72  // prepare file-base wild-card
73  if (!CsImpP){FBaseWc.ToUc();}
74 }
75 
76 #ifdef GLib_WIN
78  if (FFileDesc->FFileH!=INVALID_HANDLE_VALUE){
79  IAssert(FindClose(FFileDesc->FFileH));}
80 }
81 
82 bool TFFile::Next(TStr& FNm){
83  // if need to recurse
84  if (!SubFFile.Empty()){
85  if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
86  else {SubFFile=NULL;}
87  }
88  // for all required file-paths
89  while (FPathN<FPathV.Len()){
90  if ((FPathN!=-1)&&(FindNextFile(FFileDesc->FFileH, &FFileDesc->FDesc))){
91  // next file-name available on the current file-path
92  TStr FBase=FFileDesc->GetFBase();
93  if ((RecurseP)&&(FFileDesc->IsDir())){
94  // file-name is directory and recursion is required
95  if ((FBase!=".")&&(FBase!="..")){
96  // directory is non-trivial - prepare sub-file-find for recursion
97  TStr SubFPath=FPathV[FPathN]+FBase;
98  TStrV SubFPathV; SubFPathV.Add(SubFPath);
99  SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
100  if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
101  else {SubFFile=NULL;}
102  }
103  } else {
104  // return file-name if fits
105  if ((FBase!=".")&&(FBase!="..")){
106  FNm=FPathV[FPathN]+FBase;
107  TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
108  if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
109  ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
110  CurFNm=FNm; CurFNmN++; return true;}
111  }
112  }
113  } else {
114  // close file-find descriptor if needed
115  if (FPathN!=-1){
116  IAssert(FindClose(FFileDesc->FFileH));
117  FFileDesc->FFileH=INVALID_HANDLE_VALUE;
118  }
119  // find next file existing path from the input list
120  while ((++FPathN<FPathV.Len())&&
121  ((FFileDesc->FFileH=FindFirstFile((FPathV[FPathN]+"*.*").CStr(),
122  &FFileDesc->FDesc))==INVALID_HANDLE_VALUE)){}
123  if ((FPathN<FPathV.Len())&&(RecurseP)&&(FFileDesc->IsDir())){
124  // file-path found, file-name is directory and recursion is required
125  TStr FBase=FFileDesc->GetFBase();
126  if ((FBase!=".")&&(FBase!="..")){
127  TStr SubFPath=FPathV[FPathN]+FBase;
128  TStrV SubFPathV; SubFPathV.Add(SubFPath);
129  SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
130  if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
131  else {SubFFile=NULL;}
132  }
133  } else {
134  // return file-name if fits
135  if (FPathN<FPathV.Len()){
136  TStr FBase=FFileDesc->GetFBase();
137  if ((FBase!=".")&&(FBase!="..")){
138  FNm=FPathV[FPathN]+FBase;
139  TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
140  if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
141  ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
142  CurFNm=FNm; CurFNmN++; return true;
143  }
144  }
145  }
146  }
147  }
148  }
149  // not found
150  CurFNm=""; CurFNmN=-1; return false;
151 }
152 #elif defined(GLib_UNIX)
153 TFFile::~TFFile(){}
154 
155 bool TFFile::Next(TStr& FNm){
156  // if need to recurse
157  if (!SubFFile.Empty()){
158  if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
159  else {SubFFile=NULL;}
160  }
161  // for all required file-paths
162  while (FPathN<FPathV.Len()){
163  // try to find anything within FPathV[FPathN] directory
164  while (true) {
165  // if directory not open -> open next first
166  if (!FFileDesc->FDesc) {
167  if ((++FPathN)<FPathV.Len()) {
168  FFileDesc->FDesc = opendir(FPathV[FPathN].CStr());
169  } else break;
170  if (!FFileDesc->FDesc) break; // failed to open this one; pass control to outer loop
171  }
172 
173  FFileDesc->DirEnt = readdir(FFileDesc->FDesc);
174 
175  if (FFileDesc->DirEnt) {
176  // found something
177  TStr FBase = FFileDesc->GetFBase();
178  FNm = FPathV[FPathN]+FBase;
179 
180  struct stat Stat;
181  int ErrCd = stat(FNm.CStr(), &Stat);
182  if (ErrCd != 0) {
183  Assert(ErrCd==0); // !bn: assert-with-exception [pa se drugje po tej funkciji]
184  }
185 
186  if (S_ISREG(Stat.st_mode)) {
187  if ((FBase!=".")&&(FBase!="..")){
188  TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
189  if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
190  ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
191  CurFNm=FNm; CurFNmN++; return true;}
192  }
193  } else if (S_ISDIR(Stat.st_mode) && RecurseP) {
194  if ((FBase!=".")&&(FBase!="..")){
195  TStr SubFPath=FPathV[FPathN]+FBase;
196  TStrV SubFPathV; SubFPathV.Add(SubFPath);
197  SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
198  if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
199  else {SubFFile=NULL;}
200  }
201  }
202  } else {
203  // end of directory; clean up (ignore DirEnt, it's allocated within FDesc), pass control to outer loop
204  FFileDesc->DirEnt = NULL;
205  int ErrCd = closedir(FFileDesc->FDesc);
206  FFileDesc->FDesc = NULL;
207  if (ErrCd != 0) {
208  Assert(ErrCd==0);
209  }
210  break;
211  }
212  }
213  }
214  // not found
215  CurFNm=""; CurFNmN=-1; return false;
216 }
217 #endif
218 
220  const TStr& FPath, const TStrV& FExtV, const bool& RecurseP, TStrV& FNmV){
221  // prepare file-directory traversal
222  TStrV FPathV; FPathV.Add(FPath);
223  TFFile FFile(FPathV, FExtV, "", RecurseP); TStr FNm;
224  // traverse directory
225  FNmV.Clr();
226  while (FFile.Next(FNm)){
227  FNmV.Add(FNm);
228  }
229 }
230 
232 // Directories
234  const int MxBfL=1000;
235  char Bf[MxBfL];
236  int BfL=GetCurrentDirectory(MxBfL, Bf);
237  IAssert((BfL!=0)&&(BfL<MxBfL));
238  return TStr::GetNrFPath(TStr(Bf));
239 }
240 
242  const int MxBfL=1000;
243  char Bf[MxBfL];
244  int BfL=GetModuleFileName(NULL, Bf, MxBfL);
245  IAssert((BfL!=0)&&(BfL<MxBfL));
246  return TStr::GetNrFPath(TStr(Bf).GetFPath());
247 }
248 
249 bool TDir::Exists(const TStr& FPathFNm) {
250 #if defined(GLib_UNIX)
251  struct stat Stat;
252  const int ErrCd = stat(FPathFNm.CStr(), &Stat);
253  if (ErrCd == 0 && S_ISDIR(Stat.st_mode)) { return true; }
254 #endif
255  return false;
256 }
257 
258 bool TDir::GenDir(const TStr& FPathFNm){
259  return CreateDirectory(FPathFNm.CStr(), NULL)!=0;
260 }
261 
262 bool TDir::DelDir(const TStr& FPathFNm){
263  return RemoveDirectory(FPathFNm.CStr())!=0;
264 }
265 
267 // File-Log
268 void TFPathNotify::UpdateSOut(const TTm& Tm) {
269  if (!LogSOut.Empty()) { LogSOut->Flush(); LogSOut.Clr(); }
270  TStr FNm = TStr::Fmt("%s-Y%04d-M%02d-D%02d-H%02d.log", PrefixFNm.CStr(),
271  Tm.GetYear(), Tm.GetMonth(), Tm.GetDay(), Tm.GetHour());
272  LogSOut = TFOut::New(LogFPath + FNm, true);
273 }
274 
275 TFPathNotify::TFPathNotify(const TStr& _LogFPath, const TStr& _PrefixFNm,
276  const bool& _FlushP): LogFPath(_LogFPath), PrefixFNm(_PrefixFNm),
277  FlushP(_FlushP) {
278 
281 }
282 
283 void TFPathNotify::OnStatus(const TStr& MsgStr) {
284  // check if new hour so we switch to new log file
285  TTm NowTm = TTm::GetCurUniTm();
286  if (NowTm.GetHour() != LastTm.GetHour()) {
287  LastTm = NowTm; UpdateSOut(LastTm);
288  }
289  // write log line
290  LogSOut->PutStrLn(MsgStr);
291  // we flush for each line when in debug mode
292  if (FlushP) { LogSOut->Flush(); }
293 }
#define IAssert(Cond)
Definition: bd.h:262
TStrV FExtV
Definition: xfl.h:32
static TStr GetCurDir()
Definition: xfl.cpp:233
static PSOut New(const TStr &FNm, const bool &Append=false)
Definition: fl.cpp:442
Definition: xfl.h:30
int GetMonth() const
Definition: tm.h:276
TStr GetFPath() const
Definition: dt.cpp:1389
TStr PrefixFNm
Definition: xfl.h:87
static void GetFNmV(const TStr &FPath, const TStrV &FExtV, const bool &RecurseP, TStrV &FNmV)
Definition: xfl.cpp:219
bool Next()
Definition: xfl.h:60
#define Fail
Definition: bd.h:238
bool Empty() const
Definition: bd.h:501
PFFileDesc FFileDesc
Definition: xfl.h:37
TSizeTy Len() const
Returns the number of elements in the vector.
Definition: ds.h:575
static TTm GetCurUniTm()
Definition: tm.cpp:1029
static bool DelDir(const TStr &FPathFNm)
Definition: xfl.cpp:262
TStr GetFExt() const
Definition: dt.cpp:1421
void Clr()
Definition: bd.h:502
TStr LogFPath
Definition: xfl.h:86
bool RecurseP
Definition: xfl.h:35
int GetHour() const
Definition: tm.h:281
TFPathNotify(const TStr &_LogFPath, const TStr &_PrefixFNm, const bool &_FlushP)
Definition: xfl.cpp:275
dirent * DirEnt
Definition: xfl.h:12
bool Empty() const
Tests whether the vector is empty.
Definition: ds.h:570
int GetYear() const
Definition: tm.h:275
PFFile SubFFile
Definition: xfl.h:38
TStr GetFBase() const
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector.
Definition: ds.h:1022
int GetDay() const
Definition: tm.h:278
bool CsImpP
Definition: xfl.h:34
TStr CurFNm
Definition: xfl.h:39
#define Assert(Cond)
Definition: bd.h:251
TStr FBaseWc
Definition: xfl.h:33
const TVal & Last() const
Returns a reference to the last element of the vector.
Definition: ds.h:579
TFFile(const TStr &_FNmWc, const bool &_RecurseP=false)
Definition: xfl.cpp:37
static TStr GetNrFPath(const TStr &FPath)
Definition: dt.cpp:1430
static TStr GetNrFExt(const TStr &FExt)
Definition: dt.cpp:1455
Definition: tm.h:213
int FPathN
Definition: xfl.h:36
virtual void Flush()=0
static bool Exists(const TStr &FPathFNm)
Definition: xfl.cpp:249
TStr & ToUc()
Definition: dt.cpp:752
TTm LastTm
Definition: xfl.h:88
static PFFile New(const TStr &FNmWc, const bool &RecurseP)
Definition: xfl.h:47
Definition: dt.h:412
bool Empty() const
Definition: dt.h:491
static TStr Fmt(const char *FmtStr,...)
Definition: dt.cpp:1599
TSizeTy SearchForw(const TVal &Val, const TSizeTy &BValN=0) const
Returns the position of an element with value Val.
Definition: ds.h:1552
void OnStatus(const TStr &MsgStr)
Definition: xfl.cpp:283
TStrV FPathV
Definition: xfl.h:32
bool Next(TStr &FNm)
void UpdateSOut(const TTm &NowTm)
Definition: xfl.cpp:268
char * CStr()
Definition: dt.h:479
int PutStrLn(const TStr &Str, const bool &ForceInLn=false)
Definition: fl.h:161
Definition: xfl.h:5
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
Definition: ds.h:602
TStr GetFBase() const
Definition: dt.cpp:1396
static bool GenDir(const TStr &FPathFNm)
Definition: xfl.cpp:258
bool IsDir() const
TBool FlushP
Definition: xfl.h:90
DIR * FDesc
Definition: xfl.h:11
static TStr GetExeDir()
Definition: xfl.cpp:241
int CurFNmN
Definition: xfl.h:40
PSOut LogSOut
Definition: xfl.h:89