00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4DirProxy.h"
00015
00016 #include "TSystem.h"
00017 #include "TDirectory.h"
00018 #include "TKey.h"
00019 #include "TROOT.h"
00020 #include "TH1.h"
00021 #include "TTree.h"
00022 #include "TFile.h"
00023
00024 #include "TGo4ObjectProxy.h"
00025 #include "TGo4TreeProxy.h"
00026 #include "TGo4CanvasProxy.h"
00027 #include "TGo4HStackProxy.h"
00028 #include "TGo4Slot.h"
00029
00030 class TGo4KeyAccess : public TGo4Access {
00031 public:
00032 TGo4KeyAccess(TDirectory* dir, TKey* key) : TGo4Access(), fDir(dir), fKey(key) {}
00033
00034 virtual Bool_t CanGetObject() const
00035 { return kTRUE; }
00036
00037 virtual Bool_t GetObject(TObject* &obj, Bool_t &owner) const
00038 {
00039 TClass* cl = gROOT->GetClass(fKey->GetClassName());
00040 if ((cl!=0) && !cl->IsLoaded()) {
00041 obj = 0;
00042 owner = kFALSE;
00043 return kFALSE;
00044 }
00045
00046 owner = kTRUE;
00047 fDir->cd();
00048 obj = fKey->ReadObj();
00049 if (obj!=0)
00050 if (obj->InheritsFrom(TH1::Class()) || obj->InheritsFrom(TTree::Class()))
00051 owner = kFALSE;
00052 return obj!=0;
00053 }
00054
00055 virtual const char* GetObjectName() const
00056 { return fKey->GetName(); }
00057
00058 virtual const char* GetObjectClassName() const
00059 { return fKey->GetClassName(); }
00060
00061 private:
00062 TDirectory* fDir;
00063 TKey* fKey;
00064 };
00065
00066
00067
00068 class TGo4DirLevelIter : public TGo4LevelIter {
00069 protected:
00070 TDirectory* fDir;
00071 Bool_t fReadRight;
00072 TIterator* fIter;
00073 Bool_t fIsKeyIter;
00074 TObject* fCurrent;
00075 TString fNameBuf;
00076
00077 public:
00078 TGo4DirLevelIter(TDirectory* dir, Bool_t readright) :
00079 TGo4LevelIter(),
00080 fDir(dir),
00081 fReadRight(readright),
00082 fIter(0),
00083 fIsKeyIter(kFALSE),
00084 fCurrent(0),
00085 fNameBuf()
00086 {
00087 fIter = fDir->GetListOfKeys()->MakeIterator();
00088 fIsKeyIter = kTRUE;
00089 }
00090
00091 virtual ~TGo4DirLevelIter()
00092 {
00093 if (fIter!=0) delete fIter;
00094 }
00095
00096 virtual Bool_t next()
00097 {
00098 Bool_t donext = kTRUE;
00099
00100 while (donext) {
00101
00102 fCurrent = fIter->Next();
00103
00104 if (fCurrent==0){
00105 if(fIsKeyIter) {
00106 delete fIter;
00107 fIter = fDir->GetList()->MakeIterator();
00108 fIsKeyIter = kFALSE;
00109 continue;
00110 } else
00111 break;
00112 }
00113 donext = kFALSE;
00114
00115 if (!fIsKeyIter) {
00116 TKey* key = fDir->FindKey(fCurrent->GetName());
00117 if (key!=0)
00118 if (strcmp(fCurrent->ClassName(), key->GetClassName())==0) donext = kTRUE;
00119 }
00120 }
00121 return fCurrent!=0;
00122 }
00123
00124 virtual Bool_t isfolder()
00125 {
00126 TClass* cl = 0;
00127 if (fIsKeyIter) {
00128 TKey* key = (TKey*) fCurrent;
00129 if (fReadRight)
00130 cl = (TClass*) gROOT->GetListOfClasses()->FindObject(key->GetClassName());
00131 } else
00132 cl = fCurrent->IsA();
00133
00134 return (cl!=0) &&
00135 (cl->InheritsFrom(TDirectory::Class()) ||
00136 cl->InheritsFrom(TTree::Class()) ||
00137 cl->InheritsFrom(TCanvas::Class()) ||
00138 cl->InheritsFrom(THStack::Class()));
00139 }
00140
00141 virtual TGo4LevelIter* subiterator()
00142 {
00143 TObject* obj = fIsKeyIter ? fDir->Get(fCurrent->GetName()) : fCurrent;
00144 if (obj==0) return 0;
00145
00146 if (obj->InheritsFrom(TTree::Class()))
00147 return TGo4TreeProxy::ProduceIter((TTree*)obj);
00148
00149 if (obj->InheritsFrom(TCanvas::Class()))
00150 return TGo4CanvasProxy::ProduceIter((TCanvas*)obj);
00151
00152 if (obj->InheritsFrom(THStack::Class()))
00153 return TGo4HStackProxy::ProduceIter((THStack*)obj);
00154
00155 TDirectory* subdir = dynamic_cast<TDirectory*> (obj);
00156 return subdir==0 ? 0 : new TGo4DirLevelIter(subdir, fReadRight);
00157 }
00158
00159 virtual const char* name()
00160 {
00161 if (!fIsKeyIter) return fCurrent->GetName();
00162 TKey* key = (TKey*) fCurrent;
00163 if (isfolder() || (key->GetCycle()==1)) return key->GetName();
00164 fNameBuf.Form("%s;%d",key->GetName(),key->GetCycle());
00165 return fNameBuf.Data();
00166 }
00167
00168 virtual const char* info()
00169 {
00170 return fCurrent->GetTitle();
00171 }
00172
00173 virtual Int_t sizeinfo()
00174 {
00175 TClass* cl = 0;
00176 Int_t sz = 0;
00177 if (fIsKeyIter) {
00178 TKey* key = (TKey*) fCurrent;
00179 cl = (TClass*) gROOT->GetListOfClasses()->FindObject(key->GetClassName());
00180 sz = key->GetNbytes();
00181 TObject* obj = fDir->FindObject(key->GetName());
00182 if (obj) sz = TGo4ObjectProxy::DefineObjectSize(obj);
00183 } else {
00184 cl = fCurrent->IsA();
00185 sz = TGo4ObjectProxy::DefineObjectSize(fCurrent);
00186 }
00187 bool isdir = (cl!=0) && cl->InheritsFrom(TDirectory::Class());
00188 return isdir ? 0 : sz;
00189 }
00190
00191 virtual Int_t GetKind()
00192 {
00193 return isfolder() ? TGo4Access::kndFolder : TGo4Access::kndObject;
00194 }
00195
00196 virtual const char* GetClassName()
00197 {
00198 return fIsKeyIter ? ((TKey*) fCurrent)->GetClassName() : fCurrent->ClassName();
00199 }
00200 };
00201
00202
00203
00204 TGo4DirProxy::TGo4DirProxy() :
00205 TGo4Proxy(),
00206 fDir(0),
00207 fOwner(kFALSE),
00208 fReadRight(kFALSE)
00209 {
00210 }
00211
00212 TGo4DirProxy::TGo4DirProxy(TDirectory* dir, Bool_t readright, Bool_t owner) :
00213 TGo4Proxy(),
00214 fDir(0),
00215 fOwner(kFALSE),
00216 fReadRight(kFALSE)
00217 {
00218 SetDir(dir, readright, owner);
00219 }
00220
00221 TGo4DirProxy::~TGo4DirProxy()
00222 {
00223 ClearDir();
00224 }
00225
00226 void TGo4DirProxy::SetDir(TDirectory* dir, Bool_t readright, Bool_t owner)
00227 {
00228 ClearDir();
00229 fDir = dir;
00230 fReadRight = readright;
00231 fOwner = owner;
00232 }
00233
00234 void TGo4DirProxy::ClearDir()
00235 {
00236 if (fOwner && (fDir!=0)) delete fDir;
00237 fDir = 0;
00238 fOwner = kFALSE;
00239 }
00240
00241 Int_t TGo4DirProxy::GetObjectKind()
00242 {
00243 return (fDir!=0) ? TGo4Access::kndFolder : TGo4Access::kndNone;
00244 }
00245
00246 const char* TGo4DirProxy::GetContainedClassName()
00247 {
00248 return fDir!=0 ? fDir->ClassName() : 0;
00249 }
00250
00251 const char* TGo4DirProxy::GetContainedObjectInfo()
00252 {
00253 return fDir!=0 ? fDir->GetTitle() : 0;
00254 }
00255
00256 Int_t TGo4DirProxy::GetObjectSizeInfo()
00257 {
00258 TFile* f = dynamic_cast<TFile*> (fDir);
00259 return f==0 ? TGo4Proxy::GetObjectSizeInfo() : f->GetSize();
00260 }
00261
00262
00263 TGo4Access* TGo4DirProxy::ProduceProxy(TDirectory* dir, Bool_t readright, const char* name)
00264 {
00265 if (dir==0) return 0;
00266
00267 if ((name==0) || (*name==0)) return new TGo4ObjectAccess(dir);
00268
00269 TDirectory* curdir = dir;
00270 const char* curname = name;
00271
00272 while (curdir!=0) {
00273 const char* slash = strchr(curname,'/');
00274 TObject* obj = 0;
00275 if (slash==0) {
00276 char namebuf[10000];
00277 Short_t cyclebuf;
00278 TDirectory::DecodeNameCycle(curname, namebuf, cyclebuf);
00279 obj = curdir->GetList()->FindObject(curname);
00280 if (obj!=0) return new TGo4ObjectAccess(obj);
00281 if (cyclebuf==9999) cyclebuf=1;
00282 TKey* key = curdir->GetKey(namebuf, cyclebuf);
00283 if (key!=0) return new TGo4KeyAccess(curdir, key);
00284 return 0;
00285 }
00286
00287 UInt_t len = slash - curname;
00288 char* partname = new char[len + 1];
00289 strncpy(partname, curname, len);
00290 partname[len] = 0;
00291 if (readright) {
00292 curdir->cd();
00293 obj = curdir->Get(partname);
00294 } else
00295 obj = curdir->GetList()->FindObject(partname);
00296 delete[] partname;
00297
00298 if (obj==0) return 0;
00299
00300 curname = slash+1;
00301
00302 TTree* tr = dynamic_cast<TTree*> (obj);
00303 if (tr!=0)
00304 return TGo4TreeProxy::ProduceProxy(tr, curname);
00305
00306 TCanvas* canv = dynamic_cast<TCanvas*> (obj);
00307 if (canv!=0)
00308 return TGo4CanvasProxy::ProduceProxy(canv, curname);
00309
00310 THStack* hs = dynamic_cast<THStack*> (obj);
00311 if (hs!=0)
00312 return TGo4HStackProxy::ProduceProxy(hs, curname);
00313
00314 curdir = dynamic_cast<TDirectory*>(obj);
00315 }
00316 return 0;
00317 }
00318
00319 TGo4LevelIter* TGo4DirProxy::ProduceIter(TDirectory* dir, Bool_t readright)
00320 {
00321 return new TGo4DirLevelIter(dir, readright);
00322 }
00323
00324
00325 void TGo4DirProxy::WriteData(TGo4Slot* slot, TDirectory* dir, Bool_t onlyobjs)
00326 {
00327 if (!onlyobjs) {
00328 const char* filename = 0;
00329 if ((fDir!=0) && fDir->InheritsFrom(TFile::Class()))
00330 filename = fDir->GetName();
00331
00332 slot->SetPar("DirProxy::FileName", filename);
00333 slot->SetPar("DirProxy::gROOT", (fDir==gROOT) ? "true" : 0);
00334 }
00335 }
00336
00337 void TGo4DirProxy::ReadData(TGo4Slot* slot, TDirectory* dir)
00338 {
00339 ClearDir();
00340
00341 const char* filename = slot->GetPar("DirProxy::FileName");
00342 const char* groot = slot->GetPar("DirProxy::gROOT");
00343
00344 if (filename!=0) {
00345 TFile* f = TFile::Open(filename);
00346 if (f!=0) SetDir(f, kTRUE, kTRUE);
00347 } else
00348 if (groot!=0)
00349 SetDir(gROOT, kFALSE, kFALSE);
00350 }
00351
00352 Bool_t TGo4DirProxy::UpdateObjectInFile(const char* filepath, TObject* obj)
00353 {
00354 if ((filepath==0) || (fDir==0)) return kFALSE;
00355
00356 TFile* f = dynamic_cast<TFile*> (fDir);
00357 if (f==0) return kFALSE;
00358
00359 if (f->ReOpen("UPDATE")<0) return kFALSE;
00360
00361 TString foldername, objname;
00362 TGo4Slot::ProduceFolderAndName(filepath, foldername, objname);
00363
00364 TDirectory* objdir = f;
00365
00366 if (foldername.Length()>0) {
00367 objdir = dynamic_cast<TDirectory*> (f->Get(foldername));
00368 }
00369
00370 char namebuf[10000];
00371 Short_t cyclebuf;
00372 TDirectory::DecodeNameCycle(objname.Data(), namebuf, cyclebuf);
00373
00374
00375 if (objdir!=0) {
00376 objdir->cd();
00377 objdir->Delete(objname.Data());
00378 objdir->WriteTObject(obj, namebuf, "Overwrite");
00379 }
00380
00381 f->ReOpen("READ");
00382
00383 return kTRUE;
00384 }
00385
00386 Bool_t TGo4DirProxy::IsFile() const
00387 {
00388 return dynamic_cast<TFile*>(fDir)!=0;
00389 }
00390
00391 const char* TGo4DirProxy::GetFileName() const
00392 {
00393 return IsFile() ? fDir->GetName() : 0;
00394 }