Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TFormLeafInfoReference.cxx
Go to the documentation of this file.
1 // @(#)root/treeplayer:$Id$
2 // Author: Markus Frank 01/02/2006
3 
4 /*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers and al. *
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 "TError.h"
13 #include "TLeafObject.h"
14 #include "TInterpreter.h"
15 #include "TVirtualRefProxy.h"
16 #include "TFormLeafInfoReference.h"
17 
18 /** \class TFormLeafInfoReference
19 A small helper class to implement the following
20 of reference objects stored in a TTree
21 */
22 
23 ////////////////////////////////////////////////////////////////////////////////
24 /// Constructor.
25 
26 TFormLeafInfoReference::TFormLeafInfoReference(TClass* cl, TStreamerElement* e, int off)
27 : TFormLeafInfo(cl,off,e), fProxy(0), fBranch(0)
28 {
29  TVirtualRefProxy* p = cl->GetReferenceProxy();
30  if ( !p ) {
31  ::Error("TFormLeafInfoReference","No reference proxy for class %s availible",cl->GetName());
32  return;
33  }
34  fProxy = p->Clone();
35 }
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Copy constructor.
39 
40 TFormLeafInfoReference::TFormLeafInfoReference(const TFormLeafInfoReference& org)
41 : TFormLeafInfo(org), fProxy(0), fBranch(org.fBranch)
42 {
43  TVirtualRefProxy* p = org.fProxy;
44  if ( !p ) {
45  ::Error("TFormLeafInfoReference","No reference proxy for class %s availible",fClass->GetName());
46  return;
47  }
48  fProxy = p->Clone();
49 }
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Destructor.
53 
54 TFormLeafInfoReference::~TFormLeafInfoReference()
55 {
56  if ( fProxy ) fProxy->Release();
57 }
58 
59 ////////////////////////////////////////////////////////////////////////////////
60 /// Exception safe swap.
61 
62 void TFormLeafInfoReference::Swap(TFormLeafInfoReference &other)
63 {
64  TFormLeafInfo::Swap(other);
65  std::swap(fProxy,other.fProxy);
66  std::swap(fBranch,other.fBranch);
67 }
68 
69 ////////////////////////////////////////////////////////////////////////////////
70 /// Exception safe assignment operator.
71 
72 TFormLeafInfoReference &TFormLeafInfoReference::operator=(const TFormLeafInfoReference &other)
73 {
74  TFormLeafInfoReference tmp(other);
75  Swap(tmp);
76  return *this;
77 }
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// Virtual copy constructor.
81 
82 TFormLeafInfo* TFormLeafInfoReference::DeepCopy() const
83 {
84  return new TFormLeafInfoReference(*this);
85 }
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// Access to target class pointer (if available)
89 
90 TClass* TFormLeafInfoReference::GetClass() const
91 {
92  return fNext ? fNext->GetClass() : 0;
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Return true if any of underlying data has a array size counter
97 
98 Bool_t TFormLeafInfoReference::HasCounter() const
99 {
100  Bool_t result = fProxy ? fProxy->HasCounter() : false;
101  if (fNext) result |= fNext->HasCounter();
102  return fCounter!=0 || result;
103 }
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Return the size of the underlying array for the current entry in the TTree.
106 
107 Int_t TFormLeafInfoReference::ReadCounterValue(char *where)
108 {
109  Int_t result = 0;
110  if ( where && HasCounter() ) {
111  where = (char*)fProxy->GetPreparedReference(where);
112  if ( where ) {
113  return fProxy->GetCounterValue(this, where);
114  }
115  }
116  gInterpreter->ClearStack();
117  // Get rid of temporary return object.
118  return result;
119 }
120 
121 ////////////////////////////////////////////////////////////////////////////////
122 /// Return the current size of the array container
123 
124 Int_t TFormLeafInfoReference::GetCounterValue(TLeaf* leaf) {
125  if ( HasCounter() ) {
126  char *thisobj = 0;
127  Int_t instance = 0;
128  if (leaf->InheritsFrom(TLeafObject::Class()) ) {
129  thisobj = (char*)((TLeafObject*)leaf)->GetObject();
130  } else {
131  thisobj = GetObjectAddress((TLeafElement*)leaf, instance); // instance might be modified
132  }
133  return ReadCounterValue(thisobj);
134  }
135  return 0;
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 /// Access to the value class of the reference proxy
140 
141 TClass* TFormLeafInfoReference::GetValueClass(TLeaf* leaf)
142 {
143  return this->GetValueClass(this->GetLocalValuePointer(leaf,0));
144 }
145 
146 ////////////////////////////////////////////////////////////////////////////////
147 /// Access to the value class of the reference proxy
148 
149 TClass* TFormLeafInfoReference::GetValueClass(void* obj)
150 {
151  return fProxy ? fProxy->GetValueClass(obj) : 0;
152 }
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// TFormLeafInfo overload: Update (and propagate) cached information
156 
157 Bool_t TFormLeafInfoReference::Update()
158 {
159  Bool_t res = this->TFormLeafInfo::Update();
160  if ( fProxy ) fProxy->Update();
161  return res;
162 }
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 /// Return result of a leafobject method
166 
167 template <typename T>
168 T TFormLeafInfoReference::GetValueImpl(TLeaf *leaf, Int_t instance)
169 {
170  fBranch = leaf->GetBranch();
171  return TFormLeafInfo::GetValueImpl<T>(leaf, instance);
172 }
173 
174 template Double_t TFormLeafInfoReference::GetValueImpl<Double_t>(TLeaf*, Int_t);
175 template Long64_t TFormLeafInfoReference::GetValueImpl<Long64_t>(TLeaf*, Int_t);
176 template LongDouble_t TFormLeafInfoReference::GetValueImpl<LongDouble_t>(TLeaf*, Int_t);
177 
178 ////////////////////////////////////////////////////////////////////////////////
179 /// This is implemented here because some compiler want ALL the
180 /// signature of an overloaded function to be re-implemented.
181 
182 void *TFormLeafInfoReference::GetLocalValuePointer( TLeaf *from, Int_t instance)
183 {
184  fBranch = from->GetBranch();
185  return TFormLeafInfo::GetLocalValuePointer(from, instance);
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /// Access value of referenced object
190 
191 void *TFormLeafInfoReference::GetLocalValuePointer(char *where, Int_t instance)
192 {
193  if (where) {
194  where = (char*)fProxy->GetPreparedReference(where);
195  if (where) {
196  void* result = fProxy->GetObject(this, where, instance);
197  gInterpreter->ClearStack();
198  return result;
199  }
200  }
201  gInterpreter->ClearStack();
202  return 0;
203 }
204 
205 ////////////////////////////////////////////////////////////////////////////////
206 /// Execute the method on the given address
207 
208 template <typename T>
209 T TFormLeafInfoReference::ReadValueImpl(char *where, Int_t instance)
210 {
211  T result = 0;
212  if ( where ) {
213  where = (char*)fProxy->GetPreparedReference(where);
214  if ( where ) {
215  void* res = fProxy->GetObject(this, where, instance);
216  if ( res ) {
217  result = (fNext) ? fNext->ReadTypedValue<T>((char*)res,instance) : *(Double_t*)res;
218  }
219  }
220  }
221  gInterpreter->ClearStack();
222  // Get rid of temporary return object.
223  return result;
224 }
225 
226 template Double_t TFormLeafInfoReference::ReadValueImpl<Double_t>(char*, Int_t);
227 template Long64_t TFormLeafInfoReference::ReadValueImpl<Long64_t>(char*, Int_t);
228 template LongDouble_t TFormLeafInfoReference::ReadValueImpl<LongDouble_t>(char*, Int_t);
229