SNAP Library 4.0, Developer Reference  2017-07-27 13:18:06
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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:488
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:476
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