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 #include "TCollection.h"
00041 #include "Riostream.h"
00042 #include "Varargs.h"
00043 #include "TClass.h"
00044 #include "TROOT.h"
00045 #include "TBrowser.h"
00046 #include "TObjectTable.h"
00047 #include "TRegexp.h"
00048 #include "TPRegexp.h"
00049 #include "TVirtualMutex.h"
00050
00051 TVirtualMutex *gCollectionMutex = 0;
00052
00053 TCollection *TCollection::fgCurrentCollection = 0;
00054 TObjectTable *TCollection::fgGarbageCollection = 0;
00055 Bool_t TCollection::fgEmptyingGarbage = kFALSE;
00056 Int_t TCollection::fgGarbageStack = 0;
00057
00058 ClassImp(TCollection)
00059 ClassImp(TIter)
00060
00061
00062 void TCollection::AddAll(const TCollection *col)
00063 {
00064
00065
00066 TIter next(col);
00067 TObject *obj;
00068
00069 while ((obj = next()))
00070 Add(obj);
00071 }
00072
00073
00074 void TCollection::AddVector(TObject *va_(obj1), ...)
00075 {
00076
00077
00078
00079 va_list ap;
00080 va_start(ap, va_(obj1));
00081 TObject *obj;
00082
00083 Add(va_(obj1));
00084 while ((obj = va_arg(ap, TObject *)))
00085 Add(obj);
00086 va_end(ap);
00087 }
00088
00089
00090 Bool_t TCollection::AssertClass(TClass *cl) const
00091 {
00092
00093
00094 TObject *obj;
00095 TIter next(this);
00096 Bool_t error = kFALSE;
00097
00098 if (!cl) {
00099 Error("AssertClass", "class == 0");
00100 return kTRUE;
00101 }
00102
00103 for (int i = 0; (obj = next()); i++)
00104 if (!obj->InheritsFrom(cl)) {
00105 Error("AssertClass", "element %d is not an instance of class %s (%s)",
00106 i, cl->GetName(), obj->ClassName());
00107 error = kTRUE;
00108 }
00109 return error;
00110 }
00111
00112
00113 void TCollection::Browse(TBrowser *b)
00114 {
00115
00116
00117
00118
00119 TIter next(this);
00120 TObject *obj;
00121
00122 if (b)
00123 while ((obj = next())) b->Add(obj);
00124 else
00125 TObject::Browse(b);
00126 }
00127
00128
00129 TObject *TCollection::Clone(const char *newname) const
00130 {
00131
00132
00133
00134 TCollection *new_collection = (TCollection*)TObject::Clone(newname);
00135 if (newname && strlen(newname)) new_collection->SetName(newname);
00136 return new_collection;
00137 }
00138
00139
00140
00141 Int_t TCollection::Compare(const TObject *obj) const
00142 {
00143
00144
00145
00146 if (this == obj) return 0;
00147 return fName.CompareTo(obj->GetName());
00148 }
00149
00150
00151 void TCollection::Draw(Option_t *option)
00152 {
00153
00154
00155 TIter next(this);
00156 TObject *object;
00157
00158 while ((object = next())) {
00159 object->Draw(option);
00160 }
00161 }
00162
00163
00164 void TCollection::Dump() const
00165 {
00166
00167
00168 TIter next(this);
00169 TObject *object;
00170
00171 while ((object = next())) {
00172 object->Dump();
00173 }
00174 }
00175
00176
00177 TObject *TCollection::FindObject(const char *name) const
00178 {
00179
00180
00181
00182
00183 TIter next(this);
00184 TObject *obj;
00185
00186 while ((obj = next()))
00187 if (!strcmp(name, obj->GetName())) return obj;
00188 return 0;
00189 }
00190
00191
00192 TObject *TCollection::operator()(const char *name) const
00193 {
00194
00195
00196 return FindObject(name);
00197 }
00198
00199
00200 TObject *TCollection::FindObject(const TObject *obj) const
00201 {
00202
00203
00204
00205
00206
00207
00208 TIter next(this);
00209 TObject *ob;
00210
00211 while ((ob = next()))
00212 if (ob->IsEqual(obj)) return ob;
00213 return 0;
00214 }
00215
00216
00217 const char *TCollection::GetName() const
00218 {
00219
00220
00221
00222 if (fName.Length() > 0) return fName.Data();
00223 return ClassName();
00224 }
00225
00226
00227 Int_t TCollection::GrowBy(Int_t delta) const
00228 {
00229
00230
00231 if (delta < 0) {
00232 Error("GrowBy", "delta < 0");
00233 delta = Capacity();
00234 }
00235 return Capacity() + TMath::Range(2, kMaxInt - Capacity(), delta);
00236 }
00237
00238
00239 Bool_t TCollection::IsArgNull(const char *where, const TObject *obj) const
00240 {
00241
00242
00243 return obj ? kFALSE : (Error(where, "argument is a null pointer"), kTRUE);
00244 }
00245
00246
00247 void TCollection::ls(Option_t *option) const
00248 {
00249
00250
00251
00252
00253 TROOT::IndentLevel();
00254 cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << " : "
00255 << Int_t(TestBit(kCanDelete)) << endl;
00256
00257 TRegexp re(option,kTRUE);
00258 TIter next(this);
00259 TObject *object;
00260 char *star = 0;
00261 if (option) star = (char*)strchr(option,'*');
00262
00263 TROOT::IncreaseDirLevel();
00264 while ((object = next())) {
00265 if (star) {
00266 TString s = object->GetName();
00267 if (s != option && s.Index(re) == kNPOS) continue;
00268 }
00269 object->ls(option);
00270 }
00271 TROOT::DecreaseDirLevel();
00272 }
00273
00274
00275 void TCollection::Paint(Option_t *option)
00276 {
00277
00278
00279 this->R__FOR_EACH(TObject,Paint)(option);
00280 }
00281
00282
00283 void TCollection::PrintCollectionHeader(Option_t*) const
00284 {
00285
00286
00287 TROOT::IndentLevel();
00288 printf("Collection name='%s', class='%s', size=%d\n",
00289 GetName(), ClassName(), GetSize());
00290 }
00291
00292
00293 const char* TCollection::GetCollectionEntryName(TObject* entry) const
00294 {
00295
00296
00297
00298
00299 return entry->GetName();
00300 }
00301
00302
00303 void TCollection::PrintCollectionEntry(TObject* entry, Option_t* option, Int_t recurse) const
00304 {
00305
00306
00307 TCollection* coll = dynamic_cast<TCollection*>(entry);
00308 if (coll) {
00309 coll->Print(option, recurse);
00310 } else {
00311 TROOT::IndentLevel();
00312 entry->Print(option);
00313 }
00314 }
00315
00316
00317 void TCollection::Print(Option_t *option) const
00318 {
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 Print(option, 1);
00335 }
00336
00337
00338 void TCollection::Print(Option_t *option, Int_t recurse) const
00339 {
00340
00341
00342
00343
00344
00345
00346
00347
00348 PrintCollectionHeader(option);
00349
00350 if (recurse != 0)
00351 {
00352 TIter next(this);
00353 TObject *object;
00354
00355 TROOT::IncreaseDirLevel();
00356 while ((object = next())) {
00357 PrintCollectionEntry(object, option, recurse - 1);
00358 }
00359 TROOT::DecreaseDirLevel();
00360 }
00361 }
00362
00363
00364 void TCollection::Print(Option_t *option, const char* wildcard, Int_t recurse) const
00365 {
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 PrintCollectionHeader(option);
00376
00377 if (recurse != 0)
00378 {
00379 if (!wildcard) wildcard = "";
00380 TRegexp re(wildcard, kTRUE);
00381 Int_t nch = strlen(wildcard);
00382 TIter next(this);
00383 TObject *object;
00384
00385 TROOT::IncreaseDirLevel();
00386 while ((object = next())) {
00387 TString s = GetCollectionEntryName(object);
00388 if (nch == 0 || s == wildcard || s.Index(re) != kNPOS) {
00389 PrintCollectionEntry(object, option, recurse - 1);
00390 }
00391 }
00392 TROOT::DecreaseDirLevel();
00393 }
00394 }
00395
00396
00397 void TCollection::Print(Option_t *option, TPRegexp& regexp, Int_t recurse) const
00398 {
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 PrintCollectionHeader(option);
00409
00410 if (recurse != 0)
00411 {
00412 TIter next(this);
00413 TObject *object;
00414
00415 TROOT::IncreaseDirLevel();
00416 while ((object = next())) {
00417 TString s = GetCollectionEntryName(object);
00418 if (regexp.MatchB(s)) {
00419 PrintCollectionEntry(object, option, recurse - 1);
00420 }
00421 }
00422 TROOT::DecreaseDirLevel();
00423 }
00424 }
00425
00426
00427 void TCollection::RecursiveRemove(TObject *obj)
00428 {
00429
00430
00431
00432 if (!obj) return;
00433
00434
00435 while (Remove(obj))
00436 ;
00437
00438
00439 TIter next(this);
00440 TObject *object;
00441
00442 while ((object = next())) {
00443 if (object->TestBit(kNotDeleted)) object->RecursiveRemove(obj);
00444 }
00445 }
00446
00447
00448 void TCollection::RemoveAll(TCollection *col)
00449 {
00450
00451
00452 TIter next(col);
00453 TObject *obj;
00454
00455 while ((obj = next()))
00456 Remove(obj);
00457 }
00458
00459
00460 void TCollection::Streamer(TBuffer &b)
00461 {
00462
00463
00464 Int_t nobjects;
00465 TObject *obj;
00466 UInt_t R__s, R__c;
00467
00468 if (b.IsReading()) {
00469 Version_t v = b.ReadVersion(&R__s, &R__c);
00470 if (v > 2)
00471 TObject::Streamer(b);
00472 if (v > 1)
00473 fName.Streamer(b);
00474 b >> nobjects;
00475 for (Int_t i = 0; i < nobjects; i++) {
00476 b >> obj;
00477 Add(obj);
00478 }
00479 b.CheckByteCount(R__s, R__c,TCollection::IsA());
00480 } else {
00481 R__c = b.WriteVersion(TCollection::IsA(), kTRUE);
00482 TObject::Streamer(b);
00483 fName.Streamer(b);
00484 nobjects = GetSize();
00485 b << nobjects;
00486
00487 TIter next(this);
00488
00489 while ((obj = next())) {
00490 b << obj;
00491 }
00492 b.SetByteCount(R__c, kTRUE);
00493 }
00494 }
00495
00496
00497 Int_t TCollection::Write(const char *name, Int_t option, Int_t bsize) const
00498 {
00499
00500
00501
00502
00503
00504
00505
00506 if ((option & kSingleKey)) {
00507 return TObject::Write(name, option, bsize);
00508 } else {
00509 option &= ~kSingleKey;
00510 Int_t nbytes = 0;
00511 TIter next(this);
00512 TObject *obj;
00513 while ((obj = next())) {
00514 nbytes += obj->Write(name, option, bsize);
00515 }
00516 return nbytes;
00517 }
00518 }
00519
00520
00521 Int_t TCollection::Write(const char *name, Int_t option, Int_t bsize)
00522 {
00523
00524
00525
00526
00527
00528
00529
00530 return ((const TCollection*)this)->Write(name,option,bsize);
00531 }
00532
00533
00534
00535 TCollection *TCollection::GetCurrentCollection()
00536 {
00537
00538
00539 return fgCurrentCollection;
00540 }
00541
00542
00543 void TCollection::SetCurrentCollection()
00544 {
00545
00546
00547 fgCurrentCollection = this;
00548 }
00549
00550
00551 void TCollection::StartGarbageCollection()
00552 {
00553
00554
00555 R__LOCKGUARD2(gCollectionMutex);
00556 if (!fgGarbageCollection) {
00557 fgGarbageCollection = new TObjectTable;
00558 fgEmptyingGarbage = kFALSE;
00559 fgGarbageStack = 0;
00560 }
00561 fgGarbageStack++;
00562 }
00563
00564
00565 void TCollection::EmptyGarbageCollection()
00566 {
00567
00568
00569 R__LOCKGUARD2(gCollectionMutex);
00570 if (fgGarbageStack > 0) fgGarbageStack--;
00571 if (fgGarbageCollection && fgGarbageStack == 0 && fgEmptyingGarbage == kFALSE) {
00572 fgEmptyingGarbage = kTRUE;
00573 fgGarbageCollection->Delete();
00574 fgEmptyingGarbage = kFALSE;
00575 SafeDelete(fgGarbageCollection);
00576 }
00577 }
00578
00579
00580 void TCollection::GarbageCollect(TObject *obj)
00581 {
00582
00583
00584 R__LOCKGUARD2(gCollectionMutex);
00585 if (fgGarbageCollection) {
00586 if (!fgEmptyingGarbage) {
00587 fgGarbageCollection->Add(obj);
00588 } else
00589 delete obj;
00590 } else
00591 delete obj;
00592 }
00593
00594
00595 void TCollection::SetOwner(Bool_t enable)
00596 {
00597
00598
00599
00600
00601
00602
00603 if (enable)
00604 SetBit(kIsOwner);
00605 else
00606 ResetBit(kIsOwner);
00607 }
00608
00609
00610 TIter::TIter(const TIter &iter)
00611 {
00612
00613
00614
00615 if (iter.fIterator) {
00616 fIterator = iter.GetCollection()->MakeIterator();
00617 fIterator->operator=(*iter.fIterator);
00618 } else
00619 fIterator = 0;
00620 }
00621
00622
00623 TIter &TIter::operator=(const TIter &rhs)
00624 {
00625
00626
00627
00628 if (this != &rhs) {
00629 if (rhs.fIterator) {
00630 delete fIterator;
00631 fIterator = rhs.GetCollection()->MakeIterator();
00632 fIterator->operator=(*rhs.fIterator);
00633 }
00634 }
00635 return *this;
00636 }
00637
00638
00639 TIter &TIter::Begin()
00640 {
00641
00642
00643 fIterator->Reset();
00644 fIterator->Next();
00645 return *this;
00646 }
00647
00648
00649 TIter TIter::End()
00650 {
00651
00652
00653 return TIter(static_cast<TIterator*>(nullptr));
00654 }