// @(#)root/treeplayer:$Id$ // Author: Markus Frank 01/02/2006 /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers and al. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #include "TError.h" #include "TLeafObject.h" #include "TInterpreter.h" #include "TVirtualRefProxy.h" #include "TFormLeafInfoReference.h" //______________________________________________________________________________ // // TFormLeafInfoReference is a small helper class to implement the following // of reference objects stored in a TTree //______________________________________________________________________________ TFormLeafInfoReference::TFormLeafInfoReference(TClass* cl, TStreamerElement* e, int off) : TFormLeafInfo(cl,off,e), fProxy(0), fBranch(0) { // Constructor. TVirtualRefProxy* p = cl->GetReferenceProxy(); if ( !p ) { ::Error("TFormLeafInfoReference","No reference proxy for class %s availible",cl->GetName()); return; } fProxy = p->Clone(); } //______________________________________________________________________________ TFormLeafInfoReference::TFormLeafInfoReference(const TFormLeafInfoReference& org) : TFormLeafInfo(org), fProxy(0), fBranch(org.fBranch) { // Copy constructor. TVirtualRefProxy* p = org.fProxy; if ( !p ) { ::Error("TFormLeafInfoReference","No reference proxy for class %s availible",fClass->GetName()); return; } fProxy = p->Clone(); } //______________________________________________________________________________ TFormLeafInfoReference::~TFormLeafInfoReference() { // Destructor. if ( fProxy ) fProxy->Release(); } //______________________________________________________________________________ void TFormLeafInfoReference::Swap(TFormLeafInfoReference &other) { // Exception safe swap. TFormLeafInfo::Swap(other); std::swap(fProxy,other.fProxy); std::swap(fBranch,other.fBranch); } //______________________________________________________________________________ TFormLeafInfoReference &TFormLeafInfoReference::operator=(const TFormLeafInfoReference &other) { // Exception safe assignment operator. TFormLeafInfoReference tmp(other); Swap(tmp); return *this; } //______________________________________________________________________________ TFormLeafInfo* TFormLeafInfoReference::DeepCopy() const { // Virtual copy constructor. return new TFormLeafInfoReference(*this); } //______________________________________________________________________________ TClass* TFormLeafInfoReference::GetClass() const { // Access to target class pointer (if available) return fNext ? fNext->GetClass() : 0; } //______________________________________________________________________________ Bool_t TFormLeafInfoReference::HasCounter() const { // Return true if any of underlying data has a array size counter Bool_t result = fProxy ? fProxy->HasCounter() : false; if (fNext) result |= fNext->HasCounter(); return fCounter!=0 || result; } //______________________________________________________________________________ Int_t TFormLeafInfoReference::ReadCounterValue(char *where) { // Return the size of the underlying array for the current entry in the TTree. Int_t result = 0; if ( where && HasCounter() ) { where = (char*)fProxy->GetPreparedReference(where); if ( where ) { return fProxy->GetCounterValue(this, where); } } gInterpreter->ClearStack(); // Get rid of temporary return object. return result; } //______________________________________________________________________________ Int_t TFormLeafInfoReference::GetCounterValue(TLeaf* leaf) { // Return the current size of the array container if ( HasCounter() ) { char *thisobj = 0; Int_t instance = 0; if (leaf->InheritsFrom(TLeafObject::Class()) ) { thisobj = (char*)((TLeafObject*)leaf)->GetObject(); } else { thisobj = GetObjectAddress((TLeafElement*)leaf, instance); // instance might be modified } return ReadCounterValue(thisobj); } return 0; } //______________________________________________________________________________ TClass* TFormLeafInfoReference::GetValueClass(TLeaf* leaf) { // Access to the value class of the reference proxy return this->GetValueClass(this->GetLocalValuePointer(leaf,0)); } //______________________________________________________________________________ TClass* TFormLeafInfoReference::GetValueClass(void* obj) { // Access to the value class of the reference proxy return fProxy ? fProxy->GetValueClass(obj) : 0; } //______________________________________________________________________________ Bool_t TFormLeafInfoReference::Update() { // TFormLeafInfo overload: Update (and propagate) cached information Bool_t res = this->TFormLeafInfo::Update(); if ( fProxy ) fProxy->Update(); return res; } //______________________________________________________________________________ Double_t TFormLeafInfoReference::GetValue(TLeaf *leaf, Int_t instance) { // Return result of a leafobject method fBranch = leaf->GetBranch(); return TFormLeafInfo::GetValue(leaf, instance); } //______________________________________________________________________________ void *TFormLeafInfoReference::GetLocalValuePointer( TLeaf *from, Int_t instance) { // This is implemented here because some compiler want ALL the // signature of an overloaded function to be re-implemented. fBranch = from->GetBranch(); return TFormLeafInfo::GetLocalValuePointer(from, instance); } //______________________________________________________________________________ void *TFormLeafInfoReference::GetLocalValuePointer(char *where, Int_t instance) { // Access value of referenced object if (where) { where = (char*)fProxy->GetPreparedReference(where); if (where) { void* result = fProxy->GetObject(this, where, instance); gInterpreter->ClearStack(); return result; } } gInterpreter->ClearStack(); return 0; } //______________________________________________________________________________ Double_t TFormLeafInfoReference::ReadValue(char *where, Int_t instance) { // Execute the method on the given address Double_t result = 0; if ( where ) { where = (char*)fProxy->GetPreparedReference(where); if ( where ) { void* res = fProxy->GetObject(this, where, instance); if ( res ) { result = (fNext) ? fNext->ReadValue((char*)res,instance) : *(Double_t*)res; } } } gInterpreter->ClearStack(); // Get rid of temporary return object. return result; }