00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "Riosfwd.h"
00013 #include "Riostream.h"
00014
00015 #include "TDataSetIter.h"
00016 #include "TBrowser.h"
00017 #include "TSystem.h"
00018
00019 #ifndef WIN32
00020 # ifndef HASSTRCASE
00021 # define HASSTRCASE
00022 # endif
00023 #endif
00024
00025 #ifndef HASSTRCASE
00026 # define strcasecmp(arg1,arg2) stricmp(arg1,arg2)
00027 #endif
00028
00029 TDataSet *TDataSetIter::fgNullDataSet = (TDataSet *)(-1);
00030
00031 ClassImp(TDataSetIter)
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 TDataSetIter::TDataSetIter(TDataSet *link, Bool_t dir)
00049 {
00050
00051 fWorkingDataSet= fRootDataSet =link;
00052 fMaxDepth = fDepth =1;
00053 fDataSet= fgNullDataSet ;
00054 fNext = link ? new TIter(link->GetCollection() ,dir):0;
00055 for(UInt_t i = 0; i < sizeof(fNextSet) / sizeof(TIter*); ++i) {
00056 fNextSet[i] = (TIter*)0;
00057 }
00058 }
00059
00060
00061 TDataSetIter::TDataSetIter(TDataSet *link, Int_t depth, Bool_t dir)
00062 {
00063
00064 fRootDataSet = fWorkingDataSet = link;
00065 fMaxDepth = depth;
00066 fDepth = 1;
00067 fDataSet = fgNullDataSet;
00068 fNext = (link)? new TIter(link->GetCollection() ,dir):0;
00069
00070
00071
00072
00073
00074 for(UInt_t i = 0; i < sizeof(fNextSet) / sizeof(TIter*); ++i) {
00075 fNextSet[i] = (TIter*)0;
00076 }
00077 if (fMaxDepth != 1) {
00078 fNextSet[0] = fNext;
00079 if (fMaxDepth > 100) fMaxDepth = 100;
00080 fDepth = 0;
00081 }
00082 }
00083
00084
00085 TDataSetIter::~TDataSetIter()
00086 {
00087
00088 if (fMaxDepth != 1) {
00089 Int_t level = fDepth;
00090 if (level) level--;
00091 for (Int_t i = level;i>=0;i--) {
00092 TIter *s = fNextSet[i];
00093 if (s) delete s;
00094 }
00095 }
00096 else
00097 SafeDelete(fNext);
00098 fDepth = 0;
00099 }
00100
00101
00102
00103 TDataSet *TDataSetIter::operator *() const
00104 {
00105
00106 return fDataSet == fgNullDataSet ? fWorkingDataSet : fDataSet;
00107 }
00108
00109
00110 TDataSet *TDataSetIter::GetNullSet()
00111 {
00112
00113 return (TDataSet *)fgNullDataSet;
00114 }
00115
00116
00117 TDataSet *TDataSetIter::Add(TDataSet *set, TDataSet *dataset)
00118 {
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 if (!set) return 0;
00136 TDataSet *s = dataset;
00137 if (!s) s = Cwd();
00138 if (s) {
00139 s->Add(set);
00140 s = set;
00141 }
00142 else {
00143
00144 s = set;
00145 fRootDataSet = s;
00146 fWorkingDataSet = s;
00147 if (fNext) {
00148 Error("Add","TDataSetIter.has been corrupted ;-!");
00149 delete fNext;
00150 fNext = 0;
00151 }
00152 fNext = new TIter(s->GetCollection() );
00153 }
00154 return s;
00155 }
00156
00157
00158 TDataSet *TDataSetIter::Add(TDataSet *dataset, const Char_t *path)
00159 {
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 if (!dataset) return 0;
00174 TDataSet *set = 0;
00175 if (path && strlen(path)) set = Find(path);
00176 return Add(dataset,set);
00177 }
00178
00179
00180 TDataSet *TDataSetIter::Cd(const Char_t *dirname){
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 TDataSet *set = 0;
00196 if (strcmp(dirname,".."))
00197 set = Find(dirname);
00198 else
00199 set = fWorkingDataSet->GetParent();
00200 if (set) fWorkingDataSet = set;
00201 return set;
00202 }
00203
00204
00205 TDataSet *TDataSetIter::Cd(TDataSet *ds)
00206 {
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 TDataSet *nextSet = 0;
00222 if (Cwd()) {
00223 TDataSetIter next(Cwd(),0);
00224 while ( (nextSet = next()) )
00225 if (ds == nextSet) {fWorkingDataSet = ds; break;}
00226 }
00227 return nextSet;
00228 }
00229
00230
00231 TDataSet *TDataSetIter::Dir(Char_t *dirname)
00232 {
00233
00234
00235
00236
00237 TDataSet *set = (TDataSet *)fWorkingDataSet;
00238 if (dirname) set = Find(dirname);
00239 if (set) set->ls();
00240 return set;
00241 }
00242
00243
00244 Int_t TDataSetIter::Du() const {
00245
00246 if (!fWorkingDataSet) return 0;
00247 TDataSetIter next(fWorkingDataSet,0);
00248 TDataSet *nextset = 0;
00249 Int_t count = 0;
00250 while((nextset = (count) ? next():fWorkingDataSet)) {
00251 count++;
00252 if (nextset->IsFolder()) cout << endl;
00253 TString path = nextset->Path();
00254 cout << setw(2) << next.GetDepth() << ". ";
00255 cout << path << setw(TMath::Max(Int_t(60-strlen(path.Data())),Int_t(0))) << "...";
00256 const Char_t *type = nextset->IsFolder() ? "directory" : "table" ;
00257 cout << setw(10) << type;
00258 cout << " : " << setw(10) << nextset->GetTitle();
00259 cout << endl;
00260 }
00261 return count;
00262 }
00263
00264
00265 TDataSet *TDataSetIter::FindByName(const Char_t *name,const Char_t *path,Option_t *opt)
00266 {
00267
00268 return FindDataSet(name,path,opt);
00269 }
00270
00271
00272 TDataSet *TDataSetIter::FindByTitle(const Char_t *title,const Char_t *path,Option_t *opt)
00273 {
00274
00275 TString optt = "-t";
00276 optt += opt;
00277 return FindDataSet(title,path,optt.Data());
00278 }
00279
00280
00281 TDataSet *TDataSetIter::FindDataSet(const Char_t *name,const Char_t *path,Option_t *opt)
00282 {
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 if (!name || strlen(name) == 0) return 0;
00296 if (strchr(name,'/')) {
00297 Error("FindDataSet","The name of the object <%s> can not contain any \"/\"",name);
00298 return 0;
00299 }
00300
00301 Bool_t opti = opt ? strcasecmp(opt,"-i") == 0 : kFALSE;
00302 Bool_t optt = opt ? strcasecmp(opt,"-t") == 0 : kFALSE;
00303
00304 TDataSet *startset = 0;
00305 if (path && strlen(path)) startset = Find(path);
00306 else startset = fWorkingDataSet;
00307 if (!startset) return 0;
00308
00309 TDataSet *set = startset;
00310 if ( !((opti && strcasecmp( optt ? set->GetTitle() : set->GetName(),name) == 0 ) ||
00311 (strcmp(optt ? set->GetTitle() : set->GetName(),name) == 0)) )
00312 {
00313 TDataSetIter next(startset,0);
00314 while ((set = next()))
00315 if ( (opti && strcasecmp(optt ? set->GetTitle() : set->GetName(),name) == 0 ) ||
00316 (strcmp(optt ? set->GetTitle() : set->GetName(),name) == 0) ) break;
00317 }
00318
00319 return set;
00320 }
00321
00322
00323 TDataSet *TDataSetIter::FindDataSet(TDataSet *set,const Char_t *path,Option_t *opt)
00324 {
00325
00326
00327
00328
00329
00330
00331 if (!set) return 0;
00332 if (opt) {}
00333
00334 TDataSet *startset = 0;
00335 if (path) startset = Find(path);
00336 else startset = fWorkingDataSet;
00337 if (!startset) return 0;
00338
00339 TDataSetIter next(startset);
00340 TDataSet *nextSet = 0;
00341 while ( (nextSet = next()) )
00342 if (set == nextSet) break;
00343
00344 return nextSet;
00345 }
00346
00347 TObject *TDataSetIter::FindObject(const Char_t *name) const
00348 {
00349
00350
00351
00352 return ((TDataSetIter *)this)->FindByName(name);
00353 }
00354
00355
00356 TObject *TDataSetIter::FindObject(const TObject *dataset) const
00357 {
00358
00359
00360
00361 return ((TDataSetIter *)this)->FindByPointer((TDataSet *)dataset);
00362 }
00363
00364 TDataSet *TDataSetIter::FindByPointer(TDataSet *set,const Char_t *path,Option_t *)
00365 {
00366
00367
00368
00369
00370
00371
00372 if (!set) return 0;
00373
00374 TDataSet *startset = 0;
00375 if (path && path[0]) startset = Find(path);
00376 else startset = fWorkingDataSet;
00377 if (!startset) return 0;
00378
00379 TDataSetIter next(startset);
00380 TDataSet *nextSet = 0;
00381 while ( (nextSet = next()) )
00382 if (set == nextSet) break;
00383
00384 return nextSet;
00385 }
00386
00387
00388 Int_t TDataSetIter::Flag(const Char_t *path,UInt_t flag,TDataSet::EBitOpt reset)
00389 {
00390
00391 TDataSet *set = Find(path);
00392 if (set) set->SetBit(flag,reset);
00393 return 0;
00394 }
00395
00396 Int_t TDataSetIter::Flag(TDataSet *dataset,UInt_t flag,TDataSet::EBitOpt reset)
00397 {
00398
00399 if (dataset) dataset->SetBit(flag,reset);
00400 return 0;
00401 }
00402
00403
00404 TDataSet *TDataSetIter::Ls(const Char_t *dirname,Option_t *opt) const {
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 TDataSet *set= 0;
00416 if (dirname && strlen(dirname)) set = ((TDataSetIter*)this)->Find(dirname);
00417 if (!set && dirname==0) set=Cwd();
00418 if (set) set->ls(opt);
00419 return set;
00420 }
00421
00422
00423 TDataSet *TDataSetIter::Ls(const Char_t *dirname,Int_t depth) const {
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 TDataSet *set= fWorkingDataSet;
00438 if (dirname && strlen(dirname)) set= ((TDataSetIter*)this)->Find(dirname);
00439 if (set) set->ls(depth);
00440 return set;
00441 }
00442
00443
00444 TDataSet *TDataSetIter::Mkdir(const Char_t *dirname)
00445 {
00446
00447 TDataSet *set = 0;
00448 set = Find(dirname,0,kTRUE);
00449 if (!fNext) Reset();
00450
00451 if (!fRootDataSet ) fRootDataSet = set;
00452 if (!fWorkingDataSet) fWorkingDataSet = fRootDataSet;
00453 return set;
00454 }
00455
00456
00457 void TDataSetIter::Notify(TDataSet *)
00458 {
00459
00460
00461
00462
00463
00464
00465
00466 }
00467
00468
00469 TDataSet *TDataSetIter::Rmdir(TDataSet *dataset,Option_t *)
00470 {
00471
00472
00473
00474
00475
00476
00477
00478
00479 TDataSet *set = dataset;
00480 if (set) {
00481 if (set == fWorkingDataSet) {
00482 fWorkingDataSet = set->GetParent();
00483 }
00484 if (set == fRootDataSet) {
00485 fRootDataSet = 0;
00486 }
00487 delete set;
00488 }
00489 return Cwd();
00490 }
00491
00492
00493 TDataSet *TDataSetIter::Next( TDataSet::EDataSetPass mode)
00494 {
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 if (fMaxDepth==1) fDataSet = fNext ? NextDataSet(*fNext) :0;
00508 else {
00509
00510 if (fDepth==0) fDepth = 1;
00511 if (fDataSet && fDataSet != fgNullDataSet &&
00512 (fDepth < fMaxDepth || fMaxDepth ==0) && mode == TDataSet::kContinue )
00513 {
00514
00515 TSeqCollection *list = fDataSet->GetCollection();
00516
00517 if (list && list->GetSize() ) {
00518 fDepth++;
00519 if (fDepth >= 100) {
00520 Error("Next()"
00521 ," too many (%d) nested levels of your TDataSet has been detected",fDepth);
00522 return 0;
00523 }
00524 fNextSet[fDepth-1] = new TIter(list);
00525 }
00526 }
00527
00528
00529 TIter *next = fNextSet[fDepth-1];
00530 if (next) {
00531 fDataSet = 0;
00532 if (mode != TDataSet::kUp) fDataSet = NextDataSet(*next);
00533
00534
00535 if (!fDataSet) {
00536
00537 while (!fDataSet && fDepth > 1) {
00538 fDepth--;
00539 delete next;
00540 next = fNextSet[fDepth-1];
00541 TDataSet *set = NextDataSet(*next);
00542 if (set)
00543 fDataSet = set;
00544 }
00545 }
00546 }
00547 }
00548 return (TDataSet *)fDataSet;
00549 }
00550
00551 TDataSet *TDataSetIter::NextDataSet(TIter &next)
00552 {
00553
00554 TDataSet *ds = (TDataSet *)next();
00555 if (ds) Notify(ds);
00556 return ds;
00557 }
00558
00559
00560 TDataSet *TDataSetIter::NextDataSet(Int_t nDataSet)
00561 {
00562
00563 TIter *next = fNextSet[nDataSet];
00564 if (next) return NextDataSet(*next);
00565 return 0;
00566 }
00567
00568 TDataSet *TDataSetIter::FindByPath(const Char_t *path, TDataSet *rootset,Bool_t mkdir)
00569 {
00570
00571 return Find(path,rootset,mkdir);
00572 }
00573
00574
00575 TDataSet *TDataSetIter::Find(const Char_t *path, TDataSet *rootset,
00576 Bool_t mkdirflag,Bool_t titleFlag)
00577 {
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 TDataSet *dataset=0,*dsnext=0,*ds=0;
00598 Int_t len=0,nextlen=0,yes=0,anywhere=0,rootdir=0;
00599 const Char_t *name=0,*nextname=0;
00600 TSeqCollection *tl=0;
00601
00602 name = path;
00603 if (!name) return rootset;
00604 dataset = rootset;
00605 if (!dataset) {
00606 rootdir = 1999;
00607 dataset = (path[0]=='/') ? fRootDataSet:fWorkingDataSet;}
00608
00609 if (name[0] == '/') name++;
00610
00611 if (!strncmp(name,".*/",3)) {anywhere=1998; name +=3;}
00612
00613 len = strcspn(name," /");
00614 if (!len) return dataset;
00615
00616 if (!dataset) goto NOTFOUND;
00617
00618
00619 if (rootdir)
00620 {
00621 nextname = titleFlag ? dataset->GetTitle() : dataset->GetName();
00622 nextlen = strlen(nextname);
00623 if (nextlen==len && !strncmp(name,nextname,len))
00624 return Find(name+len,dataset,mkdirflag,titleFlag);
00625 }
00626
00627 tl = dataset->GetCollection();
00628 if (tl) {
00629 TIter next(tl);
00630 while ( (dsnext = NextDataSet(next)) )
00631 {
00632 nextname = titleFlag ? dataset->GetTitle() : dsnext->GetName();
00633 if (!nextname) continue;
00634 yes = name[0]=='*';
00635 if (!yes) {
00636 nextlen = strlen(nextname);
00637 yes = (len == nextlen);
00638 if (yes)
00639 yes = !strncmp(name,nextname,len);
00640 }
00641
00642 if (yes)
00643 {
00644 if (fDepth == 0) fDepth = 1;
00645 Notify(dsnext);
00646 fDepth++;
00647 ds = Find(name+len,dsnext,mkdirflag,titleFlag);
00648 fDepth--;
00649 if (ds)
00650 return ds;
00651 }
00652
00653 if (!anywhere) continue;
00654 ds = Find(name,dsnext,mkdirflag,titleFlag);
00655 if (ds)
00656 return ds;
00657 }
00658 }
00659
00660 NOTFOUND:
00661 if (mkdirflag && !titleFlag)
00662 {
00663
00664
00665 char buf[512];buf[0]=0; strncat(buf,name,len);
00666 if (!fRootDataSet)
00667 ds = new TDataSet(buf);
00668 else {
00669 ds = fRootDataSet->Instance();
00670 ds->SetName(buf);
00671 }
00672
00673 if (!fRootDataSet) fRootDataSet = ds;
00674 if (!fWorkingDataSet) fWorkingDataSet = ds;
00675 if (dataset)
00676 dataset->Add(ds);
00677 else {
00678 dataset = ds;
00679 name +=len;
00680 }
00681
00682 return Find(name,dataset,mkdirflag);
00683 }
00684
00685 return 0;
00686 }
00687
00688 void TDataSetIter::Reset(TDataSet *l, int depth)
00689 {
00690
00691
00692
00693
00694
00695 fDataSet = fgNullDataSet;
00696 if (fMaxDepth != 1) {
00697
00698 Int_t level = fDepth;
00699 if (level) level--;
00700 for (int i = level;i>=0;i--) {
00701 TIter *s = fNextSet[i];
00702 if (s) delete s;
00703 }
00704 fNext = 0;
00705 }
00706
00707 fDepth = 0;
00708
00709 if (l) {
00710 fRootDataSet = l;
00711 fWorkingDataSet = l;
00712 SafeDelete(fNext);
00713 if (fRootDataSet->GetCollection() )
00714 fNext = new TIter(fRootDataSet->GetCollection() );
00715 }
00716 else {
00717 fWorkingDataSet = fRootDataSet;
00718 if (fNext)
00719 fNext->Reset();
00720 else if (fRootDataSet && fRootDataSet->GetCollection() )
00721 fNext = new TIter(fRootDataSet->GetCollection() );
00722 }
00723
00724 if (depth) fMaxDepth = depth;
00725 }
00726
00727 TDataSet *TDataSetIter::Shunt(TDataSet *set, TDataSet *dataset)
00728 {
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 if (!set) return 0;
00746 TDataSet *s = dataset;
00747 if (!s) s = Cwd();
00748 if (s) {
00749 s->Shunt(set);
00750 s = set;
00751 }
00752 else {
00753
00754 s = set;
00755 fRootDataSet = s;
00756 fWorkingDataSet = s;
00757 if (fNext) {
00758 Error("Shunt","TDataSetIter.has been corrupted ;-!");
00759 delete fNext;
00760 fNext = 0;
00761 }
00762 fNext = new TIter(s->GetCollection() );
00763 }
00764 return s;
00765 }
00766
00767
00768 TDataSet *TDataSetIter::Shunt(TDataSet *dataset, const Char_t *path)
00769 {
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784 if (!dataset) return 0;
00785 TDataSet *set = 0;
00786 if (path && strlen(path)) set = Find(path);
00787 return Shunt(dataset,set);
00788 }
00789
00790
00791 TDataSet *TDataSetIter::operator[](const Char_t *path)
00792 {
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 TDataSet *dataSet = Find(path);
00805 if (dataSet && dataSet->HasData()) return dataSet;
00806 return 0;
00807 }