00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "TLeafObject.h"
00018 #include "TBranch.h"
00019 #include "TClass.h"
00020 #include "TMethodCall.h"
00021 #include "TDataType.h"
00022
00023
00024 ClassImp(TLeafObject)
00025
00026
00027 TLeafObject::TLeafObject(): TLeaf()
00028 {
00029
00030
00031 fClass = 0;
00032 fObjAddress = 0;
00033 fVirtual = kTRUE;
00034 }
00035
00036
00037 TLeafObject::TLeafObject(TBranch *parent, const char *name, const char *type)
00038 :TLeaf(parent, name,type)
00039 {
00040
00041
00042
00043
00044 SetTitle(type);
00045 fClass = TClass::GetClass(type);
00046 fObjAddress = 0;
00047 fVirtual = kTRUE;
00048 }
00049
00050
00051 TLeafObject::~TLeafObject()
00052 {
00053
00054
00055
00056 }
00057
00058
00059
00060 void TLeafObject::FillBasket(TBuffer &b)
00061 {
00062
00063
00064
00065 if (!fObjAddress) return;
00066 TObject *object = GetObject();
00067 if (object) {
00068 if (fVirtual) {
00069 UChar_t n = strlen(object->ClassName());
00070 b << n;
00071 b.WriteFastArray(object->ClassName(),n+1);
00072 }
00073 object->Streamer(b);
00074 } else {
00075 if (fClass) {
00076 if (fClass->Property() & kIsAbstract) object = new TObject;
00077 else object = (TObject *)fClass->New();
00078 object->SetBit(kInvalidObject);
00079 object->SetUniqueID(123456789);
00080 object->Streamer(b);
00081 if (fClass->Property() & kIsAbstract) delete object;
00082 else fClass->Destructor(object);
00083 } else {
00084 Error("FillBasket","Attempt to write a NULL object in leaf:%s",GetName());
00085 }
00086 }
00087 }
00088
00089
00090 TMethodCall *TLeafObject::GetMethodCall(const char *name)
00091 {
00092
00093
00094
00095
00096
00097
00098
00099 char *namecpy = new char[strlen(name)+1];
00100 strcpy(namecpy,name);
00101 char *params = strchr(namecpy,'(');
00102 if (params) { *params = 0; params++; }
00103 else params = (char *) ")";
00104
00105 if (!fClass) fClass = TClass::GetClass(GetTitle());
00106 TMethodCall *m = new TMethodCall(fClass, namecpy, params);
00107 delete [] namecpy;
00108 if (m->GetMethod()) return m;
00109 Error("GetMethodCall","Unknown method:%s",name);
00110 delete m;
00111 return 0;
00112 }
00113
00114
00115 const char *TLeafObject::GetTypeName() const
00116 {
00117
00118
00119
00120 return fTitle.Data();
00121 }
00122
00123
00124 Bool_t TLeafObject::Notify()
00125 {
00126
00127
00128 fClass = TClass::GetClass(GetTitle());
00129 return kFALSE;
00130 }
00131
00132
00133 void TLeafObject::PrintValue(Int_t) const
00134 {
00135
00136
00137 printf("%lx\n",(Long_t)GetValuePointer());
00138 }
00139
00140
00141 void TLeafObject::ReadBasket(TBuffer &b)
00142 {
00143
00144
00145
00146 char classname[128];
00147 UChar_t n;
00148 if (fVirtual) {
00149 b >> n;
00150 b.ReadFastArray(classname,n+1);
00151 fClass = TClass::GetClass(classname);
00152 }
00153 if (fClass) {
00154 TObject *object;
00155 if (!fObjAddress) {
00156 Long_t *voidobj = new Long_t[1];
00157 fObjAddress = (void **)voidobj;
00158 *fObjAddress = (TObject *)fClass->New();
00159 }
00160 object = (TObject*)(*fObjAddress);
00161 if (fBranch->IsAutoDelete()) {
00162 fClass->Destructor(object);
00163 object = (TObject *)fClass->New();
00164 }
00165 if (!object) return;
00166
00167 if (fClass->GetClassInfo()) {
00168 object->Streamer(b);
00169 } else {
00170
00171 if (!TestBit(kWarn)) {
00172 Warning("ReadBasket","%s::Streamer not available, using TClass::ReadBuffer instead",fClass->GetName());
00173 SetBit(kWarn);
00174 }
00175 fClass->ReadBuffer(b,object);
00176 }
00177
00178
00179 if (object->TestBit(kInvalidObject)) {
00180 if (object->GetUniqueID() == 123456789) {
00181 fClass->Destructor(object);
00182 object = 0;
00183 }
00184 }
00185 *fObjAddress = object;
00186 } else GetBranch()->SetAddress(0);
00187 }
00188
00189
00190 void TLeafObject::SetAddress(void *add)
00191 {
00192
00193
00194
00195 fObjAddress = (void **)add;
00196 }
00197
00198
00199 void TLeafObject::Streamer(TBuffer &b)
00200 {
00201
00202
00203 if (b.IsReading()) {
00204 UInt_t R__s, R__c;
00205 Version_t R__v = b.ReadVersion(&R__s, &R__c);
00206 if (R__v > 3 || R__v == 2) {
00207 b.ReadClassBuffer(TLeafObject::Class(), this, R__v, R__s, R__c);
00208 if (R__v == 2) fVirtual = kTRUE;
00209 fObjAddress = 0;
00210 fClass = TClass::GetClass(fTitle.Data());
00211 if (!fClass) Warning("Streamer","Cannot find class:%s",fTitle.Data());
00212 return;
00213 }
00214
00215 TLeaf::Streamer(b);
00216 fObjAddress = 0;
00217 fClass = TClass::GetClass(fTitle.Data());
00218 if (!fClass) Warning("Streamer","Cannot find class:%s",fTitle.Data());
00219 if (R__v < 1) fVirtual = kFALSE;
00220 if (R__v == 1) fVirtual = kTRUE;
00221 if (R__v == 3) b >> fVirtual;
00222
00223
00224 } else {
00225 b.WriteClassBuffer(TLeafObject::Class(),this);
00226 }
00227 }
00228
00229
00230 Bool_t TLeafObject::IsOnTerminalBranch() const
00231 {
00232
00233
00234 if (fBranch->GetListOfBranches()->GetEntriesFast()) return kFALSE;
00235 return kTRUE;
00236 }