00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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 #include "Riostream.h"
00081 #include "Strlen.h"
00082 #include "TFolder.h"
00083 #include "TBrowser.h"
00084 #include "TROOT.h"
00085 #include "TClass.h"
00086 #include "TError.h"
00087 #include "TRegexp.h"
00088
00089 static const char *gFolderD[64];
00090 static Int_t gFolderLevel = -1;
00091 static char gFolderPath[512];
00092
00093 enum { kOwnFolderList = BIT(15) };
00094
00095 ClassImp(TFolder)
00096
00097
00098 TFolder::TFolder() : TNamed()
00099 {
00100
00101
00102
00103
00104
00105 fFolders = 0;
00106 fIsOwner = kFALSE;
00107 }
00108
00109
00110 TFolder::TFolder(const char *name, const char *title) : TNamed(name,title)
00111 {
00112
00113
00114
00115 fFolders = new TList();
00116 SetBit(kOwnFolderList);
00117 fIsOwner = kFALSE;
00118 }
00119
00120
00121 TFolder::TFolder(const TFolder &folder) : TNamed(folder),fFolders(0),fIsOwner(kFALSE)
00122 {
00123
00124
00125 ((TFolder&)folder).Copy(*this);
00126 }
00127
00128
00129 TFolder::~TFolder()
00130 {
00131
00132
00133
00134 TCollection::StartGarbageCollection();
00135
00136 if (fFolders) {
00137 if (fFolders->IsOwner()) {
00138 fFolders->Delete();
00139 }
00140 if (TestBit(kOwnFolderList)) {
00141 TObjLink *iter = ((TList*)fFolders)->FirstLink();
00142 while (iter) {
00143 TObject *obj = iter->GetObject();
00144 TObjLink *next = iter->Next();
00145 if (obj && obj->IsA() == TFolder::Class()) {
00146 ((TList*)fFolders)->Remove(iter);
00147 delete obj;
00148 }
00149 iter = next;
00150 }
00151 fFolders->Clear("nodelete");
00152 SafeDelete(fFolders);
00153 }
00154 }
00155
00156 TCollection::EmptyGarbageCollection();
00157
00158 if (gDebug)
00159 cerr << "TFolder dtor called for "<< GetName() << endl;
00160 }
00161
00162
00163 void TFolder::Add(TObject *obj)
00164 {
00165
00166
00167 if (obj == 0 || fFolders == 0) return;
00168 obj->SetBit(kMustCleanup);
00169 fFolders->Add(obj);
00170 }
00171
00172
00173 TFolder *TFolder::AddFolder(const char *name, const char *title, TCollection *collection)
00174 {
00175
00176
00177
00178
00179
00180
00181
00182
00183 if (strchr(name,'/')) {
00184 ::Error("TFolder::TFolder","folder name cannot contain a slash: %s", name);
00185 return 0;
00186 }
00187 if (strlen(GetName()) == 0) {
00188 ::Error("TFolder::TFolder","folder name cannot be \"\"");
00189 return 0;
00190 }
00191 TFolder *folder = new TFolder();
00192 folder->SetName(name);
00193 folder->SetTitle(title);
00194 if (!fFolders) {
00195 fFolders = new TList();
00196 SetBit(kOwnFolderList);
00197 }
00198 fFolders->Add(folder);
00199
00200 if (collection) {
00201 folder->fFolders = collection;
00202 } else {
00203 folder->fFolders = new TList();
00204 folder->SetBit(kOwnFolderList);
00205 }
00206 return folder;
00207 }
00208
00209
00210 void TFolder::Browse(TBrowser *b)
00211 {
00212
00213
00214 if (fFolders) fFolders->Browse(b);
00215 }
00216
00217
00218 void TFolder::Clear(Option_t *option)
00219 {
00220
00221
00222 if (fFolders) fFolders->Clear(option);
00223 }
00224
00225
00226 const char *TFolder::FindFullPathName(const char *name) const
00227 {
00228
00229
00230
00231 TObject *obj = FindObject(name);
00232 if (obj || !fFolders) {
00233 gFolderLevel++;
00234 gFolderD[gFolderLevel] = GetName();
00235 gFolderPath[0] = '/';
00236 gFolderPath[1] = 0;
00237 for (Int_t l=0;l<=gFolderLevel;l++) {
00238 strlcat(gFolderPath, "/", sizeof(gFolderPath));
00239 strlcat(gFolderPath, gFolderD[l], sizeof(gFolderPath));
00240 }
00241 strlcat(gFolderPath, "/", sizeof(gFolderPath));
00242 strlcat(gFolderPath,name, sizeof(gFolderPath));
00243 gFolderLevel = -1;
00244 return gFolderPath;
00245 }
00246 if (name[0] == '/') return 0;
00247 TIter next(fFolders);
00248 TFolder *folder;
00249 const char *found;
00250 gFolderLevel++;
00251 gFolderD[gFolderLevel] = GetName();
00252 while ((obj=next())) {
00253 if (!obj->InheritsFrom(TFolder::Class())) continue;
00254 if (obj->InheritsFrom(TClass::Class())) continue;
00255 folder = (TFolder*)obj;
00256 found = folder->FindFullPathName(name);
00257 if (found) return found;
00258 }
00259 gFolderLevel--;
00260 return 0;
00261 }
00262
00263
00264
00265 const char *TFolder::FindFullPathName(const TObject *) const
00266 {
00267
00268
00269
00270 Error("FindFullPathname","Not yet implemented");
00271 return 0;
00272 }
00273
00274
00275 TObject *TFolder::FindObject(const TObject *) const
00276 {
00277
00278
00279 Error("FindObject","Not yet implemented");
00280 return 0;
00281 }
00282
00283
00284 TObject *TFolder::FindObject(const char *name) const
00285 {
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 if (!fFolders) return 0;
00300 if (name == 0) return 0;
00301 if (name[0] == '/') {
00302 if (name[1] == '/') {
00303 if (!strstr(name,"//root/")) return 0;
00304 return gROOT->GetRootFolder()->FindObject(name+7);
00305 } else {
00306 return gROOT->GetRootFolder()->FindObject(name+1);
00307 }
00308 }
00309 Int_t nch = strlen(name);
00310 char *cname;
00311 char csname[128];
00312 if (nch < (int)sizeof(csname))
00313 cname = csname;
00314 else
00315 cname = new char[nch+1];
00316 strcpy(cname, name);
00317 TObject *obj;
00318 char *slash = strchr(cname,'/');
00319 if (slash) {
00320 *slash = 0;
00321 obj = fFolders->FindObject(cname);
00322 if (!obj) {
00323 if (nch >= (int)sizeof(csname)) delete [] cname;
00324 return 0;
00325 }
00326 TObject *ret = obj->FindObject(slash+1);
00327 if (nch >= (int)sizeof(csname)) delete [] cname;
00328 return ret;
00329 } else {
00330 TObject *ret = fFolders->FindObject(cname);
00331 if (nch >= (int)sizeof(csname)) delete [] cname;
00332 return ret;
00333 }
00334 }
00335
00336
00337 TObject *TFolder::FindObjectAny(const char *name) const
00338 {
00339
00340
00341 TObject *obj = FindObject(name);
00342 if (obj || !fFolders) return obj;
00343
00344
00345 if (name[0] == '/') return 0;
00346 TIter next(fFolders);
00347 TFolder *folder;
00348 TObject *found;
00349 if (gFolderLevel >= 0) gFolderD[gFolderLevel] = GetName();
00350 while ((obj=next())) {
00351 if (!obj->InheritsFrom(TFolder::Class())) continue;
00352 if (obj->IsA() == TClass::Class()) continue;
00353 folder = (TFolder*)obj;
00354 found = folder->FindObjectAny(name);
00355 if (found) return found;
00356 }
00357 return 0;
00358 }
00359
00360
00361 Bool_t TFolder::IsOwner() const
00362 {
00363
00364
00365
00366
00367 if (!fFolders) return kFALSE;
00368 return fFolders->IsOwner();
00369 }
00370
00371
00372 void TFolder::ls(Option_t *option) const
00373 {
00374
00375
00376
00377
00378
00379
00380
00381
00382 if (!fFolders) return;
00383 TROOT::IndentLevel();
00384 cout <<ClassName()<<"*\t\t"<<GetName()<<"\t"<<GetTitle()<<endl;
00385 TROOT::IncreaseDirLevel();
00386
00387 TString opt = option;
00388 Ssiz_t dump = opt.Index("dump", 0, TString::kIgnoreCase);
00389 if (dump != kNPOS)
00390 opt.Remove(dump, 4);
00391 Ssiz_t print = opt.Index("print", 0, TString::kIgnoreCase);
00392 if (print != kNPOS)
00393 opt.Remove(print, 5);
00394 opt = opt.Strip(TString::kBoth);
00395 if (opt == "")
00396 opt = "*";
00397 TRegexp re(opt, kTRUE);
00398
00399 TObject *obj;
00400 TIter nextobj(fFolders);
00401 while ((obj = (TObject *) nextobj())) {
00402 TString s = obj->GetName();
00403 if (s.Index(re) == kNPOS) continue;
00404 if (dump != kNPOS)
00405 obj->Dump();
00406 if (print != kNPOS)
00407 obj->Print(option);
00408 obj->ls(option);
00409 }
00410 TROOT::DecreaseDirLevel();
00411 }
00412
00413
00414 Int_t TFolder::Occurence(const TObject *object) const
00415 {
00416
00417
00418
00419
00420
00421 Int_t n = 0;
00422 if (!fFolders) return 0;
00423 TIter next(fFolders);
00424 TObject *obj;
00425 while ((obj=next())) {
00426 if (strcmp(obj->GetName(),object->GetName()) == 0) n++;
00427 }
00428 if (n <=1) return n-1;
00429 n = 0;
00430 next.Reset();
00431 while ((obj=next())) {
00432 if (strcmp(obj->GetName(),object->GetName()) == 0) n++;
00433 if (obj == object) return n;
00434 }
00435 return 0;
00436 }
00437
00438
00439 void TFolder::RecursiveRemove(TObject *obj)
00440 {
00441
00442
00443 if (fFolders) fFolders->RecursiveRemove(obj);
00444 }
00445
00446
00447 void TFolder::Remove(TObject *obj)
00448 {
00449
00450
00451 if (obj == 0 || fFolders == 0) return;
00452 fFolders->Remove(obj);
00453 }
00454
00455
00456 void TFolder::SaveAs(const char *filename, Option_t *option) const
00457 {
00458
00459
00460
00461
00462 if (gDirectory) gDirectory->SaveObjectAs(this,filename,option);
00463 }
00464
00465
00466 void TFolder::SetOwner(Bool_t owner)
00467 {
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 if (!fFolders) fFolders = new TList();
00478 fFolders->SetOwner(owner);
00479 }