00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00110
00111
00112 #include <assert.h>
00113
00114 #include "TEnv.h"
00115 #include "TSystem.h"
00116 #include "TFile.h"
00117 #include "TKey.h"
00118
00119 #include "StFileIter.h"
00120 #include "TDsKey.h"
00121
00122 ClassImp(StFileIter)
00123
00124
00125 StFileIter::StFileIter(TFile *file) : fFileBackUp(0),fDirectoryBackUp(0), fNestedIterator(0)
00126 , fRootFile(file)
00127 , fEventName("event"), fRunNumber(UInt_t(-1)),fEventNumber(UInt_t(-1))
00128 , fCursorPosition(-1), fOwnTFile(kFALSE)
00129 {
00130
00131 Initialize();
00132 }
00133
00134
00135 StFileIter::StFileIter(TDirectory *directory) : fFileBackUp(0),fDirectoryBackUp(0), fNestedIterator(0)
00136 , fRootFile(directory)
00137 , fEventName("event"), fRunNumber(UInt_t(-1)),fEventNumber(UInt_t(-1))
00138 , fCursorPosition(-1), fOwnTFile(kFALSE)
00139 {
00140
00141 Initialize();
00142 }
00143
00144 StFileIter::StFileIter(const char *name, Option_t *option, const char *ftitle
00145 , Int_t compress, Int_t ) :fNestedIterator(0),fRootFile (0)
00146 {
00147
00148
00149 if (name && name[0]) {
00150 fOwnTFile = kTRUE;
00151
00152
00153
00154
00155 fRootFile = TFile::Open(MapName(name),option,ftitle,compress);
00156 Initialize();
00157 }
00158 }
00159
00160
00161 StFileIter::StFileIter(const StFileIter &dst) : TListIter()
00162 ,fFileBackUp(0), fDirectoryBackUp(0), fNestedIterator(0)
00163 ,fRootFile(dst.fRootFile),fEventName(dst.fEventName), fRunNumber(dst.fRunNumber)
00164 ,fEventNumber(dst.fRunNumber),
00165 fCursorPosition(-1), fOwnTFile(dst.fOwnTFile)
00166 {
00167
00168 assert(!fRootFile->IsWritable());
00169 if (fRootFile && fOwnTFile && !fRootFile->IsWritable()) {
00170
00171 if (fRootFile->InheritsFrom(TFile::Class()))
00172 {
00173 TFile *thisFile = (TFile *)fRootFile;
00174 fRootFile = TFile::Open(MapName(fRootFile->GetName())
00175 ,fRootFile->GetOption()
00176 ,fRootFile->GetTitle()
00177 ,thisFile->GetCompressionLevel());
00178 }
00179 }
00180
00181 Initialize();
00182
00183 SkipObjects(dst.fCursorPosition);
00184 }
00185
00186 StFileIter::~StFileIter()
00187 {
00188
00189 StFileIter *deleteit = fNestedIterator; fNestedIterator = 0;
00190 delete deleteit;
00191 if (fRootFile && fOwnTFile ) {
00192 if (fRootFile->IsWritable()) fRootFile->Write();
00193 fRootFile->Close();
00194 delete fRootFile;
00195 fRootFile = 0;
00196 }
00197 }
00198
00199
00200 void StFileIter::Initialize()
00201 {
00202
00203 if (fRootFile) {
00204 fDirection = kIterForward;
00205 if (IsOpen()) Reset();
00206 else {
00207 if (fRootFile && fOwnTFile ) delete fRootFile;
00208 fRootFile = 0;
00209 }
00210 }
00211 }
00212
00213 Bool_t StFileIter::IsOpen() const
00214 {
00215 Bool_t iOpen = kFALSE;
00216 if (fRootFile && !fRootFile->IsZombie() ) {
00217 iOpen = kTRUE;
00218 if (fRootFile->InheritsFrom(TFile::Class()) && !((TFile*)fRootFile)->IsOpen())
00219 iOpen = kFALSE;
00220 }
00221 return iOpen;
00222 }
00223
00224
00225 TKey *StFileIter::GetCurrentKey() const
00226 {
00227
00228
00229 return ((StFileIter*)this)->SkipObjects(0);
00230 }
00231
00232 Int_t StFileIter::GetDepth() const
00233 {
00234
00235
00236 return fNestedIterator ? fNestedIterator->GetDepth()+1 : 0;
00237 }
00238
00239
00240 const char *StFileIter::GetKeyName() const
00241 {
00242
00243 const char *name = 0;
00244 TKey *key = GetCurrentKey();
00245 if (key) name = key->GetName();
00246 return name;
00247 }
00248
00249 TObject *StFileIter::GetObject() const
00250 {
00251
00252
00253
00254
00255
00256
00257
00258
00259 return ReadObj(GetCurrentKey());
00260 }
00261
00262 Int_t StFileIter::GetObjlen() const
00263 {
00264
00265 Int_t lenObj = 0;
00266 TKey *key = GetCurrentKey();
00267 if (key) lenObj = ((TKey *)key)->GetObjlen();
00268 return lenObj;
00269 }
00270
00271 Int_t StFileIter::TotalKeys() const
00272 {
00273
00274
00275
00276
00277
00278
00279 Int_t size = 0;
00280 if(fList) size += fList->GetSize();
00281 return size;
00282 }
00283
00284 TObject *StFileIter::Next(Int_t nSkip)
00285 {
00286
00287
00288
00289
00290 SkipObjects(nSkip);
00291 return GetObject();
00292 }
00293
00294
00295 void StFileIter::PurgeKeys(TList *listOfKeys) {
00296 assert(listOfKeys);
00297
00298
00299
00300 listOfKeys->Sort();
00301 TObjLink *lnk = listOfKeys->FirstLink();
00302 while(lnk) {
00303 TKey *key = (TKey *)lnk->GetObject();
00304 Short_t cycle = key->GetCycle();
00305 const char *keyName = key->GetName();
00306
00307 lnk = lnk->Next();
00308 if (lnk) {
00309 TKey *nextkey = 0;
00310 TObjLink *lnkThis = lnk;
00311 while ( lnk
00312 && (nextkey = (TKey *)lnk->GetObject())
00313 && !strcmp(nextkey->GetName(), keyName)
00314 ) {
00315
00316 Short_t nextCycle = nextkey->GetCycle() ;
00317
00318
00319 assert(cycle != nextCycle);
00320 TObjLink *lnkNext = lnk->Next();
00321 if (cycle > nextCycle ) {
00322 delete listOfKeys->Remove(lnk);
00323 } else {
00324 delete listOfKeys->Remove(lnkThis);
00325 cycle = nextCycle;
00326 lnkThis = lnk;
00327 }
00328 lnk = lnkNext;
00329 }
00330 }
00331 }
00332 }
00333
00334
00335 void StFileIter::Reset()
00336 {
00337
00338 if (fNestedIterator) {
00339 StFileIter *it = fNestedIterator;
00340 fNestedIterator=0;
00341 delete it;
00342 }
00343 TListIter::Reset();
00344 if (!fRootFile->IsWritable()) {
00345 TList *listOfKeys = fRootFile->GetListOfKeys();
00346 if (listOfKeys) {
00347 if (!listOfKeys->IsSorted()) PurgeKeys(listOfKeys);
00348 fList = listOfKeys;
00349 if (fDirection == kIterForward) {
00350 fCursorPosition = 0;
00351 fCurCursor = fList->FirstLink();
00352 if (fCurCursor) fCursor = fCurCursor->Next();
00353 } else {
00354 fCursorPosition = fList->GetSize()-1;
00355 fCurCursor = fList->LastLink();
00356 if (fCurCursor) fCursor = fCurCursor->Prev();
00357 }
00358 }
00359 }
00360 }
00361
00362 void StFileIter::SetCursorPosition(const char *keyNameToFind)
00363 {
00364
00365 Reset();
00366 while( (*this != keyNameToFind) && SkipObjects() );
00367 }
00368
00369 TKey *StFileIter::SkipObjects(Int_t nSkip)
00370 {
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 TKey *nextObject = fNestedIterator ? fNestedIterator->SkipObjects(nSkip): 0;
00382 if (!nextObject) {
00383 if (fNestedIterator) {
00384 StFileIter *it = fNestedIterator;
00385 fNestedIterator = 0;
00386 delete it;
00387 }
00388 Int_t collectionSize = 0;
00389 if (fList && (collectionSize = fList->GetSize()) ) {
00390 if (fDirection !=kIterForward) nSkip = -nSkip;
00391 Int_t newPos = fCursorPosition + nSkip;
00392 if (0 <= newPos && newPos < collectionSize) {
00393 do {
00394 if (fCursorPosition < newPos) {
00395 fCursorPosition++;
00396 fCurCursor = fCursor;
00397 fCursor = fCursor->Next();
00398 } else if (fCursorPosition > newPos) {
00399 fCursorPosition--;
00400 fCurCursor = fCursor;
00401 fCursor = fCursor->Prev();
00402 }
00403 } while (fCursorPosition != newPos);
00404 if (fCurCursor) nextObject = dynamic_cast<TKey *>(fCurCursor->GetObject());
00405 } else {
00406 fCurCursor = fCursor = 0;
00407 if (newPos < 0) {
00408 fCursorPosition = -1;
00409 if (fList) fCursor = fList->FirstLink();
00410 } else {
00411 fCursorPosition = collectionSize;
00412 if (fList) fCursor = fList->LastLink();
00413 }
00414 }
00415 }
00416 }
00417 return nextObject;
00418 }
00419
00420 TKey *StFileIter::NextEventKey(UInt_t eventNumber, UInt_t runNumber, const char *name)
00421 {
00422
00423
00424
00425
00426
00427
00428 Bool_t reset = kFALSE;
00429 if (name && name[0] && name[0] != '*') { if (fEventName > name) reset = kTRUE; fEventName = name; }
00430 if (runNumber !=UInt_t(-1) ) { if (fRunNumber > runNumber) reset = kTRUE; fRunNumber = runNumber;}
00431 if (eventNumber !=UInt_t(-1) ) { if (fEventNumber > eventNumber) reset = kTRUE; fEventNumber = eventNumber;}
00432
00433 if (reset) Reset();
00434
00435 TKey *key = 0;
00436 TDsKey thisKey;
00437 while ( (key = SkipObjects()) ) {
00438 if (fDirection==kIterForward) fCursorPosition++;
00439 else fCursorPosition--;
00440 if ( strcmp(name,"*") ) {
00441 thisKey.SetKey(key->GetName());
00442 if (thisKey.GetName() < name) continue;
00443 if (thisKey.GetName() > name) { key = 0; break; }
00444 }
00445
00446 if (runNumber != UInt_t(-1)) {
00447 UInt_t thisRunNumber = thisKey.RunNumber();
00448 if (thisRunNumber < runNumber) continue;
00449 if (thisRunNumber < runNumber) { key = 0; break; }
00450 }
00451
00452 if (eventNumber != UInt_t(-1)) {
00453 UInt_t thisEventNumber = thisKey.EventNumber();
00454 if (thisEventNumber < eventNumber) continue;
00455 if (thisEventNumber > eventNumber) {key = 0; break; }
00456 }
00457 break;
00458 }
00459 return key;
00460 }
00461
00462 TObject *StFileIter::NextEventGet(UInt_t eventNumber, UInt_t runNumber, const char *name)
00463 {
00464
00465
00466
00467
00468
00469
00470 return ReadObj(NextEventKey(eventNumber,runNumber,name));
00471 }
00472
00473
00474 TObject *StFileIter::ReadObj(const TKey *key) const
00475 {
00476
00477 TObject *obj = 0;
00478 if (fNestedIterator) obj = fNestedIterator->ReadObj(key);
00479 else if (key) {
00480 obj = ((TKey *)key)->ReadObj();
00481 if (obj && obj->InheritsFrom(TDirectory::Class()) )
00482 {
00483
00484 assert(!fNestedIterator);
00485 ((StFileIter*)this)->fNestedIterator = new StFileIter((TDirectory *)obj);
00486
00487 }
00488 }
00489 return obj;
00490 }
00491
00492
00493 Int_t StFileIter::NextEventPut(TObject *obj, UInt_t eventNum, UInt_t runNumber
00494 , const char *name)
00495 {
00496
00497
00498 Int_t wBytes = 0;
00499 if (obj && IsOpen() && fRootFile->IsWritable()) {
00500 TDsKey thisKey(runNumber,eventNum);
00501 if (name && name[0])
00502 thisKey.SetName(name);
00503 else
00504 thisKey.SetName(obj->GetName());
00505
00506 if (fRootFile != gDirectory) {
00507 SaveFileScope();
00508 fRootFile->cd();
00509 }
00510 wBytes = obj->Write(thisKey.GetKey());
00511 if (fRootFile->InheritsFrom(TFile::Class())) ((TFile*)fRootFile)->Flush();
00512 if (fRootFile != gDirectory) RestoreFileScope();
00513 }
00514 return wBytes;
00515 }
00516
00517 TString StFileIter::MapName(const char *name, const char *localSystemKey,const char *mountedFileSystemKey)
00518 {
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 if ( !localSystemKey) localSystemKey = GetLocalFileNameKey();
00541 if ( !mountedFileSystemKey) mountedFileSystemKey = GetForeignFileSystemKey();
00542 TString newName = name;
00543 TString fileMap = gEnv->GetValue(GetResourceName(),GetDefaultMapFileName());
00544 const char *localName = 0;
00545 const char *foreignName = 0;
00546 if ( gSystem->AccessPathName(fileMap) == 0 ){
00547 TEnv myMapResource(fileMap);
00548 localName = myMapResource.Defined(localSystemKey) ?
00549 myMapResource.GetValue(localSystemKey,"") : 0;
00550 foreignName = myMapResource.Defined(mountedFileSystemKey) ?
00551 myMapResource.GetValue(mountedFileSystemKey,""):0;
00552 } else {
00553 localName = "/castor";
00554 foreignName = "rfio:/castor";
00555 }
00556 if (localName && localName[0]
00557 && foreignName
00558 && foreignName[0]
00559 && newName.BeginsWith(localName) )
00560 newName.Replace(0,strlen(localName),foreignName);
00561 return newName;
00562 }