Logo ROOT  
Reference Guide
TKeyXML.cxx
Go to the documentation of this file.
1// @(#)root/xml:$Id$
2// Author: Sergey Linev, Rene Brun 10.05.2004
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//________________________________________________________________________
13//
14// TKeyXML is represents one block of data in TXMLFile
15// Normally this block corresponds to data of single object like histogram,
16// TObjArray and so on.
17//________________________________________________________________________
18
19#include "TKeyXML.h"
20
21#include "TBufferXML.h"
22#include "TXMLFile.h"
23#include "TClass.h"
24#include "TROOT.h"
25
27
28////////////////////////////////////////////////////////////////////////////////
29/// Creates TKeyXML and convert object data to xml structures
30
31TKeyXML::TKeyXML(TDirectory *mother, Long64_t keyid, const TObject *obj, const char *name, const char *title)
32 : TKey(mother), fKeyNode(nullptr), fKeyId(keyid), fSubdir(kFALSE)
33{
34 if (name) {
36 } else if (obj) {
37 SetName(obj->GetName());
38 fClassName = obj->ClassName();
39 } else
40 SetName("Noname");
41
42 if (title)
43 SetTitle(title);
44
45 fCycle = GetMotherDir()->AppendKey(this);
46
47 TXMLEngine *xml = XMLEngine();
48 if (xml)
49 fKeyNode = xml->NewChild(nullptr, nullptr, xmlio::Xmlkey);
50
51 fDatime.Set();
52
53 StoreObject(obj, nullptr, kTRUE);
54}
55
56////////////////////////////////////////////////////////////////////////////////
57/// Creates TKeyXML and convert object data to xml structures
58
59TKeyXML::TKeyXML(TDirectory *mother, Long64_t keyid, const void *obj, const TClass *cl, const char *name,
60 const char *title)
61 : TKey(mother), fKeyNode(nullptr), fKeyId(keyid), fSubdir(kFALSE)
62{
63 if (name && *name)
65 else
66 SetName(cl ? cl->GetName() : "Noname");
67
68 if (title)
69 SetTitle(title);
70
71 fCycle = GetMotherDir()->AppendKey(this);
72
73 TXMLEngine *xml = XMLEngine();
74 if (xml)
75 fKeyNode = xml->NewChild(nullptr, nullptr, xmlio::Xmlkey);
76
77 fDatime.Set();
78
79 StoreObject(obj, cl, kFALSE);
80}
81
82////////////////////////////////////////////////////////////////////////////////
83/// Creates TKeyXML and takes ownership over xml node, from which object can be restored
84
86 : TKey(mother), fKeyNode(keynode), fKeyId(keyid), fSubdir(kFALSE)
87{
88 TXMLEngine *xml = XMLEngine();
89
90 SetName(xml->GetAttr(keynode, xmlio::Name));
91
92 if (xml->HasAttr(keynode, xmlio::Title))
93 SetTitle(xml->GetAttr(keynode, xmlio::Title));
94
95 fCycle = xml->GetIntAttr(keynode, xmlio::Cycle);
96
97 if (xml->HasAttr(keynode, xmlio::CreateTm)) {
98 TDatime tm(xml->GetAttr(keynode, xmlio::CreateTm));
99 fDatime = tm;
100 }
101
102 XMLNodePointer_t objnode = xml->GetChild(keynode);
103 xml->SkipEmpty(objnode);
104
105 fClassName = xml->GetAttr(objnode, xmlio::ObjClass);
106}
107
108////////////////////////////////////////////////////////////////////////////////
109/// TKeyXML destructor
110
112{
113 if (fKeyNode) {
114 TXMLEngine *xml = XMLEngine();
115 if (xml) {
116 xml->FreeNode(fKeyNode);
117 } else {
118 TXMLEngine xml_;
119 xml_.FreeNode(fKeyNode);
120 }
121 }
122}
123
124////////////////////////////////////////////////////////////////////////////////
125/// Delete key from current directory
126/// Note: TKeyXML object is not deleted. You still have to call "delete key"
127
128void TKeyXML::Delete(Option_t * /*option*/)
129{
130 TXMLEngine *xml = XMLEngine();
131 if (fKeyNode && xml) {
132 xml->FreeNode(fKeyNode);
133 fKeyNode = nullptr;
134 }
135
137}
138
139////////////////////////////////////////////////////////////////////////////////
140/// Stores keys attributes in key node
141
143{
144 TXMLEngine *xml = XMLEngine();
145 TXMLFile *f = (TXMLFile *)GetFile();
146 if (!f || !xml || !fKeyNode)
147 return;
148
149 xml->NewAttr(fKeyNode, nullptr, xmlio::Name, GetName());
150
152
153 if (f->GetIOVersion() > 1) {
154 if (strlen(GetTitle()) > 0)
155 xml->NewAttr(fKeyNode, nullptr, xmlio::Title, GetTitle());
156 if (f->TestBit(TFile::kReproducible))
158 else
160 }
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// convert object to xml structure and keep this structure in key
165
166void TKeyXML::StoreObject(const void *obj, const TClass *cl, Bool_t check_tobj)
167{
168 TXMLFile *f = (TXMLFile *)GetFile();
169 TXMLEngine *xml = XMLEngine();
170 if (!f || !xml || !fKeyNode)
171 return;
172
173 if (obj && check_tobj) {
174 TClass *actual = TObject::Class()->GetActualClass((TObject *)obj);
175 if (!actual) {
176 actual = TObject::Class();
177 } else if (actual != TObject::Class())
178 obj = (void *)((Longptr_t)obj - actual->GetBaseClassOffset(TObject::Class()));
179 cl = actual;
180 }
181
183
185 buffer.InitMap();
186 if (f->GetIOVersion() == 1)
188
189 XMLNodePointer_t node = buffer.XmlWriteAny(obj, cl);
190
191 if (node)
192 xml->AddChildFirst(fKeyNode, node);
193
194 buffer.XmlWriteBlock(fKeyNode);
195
196 if (cl)
197 fClassName = cl->GetName();
198}
199
200////////////////////////////////////////////////////////////////////////////////
201/// update key attributes in key node
202
204{
205 TXMLEngine *xml = XMLEngine();
206 if (!xml || !fKeyNode)
207 return;
208
209 xml->FreeAllAttr(fKeyNode);
210
212}
213
214////////////////////////////////////////////////////////////////////////////////
215/// updates object, stored in the node
216/// Used for TDirectory data update
217
219{
220 TXMLFile *f = (TXMLFile *)GetFile();
221 TXMLEngine *xml = XMLEngine();
222 if (!f || !xml || !obj || !fKeyNode)
223 return;
224
225 XMLNodePointer_t objnode = xml->GetChild(fKeyNode);
226 xml->SkipEmpty(objnode);
227
228 if (!objnode)
229 return;
230
231 xml->UnlinkNode(objnode);
232 xml->FreeNode(objnode);
233
234 xml->FreeAllAttr(fKeyNode);
235
236 StoreObject(obj, nullptr, kTRUE);
237}
238
239////////////////////////////////////////////////////////////////////////////////
240/// To read an object from the file.
241/// The object associated to this key is read from the file into memory.
242/// Before invoking this function, obj has been created via the
243/// default constructor.
244
246{
247 if (!tobj)
248 return 0;
249
250 void *res = XmlReadAny(tobj, nullptr);
251
252 return !res ? 0 : 1;
253}
254
255////////////////////////////////////////////////////////////////////////////////
256/// read object derived from TObject class, from key
257/// if it is not TObject or in case of error, return nullptr
258
260{
261 TObject *tobj = (TObject *)XmlReadAny(nullptr, TObject::Class());
262
263 if (tobj) {
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());
271 // set mother before reading keys
272 dir->SetMother(fMotherDir);
273 dir->ReadKeys();
274 fMotherDir->Append(dir);
275 fSubdir = kTRUE;
276 }
277 }
278
279 return tobj;
280}
281
282////////////////////////////////////////////////////////////////////////////////
283/// read object derived from TObject class, from key
284/// if it is not TObject or in case of error, return nullptr
285
286TObject *TKeyXML::ReadObjWithBuffer(char * /*bufferRead*/)
287{
288 TObject *tobj = (TObject *)XmlReadAny(nullptr, TObject::Class());
289
290 if (tobj) {
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());
298 // set mother before reading keys
299 dir->SetMother(fMotherDir);
300 dir->ReadKeys();
301 fMotherDir->Append(dir);
302 fSubdir = kTRUE;
303 }
304 }
305
306 return tobj;
307}
308
309////////////////////////////////////////////////////////////////////////////////
310/// read object of any type
311
312void *TKeyXML::ReadObjectAny(const TClass *expectedClass)
313{
314 void *res = XmlReadAny(nullptr, expectedClass);
315
316 if (res && (expectedClass == TDirectoryFile::Class())) {
317 TDirectoryFile *dir = (TDirectoryFile *)res;
318 dir->SetName(GetName());
319 dir->SetTitle(GetTitle());
320 dir->SetSeekDir(GetKeyId());
321 // set mother before reading keys
322 dir->SetMother(fMotherDir);
323 dir->ReadKeys();
324 fMotherDir->Append(dir);
325 fSubdir = kTRUE;
326 }
327
328 return res;
329}
330
331////////////////////////////////////////////////////////////////////////////////
332/// read object from key and cast to expected class
333
334void *TKeyXML::XmlReadAny(void *obj, const TClass *expectedClass)
335{
336 if (!fKeyNode)
337 return obj;
338
339 TXMLFile *f = (TXMLFile *)GetFile();
340 TXMLEngine *xml = XMLEngine();
341 if (!f || !xml)
342 return obj;
343
344 TBufferXML buffer(TBuffer::kRead, f);
345 buffer.InitMap();
346 if (f->GetIOVersion() == 1)
348
349 XMLNodePointer_t blocknode = xml->GetChild(fKeyNode);
350 xml->SkipEmpty(blocknode);
351 while (blocknode) {
352 if (strcmp(xml->GetNodeName(blocknode), xmlio::XmlBlock) == 0)
353 break;
354 xml->ShiftToNext(blocknode);
355 }
356 buffer.XmlReadBlock(blocknode);
357
358 XMLNodePointer_t objnode = xml->GetChild(fKeyNode);
359 xml->SkipEmpty(objnode);
360
361 TClass *cl = nullptr;
362 void *res = buffer.XmlReadAny(objnode, obj, &cl);
363
364 if (!cl || !res)
365 return obj;
366
367 Int_t delta = 0;
368
369 if (expectedClass) {
370 delta = cl->GetBaseClassOffset(expectedClass);
371 if (delta < 0) {
372 if (!obj)
373 cl->Destructor(res);
374 return nullptr;
375 }
376 if (cl->GetState() > TClass::kEmulated && expectedClass->GetState() <= TClass::kEmulated) {
377 // we cannot mix a compiled class with an emulated class in the inheritance
378 Warning("XmlReadAny", "Trying to read an emulated class (%s) to store in a compiled pointer (%s)",
379 cl->GetName(), expectedClass->GetName());
380 }
381 }
382
383 return ((char *)res) + delta;
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// return pointer on TXMLEngine object, used for xml conversion
388
390{
391 TXMLFile *f = (TXMLFile *)GetFile();
392 return f ? f->XML() : nullptr;
393}
int Int_t
Definition: CPyCppyy.h:43
unsigned int UInt_t
Definition: CPyCppyy.h:44
void Class()
Definition: Class.C:29
#define f(i)
Definition: RSha256.hxx:104
long Longptr_t
Definition: RtypesCore.h:82
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define ClassImp(name)
Definition: Rtypes.h:364
#define gROOT
Definition: TROOT.h:404
void * XMLNodePointer_t
Definition: TXMLEngine.h:17
void InitMap() override
Create the fMap container and initialize them with the null object.
Definition: TBufferIO.cxx:129
Class for serializing/deserializing object to/from xml.
Definition: TBufferXML.h:33
XMLNodePointer_t XmlWriteAny(const void *obj, const TClass *cl)
Convert object of any class to xml structures Return pointer on top xml element.
Definition: TBufferXML.cxx:228
void XmlReadBlock(XMLNodePointer_t node)
Read binary block of data from xml.
Definition: TBufferXML.cxx:451
void * XmlReadAny(XMLNodePointer_t node, void *obj, TClass **cl)
Recreate object from xml structure.
Definition: TBufferXML.cxx:245
void XmlWriteBlock(XMLNodePointer_t node)
Write binary data block from buffer to xml.
Definition: TBufferXML.cxx:390
@ kCannotHandleMemberWiseStreaming
Definition: TBuffer.h:76
@ kWrite
Definition: TBuffer.h:73
@ kRead
Definition: TBuffer.h:73
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
EState GetState() const
Definition: TClass.h:485
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition: TClass.cxx:5393
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition: TClass.cxx:2778
@ kEmulated
Definition: TClass.h:125
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:37
const char * AsSQLString() const
Return the date & time in SQL compatible string format, like: 1997-01-15 20:16:28.
Definition: TDatime.cxx:152
void Set()
Set Date/Time to current time as reported by the system.
Definition: TDatime.cxx:289
A ROOT file is structured in Directories (like a file system).
Int_t ReadKeys(Bool_t forceRead=kTRUE) override
Read the linked list of keys.
void SetSeekDir(Long64_t v) override
Describe directory structure in memory.
Definition: TDirectory.h:45
virtual Int_t AppendKey(TKey *)
Definition: TDirectory.h:176
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
Definition: TDirectory.cxx:191
virtual TList * GetListOfKeys() const
Definition: TDirectory.h:214
void SetName(const char *newname) override
Set the name for directory If the directory name is changed after the directory was written once,...
virtual void SetMother(TObject *mother)
Definition: TDirectory.h:248
@ kReproducible
Definition: TFile.h:189
void UpdateObject(TObject *obj)
updates object, stored in the node Used for TDirectory data update
Definition: TKeyXML.cxx:218
void Delete(Option_t *option="") final
Delete key from current directory Note: TKeyXML object is not deleted.
Definition: TKeyXML.cxx:128
Long64_t GetKeyId() const
Definition: TKeyXML.h:62
XMLNodePointer_t fKeyNode
Definition: TKeyXML.h:76
Int_t Read(TObject *tobj) final
To read an object from the file.
Definition: TKeyXML.cxx:245
TXMLEngine * XMLEngine()
return pointer on TXMLEngine object, used for xml conversion
Definition: TKeyXML.cxx:389
TObject * ReadObjWithBuffer(char *bufferRead) final
read object derived from TObject class, from key if it is not TObject or in case of error,...
Definition: TKeyXML.cxx:286
void * XmlReadAny(void *obj, const TClass *expectedClass)
read object from key and cast to expected class
Definition: TKeyXML.cxx:334
void * ReadObjectAny(const TClass *expectedClass) final
read object of any type
Definition: TKeyXML.cxx:312
virtual ~TKeyXML()
TKeyXML destructor.
Definition: TKeyXML.cxx:111
void StoreObject(const void *obj, const TClass *cl, Bool_t check_tobj=kFALSE)
convert object to xml structure and keep this structure in key
Definition: TKeyXML.cxx:166
void UpdateAttributes()
update key attributes in key node
Definition: TKeyXML.cxx:203
TKeyXML()
Definition: TKeyXML.h:27
void StoreKeyAttributes()
Stores keys attributes in key node.
Definition: TKeyXML.cxx:142
TObject * ReadObj() final
read object derived from TObject class, from key if it is not TObject or in case of error,...
Definition: TKeyXML.cxx:259
Bool_t fSubdir
unique identifier of key for search methods
Definition: TKeyXML.h:78
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:28
TFile * GetFile() const
Returns file to which key belong.
Definition: TKey.cxx:585
TDatime fDatime
Date/Time of insertion in file.
Definition: TKey.h:42
TDirectory * GetMotherDir() const
Definition: TKey.h:86
virtual const char * GetTitle() const
Returns title (title can contain 32x32 xpm thumbnail/icon).
Definition: TKey.cxx:1532
Short_t fCycle
Cycle number.
Definition: TKey.h:44
TDirectory * fMotherDir
!pointer to mother directory
Definition: TKey.h:52
TString fClassName
Object Class name.
Definition: TKey.h:47
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:822
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition: TObject.cxx:717
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:879
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
XMLNodePointer_t NewChild(XMLNodePointer_t parent, XMLNsPointer_t ns, const char *name, const char *content=nullptr)
create new child element for parent node
Definition: TXMLEngine.cxx:715
XMLNodePointer_t GetChild(XMLNodePointer_t xmlnode, Bool_t realnode=kTRUE)
returns first child of xmlnode
XMLAttrPointer_t NewAttr(XMLNodePointer_t xmlnode, XMLNsPointer_t, const char *name, const char *value)
creates new attribute for xmlnode, namespaces are not supported for attributes
Definition: TXMLEngine.cxx:586
void UnlinkNode(XMLNodePointer_t node)
unlink (detach) xmlnode from parent
XMLAttrPointer_t NewIntAttr(XMLNodePointer_t xmlnode, const char *name, Int_t value)
create node attribute with integer value
Definition: TXMLEngine.cxx:612
Bool_t HasAttr(XMLNodePointer_t xmlnode, const char *name)
checks if node has attribute of specified name
Definition: TXMLEngine.cxx:539
const char * GetNodeName(XMLNodePointer_t xmlnode)
returns name of xmlnode
const char * GetAttr(XMLNodePointer_t xmlnode, const char *name)
returns value of attribute for xmlnode
Definition: TXMLEngine.cxx:555
Int_t GetIntAttr(XMLNodePointer_t node, const char *name)
returns value of attribute as integer
Definition: TXMLEngine.cxx:571
void FreeAllAttr(XMLNodePointer_t xmlnode)
Free all attributes of the node.
Definition: TXMLEngine.cxx:647
void FreeNode(XMLNodePointer_t xmlnode)
release all memory, allocated from this node and destroys node itself
void SkipEmpty(XMLNodePointer_t &xmlnode)
Skip all current empty nodes and locate on first "true" node.
void ShiftToNext(XMLNodePointer_t &xmlnode, Bool_t realnode=kTRUE)
shifts specified node to next if realnode==kTRUE, any special nodes in between will be skipped
void AddChildFirst(XMLNodePointer_t parent, XMLNodePointer_t child)
add node as first child
Definition: TXMLEngine.cxx:824
long long Long64_t
Definition: cpp_cppyy.h:13
static const std::string name("name")
const char * Name
Definition: TXMLSetup.cxx:67
const char * Title
Definition: TXMLSetup.cxx:68
const char * XmlBlock
Definition: TXMLSetup.cxx:60
const char * Cycle
Definition: TXMLSetup.cxx:59
const char * CreateTm
Definition: TXMLSetup.cxx:69
const char * ObjClass
Definition: TXMLSetup.cxx:63
const char * Xmlkey
Definition: TXMLSetup.cxx:58