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
fl.cpp
Go to the documentation of this file.
1 #ifdef GLib_LINUX
2 extern "C" {
3  #include <sys/mman.h>
4 }
5 
6 #endif
7 
9 // Check-Sum
10 const int TCs::MxMask=0x0FFFFFFF;
11 
12 TCs TCs::GetCsFromBf(char* Bf, const int& BfL){
13  TCs Cs;
14  for (int BfC=0; BfC<BfL; BfC++){Cs+=Bf[BfC];}
15  return Cs;
16 }
17 
19 // Stream-Base
21  return TStr(SNm.CStr());
22 }
23 
25 // Input-Stream
26 TSIn::TSIn(const TStr& Str) : TSBase(Str.CStr()), FastMode(false){}
27 
28 void TSIn::LoadCs(){
29  TCs CurCs=Cs; TCs TestCs;
30  Cs+=GetBf(&TestCs, sizeof(TestCs));
31  EAssertR(CurCs==TestCs, "Invalid checksum reading '"+GetSNm()+"'.");
32 }
33 
34 void TSIn::Load(char*& CStr){
35  char Ch; Load(Ch);
36  int CStrLen=int(Ch);
37  EAssertR(CStrLen>=0, "Error reading stream '"+GetSNm()+"'.");
38  CStr=new char[CStrLen+1];
39  if (CStrLen>0){Cs+=GetBf(CStr, CStrLen);}
40  CStr[CStrLen]=TCh::NullCh;
41 }
42 
43 bool TSIn::GetNextLn(TStr& LnStr){
44  TChA LnChA;
45  const bool IsNext=GetNextLn(LnChA);
46  LnStr=LnChA;
47  return IsNext;
48 }
49 
50 bool TSIn::GetNextLn(TChA& LnChA){
51  LnChA.Clr();
52  while (!Eof()){
53  const char Ch=GetCh();
54  if (Ch=='\n'){return true;}
55  if (Ch=='\r' && PeekCh()=='\n'){GetCh(); return true;}
56  LnChA.AddCh(Ch);
57  }
58  return !LnChA.Empty();
59 }
60 
61 const PSIn TSIn::StdIn=PSIn(new TStdIn());
62 
63 TStdIn::TStdIn(): TSBase("Standard input"), TSIn("Standard input") {}
64 
66 // Output-Stream
67 TSOut::TSOut(const TStr& Str):
68  TSBase(Str.CStr()), MxLnLen(-1), LnLen(0){}
69 
70 int TSOut::UpdateLnLen(const int& StrLen, const bool& ForceInLn){
71  int Cs=0;
72  if (MxLnLen!=-1){
73  if ((!ForceInLn)&&(LnLen+StrLen>MxLnLen)){Cs+=PutLn();}
74  LnLen+=StrLen;
75  }
76  return Cs;
77 }
78 
79 int TSOut::PutMem(const TMem& Mem){
80  return PutBf(Mem(), Mem.Len());
81 }
82 
83 int TSOut::PutCh(const char& Ch, const int& Chs){
84  int Cs=0;
85  for (int ChN=0; ChN<Chs; ChN++){Cs+=PutCh(Ch);}
86  return Cs;
87 }
88 
89 int TSOut::PutBool(const bool& Bool){
90  return PutStr(TBool::GetStr(Bool));
91 }
92 
93 int TSOut::PutInt(const int& Int){
94  return PutStr(TInt::GetStr(Int));
95 }
96 
97 int TSOut::PutInt(const int& Int, const char* FmtStr){
98  return PutStr(TInt::GetStr(Int, FmtStr));
99 }
100 
101 int TSOut::PutUInt(const uint& UInt){
102  return PutStr(TUInt::GetStr(UInt));
103 }
104 
105 int TSOut::PutUInt(const uint& UInt, const char* FmtStr){
106  return PutStr(TUInt::GetStr(UInt, FmtStr));
107 }
108 
109 int TSOut::PutFlt(const double& Flt){
110  return PutStr(TFlt::GetStr(Flt));
111 }
112 
113 int TSOut::PutFlt(const double& Flt, const char* FmtStr){
114  return PutStr(TFlt::GetStr(Flt, FmtStr));
115 }
116 
117 int TSOut::PutStr(const char* CStr){
118  int Cs=UpdateLnLen(int(strlen(CStr)));
119  return Cs+PutBf(CStr, int(strlen(CStr)));
120 }
121 
122 int TSOut::PutStr(const TChA& ChA){
123  int Cs=UpdateLnLen(ChA.Len());
124  return Cs+PutBf(ChA.CStr(), ChA.Len());
125 }
126 
127 int TSOut::PutStr(const TStr& Str, const char* FmtStr){
128  return PutStr(TStr::GetStr(Str, FmtStr));
129 }
130 
131 int TSOut::PutStr(const TStr& Str, const bool& ForceInLn){
132  int Cs=UpdateLnLen(Str.Len(), ForceInLn);
133  return Cs+PutBf(Str.CStr(), Str.Len());
134 }
135 
136 int TSOut::PutStrFmt(const char *FmtStr, ...){
137  char Bf[10*1024];
138  va_list valist;
139  va_start(valist, FmtStr);
140  const int RetVal=vsnprintf(Bf, 10*1024-2, FmtStr, valist);
141  va_end(valist);
142  return RetVal!=-1 ? PutStr(TStr(Bf)) : 0;
143 }
144 
145 int TSOut::PutStrFmtLn(const char *FmtStr, ...){
146  char Bf[10*1024];
147  va_list valist;
148  va_start(valist, FmtStr);
149  const int RetVal=vsnprintf(Bf, 10*1024-2, FmtStr, valist);
150  va_end(valist);
151  return RetVal!=-1 ? PutStrLn(TStr(Bf)) : PutLn();
152 }
153 
154 int TSOut::PutIndent(const int& IndentLev){
155  return PutCh(' ', IndentLev*2);
156 }
157 
158 int TSOut::PutLn(const int& Lns){
159  LnLen=0; int Cs=0;
160  for (int LnN=0; LnN<Lns; LnN++){Cs+=PutCh('\n');}
161  return Cs;
162 }
163 
164 int TSOut::PutDosLn(const int& Lns){
165  LnLen=0; int Cs=0;
166  for (int LnN=0; LnN<Lns; LnN++){Cs+=PutCh(TCh::CrCh)+PutCh(TCh::LfCh);}
167  return Cs;
168 }
169 
170 int TSOut::PutSep(const int& NextStrLen){
171  int Cs=0;
172  if (MxLnLen==-1){
173  Cs+=PutCh(' ');
174  } else {
175  if (LnLen>0){
176  if (LnLen+1+NextStrLen>MxLnLen){Cs+=PutLn();} else {Cs+=PutCh(' ');}
177  }
178  }
179  return Cs;
180 }
181 
182 int TSOut::PutSepLn(const int& Lns){
183  int Cs=0;
184  if (LnLen>0){Cs+=PutLn();}
185  Cs+=PutLn(Lns);
186  return Cs;
187 }
188 
189 void TSOut::Save(const char* CStr){
190  int CStrLen=int(strlen(CStr));
191  EAssertR(CStrLen<=127, "Error writting stream '"+GetSNm()+"'.");
192  Save(char(CStrLen));
193  if (CStrLen>0){Cs+=PutBf(CStr, CStrLen);}
194 }
195 
196 void TSOut::Save(TSIn& SIn, const TSize& BfL){
197  Fail;
198  if (BfL==0){ //J: used to be ==-1
199  while (!SIn.Eof()){Save(SIn.GetCh());}
200  } else {
201  for (TSize BfC=0; BfC<BfL; BfC++){Save(SIn.GetCh());}
202  }
203 }
204 
206  while (!SIn.Eof())
207  operator<<((char)SIn.GetCh());
208  return *this;
209 }
210 
211 const PSOut TSOut::StdOut=PSOut(new TStdOut());
212 
213 TStdOut::TStdOut(): TSBase(TSStr("Standard output")), TSOut("Standard output"){}
214 
216 // Standard-Input
217 int TStdIn::GetBf(const void* LBf, const TSize& LBfL){
218  int LBfS=0;
219  for (TSize LBfC=0; LBfC<LBfL; LBfC++){
220  LBfS+=(((char*)LBf)[LBfC]=GetCh());}
221  return LBfS;
222 }
223 
225  // not implemented
226  FailR(TStr::Fmt("TStdIn::GetNextLnBf: not implemented").CStr());
227  return false;
228 }
229 
231 // Standard-Output
232 int TStdOut::PutBf(const void* LBf, const TSize& LBfL){
233  int LBfS=0;
234  for (TSize LBfC=0; LBfC<LBfL; LBfC++){
235  LBfS+=PutCh(((char*)LBf)[LBfC]);}
236  return LBfS;
237 }
238 
240 // Input-File
241 const int TFIn::MxBfL=16*1024;
242 
243 void TFIn::SetFPos(const int& FPos) const {
244  EAssertR(
245  fseek(FileId, FPos, SEEK_SET)==0,
246  "Error seeking into file '"+GetSNm()+"'.");
247 }
248 
249 int TFIn::GetFPos() const {
250  const int FPos=(int)ftell(FileId);
251  EAssertR(FPos!=-1, "Error seeking into file '"+GetSNm()+"'.");
252  return FPos;
253 }
254 
255 int TFIn::GetFLen() const {
256  const int FPos=GetFPos();
257  EAssertR(
258  fseek(FileId, 0, SEEK_END)==0,
259  "Error seeking into file '"+GetSNm()+"'.");
260  const int FLen=GetFPos(); SetFPos(FPos);
261  return FLen;
262 }
263 
265  EAssertR(
266  (BfC==BfL)&&((BfL==-1)||(BfL==MxBfL)),
267  "Error reading file '"+GetSNm()+"'.");
268  BfL=int(fread(Bf, 1, MxBfL, FileId));
269  EAssertR((BfC!=0)||(BfL!=0), "Error reading file '"+GetSNm()+"'.");
270  BfC=0;
271 }
272 
273 TFIn::TFIn(const TStr& FNm):
274  TSBase(FNm.CStr()), TSIn(FNm), FileId(NULL), Bf(NULL), BfC(0), BfL(0){
275  EAssertR(!FNm.Empty(), "Empty file-name.");
276  FileId=fopen(FNm.CStr(), "rb");
277  EAssertR(FileId!=NULL, "Can not open file '"+FNm+"'.");
278  Bf=new char[MxBfL]; BfC=BfL=-1; FillBf();
279 }
280 
281 TFIn::TFIn(const TStr& FNm, bool& OpenedP):
282  TSBase(FNm.CStr()), TSIn(FNm), FileId(NULL), Bf(NULL), BfC(0), BfL(0){
283  EAssertR(!FNm.Empty(), "Empty file-name.");
284  FileId=fopen(FNm.CStr(), "rb");
285  OpenedP=(FileId!=NULL);
286  if (OpenedP){
287  Bf=new char[MxBfL]; BfC=BfL=-1; FillBf();}
288 }
289 
290 PSIn TFIn::New(const TStr& FNm){
291  try {
292  return PSIn(new TFIn(FNm));
293  } catch (PExcept& Except) {
294  printf("*** Exception: %s\n", Except->GetMsgStr().CStr());
295  EFailR(Except->GetMsgStr());
296  }
297 
298  return PSIn(new TFIn(FNm));
299 }
300 
301 PSIn TFIn::New(const TStr& FNm, bool& OpenedP){
302  return PSIn(new TFIn(FNm, OpenedP));
303 }
304 
306  if (FileId!=NULL){
307  EAssertR(fclose(FileId)==0, "Can not close file '"+GetSNm()+"'.");}
308  if (Bf!=NULL){delete[] Bf;}
309 }
310 
311 int TFIn::GetBf(const void* LBf, const TSize& LBfL){
312  int LBfS=0;
313  if (TSize(BfC+LBfL)>TSize(BfL)){
314  for (TSize LBfC=0; LBfC<LBfL; LBfC++){
315  if (BfC==BfL){FillBf();}
316  LBfS+=((char*)LBf)[LBfC]=Bf[BfC++];}
317  } else {
318  for (TSize LBfC=0; LBfC<LBfL; LBfC++){
319  LBfS+=(((char*)LBf)[LBfC]=Bf[BfC++]);}
320  }
321  return LBfS;
322 }
323 
324 // Gets the next line to LnChA.
325 // Returns true, if LnChA contains a valid line.
326 // Returns false, if LnChA is empty, such as end of file was encountered.
327 
328 bool TFIn::GetNextLnBf(TChA& LnChA) {
329  int Status;
330  int BfN; // new pointer to the end of line
331  int BfP; // previous pointer to the line start
332  bool CrEnd; // last character in previous buffer was CR
333 
334  LnChA.Clr();
335 
336  CrEnd = false;
337  do {
338  if (BfC >= BfL) {
339  // reset the current pointer, FindEol() will read a new buffer
340  BfP = 0;
341  } else {
342  BfP = BfC;
343  }
344  Status = FindEol(BfN,CrEnd);
345  if (Status >= 0) {
346  if (BfN-BfP > 0) {
347  LnChA.AddBf(&Bf[BfP],BfN-BfP);
348  }
349  if (Status == 1) {
350  // got a complete line
351  return true;
352  }
353  }
354  // get more data, if the line is incomplete
355  } while (Status == 0);
356 
357  // eof or the last line has no newline
358  return !LnChA.Empty();
359 }
360 
361 // Sets BfN to the end of line or end of buffer. Reads more data, if needed.
362 // Returns 1, when an end of line was found, BfN is end of line.
363 // Returns 0, when an end of line was not found and more data is required,
364 // BfN is end of buffer.
365 // Returns -1, when an end of file was found, BfN is not defined.
366 
367 int TFIn::FindEol(int& BfN, bool& CrEnd) {
368  char Ch;
369 
370  if (BfC >= BfL) {
371  // read more data, check for eof
372  if (Eof()) {
373  return -1;
374  }
375  if (CrEnd && Bf[BfC]=='\n') {
376  BfC++;
377  BfN = BfC-1;
378  return 1;
379  }
380  }
381 
382  CrEnd = false;
383  while (BfC < BfL) {
384  Ch = Bf[BfC++];
385  if (Ch=='\n') {
386  BfN = BfC-1;
387  return 1;
388  }
389  if (Ch=='\r') {
390  if (BfC == BfL) {
391  CrEnd = true;
392  BfN = BfC-1;
393  return 0;
394  } else if (Bf[BfC]=='\n') {
395  BfC++;
396  BfN = BfC-2;
397  return 1;
398  }
399  }
400  }
401  BfN = BfC;
402 
403  return 0;
404 }
405 
407 // Output-File
408 const TSize TFOut::MxBfL=16*1024;;
409 
411  EAssertR(
412  fwrite(Bf, 1, BfL, FileId)==BfL,
413  "Error writting to the file '"+GetSNm()+"'.");
414  BfL=0;
415 }
416 
417 TFOut::TFOut(const TStr& FNm, const bool& Append):
418  TSBase(FNm.CStr()), TSOut(FNm), FileId(NULL), Bf(NULL), BfL(0){
419  if (FNm.GetUc()=="CON"){
420  FileId=stdout;
421  } else {
422  if (Append){FileId=fopen(FNm.CStr(), "a+b");}
423  else {FileId=fopen(FNm.CStr(), "w+b");}
424  EAssertR(FileId!=NULL, "Can not open file '"+FNm+"'.");
425  Bf=new char[MxBfL]; BfL=0;
426  }
427 }
428 
429 TFOut::TFOut(const TStr& FNm, const bool& Append, bool& OpenedP):
430  TSBase(FNm.CStr()), TSOut(FNm), FileId(NULL), Bf(NULL), BfL(0){
431  if (FNm.GetUc()=="CON"){
432  FileId=stdout;
433  } else {
434  if (Append){FileId=fopen(FNm.CStr(), "a+b");}
435  else {FileId=fopen(FNm.CStr(), "w+b");}
436  OpenedP=(FileId!=NULL);
437  if (OpenedP){
438  Bf=new char[MxBfL]; BfL=0;}
439  }
440 }
441 
442 PSOut TFOut::New(const TStr& FNm, const bool& Append){
443  return PSOut(new TFOut(FNm, Append));
444 }
445 
446 PSOut TFOut::New(const TStr& FNm, const bool& Append, bool& OpenedP){
447  PSOut SOut=PSOut(new TFOut(FNm, Append, OpenedP));
448  if (OpenedP){return SOut;} else {return NULL;}
449 }
450 
452  if (FileId!=NULL){FlushBf();}
453  if (Bf!=NULL){delete[] Bf;}
454  if (FileId!=NULL){
455  EAssertR(fclose(FileId)==0, "Can not close file '"+GetSNm()+"'.");}
456 }
457 
458 int TFOut::PutCh(const char& Ch){
459  if (BfL==TSize(MxBfL)){FlushBf();}
460  return Bf[BfL++]=Ch;
461 }
462 
463 int TFOut::PutBf(const void* LBf, const TSize& LBfL){
464  int LBfS=0;
465  if (BfL+LBfL>MxBfL){
466  for (TSize LBfC=0; LBfC<LBfL; LBfC++){
467  LBfS+=PutCh(((char*)LBf)[LBfC]);}
468  } else {
469  for (TSize LBfC=0; LBfC<LBfL; LBfC++){
470  LBfS+=(Bf[BfL++]=((char*)LBf)[LBfC]);}
471  }
472  return LBfS;
473 }
474 
476  FlushBf();
477  EAssertR(fflush(FileId)==0, "Can not flush file '"+GetSNm()+"'.");
478 }
479 
481 // Input-Output-File
482 TFInOut::TFInOut(const TStr& FNm, const TFAccess& FAccess, const bool& CreateIfNo) :
483  TSBase(TSStr(FNm.CStr())), FileId(NULL) {
484  switch (FAccess){
485  case faCreate: FileId=fopen(FNm.CStr(), "w+b"); break;
486  case faUpdate: FileId=fopen(FNm.CStr(), "r+b"); break;
487  case faAppend: FileId=fopen(FNm.CStr(), "r+b");
488  if (FileId!=NULL){fseek(FileId, SEEK_END, 0);} break;
489  case faRdOnly: FileId=fopen(FNm.CStr(), "rb"); break;
490  default: Fail;
491  }
492  if ((FileId==NULL)&&(CreateIfNo)){FileId=fopen(FNm.CStr(), "w+b");}
493  IAssert(FileId!=NULL);
494 }
495 
496 PSInOut TFInOut::New(const TStr& FNm, const TFAccess& FAccess, const bool& CreateIfNo) {
497  return PSInOut(new TFInOut(FNm, FAccess, CreateIfNo));
498 }
499 
500 int TFInOut::GetSize() const {
501  const int FPos = GetPos();
502  IAssert(fseek(FileId, 0, SEEK_END) == 0);
503  const int FLen = GetPos();
504  IAssert(fseek(FileId, FPos, SEEK_SET) == 0);
505  return FLen;
506 }
507 
508 int TFInOut::PutBf(const void* LBf, const TSize& LBfL) {
509  int LBfS = 0;
510  for (TSize i = 0; i < LBfL; i++) {
511  LBfS += ((char *)LBf)[i];
512  }
513  IAssert(fwrite(LBf, sizeof(char), LBfL, FileId) == (size_t) LBfL);
514  return LBfS;
515 }
516 
517 int TFInOut::GetBf(const void* LBf, const TSize& LBfL) {
518  IAssert(fread((void *)LBf, sizeof(char), LBfL, FileId) == (size_t) LBfL);
519  int LBfS = 0;
520  for (TSize i = 0; i < LBfL; i++) {
521  LBfS += ((char *)LBf)[i];
522  }
523  return LBfS;
524 }
525 
527  // not implemented
528  FailR(TStr::Fmt("TFInOut::GetNextLnBf: not implemented").CStr());
529  return false;
530 }
531 
533  return GetSNm();
534 }
535 
537 // Shared-Memory
538 TShMIn::TShMIn(const TStr& Str): TSBase("Input-Shared_Memory"),
539  TSIn("Input-Shared_Memory"), TotalLength(0),
540  SizeLeft(0) {
541 
542 #ifdef GLib_LINUX
543  TStr FNm = Str;
544  TFileId FileId;
545  int fd;
546  uint64 FLen;
547  EAssertR(!FNm.Empty(), "Empty file-name.");
548  FileId=fopen(FNm.CStr(), "rb");
549  fd = fileno(FileId);
550  EAssertR(FileId!=NULL, "Can not open file '"+FNm+"'.");
551  EAssertR(
552  fseek(FileId, 0, SEEK_END)==0,
553  "Error seeking into file '"+TStr(FNm)+"'.");
554  FLen=(uint64)ftell(FileId);
555  EAssertR(
556  fseek(FileId, 0, SEEK_SET)==0,
557  "Error seeking into file '"+TStr(FNm)+"'.");
558  char *Mapped;
559  Mapped = (char *) mmap (0, FLen, PROT_READ, MAP_PRIVATE, fd, 0);
560  EAssertR(Mapped!=MAP_FAILED, "mmap failed in TShMIn.");
561  OriginalBuffer = Mapped;
563  SizeLeft = FLen;
564  TotalLength = FLen;
565  IsMemoryMapped = true;
566 #else
567  TExcept::Throw("TMIn::TMIn(TStr, Bool): GLib_LINUX undefined.\n");
568 #endif
569  }
570 
571 TShMIn::TShMIn(void* _Bf, const TSize& _BfL): TSBase("Input-Shared_Memory"),
572  TSIn("Input-Shared_Memory"), TotalLength(_BfL), SizeLeft(_BfL), IsMemoryMapped(false) {
573  OriginalBuffer = (char*)_Bf;
574  Cursor = (char*)_Bf;
575  }
576 
578  if (OriginalBuffer!=NULL){
579  if (IsMemoryMapped) {
580 #ifdef GLib_LINUX
581  munmap(OriginalBuffer, TotalLength);
582  IsMemoryMapped = false;
583  OriginalBuffer = NULL;
584  Cursor = NULL;
585  TotalLength= 0;
586  SizeLeft = 0;
587 #endif
588  }
589  }
590 }
591 
593 // Input-Memory
594 TMIn::TMIn(const void* _Bf, const uint64& _BfL, const bool& TakeBf):
595  TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(_BfL), IsMemoryMapped(false){
596  if (TakeBf){
597  Bf=(char*)_Bf;
598  } else {
599  Bf=new char[static_cast<size_t>(BfL)]; memmove(Bf, _Bf, static_cast<size_t>(BfL));
600  }
601 }
602 
604  TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(0), IsMemoryMapped(false){
605  BfL=SIn.Len(); Bf=new char[static_cast<size_t>(BfL)];
606  for (uint64 BfC=0; BfC<BfL; BfC++){Bf[BfC]=SIn.GetCh();}
607 }
608 
609 TMIn::TMIn(const char* CStr):
610  TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(0), IsMemoryMapped(false){
611  BfL=uint64(strlen(CStr)); Bf=new char[static_cast<size_t>(BfL+1)]; strcpy(Bf, CStr);
612 }
613 
614 /* GLib_LINUX should be defined if FromFile is true */
615 TMIn::TMIn(const TStr& Str, bool FromFile):
616  TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(0){
617  if (FromFile == false) {
618  BfL=Str.Len(); Bf=new char[static_cast<size_t>(BfL)]; strncpy(Bf, Str.CStr(), static_cast<size_t>(BfL));
619  IsMemoryMapped = false;
620  }
621  else {
622 #ifdef GLib_LINUX
623  TStr FNm = Str;
624  TFileId FileId;
625  int fd;
626  uint64 FLen;
627  EAssertR(!FNm.Empty(), "Empty file-name.");
628  FileId=fopen(FNm.CStr(), "rb");
629  fd = fileno(FileId);
630 
631  EAssertR(FileId!=NULL, "Can not open file '"+FNm+"'.");
632 
633  EAssertR(
634  fseek(FileId, 0, SEEK_END)==0,
635  "Error seeking into file '"+TStr(FNm)+"'.");
636  FLen=(uint64)ftell(FileId);
637  EAssertR(
638  fseek(FileId, 0, SEEK_SET)==0,
639  "Error seeking into file '"+TStr(FNm)+"'.");
640 
641  // memory map contents of file
642  char *mapped;
643  mapped = (char *) mmap (0, FLen, PROT_READ, MAP_PRIVATE, fd, 0);
644  IsMemoryMapped = true;
645 
646  if (mapped == MAP_FAILED) {
647  printf("mmap failed: %d %s\n", fd, strerror (errno));
648  Bf = NULL;
649  BfC = BfL = 0;
650  }
651  else {
652  Bf = mapped;
653  BfC = 0;
654  BfL = FLen;
655  }
656  IsMemoryMapped = true;
657 #else
658  TExcept::Throw("TMIn::TMIn(TStr, Bool): GLib_LINUX undefined.\n");
659 #endif
660  }
661 }
662 
663 TMIn::TMIn(const TChA& ChA):
664  TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(0), IsMemoryMapped(false){
665  BfL=ChA.Len(); Bf=new char[static_cast<size_t>(BfL)]; strncpy(Bf, ChA.CStr(), static_cast<size_t>(BfL));
666 }
667 
668 PSIn TMIn::New(const void* _Bf, const uint64& _BfL, const bool& TakeBf){
669  return PSIn(new TMIn(_Bf, _BfL, TakeBf));
670 }
671 
672 PSIn TMIn::New(const char* CStr){
673  return PSIn(new TMIn(CStr));
674 }
675 
676 PSIn TMIn::New(const TStr& Str){
677  return PSIn(new TMIn(Str));
678 }
679 
680 PMIn TMIn::New(const TStr& Str, bool FromFile){
681  return new TMIn(Str, FromFile);
682 }
683 
684 PSIn TMIn::New(const TChA& ChA){
685  return PSIn(new TMIn(ChA));
686 }
687 
689  if (Bf!=NULL){
690  if (IsMemoryMapped) {
691 #ifdef GLib_LINUX
692  munmap(Bf, BfL);
693 #endif
694  }
695  else {
696  delete[] Bf;
697  }
698  }
699 }
700 
701 char TMIn::GetCh(){
702  EAssertR(BfC<BfL, "Reading beyond the end of stream.");
703  return Bf[BfC++];
704 }
705 
707  EAssertR(BfC<BfL, "Reading beyond the end of stream.");
708  return Bf[BfC];
709 }
710 
711 int TMIn::GetBf(const void* LBf, const TSize& LBfL){
712  EAssertR(TSize(BfC+LBfL)<=TSize(BfL), "Reading beyond the end of stream.");
713  int LBfS=0;
714  for (TSize LBfC=0; LBfC<LBfL; LBfC++){
715  LBfS+=(((char*)LBf)[LBfC]=Bf[BfC++]);}
716  return LBfS;
717 }
718 
719 // Sets BfN to the end of line or end of buffer.
720 // Returns 1, when an end of line was found, BfN is end of line.
721 // Returns 0, when an end of line was not found and more data is required,
722 // BfN is end of buffer.
723 // Returns -1, when an end of file was found, BfN is not defined.
724 
725 int TMIn::FindEol(uint64& BfN, bool& CrEnd) {
726  char Ch;
727  if (BfC >= BfL) {
728  // read more data, check for eof
729  if (Eof()) {
730  return -1;
731  }
732  if (CrEnd && Bf[BfC]=='\n') {
733  BfC++;
734  BfN = BfC-1;
735  return 1;
736  }
737  }
738 
739  CrEnd = false;
740  while (BfC < BfL) {
741  Ch = Bf[BfC++];
742  if (Ch=='\n') {
743  BfN = BfC-1;
744  return 1;
745  }
746  if (Ch=='\r') {
747  if (BfC == BfL) {
748  CrEnd = true;
749  BfN = BfC-1;
750  return 0;
751  } else if (Bf[BfC]=='\n') {
752  BfC++;
753  BfN = BfC-2;
754  return 1;
755  }
756  }
757  }
758  BfN = BfC;
759 
760  return 0;
761 }
762 
763 bool TMIn::GetNextLnBf(TChA& LnChA){
764  // not implemented
765  FailR(TStr::Fmt("TMIn::GetNextLnBf: not implemented").CStr());
766  return false;
767 }
768 
770  return BfC;
771 }
772 
774  return BfL;
775 }
776 
777 void TMIn::SetBfC(uint64 Pos) {
778  BfC = Pos;
779 }
780 
781 // Assumes that lines end in '\n'
783  uint64 Cnt = 0;
784  if (Lb >= BfL) {
785  return 0;
786  }
787  for (uint64 i = Lb; i < Ub; i++) {
788  if (Bf[i] == '\n') {
789  Cnt += 1;
790  }
791  }
792  return Cnt;
793 }
794 
796  while (Ind > 0 && Bf[Ind-1] != '\n') {
797  Ind--;
798  }
799  return Ind;
800 }
801 
803  while (Ind < BfL && Bf[Ind] != '\n') {
804  Ind++;
805  }
806  if (Ind == BfL) Ind--;
807  return Ind;
808 }
809 
810 char* TMIn::GetLine(uint64 Index) {
811  return &Bf[Index];
812 }
813 
815  while (BfC < BfL && TCh::IsHashCh(Bf[BfC])) {
816  while (BfC < BfL && Bf[BfC] != '\n') {
817  BfC++;
818  }
819  BfC++;
820  }
821 }
822 
824 // Output-Memory
825 void TMOut::Resize(const int& ReqLen){
826  IAssert(OwnBf&&(BfL==MxBfL || ReqLen >= 0));
827  if (Bf==NULL){
828  IAssert(MxBfL==0);
829  if (ReqLen < 0) Bf=new char[MxBfL=1024];
830  else Bf=new char[MxBfL=ReqLen];
831  } else {
832  if (ReqLen < 0){ MxBfL*=2; }
833  else if (ReqLen < MxBfL){ return; } // nothing to do
834  else { MxBfL=(2*MxBfL < ReqLen ? ReqLen : 2*MxBfL); }
835  char* NewBf=new char[MxBfL];
836  memmove(NewBf, Bf, BfL); delete[] Bf; Bf=NewBf;
837  }
838 }
839 
840 TMOut::TMOut(const int& _MxBfL):
841  TSBase("Output-Memory"), TSOut("Output-Memory"),
842  Bf(NULL), BfL(0), MxBfL(0), OwnBf(true){
843  MxBfL=_MxBfL>0?_MxBfL:1024;
844  Bf=new char[MxBfL];
845 }
846 
847 TMOut::TMOut(char* _Bf, const int& _MxBfL):
848  TSBase("Output-Memory"), TSOut("Output-Memory"),
849  Bf(_Bf), BfL(0), MxBfL(_MxBfL), OwnBf(false){}
850 
851 void TMOut::AppendBf(const void* LBf, const TSize& LBfL) {
852  Resize(Len() + (int)LBfL);
853  memcpy(Bf + BfL, LBf, LBfL);
854  BfL += (int)LBfL;
855 }
856 
857 int TMOut::PutBf(const void* LBf, const TSize& LBfL){
858  int LBfS=0;
859  if (TSize(BfL+LBfL)>TSize(MxBfL)){
860  for (TSize LBfC=0; LBfC<LBfL; LBfC++){
861  LBfS+=PutCh(((char*)LBf)[LBfC]);}
862  } else {
863  for (TSize LBfC=0; LBfC<LBfL; LBfC++){
864  LBfS+=(Bf[BfL++]=((char*)LBf)[LBfC]);}
865  }
866  return LBfS;
867 }
868 
870  TChA ChA(BfL);
871  for (int BfC=0; BfC<BfL; BfC++){ChA+=Bf[BfC];}
872  return ChA;
873 }
874 
875 void TMOut::CutBf(const int& CutBfL){
876  IAssert((0<=CutBfL)&&(CutBfL<=BfL));
877  if (CutBfL==BfL){BfL=0;}
878  else {memmove(Bf, Bf+CutBfL, BfL-CutBfL); BfL=BfL-CutBfL;}
879 }
880 
881 PSIn TMOut::GetSIn(const bool& IsCut, const int& CutBfL){
882  IAssert((CutBfL==-1)||((0<=CutBfL)));
883  int SInBfL= (CutBfL==-1) ? BfL : TInt::GetMn(BfL, CutBfL);
884  PSIn SIn;
885  if (OwnBf&&IsCut&&(SInBfL==BfL)){
886  SIn=PSIn(new TMIn(Bf, SInBfL, true));
887  Bf=NULL; BfL=MxBfL=0; OwnBf=true;
888  } else {
889  SIn=PSIn(new TMIn(Bf, SInBfL, false));
890  if (IsCut){CutBf(SInBfL);}
891  }
892  return SIn;
893 }
894 
895 bool TMOut::IsCrLfLn() const {
896  for (int BfC=0; BfC<BfL; BfC++){
897  if ((Bf[BfC]==TCh::CrCh)&&((BfC+1<BfL)&&(Bf[BfC+1]==TCh::LfCh))){return true;}}
898  return false;
899 }
900 
902  IAssert(IsCrLfLn());
903  TChA Ln;
904  for (int BfC=0; BfC<BfL; BfC++){
905  char Ch=Bf[BfC];
906  if ((Ch==TCh::CrCh)&&((BfC+1<BfL)&&(Bf[BfC+1]==TCh::LfCh))){
907  Ln+=TCh::CrCh; Ln+=TCh::LfCh; CutBf(BfC+1+1); break;
908  } else {
909  Ln+=Ch;
910  }
911  }
912  return Ln;
913 }
914 
915 bool TMOut::IsEolnLn() const {
916  for (int BfC=0; BfC<BfL; BfC++){
917  if ((Bf[BfC]==TCh::CrCh)||(Bf[BfC]==TCh::LfCh)){return true;}
918  }
919  return false;
920 }
921 
922 TStr TMOut::GetEolnLn(const bool& DoAddEoln, const bool& DoCutBf){
923  IAssert(IsEolnLn());
924  int LnChs=0; TChA Ln;
925  for (int BfC=0; BfC<BfL; BfC++){
926  char Ch=Bf[BfC];
927  if ((Ch==TCh::CrCh)||(Ch==TCh::LfCh)){
928  LnChs++; if (DoAddEoln){Ln+=Ch;}
929  if (BfC+1<BfL){
930  char NextCh=Bf[BfC+1];
931  if (((Ch==TCh::CrCh)&&(NextCh==TCh::LfCh))||
932  ((Ch==TCh::LfCh)&&(NextCh==TCh::CrCh))){
933  LnChs++; if (DoAddEoln){Ln+=NextCh;}
934  }
935  }
936  break;
937  } else {
938  LnChs++; Ln+=Ch;
939  }
940  }
941  if (DoCutBf){
942  CutBf(LnChs);
943  }
944  return Ln;
945 }
946 
948  if (!IsEolnLn()){
950 }
951 
953 // Line-Returner
954 // J: after talking to BlazF -- can be removed from GLib
955 bool TLnRet::NextLn(TStr& LnStr) {
956  if (SIn->Eof()) { return false; }
957  TChA LnChA; char Ch = TCh::EofCh;
958  while (!SIn->Eof() && ((Ch=SIn->GetCh())!='\n')) {
959  if (Ch != '\r') { LnChA += Ch; }
960  }
961  LnStr = LnChA; return true;
962 }
963 
965 // fseek-Constants-Definitions
966 // because of strange Borland CBuilder behaviour in sysdefs.h
967 #ifndef SEEK_SET
968 #define SEEK_CUR 1
969 #define SEEK_END 2
970 #define SEEK_SET 0
971 #endif
972 
974 // Random-File
976  EAssertR(
977  fseek(FileId, 0, SEEK_CUR)==0,
978  "Error seeking into file '"+TStr(FNm)+"'.");
979 }
980 
981 TFRnd::TFRnd(const TStr& _FNm, const TFAccess& FAccess,
982  const bool& CreateIfNo, const int& _HdLen, const int& _RecLen):
983  FileId(NULL), FNm(_FNm.CStr()),
984  RecAct(false), HdLen(_HdLen), RecLen(_RecLen){
985  RecAct=(HdLen>=0)&&(RecLen>0);
986  switch (FAccess){
987  case faCreate: FileId=fopen(FNm.CStr(), "w+b"); break;
988  case faUpdate: FileId=fopen(FNm.CStr(), "r+b"); break;
989  case faAppend: FileId=fopen(FNm.CStr(), "r+b");
990  if (FileId!=NULL){fseek(FileId, SEEK_END, 0);} break;
991  case faRdOnly: FileId=fopen(FNm.CStr(), "rb"); break;
992  default: Fail;
993  }
994  if ((FileId==NULL)&&(CreateIfNo)){
995  FileId=fopen(FNm.CStr(), "w+b");}
996  EAssertR(FileId!=NULL, "Can not open file '"+_FNm+"'.");
997 }
998 
1000  EAssertR(fclose(FileId)==0, "Can not close file '"+TStr(FNm)+"'.");
1001 }
1002 
1004  return FNm.CStr();
1005 }
1006 
1007 void TFRnd::SetFPos(const int& FPos){
1008  EAssertR(
1009  fseek(FileId, FPos, SEEK_SET)==0,
1010  "Error seeking into file '"+TStr(FNm)+"'.");
1011 }
1012 
1013 void TFRnd::MoveFPos(const int& DFPos){
1014  EAssertR(
1015  fseek(FileId, DFPos, SEEK_CUR)==0,
1016  "Error seeking into file '"+TStr(FNm)+"'.");
1017 }
1018 
1020  int FPos= (int) ftell(FileId);
1021  EAssertR(FPos!=-1, "Error seeking into file '"+TStr(FNm)+"'.");
1022  return FPos;
1023 }
1024 
1026  int FPos=GetFPos();
1027  EAssertR(
1028  fseek(FileId, 0, SEEK_END)==0,
1029  "Error seeking into file '"+TStr(FNm)+"'.");
1030  int FLen=GetFPos(); SetFPos(FPos); return FLen;
1031 }
1032 
1033 void TFRnd::SetRecN(const int& RecN){
1034  IAssert(RecAct);
1035  SetFPos(HdLen+RecN*RecLen);
1036 }
1037 
1039  IAssert(RecAct);
1040  int FPos=GetFPos()-HdLen;
1041  EAssertR(FPos%RecLen==0, "Invalid position in file'"+TStr(FNm)+"'.");
1042  return FPos/RecLen;
1043 }
1044 
1046  IAssert(RecAct);
1047  int FLen=GetFLen()-HdLen;
1048  EAssertR(FLen%RecLen==0, "Invalid length of file'"+TStr(FNm)+"'.");
1049  return FLen/RecLen;
1050 }
1051 
1052 void TFRnd::GetBf(void* Bf, const TSize& BfL){
1053  RefreshFPos();
1054  EAssertR(
1055  fread(Bf, 1, BfL, FileId)==BfL,
1056  "Error reading file '"+TStr(FNm)+"'.");
1057 }
1058 
1059 void TFRnd::PutBf(const void* Bf, const TSize& BfL){
1060  RefreshFPos();
1061  EAssertR(
1062  fwrite(Bf, 1, BfL, FileId)==BfL,
1063  "Error writting to the file '"+TStr(FNm)+"'.");
1064 }
1065 
1067  EAssertR(fflush(FileId)==0, "Can not flush file '"+TStr(FNm)+"'.");
1068 }
1069 
1070 void TFRnd::PutCh(const char& Ch, const int& Chs){
1071  if (Chs>0){
1072  char* CStr=new char[Chs];
1073  for (int ChN=0; ChN<Chs; ChN++){CStr[ChN]=Ch;}
1074  PutBf(CStr, Chs);
1075  delete[] CStr;
1076  }
1077 }
1078 
1079 void TFRnd::PutStr(const TStr& Str){
1080  PutBf(Str.CStr(), Str.Len()+1);
1081 }
1082 
1083 TStr TFRnd::GetStr(const int& StrLen, bool& IsOk){
1084  IsOk=false; TStr Str;
1085  if (GetFPos()+StrLen+1<=GetFLen()){
1086  char* CStr=new char[StrLen+1];
1087  GetBf(CStr, StrLen+1);
1088  if (CStr[StrLen+1-1]==TCh::NullCh){IsOk=true; Str=CStr;}
1089  delete[] CStr;
1090  }
1091  return Str;
1092 }
1093 
1094 TStr TFRnd::GetStr(const int& StrLen){
1095  TStr Str;
1096  char* CStr=new char[StrLen+1];
1097  GetBf(CStr, StrLen+1);
1098  EAssertR(CStr[StrLen+1-1]==TCh::NullCh, "Error reading file '"+TStr(FNm)+"'.");
1099  Str=CStr;
1100  delete[] CStr;
1101  return Str;
1102 }
1103 
1104 void TFRnd::PutSIn(const PSIn& SIn, TCs& Cs){
1105  int BfL=SIn->Len();
1106  char* Bf=new char[BfL];
1107  SIn->GetBf(Bf, BfL);
1108  Cs=TCs::GetCsFromBf(Bf, BfL);
1109  PutBf(Bf, BfL);
1110  delete[] Bf;
1111 }
1112 
1113 PSIn TFRnd::GetSIn(const int& BfL, TCs& Cs){
1114  char* Bf=new char[BfL];
1115  GetBf(Bf, BfL);
1116  Cs=TCs::GetCsFromBf(Bf, BfL);
1117  PSIn SIn=PSIn(new TMIn(Bf, BfL, true));
1118  return SIn;
1119 }
1120 
1122  switch (FAccess){
1123  case faCreate: return "Create";
1124  case faUpdate: return "Update";
1125  case faAppend: return "Append";
1126  case faRdOnly: return "ReadOnly";
1127  case faRestore: return "Restore";
1128  default: Fail; return TStr();
1129  }
1130 }
1131 
1133  TStr UcStr=Str.GetUc();
1134  if (UcStr=="CREATE"){return faCreate;}
1135  if (UcStr=="UPDATE"){return faUpdate;}
1136  if (UcStr=="APPEND"){return faAppend;}
1137  if (UcStr=="READONLY"){return faRdOnly;}
1138  if (UcStr=="RESTORE"){return faRestore;}
1139 
1140  if (UcStr=="NEW"){return faCreate;}
1141  if (UcStr=="CONT"){return faUpdate;}
1142  if (UcStr=="CONTINUE"){return faUpdate;}
1143  if (UcStr=="REST"){return faRestore;}
1144  if (UcStr=="RESTORE"){return faRestore;}
1145  return faUndef;
1146 }
1147 
1149 // Files
1150 const TStr TFile::TxtFExt=".Txt";
1151 const TStr TFile::HtmlFExt=".Html";
1152 const TStr TFile::HtmFExt=".Htm";
1153 const TStr TFile::GifFExt=".Gif";
1154 const TStr TFile::JarFExt=".Jar";
1155 
1156 bool TFile::Exists(const TStr& FNm){
1157  if (FNm.Empty()) { return false; }
1158  bool DoExists;
1159  TFIn FIn(FNm, DoExists);
1160  return DoExists;
1161 }
1162 
1163 #if defined(GLib_WIN32)
1164 
1165 void TFile::Copy(const TStr& SrcFNm, const TStr& DstFNm,
1166  const bool& ThrowExceptP, const bool& FailIfExistsP){
1167  if (ThrowExceptP){
1168  if (CopyFile(SrcFNm.CStr(), DstFNm.CStr(), FailIfExistsP) == 0) {
1169  int ErrorCode = (int)GetLastError();
1171  "Error %d copying file '%s' to '%s'.",
1172  ErrorCode, SrcFNm.CStr(), DstFNm.CStr()));
1173  }
1174  } else {
1175  CopyFile(SrcFNm.CStr(), DstFNm.CStr(), FailIfExistsP);
1176  }
1177 }
1178 
1179 #elif defined(GLib_LINUX)
1180 
1181 void TFile::Copy(const TStr& SrcFNm, const TStr& DstFNm,
1182  const bool& ThrowExceptP, const bool& FailIfExistsP){
1183  int input, output;
1184  size_t filesize;
1185  void *source, *target;
1186 
1187  if( (input = open(SrcFNm.CStr(), O_RDONLY)) == -1) {
1188  if (ThrowExceptP) {
1190  "Error copying file '%s' to '%s': cannot open source file for reading.",
1191  SrcFNm.CStr(), DstFNm.CStr()));
1192  } else {
1193  return;
1194  }
1195  }
1196 
1197 
1198  if( (output = open(DstFNm.CStr(), O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) {
1199  close(input);
1200 
1201  if (ThrowExceptP) {
1203  "Error copying file '%s' to '%s': cannot open destination file for writing.",
1204  SrcFNm.CStr(), DstFNm.CStr()));
1205  } else {
1206  return;
1207  }
1208  }
1209 
1210 
1211  filesize = lseek(input, 0, SEEK_END);
1212  lseek(output, filesize - 1, SEEK_SET);
1213  write(output, '\0', 1);
1214 
1215  if((source = mmap(0, filesize, PROT_READ, MAP_SHARED, input, 0)) == (void *) -1) {
1216  close(input);
1217  close(output);
1218  if (ThrowExceptP) {
1220  "Error copying file '%s' to '%s': cannot mmap input file.",
1221  SrcFNm.CStr(), DstFNm.CStr()));
1222  } else {
1223  return;
1224  }
1225  }
1226 
1227  if((target = mmap(0, filesize, PROT_WRITE, MAP_SHARED, output, 0)) == (void *) -1) {
1228  munmap(source, filesize);
1229  close(input);
1230  close(output);
1231  if (ThrowExceptP) {
1233  "Error copying file '%s' to '%s': cannot mmap output file.",
1234  SrcFNm.CStr(), DstFNm.CStr()));
1235  } else {
1236  return;
1237  }
1238  }
1239 
1240  memcpy(target, source, filesize);
1241 
1242  munmap(source, filesize);
1243  munmap(target, filesize);
1244 
1245  close(input);
1246  close(output);
1247 
1248 }
1249 
1250 
1251 
1252 #endif
1253 
1254 void TFile::Del(const TStr& FNm, const bool& ThrowExceptP){
1255  if (ThrowExceptP){
1256  EAssertR(
1257  remove(FNm.CStr())==0,
1258  "Error removing file '"+FNm+"'.");
1259  } else {
1260  remove(FNm.CStr());
1261  }
1262 }
1263 
1264 void TFile::DelWc(const TStr& WcStr, const bool& RecurseDirP){
1265  // collect file-names
1266  TStrV FNmV;
1267  TFFile FFile(WcStr, RecurseDirP); TStr FNm;
1268  while (FFile.Next(FNm)){
1269  FNmV.Add(FNm);}
1270  // delete files
1271  for (int FNmN=0; FNmN<FNmV.Len(); FNmN++){
1272  Del(FNmV[FNmN], false);}
1273 }
1274 
1275 void TFile::Rename(const TStr& SrcFNm, const TStr& DstFNm){
1276  EAssertR(
1277  rename(SrcFNm.CStr(), DstFNm.CStr())==0,
1278  "Error renaming file '"+SrcFNm+"' to "+DstFNm+"'.");
1279 }
1280 
1282  // <name>.#.txt --> <name>.<num>.txt
1283  int Cnt=1; int ch;
1284  TStr NewFNm; TStr TmpFNm=FNm;
1285  if (FNm.SearchCh('#') == -1) {
1286  for (ch = FNm.Len()-1; ch >= 0; ch--) if (FNm[ch] == '.') break;
1287  if (ch != -1) TmpFNm.InsStr(ch, ".#");
1288  else TmpFNm += ".#";
1289  }
1290  forever{
1291  NewFNm=TmpFNm;
1292  NewFNm.ChangeStr("#", TStr::Fmt("%03d", Cnt)); Cnt++;
1293  if (!TFile::Exists(NewFNm)){break;}
1294  }
1295  return NewFNm;
1296 }
1297 
1298 #ifdef GLib_WIN
1299 
1300 uint64 TFile::GetSize(const TStr& FNm) {
1301  // open
1302  HANDLE hFile = CreateFile(
1303  FNm.CStr(), // file to open
1304  GENERIC_READ, // open for reading
1305  FILE_SHARE_READ | FILE_SHARE_WRITE, // share for reading
1306  NULL, // default security
1307  OPEN_EXISTING, // existing file only
1308  FILE_ATTRIBUTE_NORMAL, // normal file
1309  NULL); // no attr. template
1310  // check if we could open it
1311  if (hFile == INVALID_HANDLE_VALUE) {
1312  TExcept::Throw("Can not open file " + FNm + "!"); }
1313  // read file times
1314  LARGE_INTEGER lpFileSizeHigh;
1315  if (!GetFileSizeEx(hFile, &lpFileSizeHigh)) {
1316  TExcept::Throw("Can not read size of file " + FNm + "!"); }
1317  // close file
1318  CloseHandle(hFile);
1319  // convert to uint64
1320  return uint64(lpFileSizeHigh.QuadPart);
1321 }
1322 
1323 uint64 TFile::GetCreateTm(const TStr& FNm) {
1324  // open
1325  HANDLE hFile = CreateFile(
1326  FNm.CStr(), // file to open
1327  GENERIC_READ, // open for reading
1328  FILE_SHARE_READ | FILE_SHARE_WRITE, // share for reading
1329  NULL, // default security
1330  OPEN_EXISTING, // existing file only
1331  FILE_ATTRIBUTE_NORMAL, // normal file
1332  NULL); // no attr. template
1333  // check if we could open it
1334  if (hFile == INVALID_HANDLE_VALUE) {
1335  TExcept::Throw("Can not open file " + FNm + "!"); }
1336  // read file times
1337  FILETIME lpCreationTime;
1338  if (!GetFileTime(hFile, &lpCreationTime, NULL, NULL)) {
1339  TExcept::Throw("Can not read time from file " + FNm + "!"); }
1340  // close file
1341  CloseHandle(hFile);
1342  // convert to uint64
1343  TUInt64 UInt64(uint(lpCreationTime.dwHighDateTime),
1344  uint(lpCreationTime.dwLowDateTime));
1345  return UInt64.Val / uint64(10000);
1346 }
1347 
1348 uint64 TFile::GetLastAccessTm(const TStr& FNm) {
1349  // open
1350  HANDLE hFile = CreateFile(
1351  FNm.CStr(), // file to open
1352  GENERIC_READ, // open for reading
1353  FILE_SHARE_READ | FILE_SHARE_WRITE, // share for reading
1354  NULL, // default security
1355  OPEN_EXISTING, // existing file only
1356  FILE_ATTRIBUTE_NORMAL, // normal file
1357  NULL); // no attr. template
1358  // check if we could open it
1359  if (hFile == INVALID_HANDLE_VALUE) {
1360  TExcept::Throw("Can not open file " + FNm + "!"); }
1361  // read file times
1362  FILETIME lpLastAccessTime;
1363  if (!GetFileTime(hFile, NULL, &lpLastAccessTime, NULL)) {
1364  TExcept::Throw("Can not read time from file " + FNm + "!"); }
1365  // close file
1366  CloseHandle(hFile);
1367  // convert to uint64
1368  TUInt64 UInt64(uint(lpLastAccessTime.dwHighDateTime),
1369  uint(lpLastAccessTime.dwLowDateTime));
1370  return UInt64.Val / uint64(10000);
1371 }
1372 
1373 uint64 TFile::GetLastWriteTm(const TStr& FNm) {
1374  // open
1375  HANDLE hFile = CreateFile(
1376  FNm.CStr(), // file to open
1377  GENERIC_READ, // open for reading
1378  FILE_SHARE_READ | FILE_SHARE_WRITE, // share for reading
1379  NULL, // default security
1380  OPEN_EXISTING, // existing file only
1381  FILE_ATTRIBUTE_NORMAL, // normal file
1382  NULL); // no attr. template
1383  // check if we could open it
1384  if (hFile == INVALID_HANDLE_VALUE) {
1385  TExcept::Throw("Can not open file " + FNm + "!"); }
1386  // read file times
1387  FILETIME lpLastWriteTime;
1388  if (!GetFileTime(hFile, NULL, NULL, &lpLastWriteTime)) {
1389  TExcept::Throw("Can not read time from file " + FNm + "!"); }
1390  // close file
1391  CloseHandle(hFile);
1392  // convert to uint64
1393  TUInt64 UInt64(uint(lpLastWriteTime.dwHighDateTime),
1394  uint(lpLastWriteTime.dwLowDateTime));
1395  return UInt64.Val / uint64(10000);
1396 }
1397 
1398 #elif defined(GLib_LINUX)
1399 
1400 uint64 TFile::GetSize(const TStr& FNm) {
1401  Fail; return 0;
1402 }
1403 
1404 uint64 TFile::GetCreateTm(const TStr& FNm) {
1405  return GetLastWriteTm(FNm);
1406 }
1407 
1408 uint64 TFile::GetLastWriteTm(const TStr& FNm) {
1409  struct stat st;
1410  if (stat(FNm.CStr(), &st) != 0) {
1411  TExcept::Throw("Cannot read tile from file " + FNm + "!");
1412  }
1413  return uint64(st.st_mtime);
1414 }
1415 
1416 
1417 #endif
int PutMem(const TMem &Mem)
Definition: fl.cpp:79
#define IAssert(Cond)
Definition: bd.h:262
Definition: bd.h:514
~TFOut()
Definition: fl.cpp:451
int SearchCh(const char &Ch, const int &BChN=0) const
Definition: dt.cpp:1043
TStr GetStr(const int &StrLen)
Definition: fl.cpp:1094
int GetBf(const void *LBf, const TSize &LBfL)
Definition: fl.cpp:711
virtual int Len() const =0
char * CStr()
Definition: bd.h:531
TStr GetStr() const
Definition: dt.h:1200
static PSOut New(const TStr &FNm, const bool &Append=false)
Definition: fl.cpp:442
Definition: xfl.h:30
int Len() const
Definition: dt.h:490
Definition: fl.h:347
TStr GetFNm() const
Definition: fl.cpp:532
int PutStrFmtLn(const char *FmtStr,...)
Definition: fl.cpp:145
int GetBf(const void *LBf, const TSize &LBfL)
Definition: fl.cpp:311
int BfL
Definition: fl.h:498
virtual int PutCh(const char &Ch)=0
bool IsMemoryMapped
Definition: fl.h:390
int BfL
Definition: fl.h:280
virtual int PutBf(const void *LBf, const TSize &LBfL)=0
static void Rename(const TStr &SrcFNm, const TStr &DstFNm)
Definition: fl.cpp:1275
static bool Exists(const TStr &FNm)
Definition: fl.cpp:1156
#define SEEK_END
Definition: fl.cpp:969
TMOut(const TMOut &)
static const TStr GifFExt
Definition: fl.h:645
TShMIn(const TStr &Str)
Definition: fl.cpp:538
TStdOut()
Definition: fl.cpp:213
int PutCh(const char &Ch)
Definition: fl.cpp:458
#define forever
Definition: bd.h:6
void AppendBf(const void *LBf, const TSize &LBfL)
Definition: fl.cpp:851
int Len() const
Definition: dt.h:134
unsigned int uint
Definition: bd.h:11
bool RecAct
Definition: fl.h:573
#define SEEK_CUR
Definition: fl.cpp:968
PSIn GetSIn(const bool &IsCut=true, const int &CutBfL=-1)
Definition: fl.cpp:881
void Flush()
Definition: fl.cpp:1066
int PutBf(const void *LBf, const TSize &LBfL)
Definition: fl.cpp:508
bool Empty() const
Definition: dt.h:260
void FillBf()
Definition: fl.cpp:264
#define Fail
Definition: bd.h:238
int FindEol(int &BfN, bool &CrEnd)
Definition: fl.cpp:367
int GetFLen()
Definition: fl.cpp:1025
TStr GetUc() const
Definition: dt.h:496
uint64 GetBfL()
Definition: fl.cpp:773
static const char NullCh
Definition: dt.h:1036
static bool IsHashCh(const char &Ch)
Definition: dt.h:1061
int PutCh(const char &Ch)
Definition: fl.h:511
bool IsEolnLn() const
Definition: fl.cpp:915
TFileId FileId
Definition: fl.h:571
void Clr()
Definition: dt.h:258
int LnLen
Definition: fl.h:130
void AddCh(const char &Ch, const int &MxLen=-1)
Definition: dt.h:271
TSizeTy Len() const
Returns the number of elements in the vector.
Definition: ds.h:575
TStdIn()
Definition: fl.cpp:63
void MkEolnLn()
Definition: fl.cpp:947
void CutBf(const int &CutBfL)
Definition: fl.cpp:875
TFileId FileId
Definition: fl.h:278
#define SEEK_SET
Definition: fl.cpp:970
void PutSIn(const PSIn &SIn, TCs &Cs)
Definition: fl.cpp:1104
int PutBf(const void *LBf, const TSize &LBfL)
Definition: fl.cpp:463
virtual int GetBf(const void *Bf, const TSize &BfL)=0
static const TStr HtmlFExt
Definition: fl.h:643
Definition: fl.h:347
int Len() const
Definition: dt.h:259
TStr GetCrLfLn()
Definition: fl.cpp:901
int PutBf(const void *LBf, const TSize &LBfL)
Definition: fl.cpp:232
~TFIn()
Definition: fl.cpp:305
char * Cursor
Definition: fl.h:389
~TFRnd()
Definition: fl.cpp:999
char PeekCh()
Definition: fl.cpp:706
bool GetNextLnBf(TChA &LnChA)
Definition: fl.cpp:763
int PutSepLn(const int &Lns=0)
Definition: fl.cpp:182
TStr GetFNm() const
Definition: fl.cpp:1003
int PutLn(const int &Lns=1)
Definition: fl.cpp:158
Definition: fl.h:275
TStr GetAsStr() const
Definition: fl.cpp:869
Definition: fl.h:40
virtual void LoadCs()
Definition: fl.cpp:28
bool GetNextLnBf(TChA &LnChA)
Definition: fl.cpp:328
char * Bf
Definition: fl.h:323
int GetFPos() const
Definition: fl.cpp:249
Definition: fl.h:437
void FlushBf()
Definition: fl.cpp:410
Definition: fl.h:58
TFileId FileId
Definition: fl.h:322
int UpdateLnLen(const int &StrLen, const bool &ForceInLn=false)
Definition: fl.cpp:70
Definition: dt.h:77
static const char EofCh
Definition: dt.h:1040
static uint64 GetSize(const TStr &FNm)
void Flush()
Definition: fl.cpp:475
char * Bf
Definition: fl.h:439
TSize SizeLeft
Definition: fl.h:388
Definition: fl.h:240
static PSIn New(const TStr &FNm)
Definition: fl.cpp:290
void SkipCommentLines()
Move stream pointer along until a non commented line is found.
Definition: fl.cpp:814
int GetBf(const void *LBf, const TSize &LBfL)
Definition: fl.cpp:217
static const int MxMask
Definition: fl.h:13
static const TStr TxtFExt
Definition: fl.h:642
static TCs GetCsFromBf(char *Bf, const int &BfL)
Definition: fl.cpp:12
static void DelWc(const TStr &WcStr, const bool &RecurseDirP=false)
Definition: fl.cpp:1264
static int GetMn(const int &Int1, const int &Int2)
Definition: dt.h:1183
char * CStr()
Definition: dt.h:255
static void Throw(const TStr &MsgStr)
Definition: ut.h:187
Definition: fl.h:347
static TStr GetUniqueFNm(const TStr &FNm)
Definition: fl.cpp:1281
bool GetNextLnBf(TChA &LnChA)
Definition: fl.cpp:224
virtual bool Eof()=0
void MoveFPos(const int &DFPos)
Definition: fl.cpp:1013
static const TStr HtmFExt
Definition: fl.h:644
unsigned long long uint64
Definition: bd.h:38
uint64 BfL
Definition: fl.h:440
void Load(bool &Bool)
Definition: fl.h:84
TFRnd(const TFRnd &)
TStr GetStr() const
Definition: dt.h:1282
size_t TSize
Definition: bd.h:58
int PutBool(const bool &Bool)
Definition: fl.cpp:89
static void Copy(const TStr &SrcFNm, const TStr &DstFNm, const bool &ThrowExceptP=true, const bool &FailIfExistsP=false)
char * Bf
Definition: fl.h:279
static void Del(const TStr &FNm, const bool &ThrowExceptP=true)
Definition: fl.cpp:1254
Definition: fl.h:347
uint64 CountNewLinesInRange(uint64 Lb, uint64 Ub)
Finds number of new line chars in interval [Lb, Ub)
Definition: fl.cpp:782
int PutBf(const void *LBf, const TSize &LBfL)
Definition: fl.cpp:857
int PutSep(const int &NextStrLen=0)
Definition: fl.cpp:170
int PutInt(const int &Int)
Definition: fl.cpp:93
bool Eof()
Definition: fl.h:298
int MxBfL
Definition: fl.h:498
uint64 GetBfC()
Definition: fl.cpp:769
void SetFPos(const int &FPos)
Definition: fl.cpp:1007
bool IsMemoryMapped
Definition: fl.h:441
#define EFailR(Reason)
Definition: bd.h:246
TPt< TSInOut > PSInOut
Definition: fl.h:236
TFileId FileId
Definition: fl.h:351
#define FailR(Reason)
Definition: bd.h:240
void PutCh(const char &Ch)
Definition: fl.h:619
static const TPt< TSOut > StdOut
Definition: fl.h:208
int FindEol(uint64 &BfN, bool &CrEnd)
Definition: fl.cpp:725
Definition: fl.h:128
int GetRecs()
Definition: fl.cpp:1045
bool OwnBf
Definition: fl.h:499
int PutIndent(const int &IndentLev=1)
Definition: fl.cpp:154
static PSIn New(const void *_Bf, const uint64 &_BfL, const bool &TakeBf=false)
Definition: fl.cpp:668
int PutFlt(const double &Flt)
Definition: fl.cpp:109
Definition: fl.h:260
static const char LfCh
Definition: dt.h:1038
TStr GetStr() const
Definition: dt.h:681
int GetRecN()
Definition: fl.cpp:1038
void Save(const bool &Bool)
Definition: fl.h:173
void PutStr(const TStr &Str)
Definition: fl.cpp:1079
static PSInOut New(const TStr &FNm, const TFAccess &FAccess, const bool &CreateIfNo)
Definition: fl.cpp:496
uint64 GetLineEndPos(uint64 Ind)
Finds end of line in which Ind is present.
Definition: fl.cpp:802
int BfC
Definition: fl.h:280
Definition: fl.h:347
Definition: dt.h:201
uint64 GetLineStartPos(uint64 Ind)
Finds beginning of line in which Ind is present.
Definition: fl.cpp:795
int PutDosLn(const int &Lns=1)
Definition: fl.cpp:164
char * GetLine(uint64 Ind)
Definition: fl.cpp:810
static const TPt< TSIn > StdIn
Definition: fl.h:116
static const TSize MxBfL
Definition: fl.h:321
void AddBf(char *NewBf, const int &BfS)
Definition: dt.h:275
static TStr GetStrFromFAccess(const TFAccess &FAccess)
Definition: fl.cpp:1121
TSIn()
Definition: fl.h:65
char GetCh()
Definition: fl.h:250
int GetBf(const void *LBf, const TSize &LBfL)
Definition: fl.cpp:517
int MxLnLen
Definition: fl.h:130
int GetPos() const
Definition: fl.h:373
Definition: dt.h:412
bool Eof()
Definition: fl.h:464
bool Empty() const
Definition: dt.h:491
static TFAccess GetFAccessFromStr(const TStr &Str)
Definition: fl.cpp:1132
static TStr Fmt(const char *FmtStr,...)
Definition: dt.cpp:1599
int PutStr(const char *CStr)
Definition: fl.cpp:117
PSIn SIn
Definition: fl.h:559
static const char CrCh
Definition: dt.h:1039
uint64 BfC
Definition: fl.h:440
FILE * TFileId
Definition: bd.h:17
#define EAssertR(Cond, MsgStr)
Definition: bd.h:283
PSIn GetSIn(const int &SInLen, TCs &Cs)
Definition: fl.cpp:1113
static TStr GetStr(const bool &Val)
Definition: dt.h:1011
virtual TStr GetSNm() const
Definition: fl.cpp:20
int PutCh(const char &Ch)
Definition: fl.h:268
static uint64 GetLastWriteTm(const TStr &FNm)
static uint64 GetCreateTm(const TStr &FNm)
void SetBfC(uint64 Pos)
Definition: fl.cpp:777
static const int MxBfL
Definition: fl.h:277
TStr GetStr() const
Definition: dt.h:1462
TSOut()
Definition: fl.h:136
int GetSize() const
Definition: fl.cpp:500
TPt< TSIn > PSIn
Definition: fl.h:119
void Resize(const int &ReqLen=-1)
Definition: fl.cpp:825
bool IsCrLfLn() const
Definition: fl.cpp:895
bool Next(TStr &FNm)
TSize BfL
Definition: fl.h:324
char * Bf
Definition: fl.h:497
void SetRecN(const int &RecN)
Definition: fl.cpp:1033
virtual char GetCh()=0
TSStr FNm
Definition: fl.h:572
int HdLen
Definition: fl.h:574
virtual char PeekCh()=0
void PutBf(const void *Bf, const TSize &BfL)
Definition: fl.cpp:1059
int GetFPos()
Definition: fl.cpp:1019
char * CStr()
Definition: dt.h:479
int Len() const
Definition: fl.h:517
void CloseMapping()
munmap the mapping. Note that munmap is not called by the destructor
Definition: fl.cpp:577
TSize TotalLength
Definition: fl.h:387
int PutStrLn(const TStr &Str, const bool &ForceInLn=false)
Definition: fl.h:161
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
Definition: ds.h:602
int GetFLen() const
Definition: fl.cpp:255
Definition: fl.h:11
int PutStrFmt(const char *FmtStr,...)
Definition: fl.cpp:136
void GetBf(void *Bf, const TSize &BfL)
Definition: fl.cpp:1052
void InsStr(const int &BChN, const TStr &Str)
Definition: dt.cpp:825
~TMIn()
Definition: fl.cpp:688
TSOut & operator<<(const bool &Bool)
Definition: fl.h:191
TFAccess
Definition: fl.h:347
int PutUInt(const uint &Int)
Definition: fl.cpp:101
int RecLen
Definition: fl.h:574
bool GetNextLnBf(TChA &LnChA)
Definition: fl.cpp:526
TPt< TSOut > PSOut
Definition: fl.h:211
Definition: fl.h:347
TStr GetEolnLn(const bool &DoAddEoln, const bool &DoCutBf)
Definition: fl.cpp:922
TSStr SNm
Definition: fl.h:43
char GetCh()
Definition: fl.cpp:701
void SetFPos(const int &FPos) const
Definition: fl.cpp:243
TCs Cs
Definition: fl.h:44
Definition: dt.h:1318
static const TStr JarFExt
Definition: fl.h:646
void RefreshFPos()
Definition: fl.cpp:975
int ChangeStr(const TStr &SrcStr, const TStr &DstStr, const int &BChN=0)
Definition: dt.cpp:1130
bool NextLn(TStr &LnStr)
Definition: fl.cpp:955
bool GetNextLn(TStr &LnStr)
Definition: fl.cpp:43
static uint64 GetLastAccessTm(const TStr &FNm)
char * OriginalBuffer
Definition: fl.h:386