StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TDataSetIter.cxx
1 // @(#)root/table:$Id$
2 // Author: Valery Fine(fine@mail.cern.ch) 03/07/98
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "Riostream.h"
13 
14 #include "TDataSetIter.h"
15 #include "TBrowser.h"
16 #include "TSystem.h"
17 
18 #ifndef WIN32
19 # ifndef HASSTRCASE
20 # define HASSTRCASE
21 # endif
22 #endif
23 
24 #ifndef HASSTRCASE
25 # define strcasecmp(arg1,arg2) stricmp(arg1,arg2)
26 #endif
27 
28 TDataSet *TDataSetIter::fgNullDataSet = (TDataSet *)(-1);
29 
30 ClassImp(TDataSetIter);
31 
33 // //
34 // TDataSetIter //
35 // //
36 // TDataSetIter is a class iterator to navigate TDataSet objects //
37 // via 4 internal pointers : //
38 // //
39 // 1. fRootDataSet - "root" dataset //
40 // 2. fWorkingDataSet - Working dataset //
41 // 3. fDataSet - the last selected TDataSet //
42 // 4. fNext - TIter for the the list of the "root" dataset //
43 // //
45 
48 
49 TDataSetIter::TDataSetIter(TDataSet *link, Bool_t dir)
50 {
51  fWorkingDataSet= fRootDataSet =link;
52  fMaxDepth = fDepth =1;
53  fDataSet= fgNullDataSet ;
54  fNext = link ? new TIter(link->GetCollection() ,dir):0;
55  for(UInt_t i = 0; i < sizeof(fNextSet) / sizeof(TIter*); ++i) {
56  fNextSet[i] = (TIter*)0;
57  }
58 }
59 
62 
63 TDataSetIter::TDataSetIter(TDataSet *link, Int_t depth, Bool_t dir)
64 {
65  fRootDataSet = fWorkingDataSet = link;
66  fMaxDepth = depth;
67  fDepth = 1;
68  fDataSet = fgNullDataSet;
69  fNext = (link)? new TIter(link->GetCollection() ,dir):0;
70 
71  // Create a DataSet iterator to pass all nodes of the
72  // "depth" levels
73  // of TDataSet *link
74 
75  for(UInt_t i = 0; i < sizeof(fNextSet) / sizeof(TIter*); ++i) {
76  fNextSet[i] = (TIter*)0;
77  }
78  if (fMaxDepth != 1) {
79  fNextSet[0] = fNext;
80  if (fMaxDepth > 100) fMaxDepth = 100;
81  fDepth = 0;
82  }
83 }
84 
87 
89 {
90  if (fMaxDepth != 1) {
91  Int_t level = fDepth;
92  if (level) level--;
93  for (Int_t i = level;i>=0;i--) {
94  TIter *s = fNextSet[i];
95  if (s) delete s;
96  }
97  }
98  else
99  SafeDelete(fNext);
100  fDepth = 0;
101 }
102 
103 
106 
108 {
109  return fDataSet == fgNullDataSet ? fWorkingDataSet : fDataSet;
110 }
111 
114 
116 {
117  return (TDataSet *)fgNullDataSet;
118 }
119 
136 
137 TDataSet *TDataSetIter::Add(TDataSet *set, TDataSet *dataset)
138 {
139  if (!set) return 0;
140  TDataSet *s = dataset;
141  if (!s) s = Cwd();
142  if (s) {
143  s->Add(set);
144  s = set;
145  }
146  else {
147  // make the coming dataset the current one for the iterator
148  s = set;
149  fRootDataSet = s;
150  fWorkingDataSet = s;
151  if (fNext) {
152  Error("Add","TDataSetIter.has been corrupted ;-!");
153  delete fNext;
154  fNext = 0;
155  }
156  fNext = new TIter(s->GetCollection() );
157  }
158  return s;
159 }
160 
175 
176 TDataSet *TDataSetIter::Add(TDataSet *dataset, const Char_t *path)
177 {
178  if (!dataset) return 0;
179  TDataSet *set = 0;
180  if (path && strlen(path)) set = Find(path);
181  return Add(dataset,set);
182 }
183 
199 
200 TDataSet *TDataSetIter::Cd(const Char_t *dirname){
201  TDataSet *set = 0;
202  if (strcmp(dirname,".."))
203  set = Find(dirname);
204  else
205  set = fWorkingDataSet->GetParent();
206  if (set) fWorkingDataSet = set;
207  return set;
208 }
209 
225 
227 {
228  TDataSet *nextSet = 0;
229  if (Cwd()) {
230  TDataSetIter next(Cwd(),0);
231  while ( (nextSet = next()) )
232  if (ds == nextSet) {fWorkingDataSet = ds; break;}
233  }
234  return nextSet;
235 }
236 
242 
243 TDataSet *TDataSetIter::Dir(Char_t *dirname)
244 {
245  TDataSet *set = (TDataSet *)fWorkingDataSet;
246  if (dirname) set = Find(dirname);
247  if (set) set->ls();
248  return set;
249 }
250 
253 
254 Int_t TDataSetIter::Du() const {
255  if (!fWorkingDataSet) return 0;
256  TDataSetIter next(fWorkingDataSet,0);
257  TDataSet *nextset = 0;
258  Int_t count = 0;
259  while((nextset = (count) ? next():fWorkingDataSet)) {
260  count++;
261  if (nextset->IsFolder()) std::cout << std::endl;
262  TString path = nextset->Path();
263  std::cout << std::setw(2) << next.GetDepth() << ". ";
264  std::cout << path << std::setw(TMath::Max(Int_t(60-strlen(path.Data())),Int_t(0))) << "...";
265  const Char_t *type = nextset->IsFolder() ? "directory" : "table" ;
266  std::cout << std::setw(10) << type;
267  std::cout << " : " << std::setw(10) << nextset->GetTitle();
268  std::cout << std::endl;
269  }
270  return count;
271 }
272 
275 
276 TDataSet *TDataSetIter::FindByName(const Char_t *name,const Char_t *path,Option_t *opt)
277 {
278  return FindDataSet(name,path,opt);
279 }
280 
283 
284 TDataSet *TDataSetIter::FindByTitle(const Char_t *title,const Char_t *path,Option_t *opt)
285 {
286  TString optt = "-t";
287  optt += opt;
288  return FindDataSet(title,path,optt.Data());
289 }
290 
303 
304 TDataSet *TDataSetIter::FindDataSet(const Char_t *name,const Char_t *path,Option_t *opt)
305 {
306  if (!name || !name[0]) return 0;
307  if (strchr(name,'/')) {
308  Error("FindDataSet","The name of the object <%s> can not contain any \"/\"",name);
309  return 0;
310  }
311 
312  Bool_t opti = opt ? strcasecmp(opt,"-i") == 0 : kFALSE;
313  Bool_t optt = opt ? strcasecmp(opt,"-t") == 0 : kFALSE;
314 
315  TDataSet *startset = 0;
316  if (path && strlen(path)) startset = Find(path);
317  else startset = fWorkingDataSet;
318  if (!startset) return 0;
319 
320  TDataSet *set = startset;
321  if ( !((opti && strcasecmp( optt ? set->GetTitle() : set->GetName(),name) == 0 ) ||
322  (strcmp(optt ? set->GetTitle() : set->GetName(),name) == 0)) )
323  {
324  TDataSetIter next(startset,0);
325  while ((set = next()))
326  if ( (opti && strcasecmp(optt ? set->GetTitle() : set->GetName(),name) == 0 ) ||
327  (strcmp(optt ? set->GetTitle() : set->GetName(),name) == 0) ) break;
328  }
329 
330  return set;
331 }
332 
340 
341 TDataSet *TDataSetIter::FindDataSet(TDataSet *set,const Char_t *path,Option_t *opt)
342 {
343  if (!set) return 0;
344  if (opt) {/* no used */}
345 
346  TDataSet *startset = 0;
347  if (path) startset = Find(path);
348  else startset = fWorkingDataSet;
349  if (!startset) return 0;
350 
351  TDataSetIter next(startset);
352  TDataSet *nextSet = 0;
353  while ( (nextSet = next()) )
354  if (set == nextSet) break;
355 
356  return nextSet;
357 }
362 
363 TObject *TDataSetIter::FindObject(const Char_t *name) const
364 {
365  return ((TDataSetIter *)this)->FindByName(name);
366 }
367 
372 
373 TObject *TDataSetIter::FindObject(const TObject *dataset) const
374 {
375  return ((TDataSetIter *)this)->FindByPointer((TDataSet *)dataset);
376 }
384 
385 TDataSet *TDataSetIter::FindByPointer(TDataSet *set,const Char_t *path,Option_t *)
386 {
387  if (!set) return 0;
388 
389  TDataSet *startset = 0;
390  if (path && path[0]) startset = Find(path);
391  else startset = fWorkingDataSet;
392  if (!startset) return 0;
393 
394  TDataSetIter next(startset);
395  TDataSet *nextSet = 0;
396  while ( (nextSet = next()) )
397  if (set == nextSet) break;
398 
399  return nextSet;
400 }
401 
404 
405 Int_t TDataSetIter::Flag(const Char_t *path,UInt_t flag,TDataSet::EBitOpt reset)
406 {
407  TDataSet *set = Find(path);
408  if (set) set->SetBit(flag,reset);
409  return 0;
410 }
413 
414 Int_t TDataSetIter::Flag(TDataSet *dataset,UInt_t flag,TDataSet::EBitOpt reset)
415 {
416  if (dataset) dataset->SetBit(flag,reset);
417  return 0;
418 }
419 
430 
431 TDataSet *TDataSetIter::Ls(const Char_t *dirname,Option_t *opt) const {
432  TDataSet *set= 0;
433  if (dirname && strlen(dirname)) set = ((TDataSetIter*)this)->Find(dirname);
434  if (!set && dirname==0) set=Cwd();
435  if (set) set->ls(opt);
436  return set;
437 }
438 
453 
454 TDataSet *TDataSetIter::Ls(const Char_t *dirname,Int_t depth) const {
455  TDataSet *set= fWorkingDataSet;
456  if (dirname && strlen(dirname)) set= ((TDataSetIter*)this)->Find(dirname);
457  if (set) set->ls(depth);
458  return set;
459 }
460 
463 
464 TDataSet *TDataSetIter::Mkdir(const Char_t *dirname)
465 {
466  TDataSet *set = 0;
467  set = Find(dirname,0,kTRUE);
468  if (!fNext) Reset(); // Create a new iterator
469  // If this dataset is first one then make it the root and working
470  if (!fRootDataSet ) fRootDataSet = set;
471  if (!fWorkingDataSet) fWorkingDataSet = fRootDataSet;
472  return set;
473 }
474 
483 
484 void TDataSetIter::Notify(TDataSet *)
485 {
486 }
487 
497 
498 TDataSet *TDataSetIter::Rmdir(TDataSet *dataset,Option_t *)
499 {
500  TDataSet *set = dataset;
501  if (set) {
502  if (set == fWorkingDataSet) {
503  fWorkingDataSet = set->GetParent();
504  }
505  if (set == fRootDataSet) {
506  fRootDataSet = 0;
507  }
508  delete set;
509  }
510  return Cwd();
511 }
512 
525 
526 TDataSet *TDataSetIter::Next( TDataSet::EDataSetPass mode)
527 {
528  if (fMaxDepth==1) fDataSet = fNext ? NextDataSet(*fNext) :0;
529  else {
530  // Check the whether the next level does exist
531  if (fDepth==0) fDepth = 1;
532  if (fDataSet && fDataSet != fgNullDataSet &&
533  (fDepth < fMaxDepth || fMaxDepth ==0) && mode == TDataSet::kContinue )
534  {
535  // create the next level iterator, go deeper
536  TSeqCollection *list = fDataSet->GetCollection();
537  // Look for the next level
538  if (list && list->GetSize() ) {
539  fDepth++;
540  if (fDepth >= 100) {
541  Error("Next()"
542  ," too many (%d) nested levels of your TDataSet has been detected",fDepth);
543  return 0;
544  }
545  fNextSet[fDepth-1] = new TIter(list);
546  }
547  }
548 
549  // Pick the next object of the current level
550  TIter *next = fNextSet[fDepth-1];
551  if (next) {
552  fDataSet = 0;
553  if (mode != TDataSet::kUp) fDataSet = NextDataSet(*next);
554 
555  // Go upstair if the current one has been escaped
556  if (!fDataSet) {
557  // go backwards direction
558  while (!fDataSet && fDepth > 1) {
559  fDepth--;
560  delete next;
561  next = fNextSet[fDepth-1];
562  TDataSet *set = NextDataSet(*next);
563  if (set)
564  fDataSet = set;
565  }
566  }
567  }
568  }
569  return (TDataSet *)fDataSet;
570 }
573 
575 {
576  TDataSet *ds = (TDataSet *)next();
577  if (ds) Notify(ds);
578  return ds;
579 }
580 
583 
585 {
586  TIter *next = fNextSet[nDataSet];
587  if (next) return NextDataSet(*next);
588  return 0;
589 }
592 
593 TDataSet *TDataSetIter::FindByPath(const Char_t *path, TDataSet *rootset,Bool_t mkdir)
594 {
595  return Find(path,rootset,mkdir);
596 }
597 
618 
619 TDataSet *TDataSetIter::Find(const Char_t *path, TDataSet *rootset,
620  Bool_t mkdirflag,Bool_t titleFlag)
621 {
622  TDataSet *dataset=0,*dsnext=0,*ds=0;
623  Int_t len=0,nextlen=0,yes=0,anywhere=0,rootdir=0;
624  const Char_t *name=0,*nextname=0;
625  TSeqCollection *tl=0;
626 
627  name = path;
628  if (!name) return rootset;
629  dataset = rootset;
630  if (!dataset) {// Starting point
631  rootdir = 1999;
632  dataset = (path[0]=='/') ? fRootDataSet:fWorkingDataSet;}
633 
634  if (name[0] == '/') name++;
635 
636  if (!strncmp(name,".*/",3)) {anywhere=1998; name +=3;}
637 
638  len = strcspn(name," /");
639  if (!len) return dataset;
640 
641  if (!dataset) goto NOTFOUND;
642 
643  // Check name of root directory
644  if (rootdir)
645  {
646  nextname = titleFlag ? dataset->GetTitle() : dataset->GetName();
647  nextlen = strlen(nextname);
648  if (nextlen==len && !strncmp(name,nextname,len))
649  return Find(name+len,dataset,mkdirflag,titleFlag);
650  }
651 
652  tl = dataset->GetCollection();
653  if (tl) {
654  TIter next(tl);
655  while ( (dsnext = NextDataSet(next)) )
656  { //horisontal loop
657  nextname = titleFlag ? dataset->GetTitle() : dsnext->GetName();
658  if (!nextname) continue;
659  yes = name[0]=='*'; // wildcard test
660  if (!yes) { // real test
661  nextlen = strlen(nextname);
662  yes = (len == nextlen);
663  if (yes)
664  yes = !strncmp(name,nextname,len);
665  }
666 
667  if (yes)
668  {//go down
669  if (fDepth == 0) fDepth = 1;
670  Notify(dsnext);
671  fDepth++;
672  ds = Find(name+len,dsnext,mkdirflag,titleFlag);
673  fDepth--;
674  if (ds)
675  return ds;
676  }
677 
678  if (!anywhere) continue; // next horizontal
679  ds = Find(name,dsnext,mkdirflag,titleFlag);
680  if (ds)
681  return ds;
682  } // end of while
683  }
684 
685 NOTFOUND:
686  if (mkdirflag && !titleFlag)
687  {
688  // create dir the same type as the type of the fRootDataSet if present
689  // Create TDataSet by default.
690  char buf[512];buf[0]=0; strncat(buf,name,len);
691  if (!fRootDataSet)
692  ds = new TDataSet(buf);
693  else {
694  ds = fRootDataSet->Instance();
695  ds->SetName(buf);
696  }
697 
698  if (!fRootDataSet) fRootDataSet = ds;
699  if (!fWorkingDataSet) fWorkingDataSet = ds;
700  if (dataset)
701  dataset->Add(ds);
702  else {
703  dataset = ds;
704  name +=len;
705  }
706 
707  return Find(name,dataset,mkdirflag);
708  }
709 
710  return 0;
711 }
718 
719 void TDataSetIter::Reset(TDataSet *l, int depth)
720 {
721  fDataSet = fgNullDataSet;
722  if (fMaxDepth != 1) {
723  // clean all interators
724  Int_t level = fDepth;
725  if (level) level--;
726  for (int i = level;i>=0;i--) {
727  TIter *s = fNextSet[i];
728  if (s) delete s;
729  }
730  fNext = 0; // this iterator has been deleted in the loop above
731  }
732 
733  fDepth = 0;
734 
735  if (l) {
736  fRootDataSet = l;
737  fWorkingDataSet = l;
738  SafeDelete(fNext);
739  if (fRootDataSet->GetCollection() )
740  fNext = new TIter(fRootDataSet->GetCollection() );
741  }
742  else {
743  fWorkingDataSet = fRootDataSet;
744  if (fNext)
745  fNext->Reset();
746  else if (fRootDataSet && fRootDataSet->GetCollection() )
747  fNext = new TIter(fRootDataSet->GetCollection() );
748  }
749  // set the new value of the maximum depth to bypass
750  if (depth) fMaxDepth = depth;
751 }
768 
769 TDataSet *TDataSetIter::Shunt(TDataSet *set, TDataSet *dataset)
770 {
771  if (!set) return 0;
772  TDataSet *s = dataset;
773  if (!s) s = Cwd();
774  if (s) {
775  s->Shunt(set);
776  s = set;
777  }
778  else {
779  // make the coming dataset the current one for the iterator
780  s = set;
781  fRootDataSet = s;
782  fWorkingDataSet = s;
783  if (fNext) {
784  Error("Shunt","TDataSetIter.has been corrupted ;-!");
785  delete fNext;
786  fNext = 0;
787  }
788  fNext = new TIter(s->GetCollection() );
789  }
790  return s;
791 }
792 
808 
809 TDataSet *TDataSetIter::Shunt(TDataSet *dataset, const Char_t *path)
810 {
811  if (!dataset) return 0;
812  TDataSet *set = 0;
813  if (path && strlen(path)) set = Find(path);
814  return Shunt(dataset,set);
815 }
816 
829 
830 TDataSet *TDataSetIter::operator[](const Char_t *path)
831 {
832  TDataSet *dataSet = Find(path);
833  if (dataSet && dataSet->HasData()) return dataSet;
834  return 0;
835 }
virtual Int_t Du() const
summarize dataset usage by Herb Ward proposal
Definition: FJcore.h:367
virtual TDataSet * Mkdir(const Char_t *dirname)
to be documented
virtual TDataSet * FindByTitle(const Char_t *title, const Char_t *path="", Option_t *opt="")
to be documented
virtual TDataSet * Instance() const
Definition: TDataSet.cxx:546
virtual TDataSet * Cd(const Char_t *dirname)
virtual TDataSet * Next(TDataSet::EDataSetPass mode=TDataSet::kContinue)
virtual TDataSet * FindByPath(const Char_t *path, TDataSet *rootset=0, Bool_t mkdir=kFALSE)
to be documented
virtual TDataSet * Dir(Char_t *dirname)
virtual TDataSet * FindByPointer(TDataSet *set, const Char_t *path=0, Option_t *opt="")
TDataSet * NextDataSet(TIter &next)
to be documented
virtual TDataSet * Ls(const Char_t *dirname="", Option_t *opt="") const
virtual TObject * FindObject(const Char_t *name) const
virtual TDataSet * operator[](const Char_t *path)
virtual void Reset(TDataSet *l=0, Int_t depth=0)
virtual ~TDataSetIter()
to be documented
virtual void ls(Option_t *option="") const
Definition: TDataSet.cxx:495
virtual TDataSet * FindByName(const Char_t *name, const Char_t *path="", Option_t *opt="")
to be documented
TDataSet * GetNullSet()
return a fake pointer == -1 casted to (TDataSet *)
virtual TDataSet * Rmdir(TDataSet *dataset, Option_t *option="")
virtual TDataSet * FindDataSet(const Char_t *name, const Char_t *path="", Option_t *opt="")
virtual void Shunt(TDataSet *newParent=0)
Definition: TDataSet.cxx:810
virtual TDataSet * Find(const Char_t *path, TDataSet *rootset=0, Bool_t mkdir=kFALSE, Bool_t titleFlag=kFALSE)
virtual TString Path() const
return the full path of this data set
Definition: TDataSet.cxx:626
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362
virtual TDataSet * operator*() const
operator *