00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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
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
00129 TXMLEngine* xml = XMLEngine();
00130 if (fKeyNode && xml)
00131 xml->FreeNode(fKeyNode);
00132 }
00133
00134
00135 void TKeyXML::Delete(Option_t * )
00136 {
00137
00138
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
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
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
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
00211
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
00234
00235
00236
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
00249
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
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 * )
00273 {
00274
00275
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
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
00301
00302 return XmlReadAny(0, expectedClass);
00303 }
00304
00305
00306 void* TKeyXML::XmlReadAny(void* obj, const TClass* expectedClass)
00307 {
00308
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
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
00359
00360 TXMLFile* f = (TXMLFile*) GetFile();
00361 return f==0 ? 0 : f->XML();
00362 }