SNAP Library , Developer Reference
2013-01-07 14:03:36
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
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