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
fl.cpp
Go to the documentation of this file.
00001 #ifdef GLib_LINUX
00002 extern "C" {
00003         #include <sys/mman.h>
00004 }
00005 
00006 #endif
00007 
00009 // Check-Sum
00010 const int TCs::MxMask=0x0FFFFFFF;
00011 
00012 TCs TCs::GetCsFromBf(char* Bf, const int& BfL){
00013   TCs Cs;
00014   for (int BfC=0; BfC<BfL; BfC++){Cs+=Bf[BfC];}
00015   return Cs;
00016 }
00017 
00019 // Stream-Base
00020 TStr TSBase::GetSNm() const {
00021   return TStr(SNm.CStr());
00022 }
00023 
00025 // Input-Stream
00026 TSIn::TSIn(const TStr& Str) : TSBase(Str.CStr()), FastMode(false){}
00027 
00028 void TSIn::LoadCs(){
00029   TCs CurCs=Cs; TCs TestCs;
00030   Cs+=GetBf(&TestCs, sizeof(TestCs));
00031   EAssertR(CurCs==TestCs, "Invalid checksum reading '"+GetSNm()+"'.");
00032 }
00033 
00034 void TSIn::Load(char*& CStr){
00035   char Ch; Load(Ch);
00036   int CStrLen=int(Ch);
00037   EAssertR(CStrLen>=0, "Error reading stream '"+GetSNm()+"'.");
00038   CStr=new char[CStrLen+1];
00039   if (CStrLen>0){Cs+=GetBf(CStr, CStrLen);}
00040   CStr[CStrLen]=TCh::NullCh;
00041 }
00042 
00043 bool TSIn::GetNextLn(TStr& LnStr){
00044   TChA LnChA;
00045   const bool IsNext=GetNextLn(LnChA);
00046   LnStr=LnChA;
00047   return IsNext;
00048 }
00049 
00050 bool TSIn::GetNextLn(TChA& LnChA){
00051   LnChA.Clr();
00052   while (!Eof()){
00053     const char Ch=GetCh();
00054     if (Ch=='\n'){return true;}
00055     if (Ch=='\r' && PeekCh()=='\n'){GetCh(); return true;}
00056     LnChA.AddCh(Ch);
00057   }
00058   return !LnChA.Empty();
00059 }
00060 
00061 const PSIn TSIn::StdIn=PSIn(new TStdIn());
00062 
00063 TStdIn::TStdIn(): TSBase("Standard input"), TSIn("Standard input") {}
00064 
00066 // Output-Stream
00067 TSOut::TSOut(const TStr& Str):
00068   TSBase(Str.CStr()), MxLnLen(-1), LnLen(0){}
00069 
00070 int TSOut::UpdateLnLen(const int& StrLen, const bool& ForceInLn){
00071   int Cs=0;
00072   if (MxLnLen!=-1){
00073     if ((!ForceInLn)&&(LnLen+StrLen>MxLnLen)){Cs+=PutLn();}
00074     LnLen+=StrLen;
00075   }
00076   return Cs;
00077 }
00078 
00079 int TSOut::PutMem(const TMem& Mem){
00080   return PutBf(Mem(), Mem.Len());
00081 }
00082 
00083 int TSOut::PutCh(const char& Ch, const int& Chs){
00084   int Cs=0;
00085   for (int ChN=0; ChN<Chs; ChN++){Cs+=PutCh(Ch);}
00086   return Cs;
00087 }
00088 
00089 int TSOut::PutBool(const bool& Bool){
00090   return PutStr(TBool::GetStr(Bool));
00091 }
00092 
00093 int TSOut::PutInt(const int& Int){
00094   return PutStr(TInt::GetStr(Int));
00095 }
00096 
00097 int TSOut::PutInt(const int& Int, const char* FmtStr){
00098   return PutStr(TInt::GetStr(Int, FmtStr));
00099 }
00100 
00101 int TSOut::PutUInt(const uint& UInt){
00102   return PutStr(TUInt::GetStr(UInt));
00103 }
00104 
00105 int TSOut::PutUInt(const uint& UInt, const char* FmtStr){
00106   return PutStr(TUInt::GetStr(UInt, FmtStr));
00107 }
00108 
00109 int TSOut::PutFlt(const double& Flt){
00110   return PutStr(TFlt::GetStr(Flt));
00111 }
00112 
00113 int TSOut::PutFlt(const double& Flt, const char* FmtStr){
00114   return PutStr(TFlt::GetStr(Flt, FmtStr));
00115 }
00116 
00117 int TSOut::PutStr(const char* CStr){
00118   int Cs=UpdateLnLen(int(strlen(CStr)));
00119   return Cs+PutBf(CStr, int(strlen(CStr)));
00120 }
00121 
00122 int TSOut::PutStr(const TChA& ChA){
00123   int Cs=UpdateLnLen(ChA.Len());
00124   return Cs+PutBf(ChA.CStr(), ChA.Len());
00125 }
00126 
00127 int TSOut::PutStr(const TStr& Str, const char* FmtStr){
00128   return PutStr(TStr::GetStr(Str, FmtStr));
00129 }
00130 
00131 int TSOut::PutStr(const TStr& Str, const bool& ForceInLn){
00132   int Cs=UpdateLnLen(Str.Len(), ForceInLn);
00133   return Cs+PutBf(Str.CStr(), Str.Len());
00134 }
00135 
00136 int TSOut::PutStrFmt(const char *FmtStr, ...){
00137   char Bf[10*1024];
00138   va_list valist;
00139   va_start(valist, FmtStr);
00140   const int RetVal=vsnprintf(Bf, 10*1024-2, FmtStr, valist);
00141   va_end(valist);
00142   return RetVal!=-1 ? PutStr(TStr(Bf)) : 0;     
00143 }
00144 
00145 int TSOut::PutStrFmtLn(const char *FmtStr, ...){
00146   char Bf[10*1024];
00147   va_list valist;
00148   va_start(valist, FmtStr);
00149   const int RetVal=vsnprintf(Bf, 10*1024-2, FmtStr, valist);
00150   va_end(valist);
00151   return RetVal!=-1 ? PutStrLn(TStr(Bf)) : PutLn();     
00152 }
00153 
00154 int TSOut::PutIndent(const int& IndentLev){
00155   return PutCh(' ', IndentLev*2);
00156 }
00157 
00158 int TSOut::PutLn(const int& Lns){
00159   LnLen=0; int Cs=0;
00160   for (int LnN=0; LnN<Lns; LnN++){Cs+=PutCh('\n');}
00161   return Cs;
00162 }
00163 
00164 int TSOut::PutDosLn(const int& Lns){
00165   LnLen=0; int Cs=0;
00166   for (int LnN=0; LnN<Lns; LnN++){Cs+=PutCh(TCh::CrCh)+PutCh(TCh::LfCh);}
00167   return Cs;
00168 }
00169 
00170 int TSOut::PutSep(const int& NextStrLen){
00171   int Cs=0;
00172   if (MxLnLen==-1){
00173     Cs+=PutCh(' ');
00174   } else {
00175     if (LnLen>0){
00176       if (LnLen+1+NextStrLen>MxLnLen){Cs+=PutLn();} else {Cs+=PutCh(' ');}
00177     }
00178   }
00179   return Cs;
00180 }
00181 
00182 int TSOut::PutSepLn(const int& Lns){
00183   int Cs=0;
00184   if (LnLen>0){Cs+=PutLn();}
00185   Cs+=PutLn(Lns);
00186   return Cs;
00187 }
00188 
00189 void TSOut::Save(const char* CStr){
00190   int CStrLen=int(strlen(CStr));
00191   EAssertR(CStrLen<=127, "Error writting stream '"+GetSNm()+"'.");
00192   Save(char(CStrLen));
00193   if (CStrLen>0){Cs+=PutBf(CStr, CStrLen);}
00194 }
00195 
00196 void TSOut::Save(TSIn& SIn, const TSize& BfL){
00197   Fail;
00198   if (BfL==0){ //J: used to be ==-1
00199     while (!SIn.Eof()){Save(SIn.GetCh());}
00200   } else {
00201     for (TSize BfC=0; BfC<BfL; BfC++){Save(SIn.GetCh());}
00202   }
00203 }
00204 
00205 TSOut& TSOut::operator<<(TSIn& SIn) {
00206   while (!SIn.Eof())
00207     operator<<((char)SIn.GetCh());
00208   return *this;
00209 }
00210 
00211 const PSOut TSOut::StdOut=PSOut(new TStdOut());
00212 
00213 TStdOut::TStdOut(): TSBase(TSStr("Standard output")), TSOut("Standard output"){}
00214 
00216 // Standard-Input
00217 int TStdIn::GetBf(const void* LBf, const TSize& LBfL){
00218   int LBfS=0;
00219   for (TSize LBfC=0; LBfC<LBfL; LBfC++){
00220     LBfS+=(((char*)LBf)[LBfC]=GetCh());}
00221   return LBfS;
00222 }
00223 
00225 // Standard-Output
00226 int TStdOut::PutBf(const void* LBf, const TSize& LBfL){
00227   int LBfS=0;
00228   for (TSize LBfC=0; LBfC<LBfL; LBfC++){
00229     LBfS+=PutCh(((char*)LBf)[LBfC]);}
00230   return LBfS;
00231 }
00232 
00234 // Input-File
00235 const int TFIn::MxBfL=16*1024;
00236 
00237 void TFIn::SetFPos(const int& FPos) const {
00238   EAssertR(
00239    fseek(FileId, FPos, SEEK_SET)==0,
00240    "Error seeking into file '"+GetSNm()+"'.");
00241 }
00242 
00243 int TFIn::GetFPos() const {
00244   const int FPos=(int)ftell(FileId);
00245   EAssertR(FPos!=-1, "Error seeking into file '"+GetSNm()+"'.");
00246   return FPos;
00247 }
00248 
00249 int TFIn::GetFLen() const {
00250   const int FPos=GetFPos();
00251   EAssertR(
00252    fseek(FileId, 0, SEEK_END)==0,
00253    "Error seeking into file '"+GetSNm()+"'.");
00254   const int FLen=GetFPos(); SetFPos(FPos);
00255   return FLen;
00256 }
00257 
00258 void TFIn::FillBf(){
00259   EAssertR(
00260    (BfC==BfL)&&((BfL==-1)||(BfL==MxBfL)),
00261    "Error reading file '"+GetSNm()+"'.");
00262   BfL=int(fread(Bf, 1, MxBfL, FileId));
00263   EAssertR((BfC!=0)||(BfL!=0), "Error reading file '"+GetSNm()+"'.");
00264   BfC=0;
00265 }
00266 
00267 TFIn::TFIn(const TStr& FNm):
00268   TSBase(FNm.CStr()), TSIn(FNm), FileId(NULL), Bf(NULL), BfC(0), BfL(0){
00269   EAssertR(!FNm.Empty(), "Empty file-name.");
00270   FileId=fopen(FNm.CStr(), "rb");
00271   EAssertR(FileId!=NULL, "Can not open file '"+FNm+"'.");
00272   Bf=new char[MxBfL]; BfC=BfL=-1; FillBf();
00273 }
00274 
00275 TFIn::TFIn(const TStr& FNm, bool& OpenedP):
00276   TSBase(FNm.CStr()), TSIn(FNm), FileId(NULL), Bf(NULL), BfC(0), BfL(0){
00277   EAssertR(!FNm.Empty(), "Empty file-name.");
00278   FileId=fopen(FNm.CStr(), "rb");
00279   OpenedP=(FileId!=NULL);
00280   if (OpenedP){
00281     Bf=new char[MxBfL]; BfC=BfL=-1; FillBf();}
00282 }
00283 
00284 PSIn TFIn::New(const TStr& FNm){
00285   return PSIn(new TFIn(FNm));
00286 }
00287 
00288 PSIn TFIn::New(const TStr& FNm, bool& OpenedP){
00289   return PSIn(new TFIn(FNm, OpenedP));
00290 }
00291 
00292 TFIn::~TFIn(){
00293   if (FileId!=NULL){
00294     EAssertR(fclose(FileId)==0, "Can not close file '"+GetSNm()+"'.");}
00295   if (Bf!=NULL){delete[] Bf;}
00296 }
00297 
00298 int TFIn::GetBf(const void* LBf, const TSize& LBfL){
00299   int LBfS=0;
00300   if (TSize(BfC+LBfL)>TSize(BfL)){
00301     for (TSize LBfC=0; LBfC<LBfL; LBfC++){
00302       if (BfC==BfL){FillBf();}
00303       LBfS+=((char*)LBf)[LBfC]=Bf[BfC++];}
00304   } else {
00305     for (TSize LBfC=0; LBfC<LBfL; LBfC++){
00306       LBfS+=(((char*)LBf)[LBfC]=Bf[BfC++]);}
00307   }
00308   return LBfS;
00309 }
00310 
00312 // Output-File
00313 const TSize TFOut::MxBfL=16*1024;;
00314 
00315 void TFOut::FlushBf(){
00316   EAssertR(
00317    fwrite(Bf, 1, BfL, FileId)==BfL,
00318    "Error writting to the file '"+GetSNm()+"'.");
00319   BfL=0;
00320 }
00321 
00322 TFOut::TFOut(const TStr& FNm, const bool& Append):
00323   TSBase(FNm.CStr()), TSOut(FNm), FileId(NULL), Bf(NULL), BfL(0){
00324   if (FNm.GetUc()=="CON"){
00325     FileId=stdout;
00326   } else {
00327     if (Append){FileId=fopen(FNm.CStr(), "a+b");}
00328     else {FileId=fopen(FNm.CStr(), "w+b");}
00329     EAssertR(FileId!=NULL, "Can not open file '"+FNm+"'.");
00330     Bf=new char[MxBfL]; BfL=0;
00331   }
00332 }
00333 
00334 TFOut::TFOut(const TStr& FNm, const bool& Append, bool& OpenedP):
00335   TSBase(FNm.CStr()), TSOut(FNm), FileId(NULL), Bf(NULL), BfL(0){
00336   if (FNm.GetUc()=="CON"){
00337     FileId=stdout;
00338   } else {
00339     if (Append){FileId=fopen(FNm.CStr(), "a+b");}
00340     else {FileId=fopen(FNm.CStr(), "w+b");}
00341     OpenedP=(FileId!=NULL);
00342     if (OpenedP){
00343       Bf=new char[MxBfL]; BfL=0;}
00344   }
00345 }
00346 
00347 PSOut TFOut::New(const TStr& FNm, const bool& Append){
00348   return PSOut(new TFOut(FNm, Append));
00349 }
00350 
00351 PSOut TFOut::New(const TStr& FNm, const bool& Append, bool& OpenedP){
00352   PSOut SOut=PSOut(new TFOut(FNm, Append, OpenedP));
00353   if (OpenedP){return SOut;} else {return NULL;}
00354 }
00355 
00356 TFOut::~TFOut(){
00357   if (FileId!=NULL){FlushBf();}
00358   if (Bf!=NULL){delete[] Bf;}
00359   if (FileId!=NULL){
00360     EAssertR(fclose(FileId)==0, "Can not close file '"+GetSNm()+"'.");}
00361 }
00362 
00363 int TFOut::PutCh(const char& Ch){
00364   if (BfL==TSize(MxBfL)){FlushBf();}
00365   return Bf[BfL++]=Ch;
00366 }
00367 
00368 int TFOut::PutBf(const void* LBf, const TSize& LBfL){
00369   int LBfS=0;
00370   if (BfL+LBfL>MxBfL){
00371     for (TSize LBfC=0; LBfC<LBfL; LBfC++){
00372       LBfS+=PutCh(((char*)LBf)[LBfC]);}
00373   } else {
00374     for (TSize LBfC=0; LBfC<LBfL; LBfC++){
00375       LBfS+=(Bf[BfL++]=((char*)LBf)[LBfC]);}
00376   }
00377   return LBfS;
00378 }
00379 
00380 void TFOut::Flush(){
00381   FlushBf();
00382   EAssertR(fflush(FileId)==0, "Can not flush file '"+GetSNm()+"'.");
00383 }
00384 
00386 // Input-Output-File
00387 TFInOut::TFInOut(const TStr& FNm, const TFAccess& FAccess, const bool& CreateIfNo) :
00388  TSBase(TSStr(FNm.CStr())), FileId(NULL) {
00389   switch (FAccess){
00390     case faCreate: FileId=fopen(FNm.CStr(), "w+b"); break;
00391     case faUpdate: FileId=fopen(FNm.CStr(), "r+b"); break;
00392     case faAppend: FileId=fopen(FNm.CStr(), "r+b");
00393       if (FileId!=NULL){fseek(FileId, SEEK_END, 0);} break;
00394     case faRdOnly: FileId=fopen(FNm.CStr(), "rb"); break;
00395     default: Fail;
00396   }
00397   if ((FileId==NULL)&&(CreateIfNo)){FileId=fopen(FNm.CStr(), "w+b");}
00398   IAssert(FileId!=NULL);
00399 }
00400 
00401 PSInOut TFInOut::New(const TStr& FNm, const TFAccess& FAccess, const bool& CreateIfNo) {
00402   return PSInOut(new TFInOut(FNm, FAccess, CreateIfNo));
00403 }
00404 
00405 int TFInOut::GetSize() const {
00406   const int FPos = GetPos();
00407   IAssert(fseek(FileId, 0, SEEK_END) == 0);
00408   const int FLen = GetPos();
00409   IAssert(fseek(FileId, FPos, SEEK_SET) == 0);
00410   return FLen;
00411 }
00412 
00413 int TFInOut::PutBf(const void* LBf, const TSize& LBfL) {
00414   int LBfS = 0;
00415   for (TSize i = 0; i < LBfL; i++) {
00416     LBfS += ((char *)LBf)[i];
00417   }
00418   IAssert(fwrite(LBf, sizeof(char), LBfL, FileId) == (size_t) LBfL);
00419   return LBfS;
00420 }
00421 
00422 int TFInOut::GetBf(const void* LBf, const TSize& LBfL) {
00423   IAssert(fread((void *)LBf, sizeof(char), LBfL, FileId) == (size_t) LBfL);
00424   int LBfS = 0;
00425   for (TSize i = 0; i < LBfL; i++) {
00426     LBfS += ((char *)LBf)[i];
00427   }
00428   return LBfS;
00429 }
00430 
00431 TStr TFInOut::GetFNm() const {
00432   return GetSNm();
00433 }
00434 
00436 // Input-Memory
00437 TMIn::TMIn(const void* _Bf, const int& _BfL, const bool& TakeBf):
00438   TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(_BfL){
00439   if (TakeBf){
00440     Bf=(char*)_Bf;
00441   } else {
00442     Bf=new char[BfL]; memmove(Bf, _Bf, BfL);
00443   }
00444 }
00445 
00446 TMIn::TMIn(TSIn& SIn):
00447   TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(0){
00448   BfL=SIn.Len(); Bf=new char[BfL];
00449   for (int BfC=0; BfC<BfL; BfC++){Bf[BfC]=SIn.GetCh();}
00450 }
00451 
00452 TMIn::TMIn(const char* CStr):
00453   TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(0){
00454   BfL=int(strlen(CStr)); Bf=new char[BfL+1]; strcpy(Bf, CStr);
00455 }
00456 
00457 TMIn::TMIn(const TStr& Str):
00458   TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(0){
00459   BfL=Str.Len(); Bf=new char[BfL]; strncpy(Bf, Str.CStr(), BfL);
00460 }
00461 
00462 TMIn::TMIn(const TChA& ChA):
00463   TSBase("Input-Memory"), TSIn("Input-Memory"), Bf(NULL), BfC(0), BfL(0){
00464   BfL=ChA.Len(); Bf=new char[BfL]; strncpy(Bf, ChA.CStr(), BfL);
00465 }
00466 
00467 PSIn TMIn::New(const char* CStr){
00468   return PSIn(new TMIn(CStr));
00469 }
00470 
00471 PSIn TMIn::New(const TStr& Str){
00472   return PSIn(new TMIn(Str));
00473 }
00474 
00475 PSIn TMIn::New(const TChA& ChA){
00476   return PSIn(new TMIn(ChA));
00477 }
00478 
00479 char TMIn::GetCh(){
00480   EAssertR(BfC<BfL, "Reading beyond the end of stream.");
00481   return Bf[BfC++];
00482 }
00483 
00484 char TMIn::PeekCh(){
00485   EAssertR(BfC<BfL, "Reading beyond the end of stream.");
00486   return Bf[BfC];
00487 }
00488 
00489 int TMIn::GetBf(const void* LBf, const TSize& LBfL){
00490   EAssertR(TSize(BfC+LBfL)<=TSize(BfL), "Reading beyond the end of stream.");
00491   int LBfS=0;
00492   for (TSize LBfC=0; LBfC<LBfL; LBfC++){
00493     LBfS+=(((char*)LBf)[LBfC]=Bf[BfC++]);}
00494   return LBfS;
00495 }
00496 
00498 // Output-Memory
00499 void TMOut::Resize(){
00500   IAssert(OwnBf&&(BfL==MxBfL));
00501   if (Bf==NULL){
00502     IAssert(MxBfL==0); Bf=new char[MxBfL=1024];
00503   } else {
00504     MxBfL*=2; char* NewBf=new char[MxBfL];
00505     memmove(NewBf, Bf, BfL); delete[] Bf; Bf=NewBf;
00506   }
00507 }
00508 
00509 TMOut::TMOut(const int& _MxBfL):
00510   TSBase("Output-Memory"), TSOut("Output-Memory"),
00511   Bf(NULL), BfL(0), MxBfL(0), OwnBf(true){
00512   MxBfL=_MxBfL>0?_MxBfL:1024;
00513   Bf=new char[MxBfL];
00514 }
00515 
00516 TMOut::TMOut(char* _Bf, const int& _MxBfL):
00517   TSBase("Output-Memory"), TSOut("Output-Memory"),
00518   Bf(_Bf), BfL(0), MxBfL(_MxBfL), OwnBf(false){}
00519 
00520 int TMOut::PutBf(const void* LBf, const TSize& LBfL){
00521   int LBfS=0;
00522   if (TSize(BfL+LBfL)>TSize(MxBfL)){
00523     for (TSize LBfC=0; LBfC<LBfL; LBfC++){
00524       LBfS+=PutCh(((char*)LBf)[LBfC]);}
00525   } else {
00526     for (TSize LBfC=0; LBfC<LBfL; LBfC++){
00527       LBfS+=(Bf[BfL++]=((char*)LBf)[LBfC]);}
00528   }
00529   return LBfS;
00530 }
00531 
00532 TStr TMOut::GetAsStr() const {
00533   TChA ChA(BfL);
00534   for (int BfC=0; BfC<BfL; BfC++){ChA+=Bf[BfC];}
00535   return ChA;
00536 }
00537 
00538 void TMOut::CutBf(const int& CutBfL){
00539   IAssert((0<=CutBfL)&&(CutBfL<=BfL));
00540   if (CutBfL==BfL){BfL=0;}
00541   else {memmove(Bf, Bf+CutBfL, BfL-CutBfL); BfL=BfL-CutBfL;}
00542 }
00543 
00544 PSIn TMOut::GetSIn(const bool& IsCut, const int& CutBfL){
00545   IAssert((CutBfL==-1)||((0<=CutBfL)));
00546   int SInBfL= (CutBfL==-1) ? BfL : TInt::GetMn(BfL, CutBfL);
00547   PSIn SIn;
00548   if (OwnBf&&IsCut&&(SInBfL==BfL)){
00549     SIn=PSIn(new TMIn(Bf, SInBfL, true));
00550     Bf=NULL; BfL=MxBfL=0; OwnBf=true;
00551   } else {
00552     SIn=PSIn(new TMIn(Bf, SInBfL, false));
00553     if (IsCut){CutBf(SInBfL);}
00554   }
00555   return SIn;
00556 }
00557 
00558 bool TMOut::IsCrLfLn() const {
00559   for (int BfC=0; BfC<BfL; BfC++){
00560     if ((Bf[BfC]==TCh::CrCh)&&((BfC+1<BfL)&&(Bf[BfC+1]==TCh::LfCh))){return true;}}
00561   return false;
00562 }
00563 
00564 TStr TMOut::GetCrLfLn(){
00565   IAssert(IsCrLfLn());
00566   TChA Ln;
00567   for (int BfC=0; BfC<BfL; BfC++){
00568     char Ch=Bf[BfC];
00569     if ((Ch==TCh::CrCh)&&((BfC+1<BfL)&&(Bf[BfC+1]==TCh::LfCh))){
00570       Ln+=TCh::CrCh; Ln+=TCh::LfCh; CutBf(BfC+1+1); break;
00571     } else {
00572       Ln+=Ch;
00573     }
00574   }
00575   return Ln;
00576 }
00577 
00578 bool TMOut::IsEolnLn() const {
00579   for (int BfC=0; BfC<BfL; BfC++){
00580     if ((Bf[BfC]==TCh::CrCh)||(Bf[BfC]==TCh::LfCh)){return true;}
00581   }
00582   return false;
00583 }
00584 
00585 TStr TMOut::GetEolnLn(const bool& DoAddEoln, const bool& DoCutBf){
00586   IAssert(IsEolnLn());
00587   int LnChs=0; TChA Ln;
00588   for (int BfC=0; BfC<BfL; BfC++){
00589     char Ch=Bf[BfC];
00590     if ((Ch==TCh::CrCh)||(Ch==TCh::LfCh)){
00591       LnChs++; if (DoAddEoln){Ln+=Ch;}
00592       if (BfC+1<BfL){
00593         char NextCh=Bf[BfC+1];
00594         if (((Ch==TCh::CrCh)&&(NextCh==TCh::LfCh))||
00595          ((Ch==TCh::LfCh)&&(NextCh==TCh::CrCh))){
00596           LnChs++; if (DoAddEoln){Ln+=NextCh;}
00597         }
00598       }
00599       break;
00600     } else {
00601       LnChs++; Ln+=Ch;
00602     }
00603   }
00604   if (DoCutBf){
00605     CutBf(LnChs);
00606   }
00607   return Ln;
00608 }
00609 
00610 void TMOut::MkEolnLn(){
00611   if (!IsEolnLn()){
00612     PutCh(TCh::CrCh); PutCh(TCh::LfCh);}
00613 }
00614 
00616 // Line-Returner
00617 // J: after talking to BlazF -- can be removed from GLib
00618 bool TLnRet::NextLn(TStr& LnStr) {
00619     if (SIn->Eof()) { return false; }
00620     TChA LnChA; char Ch = TCh::EofCh;
00621     while (!SIn->Eof() && ((Ch=SIn->GetCh())!='\n')) {
00622         if (Ch != '\r') { LnChA += Ch; }
00623     }
00624     LnStr = LnChA; return true;
00625 }
00626 
00628 // fseek-Constants-Definitions
00629 // because of strange Borland CBuilder behaviour in sysdefs.h
00630 #ifndef SEEK_SET
00631 #define SEEK_CUR    1
00632 #define SEEK_END    2
00633 #define SEEK_SET    0
00634 #endif
00635 
00637 // Random-File
00638 void TFRnd::RefreshFPos(){
00639   EAssertR(
00640    fseek(FileId, 0, SEEK_CUR)==0,
00641    "Error seeking into file '"+TStr(FNm)+"'.");
00642 }
00643 
00644 TFRnd::TFRnd(const TStr& _FNm, const TFAccess& FAccess,
00645  const bool& CreateIfNo, const int& _HdLen, const int& _RecLen):
00646   FileId(NULL), FNm(_FNm.CStr()),
00647   RecAct(false), HdLen(_HdLen), RecLen(_RecLen){
00648   RecAct=(HdLen>=0)&&(RecLen>0);
00649   switch (FAccess){
00650     case faCreate: FileId=fopen(FNm.CStr(), "w+b"); break;
00651     case faUpdate: FileId=fopen(FNm.CStr(), "r+b"); break;
00652     case faAppend: FileId=fopen(FNm.CStr(), "r+b");
00653       if (FileId!=NULL){fseek(FileId, SEEK_END, 0);} break;
00654     case faRdOnly: FileId=fopen(FNm.CStr(), "rb"); break;
00655     default: Fail;
00656   }
00657   if ((FileId==NULL)&&(CreateIfNo)){
00658     FileId=fopen(FNm.CStr(), "w+b");}
00659   EAssertR(FileId!=NULL, "Can not open file '"+_FNm+"'.");
00660 }
00661 
00662 TFRnd::~TFRnd(){
00663   EAssertR(fclose(FileId)==0, "Can not close file '"+TStr(FNm)+"'.");
00664 }
00665 
00666 TStr TFRnd::GetFNm() const {
00667   return FNm.CStr();
00668 }
00669 
00670 void TFRnd::SetFPos(const int& FPos){
00671   EAssertR(
00672    fseek(FileId, FPos, SEEK_SET)==0,
00673    "Error seeking into file '"+TStr(FNm)+"'.");
00674 }
00675 
00676 void TFRnd::MoveFPos(const int& DFPos){
00677   EAssertR(
00678    fseek(FileId, DFPos, SEEK_CUR)==0,
00679    "Error seeking into file '"+TStr(FNm)+"'.");
00680 }
00681 
00682 int TFRnd::GetFPos(){
00683   int FPos= (int) ftell(FileId);
00684   EAssertR(FPos!=-1, "Error seeking into file '"+TStr(FNm)+"'.");
00685   return FPos;
00686 }
00687 
00688 int TFRnd::GetFLen(){
00689   int FPos=GetFPos();
00690   EAssertR(
00691    fseek(FileId, 0, SEEK_END)==0,
00692    "Error seeking into file '"+TStr(FNm)+"'.");
00693   int FLen=GetFPos(); SetFPos(FPos); return FLen;
00694 }
00695 
00696 void TFRnd::SetRecN(const int& RecN){
00697   IAssert(RecAct);
00698   SetFPos(HdLen+RecN*RecLen);
00699 }
00700 
00701 int TFRnd::GetRecN(){
00702   IAssert(RecAct);
00703   int FPos=GetFPos()-HdLen;
00704   EAssertR(FPos%RecLen==0, "Invalid position in file'"+TStr(FNm)+"'.");
00705   return FPos/RecLen;
00706 }
00707 
00708 int TFRnd::GetRecs(){
00709   IAssert(RecAct);
00710   int FLen=GetFLen()-HdLen;
00711   EAssertR(FLen%RecLen==0, "Invalid length of file'"+TStr(FNm)+"'.");
00712   return FLen/RecLen;
00713 }
00714 
00715 void TFRnd::GetBf(void* Bf, const TSize& BfL){
00716   RefreshFPos();
00717   EAssertR(
00718    fread(Bf, 1, BfL, FileId)==BfL,
00719    "Error reading file '"+TStr(FNm)+"'.");
00720 }
00721 
00722 void TFRnd::PutBf(const void* Bf, const TSize& BfL){
00723   RefreshFPos();
00724   EAssertR(
00725    fwrite(Bf, 1, BfL, FileId)==BfL,
00726    "Error writting to the file '"+TStr(FNm)+"'.");
00727 }
00728 
00729 void TFRnd::Flush(){
00730   EAssertR(fflush(FileId)==0, "Can not flush file '"+TStr(FNm)+"'.");
00731 }
00732 
00733 void TFRnd::PutCh(const char& Ch, const int& Chs){
00734   if (Chs>0){
00735     char* CStr=new char[Chs];
00736     for (int ChN=0; ChN<Chs; ChN++){CStr[ChN]=Ch;}
00737     PutBf(CStr, Chs);
00738     delete[] CStr;
00739   }
00740 }
00741 
00742 void TFRnd::PutStr(const TStr& Str){
00743   PutBf(Str.CStr(), Str.Len()+1);
00744 }
00745 
00746 TStr TFRnd::GetStr(const int& StrLen, bool& IsOk){
00747   IsOk=false; TStr Str;
00748   if (GetFPos()+StrLen+1<=GetFLen()){
00749     char* CStr=new char[StrLen+1];
00750     GetBf(CStr, StrLen+1);
00751     if (CStr[StrLen+1-1]==TCh::NullCh){IsOk=true; Str=CStr;}
00752     delete[] CStr;
00753   }
00754   return Str;
00755 }
00756 
00757 TStr TFRnd::GetStr(const int& StrLen){
00758   TStr Str;
00759   char* CStr=new char[StrLen+1];
00760   GetBf(CStr, StrLen+1);
00761   EAssertR(CStr[StrLen+1-1]==TCh::NullCh, "Error reading file '"+TStr(FNm)+"'.");
00762   Str=CStr;
00763   delete[] CStr;
00764   return Str;
00765 }
00766 
00767 void TFRnd::PutSIn(const PSIn& SIn, TCs& Cs){
00768   int BfL=SIn->Len();
00769   char* Bf=new char[BfL];
00770   SIn->GetBf(Bf, BfL);
00771   Cs=TCs::GetCsFromBf(Bf, BfL);
00772   PutBf(Bf, BfL);
00773   delete[] Bf;
00774 }
00775 
00776 PSIn TFRnd::GetSIn(const int& BfL, TCs& Cs){
00777   char* Bf=new char[BfL];
00778   GetBf(Bf, BfL);
00779   Cs=TCs::GetCsFromBf(Bf, BfL);
00780   PSIn SIn=PSIn(new TMIn(Bf, BfL, true));
00781   return SIn;
00782 }
00783 
00784 TStr TFRnd::GetStrFromFAccess(const TFAccess& FAccess){
00785   switch (FAccess){
00786     case faCreate: return "Create";
00787     case faUpdate: return "Update";
00788     case faAppend: return "Append";
00789     case faRdOnly: return "ReadOnly";
00790     case faRestore: return "Restore";
00791     default: Fail; return TStr();
00792   }
00793 }
00794 
00795 TFAccess TFRnd::GetFAccessFromStr(const TStr& Str){
00796   TStr UcStr=Str.GetUc();
00797   if (UcStr=="CREATE"){return faCreate;}
00798   if (UcStr=="UPDATE"){return faUpdate;}
00799   if (UcStr=="APPEND"){return faAppend;}
00800   if (UcStr=="READONLY"){return faRdOnly;}
00801   if (UcStr=="RESTORE"){return faRestore;}
00802 
00803   if (UcStr=="NEW"){return faCreate;}
00804   if (UcStr=="CONT"){return faUpdate;}
00805   if (UcStr=="CONTINUE"){return faUpdate;}
00806   if (UcStr=="REST"){return faRestore;}
00807   if (UcStr=="RESTORE"){return faRestore;}
00808   return faUndef;
00809 }
00810 
00812 // Files
00813 const TStr TFile::TxtFExt=".Txt";
00814 const TStr TFile::HtmlFExt=".Html";
00815 const TStr TFile::HtmFExt=".Htm";
00816 const TStr TFile::GifFExt=".Gif";
00817 const TStr TFile::JarFExt=".Jar";
00818 
00819 bool TFile::Exists(const TStr& FNm){
00820   if (FNm.Empty()) { return false; }
00821   bool DoExists;
00822   TFIn FIn(FNm, DoExists);
00823   return DoExists;
00824 }
00825 
00826 #if defined(GLib_WIN32)
00827 
00828 void TFile::Copy(const TStr& SrcFNm, const TStr& DstFNm, 
00829  const bool& ThrowExceptP, const bool& FailIfExistsP){
00830   if (ThrowExceptP){
00831     if (CopyFile(SrcFNm.CStr(), DstFNm.CStr(), FailIfExistsP) == 0) {
00832         int ErrorCode = (int)GetLastError();
00833         TExcept::Throw(TStr::Fmt(
00834             "Error %d copying file '%s' to '%s'.", 
00835             ErrorCode, SrcFNm.CStr(), DstFNm.CStr()));
00836     }
00837   } else {
00838     CopyFile(SrcFNm.CStr(), DstFNm.CStr(), FailIfExistsP);
00839   }
00840 }
00841 
00842 #elif defined(GLib_LINUX)
00843 
00844 void TFile::Copy(const TStr& SrcFNm, const TStr& DstFNm,
00845  const bool& ThrowExceptP, const bool& FailIfExistsP){
00846         int input, output;
00847         size_t filesize;
00848         void *source, *target;
00849 
00850         if( (input = open(SrcFNm.CStr(), O_RDONLY)) == -1) {
00851                 if (ThrowExceptP) {
00852                         TExcept::Throw(TStr::Fmt(
00853                                     "Error copying file '%s' to '%s': cannot open source file for reading.",
00854                                     SrcFNm.CStr(), DstFNm.CStr()));
00855                 } else {
00856                         return;
00857                 }
00858         }
00859 
00860 
00861         if( (output = open(DstFNm.CStr(), O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1)     {
00862                 close(input);
00863 
00864                 if (ThrowExceptP) {
00865                         TExcept::Throw(TStr::Fmt(
00866                                     "Error copying file '%s' to '%s': cannot open destination file for writing.",
00867                                     SrcFNm.CStr(), DstFNm.CStr()));
00868                 } else {
00869                         return;
00870                 }
00871         }
00872 
00873 
00874         filesize = lseek(input, 0, SEEK_END);
00875         lseek(output, filesize - 1, SEEK_SET);
00876         write(output, '\0', 1);
00877 
00878         if((source = mmap(0, filesize, PROT_READ, MAP_SHARED, input, 0)) == (void *) -1) {
00879                 close(input);
00880                 close(output);
00881                 if (ThrowExceptP) {
00882                         TExcept::Throw(TStr::Fmt(
00883                                                 "Error copying file '%s' to '%s': cannot mmap input file.",
00884                                                 SrcFNm.CStr(), DstFNm.CStr()));
00885                 } else {
00886                         return;
00887                 }
00888         }
00889 
00890         if((target = mmap(0, filesize, PROT_WRITE, MAP_SHARED, output, 0)) == (void *) -1) {
00891                 munmap(source, filesize);
00892                 close(input);
00893                 close(output);
00894                 if (ThrowExceptP) {
00895                         TExcept::Throw(TStr::Fmt(
00896                                                 "Error copying file '%s' to '%s': cannot mmap output file.",
00897                                                 SrcFNm.CStr(), DstFNm.CStr()));
00898                 } else {
00899                         return;
00900                 }
00901         }
00902 
00903         memcpy(target, source, filesize);
00904 
00905         munmap(source, filesize);
00906         munmap(target, filesize);
00907 
00908         close(input);
00909         close(output);
00910 
00911 }
00912 
00913 
00914 
00915 #endif
00916 
00917 void TFile::Del(const TStr& FNm, const bool& ThrowExceptP){
00918   if (ThrowExceptP){
00919     EAssertR(
00920      remove(FNm.CStr())==0,
00921      "Error removing file '"+FNm+"'.");
00922   } else {
00923     remove(FNm.CStr());
00924   }
00925 }
00926 
00927 void TFile::DelWc(const TStr& WcStr, const bool& RecurseDirP){
00928   // collect file-names
00929   TStrV FNmV;
00930   TFFile FFile(WcStr, RecurseDirP); TStr FNm;
00931   while (FFile.Next(FNm)){
00932     FNmV.Add(FNm);}
00933   // delete files
00934   for (int FNmN=0; FNmN<FNmV.Len(); FNmN++){
00935     Del(FNmV[FNmN], false);}
00936 }
00937 
00938 void TFile::Rename(const TStr& SrcFNm, const TStr& DstFNm){
00939   EAssertR(
00940    rename(SrcFNm.CStr(), DstFNm.CStr())==0,
00941    "Error renaming file '"+SrcFNm+"' to "+DstFNm+"'.");
00942 }
00943 
00944 TStr TFile::GetUniqueFNm(const TStr& FNm){
00945   // <name>.#.txt --> <name>.<num>.txt
00946   int Cnt=1; int ch;
00947   TStr NewFNm; TStr TmpFNm=FNm;
00948   if (FNm.SearchCh('#') == -1) {
00949     for (ch = FNm.Len()-1; ch >= 0; ch--) if (FNm[ch] == '.') break;
00950     if (ch != -1) TmpFNm.InsStr(ch, ".#");
00951     else TmpFNm += ".#";
00952   }
00953   forever{
00954     NewFNm=TmpFNm;
00955     NewFNm.ChangeStr("#", TStr::Fmt("%03d", Cnt)); Cnt++;
00956     if (!TFile::Exists(NewFNm)){break;}
00957   }
00958   return NewFNm;
00959 }
00960 
00961 #ifdef GLib_WIN
00962 
00963 uint64 TFile::GetSize(const TStr& FNm) {
00964     // open 
00965     HANDLE hFile = CreateFile(
00966        FNm.CStr(),            // file to open
00967        GENERIC_READ,          // open for reading
00968        FILE_SHARE_READ | FILE_SHARE_WRITE,       // share for reading
00969        NULL,                  // default security
00970        OPEN_EXISTING,         // existing file only
00971        FILE_ATTRIBUTE_NORMAL, // normal file
00972        NULL);                 // no attr. template
00973     // check if we could open it
00974     if (hFile == INVALID_HANDLE_VALUE) {
00975         TExcept::Throw("Can not open file " + FNm + "!"); }
00976     // read file times
00977     LARGE_INTEGER lpFileSizeHigh;
00978         if (!GetFileSizeEx(hFile, &lpFileSizeHigh)) {
00979         TExcept::Throw("Can not read size of file " + FNm + "!"); }
00980     // close file
00981     CloseHandle(hFile);
00982     // convert to uint64
00983         return uint64(lpFileSizeHigh.QuadPart);
00984 }
00985 
00986 uint64 TFile::GetCreateTm(const TStr& FNm) {
00987     // open 
00988     HANDLE hFile = CreateFile(
00989        FNm.CStr(),            // file to open
00990        GENERIC_READ,          // open for reading
00991        FILE_SHARE_READ | FILE_SHARE_WRITE,       // share for reading
00992        NULL,                  // default security
00993        OPEN_EXISTING,         // existing file only
00994        FILE_ATTRIBUTE_NORMAL, // normal file
00995        NULL);                 // no attr. template
00996     // check if we could open it
00997     if (hFile == INVALID_HANDLE_VALUE) {
00998         TExcept::Throw("Can not open file " + FNm + "!"); }
00999     // read file times
01000     FILETIME lpCreationTime;
01001     if (!GetFileTime(hFile, &lpCreationTime, NULL, NULL)) {
01002         TExcept::Throw("Can not read time from file " + FNm + "!"); }
01003     // close file
01004     CloseHandle(hFile);
01005     // convert to uint64
01006     TUInt64 UInt64(uint(lpCreationTime.dwHighDateTime), 
01007         uint(lpCreationTime.dwLowDateTime));
01008     return UInt64.Val / uint64(10000);
01009 }
01010 
01011 uint64 TFile::GetLastAccessTm(const TStr& FNm) {
01012     // open 
01013     HANDLE hFile = CreateFile(
01014        FNm.CStr(),            // file to open
01015        GENERIC_READ,          // open for reading
01016        FILE_SHARE_READ | FILE_SHARE_WRITE,       // share for reading
01017        NULL,                  // default security
01018        OPEN_EXISTING,         // existing file only
01019        FILE_ATTRIBUTE_NORMAL, // normal file
01020        NULL);                 // no attr. template
01021     // check if we could open it
01022     if (hFile == INVALID_HANDLE_VALUE) {
01023         TExcept::Throw("Can not open file " + FNm + "!"); }
01024     // read file times
01025     FILETIME lpLastAccessTime;
01026     if (!GetFileTime(hFile, NULL, &lpLastAccessTime, NULL)) {
01027         TExcept::Throw("Can not read time from file " + FNm + "!"); }
01028     // close file
01029     CloseHandle(hFile);
01030     // convert to uint64
01031     TUInt64 UInt64(uint(lpLastAccessTime.dwHighDateTime), 
01032         uint(lpLastAccessTime.dwLowDateTime));
01033     return UInt64.Val / uint64(10000);
01034 }
01035 
01036 uint64 TFile::GetLastWriteTm(const TStr& FNm) {
01037     // open 
01038     HANDLE hFile = CreateFile(
01039        FNm.CStr(),            // file to open
01040        GENERIC_READ,          // open for reading
01041        FILE_SHARE_READ | FILE_SHARE_WRITE,       // share for reading
01042        NULL,                  // default security
01043        OPEN_EXISTING,         // existing file only
01044        FILE_ATTRIBUTE_NORMAL, // normal file
01045        NULL);                 // no attr. template
01046     // check if we could open it
01047     if (hFile == INVALID_HANDLE_VALUE) {
01048         TExcept::Throw("Can not open file " + FNm + "!"); }
01049     // read file times
01050     FILETIME lpLastWriteTime;
01051     if (!GetFileTime(hFile, NULL, NULL, &lpLastWriteTime)) {
01052         TExcept::Throw("Can not read time from file " + FNm + "!"); }
01053     // close file
01054     CloseHandle(hFile);
01055     // convert to uint64
01056     TUInt64 UInt64(uint(lpLastWriteTime.dwHighDateTime), 
01057         uint(lpLastWriteTime.dwLowDateTime));
01058     return UInt64.Val / uint64(10000);
01059 }
01060 
01061 #elif defined(GLib_LINUX)
01062 
01063 uint64 TFile::GetSize(const TStr& FNm) {
01064         Fail; return 0;
01065 }
01066 
01067 uint64 TFile::GetCreateTm(const TStr& FNm) {
01068         return GetLastWriteTm(FNm);
01069 }
01070 
01071 uint64 TFile::GetLastWriteTm(const TStr& FNm) {
01072         struct stat st;
01073         if (stat(FNm.CStr(), &st) != 0) {
01074                 TExcept::Throw("Cannot read tile from file " + FNm + "!");
01075         }
01076         return uint64(st.st_mtime);
01077 }
01078 
01079 
01080 #endif