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