31 TKeyXML::TKeyXML(TDirectory *mother, Long64_t keyid,
const TObject *obj,
const char *name,
const char *title)
32 : TKey(mother), fKeyNode(nullptr), fKeyId(keyid), fSubdir(kFALSE)
37 SetName(obj->GetName());
38 fClassName = obj->ClassName();
45 fCycle = GetMotherDir()->AppendKey(
this);
47 TXMLEngine *xml = XMLEngine();
49 fKeyNode = xml->NewChild(
nullptr,
nullptr, xmlio::Xmlkey);
53 StoreObject(obj,
nullptr, kTRUE);
59 TKeyXML::TKeyXML(TDirectory *mother, Long64_t keyid,
const void *obj,
const TClass *cl,
const char *name,
61 : TKey(mother), fKeyNode(nullptr), fKeyId(keyid), fSubdir(kFALSE)
66 SetName(cl ? cl->GetName() :
"Noname");
71 fCycle = GetMotherDir()->AppendKey(
this);
73 TXMLEngine *xml = XMLEngine();
75 fKeyNode = xml->NewChild(
nullptr,
nullptr, xmlio::Xmlkey);
79 StoreObject(obj, cl, kFALSE);
85 TKeyXML::TKeyXML(TDirectory *mother, Long64_t keyid, XMLNodePointer_t keynode)
86 : TKey(mother), fKeyNode(keynode), fKeyId(keyid), fSubdir(kFALSE)
88 TXMLEngine *xml = XMLEngine();
90 SetName(xml->GetAttr(keynode, xmlio::Name));
92 if (xml->HasAttr(keynode, xmlio::Title))
93 SetTitle(xml->GetAttr(keynode, xmlio::Title));
95 fCycle = xml->GetIntAttr(keynode, xmlio::Cycle);
97 if (xml->HasAttr(keynode, xmlio::CreateTm)) {
98 TDatime tm(xml->GetAttr(keynode, xmlio::CreateTm));
102 XMLNodePointer_t objnode = xml->GetChild(keynode);
103 xml->SkipEmpty(objnode);
105 fClassName = xml->GetAttr(objnode, xmlio::ObjClass);
114 TXMLEngine *xml = XMLEngine();
116 xml->FreeNode(fKeyNode);
119 xml_.FreeNode(fKeyNode);
128 void TKeyXML::Delete(Option_t * )
130 TXMLEngine *xml = XMLEngine();
131 if (fKeyNode && xml) {
132 xml->FreeNode(fKeyNode);
136 fMotherDir->GetListOfKeys()->Remove(
this);
142 void TKeyXML::StoreKeyAttributes()
144 TXMLEngine *xml = XMLEngine();
145 TXMLFile *f = (TXMLFile *)GetFile();
146 if (!f || !xml || !fKeyNode)
149 xml->NewAttr(fKeyNode,
nullptr, xmlio::Name, GetName());
151 xml->NewIntAttr(fKeyNode, xmlio::Cycle, fCycle);
153 if (f->GetIOVersion() > 1) {
154 if (strlen(GetTitle()) > 0)
155 xml->NewAttr(fKeyNode,
nullptr, xmlio::Title, GetTitle());
156 if (f->TestBit(TFile::kReproducible))
157 xml->NewAttr(fKeyNode,
nullptr, xmlio::CreateTm, TDatime((UInt_t) 1).AsSQLString());
159 xml->NewAttr(fKeyNode,
nullptr, xmlio::CreateTm, fDatime.AsSQLString());
166 void TKeyXML::StoreObject(
const void *obj,
const TClass *cl, Bool_t check_tobj)
168 TXMLFile *f = (TXMLFile *)GetFile();
169 TXMLEngine *xml = XMLEngine();
170 if (!f || !xml || !fKeyNode)
173 if (obj && check_tobj) {
174 TClass *actual = TObject::Class()->GetActualClass((TObject *)obj);
176 actual = TObject::Class();
177 }
else if (actual != TObject::Class())
178 obj = (
void *)((Long_t)obj - actual->GetBaseClassOffset(TObject::Class()));
182 StoreKeyAttributes();
184 TBufferXML buffer(TBuffer::kWrite, f);
186 if (f->GetIOVersion() == 1)
187 buffer.SetBit(TBuffer::kCannotHandleMemberWiseStreaming, kFALSE);
189 XMLNodePointer_t node = buffer.XmlWriteAny(obj, cl);
192 xml->AddChildFirst(fKeyNode, node);
194 buffer.XmlWriteBlock(fKeyNode);
197 fClassName = cl->GetName();
203 void TKeyXML::UpdateAttributes()
205 TXMLEngine *xml = XMLEngine();
206 if (!xml || !fKeyNode)
209 xml->FreeAllAttr(fKeyNode);
211 StoreKeyAttributes();
218 void TKeyXML::UpdateObject(TObject *obj)
220 TXMLFile *f = (TXMLFile *)GetFile();
221 TXMLEngine *xml = XMLEngine();
222 if (!f || !xml || !obj || !fKeyNode)
225 XMLNodePointer_t objnode = xml->GetChild(fKeyNode);
226 xml->SkipEmpty(objnode);
231 xml->UnlinkNode(objnode);
232 xml->FreeNode(objnode);
234 xml->FreeAllAttr(fKeyNode);
236 StoreObject(obj,
nullptr, kTRUE);
245 Int_t TKeyXML::Read(TObject *tobj)
250 void *res = XmlReadAny(tobj,
nullptr);
259 TObject *TKeyXML::ReadObj()
261 TObject *tobj = (TObject *)XmlReadAny(
nullptr, TObject::Class());
264 if (gROOT->GetForceStyle())
265 tobj->UseCurrentStyle();
266 if (tobj->IsA() == TDirectoryFile::Class()) {
267 TDirectoryFile *dir = (TDirectoryFile *)tobj;
268 dir->SetName(GetName());
269 dir->SetTitle(GetTitle());
270 dir->SetSeekDir(GetKeyId());
272 dir->SetMother(fMotherDir);
274 fMotherDir->Append(dir);
286 TObject *TKeyXML::ReadObjWithBuffer(
char * )
288 TObject *tobj = (TObject *)XmlReadAny(
nullptr, TObject::Class());
291 if (gROOT->GetForceStyle())
292 tobj->UseCurrentStyle();
293 if (tobj->IsA() == TDirectoryFile::Class()) {
294 TDirectoryFile *dir = (TDirectoryFile *)tobj;
295 dir->SetName(GetName());
296 dir->SetTitle(GetTitle());
297 dir->SetSeekDir(GetKeyId());
299 dir->SetMother(fMotherDir);
301 fMotherDir->Append(dir);
312 void *TKeyXML::ReadObjectAny(
const TClass *expectedClass)
314 void *res = XmlReadAny(
nullptr, expectedClass);
316 if (res && (expectedClass == TDirectoryFile::Class())) {
317 TDirectoryFile *dir = (TDirectoryFile *)res;
318 dir->SetName(GetName());
319 dir->SetTitle(GetTitle());
320 dir->SetSeekDir(GetKeyId());
322 dir->SetMother(fMotherDir);
324 fMotherDir->Append(dir);
334 void *TKeyXML::XmlReadAny(
void *obj,
const TClass *expectedClass)
339 TXMLFile *f = (TXMLFile *)GetFile();
340 TXMLEngine *xml = XMLEngine();
344 TBufferXML buffer(TBuffer::kRead, f);
346 if (f->GetIOVersion() == 1)
347 buffer.SetBit(TBuffer::kCannotHandleMemberWiseStreaming, kFALSE);
349 XMLNodePointer_t blocknode = xml->GetChild(fKeyNode);
350 xml->SkipEmpty(blocknode);
352 if (strcmp(xml->GetNodeName(blocknode), xmlio::XmlBlock) == 0)
354 xml->ShiftToNext(blocknode);
356 buffer.XmlReadBlock(blocknode);
358 XMLNodePointer_t objnode = xml->GetChild(fKeyNode);
359 xml->SkipEmpty(objnode);
361 TClass *cl =
nullptr;
362 void *res = buffer.XmlReadAny(objnode, obj, &cl);
370 delta = cl->GetBaseClassOffset(expectedClass);
376 if (cl->GetState() > TClass::kEmulated && expectedClass->GetState() <= TClass::kEmulated) {
378 Warning(
"XmlReadAny",
"Trying to read an emulated class (%s) to store in a compiled pointer (%s)",
379 cl->GetName(), expectedClass->GetName());
383 return ((
char *)res) + delta;
389 TXMLEngine *TKeyXML::XMLEngine()
391 TXMLFile *f = (TXMLFile *)GetFile();
392 return f ? f->XML() :
nullptr;