TKeyXML.cxx

Go to the documentation of this file.
00001 // @(#)root/xml:$Id: TKeyXML.cxx 24037 2008-05-28 06:32:07Z brun $
00002 // Author: Sergey Linev, Rene Brun  10.05.2004
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //________________________________________________________________________
00013 //
00014 // TKeyXML is represents one block of data in TXMLFile
00015 // Normally this block corresponds to data of single object like histogram,
00016 // TObjArray and so on.
00017 //________________________________________________________________________
00018 
00019 
00020 #include "TKeyXML.h"
00021 
00022 #include "TBufferXML.h"
00023 #include "TXMLFile.h"
00024 #include "TClass.h"
00025 #include "TROOT.h"
00026 #include "TBrowser.h"
00027 
00028 ClassImp(TKeyXML);
00029 
00030 //______________________________________________________________________________
00031 TKeyXML::TKeyXML() :
00032    TKey(),
00033    fKeyNode(0),
00034    fKeyId(0),
00035    fSubdir(kFALSE)
00036 {
00037    // default constructor
00038 }
00039 
00040 //______________________________________________________________________________
00041 TKeyXML::TKeyXML(TDirectory* mother, Long64_t keyid, const TObject* obj, const char* name, const char* title) :
00042     TKey(mother),
00043     fKeyNode(0),
00044     fKeyId(keyid),
00045     fSubdir(kFALSE)
00046 {
00047    // Creates TKeyXML and convert obj data to xml structures
00048 
00049    if (name)
00050       SetName(name);
00051    else
00052       if (obj!=0) {
00053          SetName(obj->GetName());
00054          fClassName=obj->ClassName();
00055       } else
00056          SetName("Noname");
00057 
00058    if (title) SetTitle(title);
00059 
00060    fCycle  = GetMotherDir()->AppendKey(this);
00061 
00062    TXMLEngine* xml = XMLEngine();
00063    if (xml!=0)
00064       fKeyNode = xml->NewChild(0, 0, xmlio::Xmlkey, 0);
00065 
00066    fDatime.Set();
00067 
00068    StoreObject((void*)obj, obj ? obj->IsA() : 0);
00069 }
00070 
00071 //______________________________________________________________________________
00072 TKeyXML::TKeyXML(TDirectory* mother, Long64_t keyid, const void* obj, const TClass* cl, const char* name, const char* title) :
00073    TKey(mother),
00074    fKeyNode(0),
00075    fKeyId(keyid),
00076    fSubdir(kFALSE)
00077 {
00078    // Creates TKeyXML and convert obj data to xml structures
00079 
00080    if (name && *name) SetName(name);
00081    else SetName(cl ? cl->GetName() : "Noname");
00082 
00083    if (title) SetTitle(title);
00084 
00085    fCycle  = GetMotherDir()->AppendKey(this);
00086 
00087    TXMLEngine* xml = XMLEngine();
00088    if (xml!=0)
00089       fKeyNode = xml->NewChild(0, 0, xmlio::Xmlkey, 0);
00090 
00091    fDatime.Set();
00092 
00093    StoreObject(obj, cl);
00094 }
00095 
00096 //______________________________________________________________________________
00097 TKeyXML::TKeyXML(TDirectory* mother, Long64_t keyid, XMLNodePointer_t keynode) :
00098    TKey(mother),
00099    fKeyNode(keynode),
00100    fKeyId(keyid),
00101    fSubdir(kFALSE)
00102 {
00103    // Creates TKeyXML and takes ownership over xml node, from which object can be restored
00104 
00105    TXMLEngine* xml = XMLEngine();
00106 
00107    SetName(xml->GetAttr(keynode, xmlio::Name));
00108    
00109    if (xml->HasAttr(keynode, xmlio::Title))
00110       SetTitle(xml->GetAttr(keynode, xmlio::Title));
00111 
00112    fCycle = xml->GetIntAttr(keynode, xmlio::Cycle);
00113       
00114    if (xml->HasAttr(keynode, xmlio::CreateTm)) {
00115       TDatime tm(xml->GetAttr(keynode, xmlio::CreateTm)); 
00116       fDatime = tm;
00117    }
00118 
00119    XMLNodePointer_t objnode = xml->GetChild(keynode);
00120    xml->SkipEmpty(objnode);
00121 
00122    fClassName = xml->GetAttr(objnode, xmlio::ObjClass);
00123 }
00124 
00125 //______________________________________________________________________________
00126 TKeyXML::~TKeyXML()
00127 {
00128    // TKeyXML destructor
00129    TXMLEngine* xml = XMLEngine();
00130    if (fKeyNode && xml)
00131       xml->FreeNode(fKeyNode);
00132 }
00133 
00134 //______________________________________________________________________________
00135 void TKeyXML::Delete(Option_t * /*option*/)
00136 {
00137    // Delete key from current directory
00138    // Note: TKeyXML object is not deleted. You still have to call "delete key"
00139 
00140    TXMLEngine* xml = XMLEngine();
00141    if (fKeyNode && xml) {
00142       xml->FreeNode(fKeyNode);
00143       fKeyNode = 0;
00144    }
00145 
00146    fMotherDir->GetListOfKeys()->Remove(this);
00147 }
00148 
00149 //______________________________________________________________________________
00150 void TKeyXML::StoreKeyAttributes()
00151 {
00152    // Stores keys attributes in key node
00153    
00154    TXMLEngine* xml = XMLEngine();
00155    TXMLFile* f = (TXMLFile*) GetFile();
00156    if ((f==0) || (xml==0) || (fKeyNode==0)) return;
00157 
00158    xml->NewAttr(fKeyNode, 0, xmlio::Name, GetName());
00159    
00160    xml->NewIntAttr(fKeyNode, xmlio::Cycle, fCycle);
00161    
00162    if (f->GetIOVersion()>1) {
00163       if (strlen(GetTitle())>0)
00164          xml->NewAttr(fKeyNode, 0, xmlio::Title, GetTitle());
00165       xml->NewAttr(fKeyNode, 0, xmlio::CreateTm, fDatime.AsSQLString());
00166    }
00167 }
00168 
00169 //______________________________________________________________________________
00170 void TKeyXML::StoreObject(const void* obj, const TClass* cl)
00171 {
00172    //  convert object to xml structure and keep this structure in key
00173    
00174    TXMLFile* f = (TXMLFile*) GetFile();
00175    TXMLEngine* xml = XMLEngine();
00176    if ((f==0) || (xml==0) || (fKeyNode==0)) return;
00177 
00178    StoreKeyAttributes();
00179 
00180    TBufferXML buffer(TBuffer::kWrite, f);
00181    if (f->GetIOVersion()==1)
00182       buffer.SetBit(TBuffer::kCannotHandleMemberWiseStreaming, kFALSE);
00183    
00184    XMLNodePointer_t node = buffer.XmlWriteAny(obj, cl);
00185 
00186    if (node!=0)
00187       xml->AddChildFirst(fKeyNode, node);
00188       
00189    buffer.XmlWriteBlock(fKeyNode);
00190 
00191    if (cl) fClassName = cl->GetName();
00192 }
00193 
00194 //______________________________________________________________________________
00195 void TKeyXML::UpdateAttributes()
00196 {
00197    // update key attributes in key node
00198    
00199    TXMLEngine* xml = XMLEngine();
00200    if ((xml==0) || (fKeyNode==0)) return;
00201 
00202    xml->FreeAllAttr(fKeyNode);
00203    
00204    StoreKeyAttributes();
00205 }
00206 
00207 //______________________________________________________________________________
00208 void TKeyXML::UpdateObject(TObject* obj)
00209 {
00210    // updates object, stored in the node
00211    // Used for TDirectory data update
00212 
00213    TXMLFile* f = (TXMLFile*) GetFile();
00214    TXMLEngine* xml = XMLEngine();
00215    if ((f==0) || (xml==0) || (obj==0) || (fKeyNode==0)) return;
00216    
00217    XMLNodePointer_t objnode = xml->GetChild(fKeyNode);
00218    xml->SkipEmpty(objnode);
00219 
00220    if (objnode==0) return;
00221 
00222    xml->UnlinkNode(objnode);
00223    xml->FreeNode(objnode);
00224    
00225    xml->FreeAllAttr(fKeyNode);
00226    
00227    StoreObject(obj, obj->IsA());
00228 }
00229 
00230 //______________________________________________________________________________
00231 Int_t TKeyXML::Read(TObject* tobj)
00232 {
00233    // To read an object from the file.
00234    // The object associated to this key is read from the file into memory.
00235    // Before invoking this function, obj has been created via the
00236    // default constructor.
00237 
00238    if (tobj==0) return 0; 
00239     
00240    void* res = XmlReadAny(tobj, 0);
00241    
00242    return res==0 ? 0 : 1;
00243 }
00244 
00245 //______________________________________________________________________________
00246 TObject* TKeyXML::ReadObj()
00247 {
00248    // read object derived from TObject class, from key
00249    // if it is not TObject or in case of error, return 0
00250 
00251    TObject* tobj = (TObject*) XmlReadAny(0, TObject::Class());
00252    
00253    if (tobj!=0) {
00254       if (gROOT->GetForceStyle()) tobj->UseCurrentStyle(); 
00255       if (tobj->IsA() == TDirectoryFile::Class()) {
00256          TDirectoryFile *dir = (TDirectoryFile*) tobj;
00257          dir->SetName(GetName());
00258          dir->SetTitle(GetTitle());
00259          dir->SetSeekDir(GetKeyId());
00260          // set mother before reading keys
00261          dir->SetMother(fMotherDir);
00262          dir->ReadKeys();
00263          fMotherDir->Append(dir);
00264          fSubdir = kTRUE;
00265       }
00266    }
00267        
00268    return tobj;
00269 }
00270 
00271 //______________________________________________________________________________
00272 TObject* TKeyXML::ReadObjWithBuffer(char * /*bufferRead*/)
00273 {
00274    // read object derived from TObject class, from key
00275    // if it is not TObject or in case of error, return 0
00276 
00277    TObject* tobj = (TObject*) XmlReadAny(0, TObject::Class());
00278    
00279    if (tobj!=0) {
00280       if (gROOT->GetForceStyle()) tobj->UseCurrentStyle(); 
00281       if (tobj->IsA() == TDirectoryFile::Class()) {
00282          TDirectoryFile *dir = (TDirectoryFile*) tobj;
00283          dir->SetName(GetName());
00284          dir->SetTitle(GetTitle());
00285          dir->SetSeekDir(GetKeyId());
00286          // set mother before reading keys
00287          dir->SetMother(fMotherDir);
00288          dir->ReadKeys();
00289          fMotherDir->Append(dir);
00290          fSubdir = kTRUE;
00291       }
00292    }
00293        
00294    return tobj;
00295 }
00296 
00297 //______________________________________________________________________________
00298 void* TKeyXML::ReadObjectAny(const TClass *expectedClass)
00299 {
00300    // read object of any type
00301    
00302    return XmlReadAny(0, expectedClass);
00303 }
00304 
00305 //______________________________________________________________________________
00306 void* TKeyXML::XmlReadAny(void* obj, const TClass* expectedClass)
00307 {
00308    // read object from key and cast to expected class
00309 
00310    if (fKeyNode==0) return obj;
00311    
00312    TXMLFile* f = (TXMLFile*) GetFile();
00313    TXMLEngine* xml = XMLEngine();
00314    if ((f==0) || (xml==0)) return obj;
00315    
00316    TBufferXML buffer(TBuffer::kRead, f);
00317    if (f->GetIOVersion()==1)
00318       buffer.SetBit(TBuffer::kCannotHandleMemberWiseStreaming, kFALSE);
00319 
00320    XMLNodePointer_t blocknode = xml->GetChild(fKeyNode);
00321    xml->SkipEmpty(blocknode);
00322    while (blocknode!=0) {
00323       if (strcmp(xml->GetNodeName(blocknode), xmlio::XmlBlock)==0) break;
00324       xml->ShiftToNext(blocknode);
00325    }
00326    buffer.XmlReadBlock(blocknode);
00327 
00328    XMLNodePointer_t objnode = xml->GetChild(fKeyNode);
00329    xml->SkipEmpty(objnode);
00330 
00331    TClass* cl = 0;
00332    void* res = buffer.XmlReadAny(objnode, obj, &cl);
00333    
00334    if ((cl==0) || (res==0)) return obj;
00335    
00336    Int_t delta = 0;
00337    
00338    if (expectedClass!=0) {
00339       delta = cl->GetBaseClassOffset(expectedClass);
00340       if (delta<0) {
00341          if (obj==0) cl->Destructor(res);
00342          return 0;
00343       }
00344       if (cl->GetClassInfo() && !expectedClass->GetClassInfo()) {
00345          //we cannot mix a compiled class with an emulated class in the inheritance
00346          Warning("XmlReadAny",
00347                  "Trying to read an emulated class (%s) to store in a compiled pointer (%s)",
00348                  cl->GetName(),expectedClass->GetName());
00349       }
00350    }
00351    
00352    return ((char*)res) + delta;
00353 }
00354 
00355 //______________________________________________________________________________
00356 TXMLEngine* TKeyXML::XMLEngine()
00357 {
00358    // return pointer on TXMLEngine object, used for xml conversion 
00359     
00360    TXMLFile* f = (TXMLFile*) GetFile();
00361    return f==0 ? 0 : f->XML();
00362 }

Generated on Tue Jul 5 14:30:37 2011 for ROOT_528-00b_version by  doxygen 1.5.1