From 9a0279cf6faf8a085381316e4688b446871ac5cb Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Mon, 10 May 2004 21:29:26 +0000 Subject: [PATCH] Introduce new package xml. Originally proposed by Hans Essel from GSI. Main implementation by Sergey Linev from GSI. Adaptation to ROOT framework by Rene Brun. "xml" is an optional package that can be used to write file.xml instead of file.root. XML files do not have any advantages compared to the normal ROOT files, except that the information in these files can be edited via a normal editor. The main motivation for this new format is to facilitate the communication with other non ROOT applications. Currently writing and reading XML files is limited to ROOT applications. It is our intention to develop a simple reader independent of the ROOT libraries that could be used as an example for real applications. The XML format should be used only for small data volumes, typically histogram files, pictures, geometries, calibrations. The XML file is built in memory before being dumped to disk. Like for normal ROOT files, XML files use the same I/O mechanism exploiting the ROOT/CINT dictionary. Any class having a dictionary can be saved in XML format. This first implementation does not support subdirectories or Trees. The shared library libRXML.so may be loaded dynamically via gSystem->Load("libRXML"). This library is automatically loaded by the plugin manager as soon as a XML file is created via, eg TFile::Open("file.xml","recreate"); TFile::Open returns a TXMLFile object. When a XML file is open in write mode, one can use the normal TObject::Write to write an object in the file. Alternatively one can use the new functions TDirectory::WriteObject and TDirectory::WriteObjectAny to write a TObject* or any class not deriving from TObject. example of a session saving a histogram to a XML file ===================================================== TFile *f = TFile::Open("Example.xml","recreate"); TH1F *h = new TH1F("h","test",1000,-2,2); h->FillRandom("gaus"); h->Write(); delete f; example of a session reading the histogram from the file ======================================================== TFile *f = TFile::Open("Example.xml"); TH1F *h = (TH1F*)f->Get("h"); h->Draw(); A new option in the canvas "File" menu is available to save a TCanvas as a XML file. One can also do canvas->Print("Example.xml"); Configuring ROOT with the option "xml" ====================================== The XML package uses the public XML parser and toolkit from Gnome. You should download the latest version 2-6.9 from http://www.xmlsoft.org/downloads.html. On Unix systems dowload "libxml2-2.6.9.tar.gz" and create XMLDIR pointing to the directory libxml2-2.6.9. in the XMLDIR directory, run the normal ./configure make On Windows, from the same web site download libxml2-2.6.9.win32.zip iconv-1.9.1.win32.zip unzip the two files, then copy the file iconv.h from the iconv/include file to $XMLDIR/include. Also copy iconv.dll, iconv.lib and iconv_a.lib from the iconv/lib directory to $XMLDIR/lib. You are now ready to configure ROOT with the XML option. do: ./configure -enable-xml -enable-xxxxx, etc documentation ============= The "xml" package is currently under development. A more complete documentation will be provided shortly in the classes reference guide. See classes TXMLFile, TXMLKey, TXMLBuffer, TXMLEngine, TXMLSetup and TXMLDtdGenerator. An example of XML file corresponding to the small example below can be found at http://root.cern.ch/root/Example.xml. git-svn-id: http://root.cern.ch/svn/root/trunk@8860 27541ba8-7e3a-0410-8455-c3a389f83636 --- Makefile | 2 +- config/Makefile.in | 4 + configure | 45 + xml/Module.mk | 74 ++ xml/inc/LinkDef.h | 24 + xml/inc/TXMLBuffer.h | 295 ++++++ xml/inc/TXMLDtdGenerator.h | 77 ++ xml/inc/TXMLEngine.h | 96 ++ xml/inc/TXMLFile.h | 125 +++ xml/inc/TXMLKey.h | 76 ++ xml/inc/TXMLSetup.h | 121 +++ xml/src/TXMLBuffer.cxx | 1939 ++++++++++++++++++++++++++++++++++ xml/src/TXMLDtdGenerator.cxx | 602 +++++++++++ xml/src/TXMLEngine.cxx | 229 ++++ xml/src/TXMLFile.cxx | 669 ++++++++++++ xml/src/TXMLKey.cxx | 162 +++ xml/src/TXMLSetup.cxx | 183 ++++ 17 files changed, 4722 insertions(+), 1 deletion(-) create mode 100644 xml/Module.mk create mode 100644 xml/inc/LinkDef.h create mode 100644 xml/inc/TXMLBuffer.h create mode 100644 xml/inc/TXMLDtdGenerator.h create mode 100644 xml/inc/TXMLEngine.h create mode 100644 xml/inc/TXMLFile.h create mode 100644 xml/inc/TXMLKey.h create mode 100644 xml/inc/TXMLSetup.h create mode 100644 xml/src/TXMLBuffer.cxx create mode 100644 xml/src/TXMLDtdGenerator.cxx create mode 100644 xml/src/TXMLEngine.cxx create mode 100644 xml/src/TXMLFile.cxx create mode 100644 xml/src/TXMLKey.cxx create mode 100644 xml/src/TXMLSetup.cxx diff --git a/Makefile b/Makefile index d3f2965956e..b72318910b6 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ endif MODULES = build cint metautils utils base cont meta net zip clib matrix \ newdelete hist tree freetype graf g3d gpad gui minuit \ histpainter treeplayer treeviewer proof physics postscript \ - rint html eg geom geompainter vmc fumili mlp gedold ged + rint html eg geom geompainter vmc fumili mlp gedold ged xml ifeq ($(ARCH),win32) MODULES += winnt win32 gl diff --git a/config/Makefile.in b/config/Makefile.in index 748e5b9ef9c..56eadea72ea 100644 --- a/config/Makefile.in +++ b/config/Makefile.in @@ -113,6 +113,10 @@ PYTHONLIB := @pythonlib@ PYTHONINCDIR := @pythonincdir@ PYTHONLIBFLAGS := @pythonlibflags@ +XMLLIBDIR := @xmllibdir@ +XMLLIB := @xmllib@ +XMLINCDIR := @xmlincdir@ + SRPLIBDIR := @srplibdir@ SRPLIB := @srplib@ SRPINCDIR := @srpincdir@ diff --git a/configure b/configure index f61a1fbf60b..eaa2af99a85 100755 --- a/configure +++ b/configure @@ -51,6 +51,7 @@ options=" \ enable_table \ enable_thread \ enable_venus \ + enable_xml \ " # @@ -83,6 +84,7 @@ RFIO \ CERNLIB \ PYTHIA \ PYTHIA6 \ +PYTHONDIR \ VENUS \ DCACHE \ CHIRP \ @@ -93,6 +95,7 @@ GLOBUS_LOCATION \ SRP \ AFS \ TABLE \ +XMLDIR \ " configenvvars= for c in $envvars ; do @@ -572,6 +575,7 @@ enable/disable options, prefix with either --enable- or --disable- table Build libTable contrib library thread Thread support (currently only POSIX threads) venus Venus EG support, requires libVenus + xml XML I/O interface with options, prefix with --with-, enables corresponding support @@ -735,6 +739,8 @@ if test $# -gt 0 ; then --with-sys-iconpath=*) extraiconpath=$optarg ;; --with-thread-libdir=*) threadlibdir=$optarg ; enable_thread="yes" ;; --with-venus-libdir=*) venuslibdir=$optarg ; enable_venus="yes" ;; + --with-xml-incdir=*) xmlincdir=$optarg ; enable_xml="yes" ;; + --with-xml-libdir=*) xmllibdir=$optarg ; enable_xml="yes" ;; --with-x11-libdir=*) x11libdir=$optarg ;; --with-xpm-libdir=*) xpmlibdir=$optarg ;; ################################################################ @@ -1540,6 +1546,42 @@ if test ! "x$enable_python" = "xno" ; then fi fi +###################################################################### +# +### echo %%% xml - the XML I/O interface +# +# (See http://www.xmlsoft.org) +# +# If the user has set the flags "--disable-xml", we don't check for +# XML at all. +# +if test ! "x$enable_xml" = "xno" ; then + # Check for xml include and library + if test "x$platform" = "xwin32"; then + check_header "libxml/tree.h" "$xmlincdir" $XMLDIR/include + xmlincdir=$found_dir + + check_library "libxml2_a" "$enable_shared" "$xmllibdir" $XMLDIR/lib + xmllib=$found_lib + xmllibdir=$found_dir + xmllibextra=" lib/iconv_a.lib Ws2_32.lib" + else + check_header "libxml/tree.h" "$xmlincdir" $XMLDIR $XMLDIR/include \ + /opt/libxml2/include /usr/local/include/libxml2 /usr/include/libxml2 + xmlincdir=$found_dir + + check_library "libxml2" "$enable_shared" "$xmllibdir" $XMLDIR $XMLDIR/lib \ + $XMLDIR/.libs /opt/libxml2/lib /usr/local/lib /usr/lib + xmllib=$found_lib + xmllibdir=$found_dir + xmllibextra=" -lxml2" + fi + + if test "x$xmlincdir" = "x" || test "x$xmllib" = "x"; then + enable_xml="no" + fi +fi + ###################################################################### # ### echo %%% Globus Support - Third party libraries @@ -2475,6 +2517,9 @@ sed -e "s|@ldflags@||" \ -e "s|@tutdir@|$tutdir|" \ -e "s|@venuslib@|$venuslib|" \ -e "s|@venuslibdir@|$venuslibdir|" \ + -e "s|@xmlincdir@|$xmlincdir|" \ + -e "s|@xmllib@|$xmllib|" \ + -e "s|@xmllibdir@|$xmllibdir|" \ -e "s|@x11libdir@|$x11libdir|" \ -e "s|@xpmlib@|$xpmlib|" \ -e "s|@xpmlibdir@|$xpmlibdir|" \ diff --git a/xml/Module.mk b/xml/Module.mk new file mode 100644 index 00000000000..60ec4905f33 --- /dev/null +++ b/xml/Module.mk @@ -0,0 +1,74 @@ +# Module.mk for xml module +# Copyright (c) 2004 Rene Brun and Fons Rademakers +# +# Authors: Linev Sergey, Rene Brun 10/05/2004 + +XMLINCDIR := $(XMLDIR)/include +ifeq ($(PLATFORM),win32) +XMLLIBDIR := $(XMLDIR)/lib/libxml2_a.lib $(XMLDIR)/lib/iconv_a.lib Ws2_32.lib +XMLLIBEXTRA := +else +XMLLIBDIR := -L$(XMLDIR)/.libs +XMLLIBEXTRA := -lxml2 +endif + +MODDIR := xml +MODDIRS := $(MODDIR)/src +MODDIRI := $(MODDIR)/inc + +XMLDIR := $(MODDIR) +XMLDIRS := $(XMLDIR)/src +XMLDIRI := $(XMLDIR)/inc + +##### libRXML ##### +XMLL := $(MODDIRI)/LinkDef.h +XMLDS := $(MODDIRS)/G__XML.cxx +XMLDO := $(XMLDS:.cxx=.o) +XMLDH := $(XMLDS:.cxx=.h) + +XMLH := $(filter-out $(MODDIRI)/LinkDef%,$(wildcard $(MODDIRI)/*.h)) +XMLS := $(filter-out $(MODDIRS)/G__%,$(wildcard $(MODDIRS)/*.cxx)) +XMLO := $(XMLS:.cxx=.o) + +XMLDEP := $(XMLO:.o=.d) $(XMLDO:.o=.d) + +XMLLIB := $(LPATH)/libRXML.$(SOEXT) + +# used in the main Makefile +ALLHDRS += $(patsubst $(MODDIRI)/%.h,include/%.h,$(XMLH)) +ALLLIBS += $(XMLLIB) + +# include all dependency files +INCLUDEFILES += $(XMLDEP) + +##### local rules ##### +include/%.h: $(XMLDIRI)/%.h + cp $< $@ + +$(XMLLIB): $(XMLO) $(XMLDO) $(MAINLIBS) + @$(MAKELIB) $(PLATFORM) $(LD) "$(LDFLAGS)" \ + "$(SOFLAGS)" libRXML.$(SOEXT) $@ "$(XMLO) $(XMLDO)" \ + "$(XMLLIBDIR) $(XMLLIBEXTRA) " + +$(XMLDS): $(XMLH) $(XMLL) $(ROOTCINTTMP) + @echo "Generating dictionary $@..." + $(ROOTCINTTMP) -f $@ -c $(XMLH) $(XMLL) + +$(XMLDO): $(XMLDS) + $(CXX) $(NOOPT) $(CXXFLAGS) -I. -o $@ -c $< + +all-xml: $(XMLLIB) + +clean-xml: + @rm -f $(XMLO) $(XMLDO) + +clean:: clean-xml + +distclean-xml: clean-xml + @rm -f $(XMLDEP) $(XMLDS) $(XMLDH) $(XMLLIB) + +distclean:: distclean-xml + +##### extra rules ###### +$(XMLO): %.o: %.cxx + $(CXX) $(OPT) $(CXXFLAGS) -I$(XMLINCDIR) -o $@ -c $< diff --git a/xml/inc/LinkDef.h b/xml/inc/LinkDef.h new file mode 100644 index 00000000000..71c65ba747c --- /dev/null +++ b/xml/inc/LinkDef.h @@ -0,0 +1,24 @@ +/* @(#)root/xml:$Name: $:$Id: LinkDef.h,v 1.0 2003/01/30 11:33:48 brun Exp $ */ + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class TXMLEngine; +#pragma link C++ class TXMLSetup; +#pragma link C++ class TXMLBuffer; +#pragma link C++ class TXMLFile; +#pragma link C++ class TXMLKey; +#pragma link C++ class TXMLDtdGenerator; + +#endif diff --git a/xml/inc/TXMLBuffer.h b/xml/inc/TXMLBuffer.h new file mode 100644 index 00000000000..b03b2b856b6 --- /dev/null +++ b/xml/inc/TXMLBuffer.h @@ -0,0 +1,295 @@ +// @(#)root/xml:$Name: $:$Id: TXMLBuffer.h,v 1.0 2004/01/28 22:31:11 brun Exp $ +// Author: Sergey Linev 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef TXMLBUFFER_H +#define TXMLBUFFER_H + +#include "TBuffer.h" +#include "TXMLSetup.h" +#include "TXMLEngine.h" +#include "TString.h" +#include "TObjArray.h" + +class TExMap; +class TStreamerInfo; +class TStreamerElement; +class TObjArray; +class TMemberStreamer; +class TXMLDtdGenerator; +class TXMLFile; +class TXMLStackObj; + +class TXMLBuffer : public TBuffer, public TXMLSetup { + public: + + TXMLBuffer(TBuffer::EMode mode, const TXMLSetup& setup, TXMLFile* file = 0); + virtual ~TXMLBuffer(); + + xmlNodePointer XmlWrite(const TObject* obj); + xmlNodePointer XmlWrite(const void* obj, const TClass* cl); + + TObject* XmlRead(xmlNodePointer node); + void* XmlReadAny(xmlNodePointer node); + + void SetDtdGenerator(TXMLDtdGenerator* gen) { fDtdGener = gen; } + + // suppress class writing/reading + + virtual TClass* ReadClass(const TClass* cl = 0, UInt_t* objTag = 0); + virtual void WriteClass(const TClass* cl); + + // redefined virtual functions of TBuffer + + virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss); // SL + virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const char *classname); // SL + virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion = kFALSE); // SL + + virtual Version_t ReadVersion(UInt_t *start = 0, UInt_t *bcnt = 0, const TClass *cl = 0); // SL + virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt = kFALSE); // SL + + virtual void* ReadObjectAny(const TClass* clCast); + + virtual void IncrementLevel(TStreamerInfo*); + virtual void StartElement(TStreamerElement*); + virtual void SetStreamerElementNumber(Int_t); + + virtual void DecrementLevel(TStreamerInfo*); + + // end of redefined virtual functions of XMLStyle1 + + virtual void WriteObject(const TObject *obj); + + + // redefined virtual functions of TBuffer + + virtual Int_t ReadArray(Bool_t *&b); + virtual Int_t ReadArray(Char_t *&c); + virtual Int_t ReadArray(UChar_t *&c); + virtual Int_t ReadArray(Short_t *&h); + virtual Int_t ReadArray(UShort_t *&h); + virtual Int_t ReadArray(Int_t *&i); + virtual Int_t ReadArray(UInt_t *&i); + virtual Int_t ReadArray(Long_t *&l); + virtual Int_t ReadArray(ULong_t *&l); + virtual Int_t ReadArray(Long64_t *&l); + virtual Int_t ReadArray(ULong64_t *&l); + virtual Int_t ReadArray(Float_t *&f); + virtual Int_t ReadArray(Double_t *&d); + virtual Int_t ReadArrayDouble32(Double_t *&d); + + virtual Int_t ReadStaticArray(Bool_t *b); + virtual Int_t ReadStaticArray(Char_t *c); + virtual Int_t ReadStaticArray(UChar_t *c); + virtual Int_t ReadStaticArray(Short_t *h); + virtual Int_t ReadStaticArray(UShort_t *h); + virtual Int_t ReadStaticArray(Int_t *i); + virtual Int_t ReadStaticArray(UInt_t *i); + virtual Int_t ReadStaticArray(Long_t *l); + virtual Int_t ReadStaticArray(ULong_t *l); + virtual Int_t ReadStaticArray(Long64_t *l); + virtual Int_t ReadStaticArray(ULong64_t *l); + virtual Int_t ReadStaticArray(Float_t *f); + virtual Int_t ReadStaticArray(Double_t *d); + virtual Int_t ReadStaticArrayDouble32(Double_t *d); + + virtual void ReadFastArray(Bool_t *b, Int_t n); + virtual void ReadFastArray(Char_t *c, Int_t n); + virtual void ReadFastArray(UChar_t *c, Int_t n); + virtual void ReadFastArray(Short_t *h, Int_t n); + virtual void ReadFastArray(UShort_t *h, Int_t n); + virtual void ReadFastArray(Int_t *i, Int_t n); + virtual void ReadFastArray(UInt_t *i, Int_t n); + virtual void ReadFastArray(Long_t *l, Int_t n); + virtual void ReadFastArray(ULong_t *l, Int_t n); + virtual void ReadFastArray(Long64_t *l, Int_t n); + virtual void ReadFastArray(ULong64_t *l, Int_t n); + virtual void ReadFastArray(Float_t *f, Int_t n); + virtual void ReadFastArray(Double_t *d, Int_t n); + virtual void ReadFastArrayDouble32(Double_t *d, Int_t n); + + virtual void WriteArray(const Bool_t *b, Int_t n); + virtual void WriteArray(const Char_t *c, Int_t n); + virtual void WriteArray(const UChar_t *c, Int_t n); + virtual void WriteArray(const Short_t *h, Int_t n); + virtual void WriteArray(const UShort_t *h, Int_t n); + virtual void WriteArray(const Int_t *i, Int_t n); + virtual void WriteArray(const UInt_t *i, Int_t n); + virtual void WriteArray(const Long_t *l, Int_t n); + virtual void WriteArray(const ULong_t *l, Int_t n); + virtual void WriteArray(const Long64_t *l, Int_t n); + virtual void WriteArray(const ULong64_t *l, Int_t n); + virtual void WriteArray(const Float_t *f, Int_t n); + virtual void WriteArray(const Double_t *d, Int_t n); + virtual void WriteArrayDouble32(const Double_t *d, Int_t n); + virtual void ReadFastArray(void *start , const TClass *cl, Int_t n=1, TMemberStreamer *s=0); + virtual void ReadFastArray(void **startp, const TClass *cl, Int_t n=1, Bool_t isPreAlloc=kFALSE, TMemberStreamer *s=0); + + virtual void WriteFastArray(const Bool_t *b, Int_t n); + virtual void WriteFastArray(const Char_t *c, Int_t n); + virtual void WriteFastArray(const UChar_t *c, Int_t n); + virtual void WriteFastArray(const Short_t *h, Int_t n); + virtual void WriteFastArray(const UShort_t *h, Int_t n); + virtual void WriteFastArray(const Int_t *i, Int_t n); + virtual void WriteFastArray(const UInt_t *i, Int_t n); + virtual void WriteFastArray(const Long_t *l, Int_t n); + virtual void WriteFastArray(const ULong_t *l, Int_t n); + virtual void WriteFastArray(const Long64_t *l, Int_t n); + virtual void WriteFastArray(const ULong64_t *l, Int_t n); + virtual void WriteFastArray(const Float_t *f, Int_t n); + virtual void WriteFastArray(const Double_t *d, Int_t n); + virtual void WriteFastArrayDouble32(const Double_t *d, Int_t n); + virtual void WriteFastArray(void *start, const TClass *cl, Int_t n=1, TMemberStreamer *s=0); + virtual Int_t WriteFastArray(void **startp, const TClass *cl, Int_t n=1, Bool_t isPreAlloc=kFALSE, TMemberStreamer *s=0); + + virtual void StreamObject(void *obj, const type_info &typeinfo); + virtual void StreamObject(void *obj, const char *className); + virtual void StreamObject(void *obj, const TClass *cl); + + virtual TBuffer &operator>>(Bool_t &b); + virtual TBuffer &operator>>(Char_t &c); + virtual TBuffer &operator>>(UChar_t &c); + virtual TBuffer &operator>>(Short_t &h); + virtual TBuffer &operator>>(UShort_t &h); + virtual TBuffer &operator>>(Int_t &i); + virtual TBuffer &operator>>(UInt_t &i); + virtual TBuffer &operator>>(Long_t &l); + virtual TBuffer &operator>>(ULong_t &l); + virtual TBuffer &operator>>(Long64_t &l); + virtual TBuffer &operator>>(ULong64_t &l); + virtual TBuffer &operator>>(Float_t &f); + virtual TBuffer &operator>>(Double_t &d); + virtual TBuffer &operator>>(Char_t *c); + + virtual TBuffer &operator<<(Bool_t b); + virtual TBuffer &operator<<(Char_t c); + virtual TBuffer &operator<<(UChar_t c); + virtual TBuffer &operator<<(Short_t h); + virtual TBuffer &operator<<(UShort_t h); + virtual TBuffer &operator<<(Int_t i); + virtual TBuffer &operator<<(UInt_t i); + virtual TBuffer &operator<<(Long_t l); + virtual TBuffer &operator<<(ULong_t l); + virtual TBuffer &operator<<(Long64_t l); + virtual TBuffer &operator<<(ULong64_t l); + virtual TBuffer &operator<<(Float_t f); + virtual TBuffer &operator<<(Double_t d); + virtual TBuffer &operator<<(const Char_t *c); + + // end of redefined virtual functions + + protected: + // redefined protected virtual functions + + virtual void WriteObject(const void *actualObjStart, const TClass *actualClass); + + // end redefined protected virtual functions + + TXMLBuffer(); + + //TXMLBuffer(const TXMLBuffer&); + + TXMLStackObj* PushStack(xmlNodePointer current, Bool_t simple = kFALSE); + void PopStack(); + void ShiftStack(const char* info = 0); + + xmlNodePointer StackNode(); + TXMLStackObj* Stack(Int_t depth); + + Bool_t VerifyNode(xmlNodePointer node, const char* name, const char* errinfo = 0); + Bool_t VerifyStackNode(const char* name, const char* errinfo = 0); + + Bool_t VerifyProp(xmlNodePointer node, const char* propname, const char* propvalue, const char* errinfo = 0); + Bool_t VerifyStackProp(const char* propname, const char* propvalue, const char* errinfo = 0); + + xmlNodePointer XmlCreateMember(const char* name, + const char* type, + const char* value = 0, + Int_t size = -1); + + Bool_t VerifyMember(const char* name, + const char* type, + Int_t size = -1, + const char* errinfo = 0); + + void XmlWriteBlock(Bool_t force = kFALSE); + void XmlReadBlock(xmlNodePointer node = 0); + + Bool_t ProcessPointer(const void* ptr, xmlNodePointer node); + void RegisterPointer(const void* ptr, xmlNodePointer node); + Bool_t ExtractPointer(xmlNodePointer node, void* &ptr); + void ExtractObjectId(xmlNodePointer node, const void* ptr); + + xmlNodePointer XmlWriteBasic(Char_t value); + xmlNodePointer XmlWriteBasic(Short_t value); + xmlNodePointer XmlWriteBasic(Int_t value); + xmlNodePointer XmlWriteBasic(Long_t value); + xmlNodePointer XmlWriteBasic(Long64_t value); + xmlNodePointer XmlWriteBasic(Float_t value); + xmlNodePointer XmlWriteBasic(Double_t value); + xmlNodePointer XmlWriteBasic(Bool_t value); + xmlNodePointer XmlWriteBasic(UChar_t value); + xmlNodePointer XmlWriteBasic(UShort_t value); + xmlNodePointer XmlWriteBasic(UInt_t value); + xmlNodePointer XmlWriteBasic(ULong_t value); + xmlNodePointer XmlWriteBasic(ULong64_t value); + xmlNodePointer XmlWriteValue(const char* value, const char* name); + + void XmlReadBasic(Char_t& value); + void XmlReadBasic(Short_t& value); + void XmlReadBasic(Int_t& value); + void XmlReadBasic(Long_t& value); + void XmlReadBasic(Long64_t& value); + void XmlReadBasic(Float_t& value); + void XmlReadBasic(Double_t& value); + void XmlReadBasic(Bool_t& value); + void XmlReadBasic(UChar_t& value); + void XmlReadBasic(UShort_t& value); + void XmlReadBasic(UInt_t& value); + void XmlReadBasic(ULong_t& value); + void XmlReadBasic(ULong64_t& value); + const char* XmlReadValue(const char* name); + + TXMLFile* XmlFile(); + + xmlNodePointer XmlWriteObjectNew(const void* obj, const TClass* objClass); + void* XmlReadObjectNew(void* obj); + + void CreateElemNode(const TStreamerElement* elem, Int_t number = -1); + Bool_t VerifyElemNode(const TStreamerElement* elem, Int_t number = -1); + + void BeforeIOoperation(); + void CheckVersionBuf(); + + Int_t fStoredBuffePos; //! + + TObjArray fStack; //! + + Version_t fVersionBuf; //! + + TXMLDtdGenerator* fDtdGener; //! + TXMLFile* fXmlFile; //! + + TExMap* fObjMap; //! + TObjArray* fIdArray; //! + + TString fValueBuf; //! + + Int_t fErrorFlag; //! + + Bool_t fCanUseCompact; //! + Bool_t fExpectedChain; //! + + ClassDef(TXMLBuffer,1); +}; + +#endif + + diff --git a/xml/inc/TXMLDtdGenerator.h b/xml/inc/TXMLDtdGenerator.h new file mode 100644 index 00000000000..0da2ef087d5 --- /dev/null +++ b/xml/inc/TXMLDtdGenerator.h @@ -0,0 +1,77 @@ +// @(#)root/xml:$Name: $:$Id: TXMLDtdGenerator.h,v 1.0 2004/01/28 22:31:11 brun Exp $ +// Author: Sergey Linev 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef TXMLDtdGenerator_h +#define TXMLDtdGenerator_h + +#include "TXMLSetup.h" +#include "TObjArray.h" + +class TCollection; +class TClass; +class TStreamerElement; +class TStreamerInfo; + +class TXMLDtdGenerator : public TXMLSetup { + public: + TXMLDtdGenerator(); + TXMLDtdGenerator(const char* setup); + TXMLDtdGenerator(const TXMLSetup& setup); + virtual ~TXMLDtdGenerator(); + + void Produce(const char* fname, TClass* onlyclass = 0); + + void AddClassSpace(TCollection* col = 0); + + void AddInstrumentedClass(TStreamerInfo* info); + + void AddBlackClass(TClass* cl); + + void AddUsedClass(TClass * cl); + + protected: + enum {dtd_none, dtd_attr, dtd_elem, dtd_charstar, dtd_base, dtd_object, dtd_objptr, + dtd_fixarray, dtd_array, dtd_fastobj1, dtd_fastobj2, + dtd_everyobj, dtd_stlp, dtd_objects, dtd_any}; + + enum { MaxBaseTypeNum = 21}; + + Int_t dtdType(TStreamerElement* el); + + const char* dtdBaseTypeName(int typ); + const char* dtdUseBaseType(TStreamerElement* el); + + void ProduceDtdForItem(ofstream& fs, const char* name); + + void ProduceDtdForInstrumentedClass(ofstream& fs, TStreamerInfo* info); + + void ProduceDtdForBlackClass(ofstream& fs, TClass* cl); + + void ProduceObjectElement(ofstream& fs, const char* name, TClass* cl, Bool_t isPointer = kFALSE); + + void ProduceGeneralDtd(ofstream& fs, TClass* onlyclass = 0); + void ProduceSpecificDtd(ofstream& fs, TClass* onlyclass = 0); + + TObjArray fClassSpace; + TObjArray fInstrumentedClasses; + TObjArray fBlackClasses; + + TObjArray fUsedClasses; + + TString fDtdBuf; + Bool_t fUsedBaseTypes[MaxBaseTypeNum]; + + ClassDef(TXMLDtdGenerator,1); +}; + + +#endif + diff --git a/xml/inc/TXMLEngine.h b/xml/inc/TXMLEngine.h new file mode 100644 index 00000000000..021ccfc4b9f --- /dev/null +++ b/xml/inc/TXMLEngine.h @@ -0,0 +1,96 @@ +// @(#)root/xml:$Name: $:$Id: TXMLEngine.h,v 1.0 2004/01/28 22:31:11 brun Exp $ +// Author: Sergey Linev 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef TXMLEngine_h +#define TXMLEngine_h + +#include "TObject.h" +#include "TString.h" + +typedef void* xmlNodePointer; +typedef void* xmlNsPointer; +typedef void* xmlAttrPointer; +typedef void* xmlDocPointer; + +class TXMLEngine : public TObject { + protected: + TXMLEngine(); + virtual ~TXMLEngine(); + static TXMLEngine* fgInstance; + + public: + + static TXMLEngine* GetInstance() { return fgInstance; } + + Bool_t HasProp(xmlNodePointer node, const char* name); + + const char* GetProp(xmlNodePointer node, const char* name); + + xmlAttrPointer NewProp(xmlNodePointer node, + xmlNsPointer ns, + const char* name, + const char* value); + + xmlNodePointer NewChild(xmlNodePointer parent, + xmlNsPointer ns, + const char* name, + const char* content = 0); + + xmlNsPointer NewNS(xmlNodePointer node, + const char* reference, + const char* name = 0); + + void AddChild(xmlNodePointer parent, xmlNodePointer child); + + void UnlinkChild(xmlNodePointer node); + + void FreeNode(xmlNodePointer node); + + const char* GetNodeName(xmlNodePointer node); + + const char* GetNodeContent(xmlNodePointer node); + + xmlNodePointer GetChild(xmlNodePointer node); + + xmlNodePointer GetParent(xmlNodePointer node); + + xmlNodePointer GetNext(xmlNodePointer node); + + void ShiftToNext(xmlNodePointer &node, Bool_t skipempty = kTRUE); + + void SkipEmpty(xmlNodePointer &node); + + xmlDocPointer NewDoc(const char* version = 0); + + void AssignDtd(xmlDocPointer doc, const char* dtdname, const char* rootname); + + void FreeDoc(xmlDocPointer doc); + + void SaveDoc(xmlDocPointer doc, const char* filename, Int_t layout = 1); + + void DocSetRootElement(xmlDocPointer doc, xmlNodePointer node); + + xmlNodePointer DocGetRootElement(xmlDocPointer doc); + + xmlDocPointer ParseFile(const char* filename); + + Bool_t ValidateDocument(xmlDocPointer doc, Bool_t doout = kFALSE); + + protected: + + TString fStrBuf; + + ClassDef(TXMLEngine,1); +}; + +extern TXMLEngine* gXML; + +#endif diff --git a/xml/inc/TXMLFile.h b/xml/inc/TXMLFile.h new file mode 100644 index 00000000000..4d0a729a786 --- /dev/null +++ b/xml/inc/TXMLFile.h @@ -0,0 +1,125 @@ +// @(#)root/xml:$Name: $:$Id: TXMLFile.h,v 1.0 2004/01/28 22:31:11 brun Exp $ +// Author: Sergey Linev 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef TXMLFILE_H +#define TXMLFILE_H + +#include "TXMLEngine.h" +#include "TFile.h" +#include "TXMLSetup.h" + +class TXMLKey; +class TList; +class TXMLDtdGenerator; +class TStreamerElement; +class TStreamerInfo; + +class TXMLFile : public TFile, public TXMLSetup { + protected: + // Interface to basic system I/O routines + virtual Int_t SysOpen(const char*, Int_t, UInt_t) { return 0; } + virtual Int_t SysClose(Int_t) { return 0; } + virtual Int_t SysRead(Int_t, void*, Int_t) { return 0; } + virtual Int_t SysWrite(Int_t, const void*, Int_t) { return 0; } + virtual Long64_t SysSeek(Int_t, Long64_t, Int_t) { return 0; } + virtual Int_t SysStat(Int_t, Long_t*, Long64_t*, Long_t*, Long_t*) { return 0; } + virtual Int_t SysSync(Int_t) { return 0; } + + private: + //let the compiler do the job. gcc complains when the following line is activated + //TXMLFile(const TXMLFile &) {} //Files cannot be copied + void operator=(const TXMLFile &); + + public: + TXMLFile(); + TXMLFile(const char* filename, Option_t* option = "read", const char* title = "title", Int_t compression = 1); + virtual ~TXMLFile(); + + virtual void Browse(TBrowser *b); + virtual Bool_t cd(const char* path = ""); + + virtual void Close(Option_t* = "") {} // *MENU* + virtual void Draw(Option_t* = "") {} + virtual void DrawMap(const char* ="*",Option_t* ="") {} // *MENU* + virtual void FillBuffer(char* &) {} + virtual void Flush() {} + + virtual Long64_t GetEND() const { return 0; } + virtual Int_t GetErrno() const { return 0; } + virtual void ResetErrno() const {} + + virtual Int_t GetNfree() const { return 0; } + virtual Int_t GetNbytesInfo() const {return 0; } + virtual Int_t GetNbytesFree() const {return 0; } + virtual Long64_t GetSeekFree() const {return 0; } + virtual Long64_t GetSeekInfo() const {return 0; } + virtual Long64_t GetSize() const { return 0; } + + virtual Bool_t IsOpen() const; + + virtual void MakeFree(Long64_t, Long64_t) {} + virtual void MakeProject(const char *, const char* ="*", Option_t* ="new") {} // *MENU* + virtual void Map() {} // *MENU* + virtual void Paint(Option_t* ="") {} + virtual void Print(Option_t* ="") const {} + virtual Bool_t ReadBuffer(char*, Int_t) { return kFALSE; } + virtual void ReadFree() {} + virtual void ReadStreamerInfo() {} + virtual Int_t Recover() { return 0; } + virtual Int_t ReOpen(Option_t *mode); + virtual void Seek(Long64_t, ERelativeTo=kBeg) {} + + virtual void SetEND(Long64_t) {} + virtual void ShowStreamerInfo() {} + virtual Int_t Sizeof() const { return 0; } + + virtual void UseCache(Int_t = 10, Int_t = TCache::kDfltPageSize) {} + virtual Bool_t WriteBuffer(const char*, Int_t) { return kFALSE; } + virtual Int_t Write(const char* =0, Int_t=0, Int_t=0) { return 0; } + virtual void WriteFree() {} + virtual void WriteHeader() {} + virtual Int_t WriteObject(const TObject* obj, const char* name = 0, Option_t *option=""); + virtual Int_t WriteObjectAny(const void* obj, const TClass* cl, const char* name, Option_t *option=""); + virtual void WriteStreamerInfo() {} + + // XML specific functions + + TXMLDtdGenerator* GetDtdGenerator() const { return fDtdGener; } + TObject* Get(const char* name); + void* GetAny(const char* name); + + protected: + // functions to store streamer infos + + xmlNodePointer CreateStreamerInfoNode(); + void ReadStreamerInfos(xmlNodePointer fRootNode); + + void StoreStreamerElement(xmlNodePointer node, TStreamerElement* elem); + void ReadStreamerElement(xmlNodePointer node, TStreamerInfo* info); + + + Bool_t ReadFromFile(); + + void SaveToFile(); + + static void ProduceFileNames(const char* filename, TString& fname, TString& dtdname); + + xmlDocPointer fDoc; //! + + TXMLDtdGenerator* fDtdGener; //! + + ClassDef(TXMLFile,1); +}; + + + +#endif + diff --git a/xml/inc/TXMLKey.h b/xml/inc/TXMLKey.h new file mode 100644 index 00000000000..b711d41db60 --- /dev/null +++ b/xml/inc/TXMLKey.h @@ -0,0 +1,76 @@ +// @(#)root/xml:$Name: $:$Id: TXMLKey.h,v 1.0 2004/01/28 22:31:11 brun Exp $ +// Author: Sergey Linev 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef TXMLKEY_H +#define TXMLKEY_H + +#include "TXMLEngine.h" +#include "TKey.h" + +class TXMLFile; + +class TXMLKey : public TKey { + public: + TXMLKey(); + + TXMLKey(TXMLFile* file, const TObject* obj, const char* name = 0); + TXMLKey(TXMLFile* file, const void* obj, const TClass* cl, const char* name); + TXMLKey(TXMLFile* file, xmlNodePointer keynode); + + + // redefined TKey Methods + virtual void Browse(TBrowser *b); + virtual void Delete(Option_t *option=""); + virtual void DeleteBuffer() {} + virtual void FillBuffer(char *&) {} + virtual char *GetBuffer() const { return 0; } + virtual Long64_t GetSeekKey() const {return 0; } + virtual Long64_t GetSeekPdir() const {return 0;} + //virtual ULong_t Hash() const { return 0; } + virtual void Keep() {} + virtual void ls(Option_t* ="") const; + //virtual void Print(Option_t* ="") const {} + + virtual Int_t Read(TObject*) { return 0; } + virtual TObject *ReadObj() { return 0;} + virtual void ReadBuffer(char *&) {} + virtual void ReadFile() {} + virtual void SetBuffer() { fBuffer = 0; } + virtual void SetParent(const TObject* ) { } + virtual Int_t Sizeof() const { return 0; } + virtual Int_t WriteFile(Int_t =1) { return 0; } + + + // TXML xpecific methods + + virtual ~TXMLKey(); + + xmlNodePointer KeyNode() const { return fKeyNode; } + + TObject* GetObject(); + void* GetObjectAny(); + + protected: + virtual Int_t Read(const char *name) { return TKey::Read(name); } + void StoreObject(TXMLFile* file, const void* obj, const TClass* cl); + xmlNodePointer ObjNode(); + + TXMLFile* fFile; //! + xmlNodePointer fKeyNode; //! + void* fObject; //! + + ClassDef(TXMLKey,1); +}; + + + + +#endif diff --git a/xml/inc/TXMLSetup.h b/xml/inc/TXMLSetup.h new file mode 100644 index 00000000000..842acfe2f86 --- /dev/null +++ b/xml/inc/TXMLSetup.h @@ -0,0 +1,121 @@ +// @(#)root/xml:$Name: $:$Id: TXMLSetup.h,v 1.0 2004/01/28 22:31:11 brun Exp $ +// Author: Sergey Linev 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef TXMLSETUP_H +#define TXMLSETUP_H + +#include "TXMLEngine.h" +#include "TObject.h" +#include "TString.h" + +extern const char* NameSpaceBase; + +extern const char* xmlNames_Root; +extern const char* xmlNames_Setup; +extern const char* xmlNames_Version; +extern const char* xmlNames_Ptr; +extern const char* xmlNames_Ref; +extern const char* xmlNames_Null; +extern const char* xmlNames_IdBase; +extern const char* xmlNames_Size; +extern const char* xmlNames_Xmlobject; +extern const char* xmlNames_Xmlkey; +extern const char* xmlNames_Cycle; +extern const char* xmlNames_XmlBlock; +extern const char* xmlNames_Zip; +extern const char* xmlNames_Object; +extern const char* xmlNames_Class; +extern const char* xmlNames_Member; +extern const char* xmlNames_Item; +extern const char* xmlNames_Name; +extern const char* xmlNames_Type; +extern const char* xmlNames_Value; + +extern const char* xmlNames_Array; +extern const char* xmlNames_Bool; +extern const char* xmlNames_Char; +extern const char* xmlNames_Short; +extern const char* xmlNames_Int; +extern const char* xmlNames_Long; +extern const char* xmlNames_Long64; +extern const char* xmlNames_Float; +extern const char* xmlNames_Double; +extern const char* xmlNames_UChar; +extern const char* xmlNames_UShort; +extern const char* xmlNames_UInt; +extern const char* xmlNames_ULong; +extern const char* xmlNames_ULong64; +extern const char* xmlNames_String; +extern const char* xmlNames_CharStar; + + + +class TStreamerElement; + +class TXMLSetup { + public: + enum TXMLLayout { kSpecialized = 2, + kGeneralized = 3 }; + + TXMLSetup(); + TXMLSetup(const char* opt); + TXMLSetup(const TXMLSetup& src); + virtual ~TXMLSetup(); + + void StoreSetup(xmlNodePointer node); + Bool_t ReadSetup(xmlNodePointer node); + + void PrintSetup(); + + TXMLLayout GetXmlLayout() const { return fXmlLayout; } + void SetXmlLayout(TXMLLayout layout) { fXmlLayout = layout; } + + Bool_t IsaSolidDataBlock() const { return fSolidDataBlock; } + void SetSolidDataBlock(Bool_t iSolid = kTRUE) { fSolidDataBlock = iSolid; } + + Bool_t IsConvertBasicTypes() const { return fConvertBasicTypes; } + void SetConvertBasicTypes(Bool_t iConvert = kTRUE) { fConvertBasicTypes = iConvert; } + + Bool_t IsUseDtd() const { return fUseDtd; } + void SetUsedDtd(Bool_t use = kTRUE) { fUseDtd = use; } + + Bool_t IsUseNamespaces() const { return fUseNamespaces; } + void SetUseNamespaces(Bool_t iUseNamespaces = kTRUE) { fUseNamespaces = iUseNamespaces; } + + const char* XmlConvertClassName(const TClass* cl); + const char* XmlClassNameSpaceRef(const TClass* cl); + + Int_t GetNextRefCounter() { return fRefCounter++; } + + protected: + + TClass* XmlDefineClass(const char* xmlClassName); + const char* GetElItemName(TStreamerElement* el); + const char* GetElName(TStreamerElement* el); + + Bool_t ReadSetupFromStr(const char* setupstr); + + TXMLLayout fXmlLayout; + Bool_t fSolidDataBlock; + Bool_t fConvertBasicTypes; + Bool_t fUseDtd; + Bool_t fUseNamespaces; + + Int_t fRefCounter; + + TString fStrBuf; //! + TString fNameBuf; //! + + ClassDef(TXMLSetup,1); +}; + +#endif + diff --git a/xml/src/TXMLBuffer.cxx b/xml/src/TXMLBuffer.cxx new file mode 100644 index 00000000000..f44fa27b90e --- /dev/null +++ b/xml/src/TXMLBuffer.cxx @@ -0,0 +1,1939 @@ +// @(#)root/xml:$Name: $:$Id: TXMLBuffer.cxx,v 1.0 2004/04/21 15:06:45 brun Exp $ +// Author: Sergey Linev, Rene Brun 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#include "TXMLBuffer.h" +#include "TXMLDtdGenerator.h" +#include "TXMLFile.h" + +#include "TObjArray.h" +#include "TROOT.h" +#include "TClass.h" +#include "TClassTable.h" +#include "TExMap.h" +#include "TMethodCall.h" +#include "TStreamerInfo.h" +#include "TStreamerElement.h" +#include "TProcessID.h" +#include "TFile.h" +#include "TMemberStreamer.h" +#include "TStreamer.h" + +#include <Riostream.h> + +extern "C" void R__zip(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep); + +extern "C" void R__unzip(int *srcsize, unsigned char *src, int *tgtsize, unsigned char *tgt, int *irep); + +ClassImp(TXMLBuffer); + +//______________________________________________________________________________ +TXMLBuffer::TXMLBuffer() : + TBuffer(), + TXMLSetup() { +} + +//______________________________________________________________________________ +TXMLBuffer::TXMLBuffer(TBuffer::EMode mode, const TXMLSetup& setup, TXMLFile* file) : + TBuffer(mode), + TXMLSetup(setup), + fStoredBuffePos(0), + fStack(), + fVersionBuf(-111), + fDtdGener(0), + fXmlFile(file), + fObjMap(0), + fIdArray(0), + fErrorFlag(0), + fCanUseCompact(kFALSE), + fExpectedChain(kFALSE) { +} + +//______________________________________________________________________________ +TXMLBuffer::~TXMLBuffer() { + if (fObjMap) delete fObjMap; + if (fIdArray) delete fIdArray; + fStack.Delete(); +} + +//______________________________________________________________________________ +TXMLFile* TXMLBuffer::XmlFile() { + return fXmlFile; +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWrite(const TObject* obj) { + if (obj==0) return XmlWrite(0,0); + else return XmlWrite(obj, obj->IsA()); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWrite(const void* obj, const TClass* cl) { + fErrorFlag = 0; + + fStoredBuffePos = Length(); + + xmlNodePointer res = XmlWriteObjectNew(obj, cl); + + XmlWriteBlock(kTRUE); + return res; +} + +//______________________________________________________________________________ +TObject* TXMLBuffer::XmlRead(xmlNodePointer node) { + void* obj = XmlReadAny(node); + + return (TObject*) obj; +} + +//______________________________________________________________________________ +void* TXMLBuffer::XmlReadAny(xmlNodePointer node) { + if (node==0) return 0; + + fErrorFlag = 0; + + PushStack(node, kTRUE); + + if (IsaSolidDataBlock()) + XmlReadBlock(gXML->GetChild(node)); + + void* obj = XmlReadObjectNew(0); + + return obj; +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteObject(const TObject *obj) { + TBuffer::WriteObject(obj); +} + +// **************************** stack functions ***************************** + +class TXMLStackObj : public TObject { + public: + TXMLStackObj(xmlNodePointer node) : + TObject(), fNode(node), fInfo(0), fLastElem(0), fElemNumber(0) {} + + xmlNodePointer fNode; + TStreamerInfo* fInfo; + TStreamerElement* fLastElem; + Int_t fElemNumber; +}; + +//______________________________________________________________________________ +TXMLStackObj* TXMLBuffer::PushStack(xmlNodePointer current, Bool_t simple) { + if (IsReading() && !simple) { + current = gXML->GetChild(current); + gXML->SkipEmpty(current); + } + + TXMLStackObj* stack = new TXMLStackObj(current); + fStack.Add(stack); + return stack; +} + +//______________________________________________________________________________ +void TXMLBuffer::PopStack() { + TObject* last = fStack.Last(); + if (last!=0) { + fStack.Remove(last); + delete last; + fStack.Compress(); + } +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::StackNode() { + TXMLStackObj* stack = dynamic_cast<TXMLStackObj*> (fStack.Last()); + if (stack==0) return 0; + return stack->fNode; +} + +//______________________________________________________________________________ +TXMLStackObj* TXMLBuffer::Stack(Int_t depth) { + TXMLStackObj* stack = 0; + if (depth<=fStack.GetLast()) + stack = dynamic_cast<TXMLStackObj*> (fStack.At(fStack.GetLast()-depth)); + return stack; +} + +//______________________________________________________________________________ +void TXMLBuffer::ShiftStack(const char* errinfo) { + TXMLStackObj* stack = dynamic_cast<TXMLStackObj*> (fStack.Last()); + if (stack) { + if (gDebug>4) + cout << " Shift " << errinfo << " from " << gXML->GetNodeName(stack->fNode); + gXML->ShiftToNext(stack->fNode); + if (gDebug>4) + cout << " to " << gXML->GetNodeName(stack->fNode) << endl; + } +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlWriteBlock(Bool_t force) { + if ((StackNode()==0) || (fStoredBuffePos>=Length()) || (IsaSolidDataBlock() && !force)) return; + + int BlockSize = Length() - fStoredBuffePos; + + const char* src = Buffer() + fStoredBuffePos; + int srcSize = BlockSize; + + char* fZipBuffer = 0; + + if ((BlockSize > 512) && (GetXmlLayout()!=kGeneralized)) { + int ZipBufferSize = BlockSize; + fZipBuffer = new char[ZipBufferSize]; + int CompressedSize = 0; + R__zip(1, &BlockSize, Buffer() + fStoredBuffePos, &ZipBufferSize, fZipBuffer, &CompressedSize); + + src = fZipBuffer; + srcSize = CompressedSize; + } + + + TString res; //("\n"); + char sbuf[200]; + int block = 0; + char* tgt = sbuf; + int srcCnt = 0; + + while (srcCnt++<srcSize) { + tgt+=sprintf(tgt, " %02x", (unsigned char) *src); + src++; + if (block++==15) { + res += sbuf; + block = 0; + tgt = sbuf; + } + } + + if (block>0) res += sbuf; + + xmlNodePointer node = 0; + + if (GetXmlLayout()==kGeneralized) { + node = XmlCreateMember(0, "block", res, BlockSize); + } else { + node = gXML->NewChild(StackNode(), 0, xmlNames_XmlBlock, res); + sprintf(sbuf, "%d", BlockSize); + gXML->NewProp(node, 0, xmlNames_Size, sbuf); + + if (fZipBuffer) { + sprintf(sbuf, "%d", srcSize); + gXML->NewProp(node, 0, xmlNames_Zip, sbuf); + delete[] fZipBuffer; + } + } + + fStoredBuffePos = Length(); +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBlock(xmlNodePointer node) { + return; + + xmlNodePointer blocknode = 0; + + bool usestacknode = (node==0); + if (usestacknode) node = StackNode(); + else gXML->SkipEmpty(node); + + while (node!=0) { + if (GetXmlLayout()==kGeneralized) { + if (VerifyNode(node, xmlNames_Item) && VerifyProp(node, xmlNames_Type, "block")) { + blocknode = node; + break; + } + } else { + if (VerifyNode(node, xmlNames_XmlBlock)) { + blocknode = node; + break; + } + } + if (usestacknode) break; + else gXML->ShiftToNext(node); + } + + if (blocknode==0) return; + + Int_t blockSize = atoi(gXML->GetProp(blocknode, xmlNames_Size)); + bool blockCompressed = gXML->HasProp(blocknode, xmlNames_Zip); + char* fUnzipBuffer = 0; + + if (gDebug>2) { + cout << " TXMLBuffer::XmlReadBlock " << endl; + cout << " block size = " << blockSize << endl; + cout << " Length = " << Length() << endl; + cout << " compressed = " << blockCompressed << endl; + } + + int pos = fStoredBuffePos; + if (pos+blockSize>BufferSize()) Expand(pos+blockSize); + + char* tgt = Buffer()+pos; + Int_t readSize = blockSize; + + TString content; + + if (GetXmlLayout()==kGeneralized) + content = gXML->GetProp(blocknode, xmlNames_Value); + else + content = gXML->GetNodeContent(blocknode); + + if (blockCompressed) { + Int_t zipSize = atoi(gXML->GetProp(blocknode, xmlNames_Zip)); + fUnzipBuffer = new char[zipSize]; + + tgt = fUnzipBuffer; + readSize = zipSize; + } + + if (gDebug>3) + cout << "Content = " << content << endl; + + char* ptr = (char*) content.Data(); + + for (int i=0;i<readSize;i++) { + while ((*ptr<48) || ((*ptr>57) && (*ptr<97)) || (*ptr>102)) ptr++; + + char* z = ptr; + int b_hi = (*ptr>57) ? *ptr-87 : *ptr-48; + ptr++; + int b_lo = (*ptr>57) ? *ptr-87 : *ptr-48; + ptr++; + + *tgt=b_hi*16+b_lo; + tgt++; + + if (gDebug>3) + cout << "Buf[" << i+pos << "] = " << b_hi*16.+b_lo << " " << *z << *(z+1) << " "<< b_hi << " " << b_lo << endl; + } + + if (fUnzipBuffer) { + int unzipRes = 0; + R__unzip(&readSize, (unsigned char*) fUnzipBuffer, &blockSize, + (unsigned char*) (Buffer()+pos), &unzipRes); + if (gDebug>2) + if (unzipRes!=blockSize) cout << "decompression error " << unzipRes << endl; + else cout << "unzip ok" << endl; + delete[] fUnzipBuffer; + } + + fStoredBuffePos += blockSize; + + if (usestacknode) ShiftStack("blockread"); +} + + +//______________________________________________________________________________ +Bool_t TXMLBuffer::ProcessPointer(const void* ptr, xmlNodePointer node) { + if (node==0) return kFALSE; + + TString refvalue; + + if (ptr==0) + refvalue = xmlNames_Null; //null + else { + if (fObjMap==0) return kFALSE; + + ULong_t hash = TMath::Hash(&ptr, sizeof(void*)); + + xmlNodePointer refnode = (xmlNodePointer) fObjMap->GetValue(hash, (Long_t) ptr); + if (refnode==0) return kFALSE; + + if (gXML->HasProp(refnode, xmlNames_Ref)) + refvalue = gXML->GetProp(refnode, xmlNames_Ref); + else { + refvalue = xmlNames_IdBase; + if (XmlFile()) refvalue += XmlFile()->GetNextRefCounter(); + else refvalue += GetNextRefCounter(); + gXML->NewProp(refnode, 0, xmlNames_Ref, refvalue.Data()); + } + } + if (refvalue.Length()>0) { + gXML->NewProp(node, 0, xmlNames_Ptr, refvalue.Data()); + return kTRUE; + } + + return kFALSE; +} + + +//______________________________________________________________________________ +Bool_t TXMLBuffer::ExtractPointer(xmlNodePointer node, void* &ptr) { + + if (!gXML->HasProp(node,xmlNames_Ptr)) return kFALSE; + + const char* ptrid = gXML->GetProp(node, xmlNames_Ptr); + + if (ptrid==0) return kFALSE; + + // null + if (strcmp(ptrid, xmlNames_Null)==0) { + ptr = 0; + return kTRUE; + } + + if ((fIdArray==0) || (fObjMap==0)) return kFALSE; + + TObject* obj = fIdArray->FindObject(ptrid); + if (obj) { + ptr = (void*) fObjMap->GetValue((Long_t) fIdArray->IndexOf(obj)); + return kTRUE; + } + return kFALSE; +} + +//______________________________________________________________________________ +void TXMLBuffer::RegisterPointer(const void* ptr, xmlNodePointer node) { + if ((node==0) || (ptr==0)) return; + + ULong_t hash = TMath::Hash(&ptr, sizeof(void*)); + + if (fObjMap==0) fObjMap = new TExMap(); + + if (fObjMap->GetValue(hash, (Long_t) ptr)==0) + fObjMap->Add(hash, (Long_t) ptr, (Long_t) node); +} + +//______________________________________________________________________________ +void TXMLBuffer::ExtractObjectId(xmlNodePointer node, const void* ptr) { + if ((node==0) || (ptr==0)) return; + + const char* refid = gXML->GetProp(node, xmlNames_Ref); + + if (refid==0) return; + + if (fIdArray==0) { + fIdArray = new TObjArray; fIdArray->SetOwner(kTRUE); + } + TNamed* nid = new TNamed(refid,0); + fIdArray->Add(nid); + + if (fObjMap==0) fObjMap = new TExMap(); + + fObjMap->Add((Long_t) fIdArray->IndexOf(nid), (Long_t) ptr); + + if (gDebug>2) + cout << "----- Find reference " << refid << " for object " << ptr << " ----- "<< endl; +} + +//______________________________________________________________________________ +Bool_t TXMLBuffer::VerifyNode(xmlNodePointer node, const char* name, const char* errinfo) { + if ((name==0) || (node==0)) return kFALSE; + + if (strcmp(gXML->GetNodeName(node), name)!=0) { + if (errinfo) { + cout << " Error reading XML file (" << errinfo << "). Get: " << gXML->GetNodeName(node) << " expects " << name << endl; + fErrorFlag = 1; + } + return kFALSE; + } + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t TXMLBuffer::VerifyStackNode(const char* name, const char* errinfo) { + return VerifyNode(StackNode(), name, errinfo); +} + +//______________________________________________________________________________ +Bool_t TXMLBuffer::VerifyProp(xmlNodePointer node, const char* propname, const char* propvalue, const char* errinfo) { + if ((node==0) || (propname==0) || (propvalue==0)) return kFALSE; + const char* cont = gXML->GetProp(node, propname); + if (((cont==0) || (strcmp(cont, propvalue)!=0))) { + if (errinfo) { + cout << " Error reading XML file (" << errinfo << ") expected " << propvalue << + " for tag property " << propname << " obtain " << cont << endl; + fErrorFlag = 1; + } + return kFALSE; + } + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t TXMLBuffer::VerifyStackProp(const char* propname, const char* propvalue, const char* errinfo) { + return VerifyProp(StackNode(), propname, propvalue, errinfo); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlCreateMember(const char* name, + const char* type, + const char* value, + Int_t size) { + xmlNodePointer node = 0; + if (GetXmlLayout()==kGeneralized) { + if (name!=0) { + node = gXML->NewChild(StackNode(), 0, xmlNames_Member, 0); + gXML->NewProp(node, 0, xmlNames_Name, name); + } else + node = gXML->NewChild(StackNode(), 0, xmlNames_Item, 0); + gXML->NewProp(node, 0, xmlNames_Type, type); + if (value) gXML->NewProp(node, 0, xmlNames_Value, value); + if (size>=0) { + char ssize[30]; + sprintf(ssize,"%d",size); + gXML->NewProp(node, 0, xmlNames_Size, ssize); + } + } else { + if (name!=0) + node = gXML->NewChild(StackNode(), 0, name, value); + else + node = gXML->NewChild(StackNode(), 0, type, value); + } + return node; +} + +//______________________________________________________________________________ +Bool_t TXMLBuffer::VerifyMember(const char* name, + const char* type, + Int_t size, + const char* errinfo) { + if (GetXmlLayout()==kGeneralized) { + if (name!=0) { + if (!VerifyStackNode(xmlNames_Member, errinfo)) return kFALSE; + if (!VerifyStackProp(xmlNames_Name, name, errinfo)) return kFALSE; + } else + if (!VerifyStackNode(xmlNames_Item, errinfo)) return kFALSE; + + if (!VerifyStackProp(xmlNames_Type, type, errinfo)) return kFALSE; + if (size>=0) { + const char* ssize = gXML->GetProp(StackNode(), xmlNames_Size); + if ((ssize==0) || (atoi(ssize) != size)) { + cout << errinfo << " : invalid Member " << name <<" size property. Expected " + << size << ", get " << ssize << endl; + fErrorFlag = 1; + return kFALSE; + } + } + return kTRUE; + } else + if (name!=0) + return VerifyStackNode(name, errinfo); + else + return VerifyStackNode(type, errinfo); +} + + +// ################ redefined virtual functions ########################### + +//______________________________________________________________________________ +TClass* TXMLBuffer::ReadClass(const TClass*, UInt_t*) { + if (gDebug>2) + cout << " TXMLBuffer::ReadClass SUPPRESSED ???????????????????? " << endl; + return 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteClass(const TClass*) { + if (gDebug>2) + cout << "TXMLBuffer_first::WriteClass SUPPRESSED!!!!!!" << endl; +} + + +// ########################### XMLStyle1 ################################ + + +//______________________________________________________________________________ +Int_t TXMLBuffer::CheckByteCount(UInt_t /*r_s */, UInt_t /*r_c*/, const TClass* /*cl*/) { + return 0; +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::CheckByteCount(UInt_t, UInt_t, const char*) { + return 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::SetByteCount(UInt_t, Bool_t) { +} + +Version_t TXMLBuffer::ReadVersion(UInt_t *start, UInt_t *bcnt, const TClass * /*cl*/) { + + BeforeIOoperation(); + + Version_t res = 0; + + if (start) *start = 0; + if (bcnt) *bcnt = 0; + + if (VerifyNode(StackNode(),"Version")) { + res = atoi(XmlReadValue("Version")); + // cout << "Reading version from Version tag" << endl; + } else + if (VerifyNode(StackNode(),xmlNames_Class)) { + res = atoi(gXML->GetProp(StackNode(), xmlNames_Version)); + } else { + cerr << "Error reading version " << endl; + fErrorFlag = 1; + } + + if (gDebug>2) + cout << " version = " << res << endl; + + return res; +} + +//______________________________________________________________________________ +void TXMLBuffer::CheckVersionBuf() { + if (IsWriting() && (fVersionBuf>=-100)) { + char sbuf[20]; + sprintf(sbuf, "%d", fVersionBuf); + XmlWriteValue(sbuf, "Version"); + fVersionBuf = -111; + } +} + + +//______________________________________________________________________________ +UInt_t TXMLBuffer::WriteVersion(const TClass *cl, Bool_t /* useBcnt */) { +// cout << " ----> " << cl->GetName() << endl; + + BeforeIOoperation(); + + fVersionBuf = cl->GetClassVersion(); + + + if (gDebug>2) + cout << "##### TXMLBuffer::WriteVersion " << endl; + +// XmlWriteBasic(cl->GetClassVersion(), "Version"); + + return 0; +} + +//______________________________________________________________________________ +void* TXMLBuffer::ReadObjectAny(const TClass*) { + BeforeIOoperation(); + if (gDebug>2) + cout << "TXMLBuffer::ReadObjectAny " << gXML->GetNodeName(StackNode()) << endl; + void* res = XmlReadObjectNew(0); + return res; +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteObject(const void *actualObjStart, const TClass *actualClass) { + BeforeIOoperation(); + if (gDebug>2) + cout << "TXMLBuffer::WriteObject of class " << (actualClass ? actualClass->GetName() : " null") << endl; + XmlWriteObjectNew(actualObjStart, actualClass); +} + +// ########################### XMLStyle2 ################################ + +#define TXMLReadArrayCompress0(vname) { \ + for(Int_t indx=0;indx<n;indx++) \ + XmlReadBasic(vname[indx]); \ +} + +#define TXMLReadArrayCompress(vname) { \ + Int_t indx = 0; \ + while(indx<n) { \ + Int_t cnt = 1; \ + if (gXML->HasProp(StackNode(), "cnt")) { \ + cnt = atoi(gXML->GetProp(StackNode(), "cnt")); \ + } \ + XmlReadBasic(vname[indx]); \ + Int_t curr = indx; indx++; \ + while(cnt>1) {\ + vname[indx] = vname[curr]; \ + cnt--; indx++; \ + } \ + } \ +} + + + +#define TXMLBuffer_ReadArray(tname, vname) \ +{ \ + BeforeIOoperation(); \ + if (!IsConvertBasicTypes()) \ + return TBuffer::ReadArray(vname); \ + Int_t n = atoi(gXML->GetProp(StackNode(), xmlNames_Size)); \ + if (n<=0) return 0; \ + if (!vname) vname = new tname[n]; \ + PushStack(StackNode()); \ + TXMLReadArrayCompress(vname); \ + PopStack(); \ + ShiftStack("readarr"); \ + return n; \ +} + + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(Bool_t *&b) { + TXMLBuffer_ReadArray(Bool_t,b); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(Char_t *&c) { + TXMLBuffer_ReadArray(Char_t,c); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(UChar_t *&c) { + TXMLBuffer_ReadArray(UChar_t,c); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(Short_t *&h) { + TXMLBuffer_ReadArray(Short_t,h); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(UShort_t *&h) { + TXMLBuffer_ReadArray(UShort_t,h); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(Int_t *&i) { + TXMLBuffer_ReadArray(Int_t,i); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(UInt_t *&i) { + TXMLBuffer_ReadArray(UInt_t,i); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(Long_t *&l) { + TXMLBuffer_ReadArray(Long_t,l); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(ULong_t *&l) { + TXMLBuffer_ReadArray(ULong_t,l); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(Long64_t *&l) { + TXMLBuffer_ReadArray(Long64_t,l); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(ULong64_t *&l) { + TXMLBuffer_ReadArray(ULong64_t,l); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(Float_t *&f) { + TXMLBuffer_ReadArray(Float_t,f); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArray(Double_t *&d) { + TXMLBuffer_ReadArray(Double_t,d); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadArrayDouble32(Double_t *&d) { + if (!IsConvertBasicTypes()) + return TBuffer::ReadArrayDouble32(d); + TXMLBuffer_ReadArray(Double_t,d); +} + + +#define TXMLBuffer_ReadStaticArray(vname) \ +{ \ + BeforeIOoperation(); \ + if (!IsConvertBasicTypes()) \ + return TBuffer::ReadStaticArray(vname); \ + Int_t n = atoi(gXML->GetProp(StackNode(), xmlNames_Size)); \ + if (n<=0) return 0; \ + if (!vname) return 0; \ + PushStack(StackNode()); \ + TXMLReadArrayCompress(vname); \ + PopStack(); \ + ShiftStack("readstatarr"); \ + return n; \ +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(Bool_t *b) { + TXMLBuffer_ReadStaticArray(b); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(Char_t *c) { + TXMLBuffer_ReadStaticArray(c); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(UChar_t *c) { + TXMLBuffer_ReadStaticArray(c); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(Short_t *h) { + TXMLBuffer_ReadStaticArray(h); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(UShort_t *h) { + TXMLBuffer_ReadStaticArray(h); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(Int_t *i) { + TXMLBuffer_ReadStaticArray(i); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(UInt_t *i) { + TXMLBuffer_ReadStaticArray(i); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(Long_t *l) { + TXMLBuffer_ReadStaticArray(l); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(ULong_t *l) { + TXMLBuffer_ReadStaticArray(l); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(Long64_t *l) { + TXMLBuffer_ReadStaticArray(l); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(ULong64_t *l) { + TXMLBuffer_ReadStaticArray(l); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(Float_t *f) { + TXMLBuffer_ReadStaticArray(f); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArray(Double_t *d) { + TXMLBuffer_ReadStaticArray(d); +} + +//______________________________________________________________________________ +Int_t TXMLBuffer::ReadStaticArrayDouble32(Double_t *d) { + if (!IsConvertBasicTypes()) + return TBuffer::ReadStaticArrayDouble32(d); + TXMLBuffer_ReadStaticArray(d); +} + +#define TXMLBuffer_ReadFastArray(vname) \ +{ \ + BeforeIOoperation(); \ + if (!IsConvertBasicTypes()) { \ + TBuffer::ReadFastArray(vname, n); \ + return; \ + } \ + if (n<=0) return; \ + if (fExpectedChain) { \ + fExpectedChain = kFALSE; \ + TStreamerInfo* info = Stack(1)->fInfo; \ + Int_t startnumber = Stack(0)->fElemNumber; \ + fCanUseCompact = kTRUE; \ + XmlReadBasic(vname[0]); \ + for(Int_t indx=1;indx<n; indx++) { \ + PopStack(); \ + ShiftStack("chainreader"); \ + TStreamerElement* elem = info->GetStreamerElementReal(startnumber, indx); \ + fCanUseCompact = kTRUE; \ + VerifyElemNode(elem); \ + XmlReadBasic(vname[indx]); \ + } \ + } else { \ + PushStack(StackNode()); \ + TXMLReadArrayCompress(vname); \ + PopStack(); \ + ShiftStack("readfastarr"); \ + } \ +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(Bool_t *b, Int_t n) { + TXMLBuffer_ReadFastArray(b); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(Char_t *c, Int_t n) { + if ((n>0) && VerifyNode(StackNode(), xmlNames_CharStar)) { + const char* buf = XmlReadValue(xmlNames_CharStar); + Int_t size = strlen(buf); + if (size<n) size = n; + memcpy(c, buf, size); + } else + TXMLBuffer_ReadFastArray(c); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(UChar_t *c, Int_t n) { + TXMLBuffer_ReadFastArray(c); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(Short_t *h, Int_t n) { + TXMLBuffer_ReadFastArray(h); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(UShort_t *h, Int_t n) { + TXMLBuffer_ReadFastArray(h); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(Int_t *i, Int_t n) { + TXMLBuffer_ReadFastArray(i); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(UInt_t *i, Int_t n) { + TXMLBuffer_ReadFastArray(i); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(Long_t *l, Int_t n) { + TXMLBuffer_ReadFastArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(ULong_t *l, Int_t n) { + TXMLBuffer_ReadFastArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(Long64_t *l, Int_t n) { + TXMLBuffer_ReadFastArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(ULong64_t *l, Int_t n) { + TXMLBuffer_ReadFastArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(Float_t *f, Int_t n) { + TXMLBuffer_ReadFastArray(f); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(Double_t *d, Int_t n) { + TXMLBuffer_ReadFastArray(d); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArrayDouble32(Double_t *d, Int_t n) { + BeforeIOoperation(); + if (!IsConvertBasicTypes()) { + TBuffer::ReadFastArrayDouble32(d, n); + return; + } + TXMLBuffer_ReadFastArray(d); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(void *start, const TClass *cl, Int_t n, TMemberStreamer *s) { + TBuffer::ReadFastArray(start, cl, n, s); +} + +//______________________________________________________________________________ +void TXMLBuffer::ReadFastArray(void **startp, const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *s) { + TBuffer::ReadFastArray(startp, cl, n, isPreAlloc, s); +} + +#define TXMLWriteArrayCompress0(vname) { \ + for(Int_t indx=0;indx<n;indx++) \ + XmlWriteBasic(vname[indx]); \ +} + + +#define TXMLWriteArrayCompress(vname) { \ + Int_t indx = 0; \ + while(indx<n) { \ + xmlNodePointer elemnode = XmlWriteBasic(vname[indx]); \ + Int_t curr = indx; indx++; \ + while ((indx<n) && (vname[indx]==vname[curr])) indx++; \ + if (indx-curr > 1) { \ + char sbuf[10]; \ + sprintf(sbuf,"%d",indx-curr); \ + gXML->NewProp(elemnode,0,"cnt",sbuf); \ + } \ + } \ +} + + +#define TXMLBuffer_WriteArray(vname) \ +{ \ + BeforeIOoperation(); \ + if (!IsConvertBasicTypes()) { \ + TBuffer::WriteArray(vname, n); \ + return; \ + } \ + xmlNodePointer arrnode = gXML->NewChild(StackNode(), 0, xmlNames_Array, 0); \ + char sbuf[50]; \ + sprintf(sbuf,"%d",n); \ + gXML->NewProp(arrnode, 0, xmlNames_Size, sbuf); \ + PushStack(arrnode); \ + TXMLWriteArrayCompress(vname); \ + PopStack(); \ +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const Bool_t *b, Int_t n) { + TXMLBuffer_WriteArray(b); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const Char_t *c, Int_t n) { + TXMLBuffer_WriteArray(c); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const UChar_t *c, Int_t n) { + TXMLBuffer_WriteArray(c); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const Short_t *h, Int_t n) { + TXMLBuffer_WriteArray(h); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const UShort_t *h, Int_t n) { + TXMLBuffer_WriteArray(h); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const Int_t *i, Int_t n) { + TXMLBuffer_WriteArray(i); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const UInt_t *i, Int_t n) { + TXMLBuffer_WriteArray(i); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const Long_t *l, Int_t n) { + TXMLBuffer_WriteArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const ULong_t *l, Int_t n) { + TXMLBuffer_WriteArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const Long64_t *l, Int_t n) { + TXMLBuffer_WriteArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const ULong64_t *l, Int_t n) { + TXMLBuffer_WriteArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const Float_t *f, Int_t n) { + TXMLBuffer_WriteArray(f); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArray(const Double_t *d, Int_t n) { + TXMLBuffer_WriteArray(d); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteArrayDouble32(const Double_t *d, Int_t n) { + if (!IsConvertBasicTypes()) { + TBuffer::WriteArrayDouble32(d, n); + return; + } + TXMLBuffer_WriteArray(d); +} + + +#define TXMLBuffer_WriteFastArray(vname) \ +{ \ + BeforeIOoperation(); \ + if (!IsConvertBasicTypes()) { \ + TBuffer::WriteFastArray(vname, n); \ + return; \ + } \ + if (n<=0) return; \ + if (fExpectedChain) { \ + fExpectedChain = kFALSE; \ + TStreamerInfo* info = Stack(1)->fInfo; \ + Int_t startnumber = Stack(0)->fElemNumber; \ + fCanUseCompact = kTRUE; \ + XmlWriteBasic(vname[0]); \ + for(Int_t indx=1;indx<n; indx++) { \ + PopStack(); \ + TStreamerElement* elem = info->GetStreamerElementReal(startnumber, indx); \ + CreateElemNode(elem); \ + fCanUseCompact = kTRUE; \ + XmlWriteBasic(vname[indx]); \ + } \ + } else {\ + xmlNodePointer arrnode = gXML->NewChild(StackNode(), 0, xmlNames_Array, 0); \ + PushStack(arrnode); \ + TXMLWriteArrayCompress(vname); \ + PopStack(); \ + } \ +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const Bool_t *b, Int_t n) { + TXMLBuffer_WriteFastArray(b); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const Char_t *c, Int_t n) { + Bool_t usedefault = (n==0) || fExpectedChain; + const Char_t* buf = c; + if (!usedefault) + for (int i=0;i<n;i++) { + if ((*buf<26) || (*buf=='<') || (*buf=='>') || (*buf=='\"')) + { usedefault = kTRUE; break; } + buf++; + } + if (usedefault) { + TXMLBuffer_WriteFastArray(c); + } else { + Char_t* buf = new Char_t[n+1]; + memcpy(buf, c, n); + buf[n] = 0; + XmlWriteValue(buf, xmlNames_CharStar); + delete[] buf; + } +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const UChar_t *c, Int_t n) { + TXMLBuffer_WriteFastArray(c); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const Short_t *h, Int_t n) { + TXMLBuffer_WriteFastArray(h); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const UShort_t *h, Int_t n) { + TXMLBuffer_WriteFastArray(h); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const Int_t *i, Int_t n) { + TXMLBuffer_WriteFastArray(i); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const UInt_t *i, Int_t n) { + TXMLBuffer_WriteFastArray(i); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const Long_t *l, Int_t n) { + TXMLBuffer_WriteFastArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const ULong_t *l, Int_t n) { + TXMLBuffer_WriteFastArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const Long64_t *l, Int_t n) { + TXMLBuffer_WriteFastArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const ULong64_t *l, Int_t n) { + TXMLBuffer_WriteFastArray(l); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const Float_t *f, Int_t n) { + TXMLBuffer_WriteFastArray(f); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(const Double_t *d, Int_t n) { + TXMLBuffer_WriteFastArray(d); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArrayDouble32(const Double_t *d, Int_t n) { + BeforeIOoperation(); + if (!IsConvertBasicTypes()) { + TBuffer::WriteFastArrayDouble32(d, n); + return; + } + TXMLBuffer_WriteFastArray(d); +} + +//______________________________________________________________________________ +void TXMLBuffer::WriteFastArray(void *start, const TClass *cl, Int_t n, TMemberStreamer *s) { + TBuffer::WriteFastArray(start, cl, n, s); +} + +Int_t TXMLBuffer::WriteFastArray(void **startp, const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *s) { + return TBuffer::WriteFastArray(startp, cl, n, isPreAlloc, s); +} + + +//______________________________________________________________________________ +void TXMLBuffer::StreamObject(void *obj, const type_info &typeinfo) { + StreamObject(obj, gROOT->GetClass(typeinfo)); +} + +//______________________________________________________________________________ +void TXMLBuffer::StreamObject(void *obj, const char *className) { + StreamObject(obj, gROOT->GetClass(className)); +} + +//______________________________________________________________________________ +void TXMLBuffer::StreamObject(void *obj, const TClass *cl) { + BeforeIOoperation(); + if (gDebug>1) + cout << " TXMLBuffer::StreamObject class = " << (cl ? cl->GetName() : "none") << endl; + if (IsReading()) { + XmlReadObjectNew(obj); + } else { + XmlWriteObjectNew(obj, cl); + } +} + +#define TXMLBuffer_operatorin(vname) \ +{ \ + BeforeIOoperation(); \ + if (IsConvertBasicTypes()) { \ + XmlReadBasic(vname); \ + return *this; \ + } else \ + return TBuffer::operator>>(vname); \ +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(Bool_t &b) { + TXMLBuffer_operatorin(b); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(Char_t &c) { + TXMLBuffer_operatorin(c); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(UChar_t &c) { + TXMLBuffer_operatorin(c); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(Short_t &h) { + TXMLBuffer_operatorin(h); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(UShort_t &h) { + TXMLBuffer_operatorin(h); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(Int_t &i) { + TXMLBuffer_operatorin(i); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(UInt_t &i) { + TXMLBuffer_operatorin(i); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(Long_t &l) { + TXMLBuffer_operatorin(l); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(ULong_t &l) { + TXMLBuffer_operatorin(l); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(Long64_t &l) { + TXMLBuffer_operatorin(l); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(ULong64_t &l) { + TXMLBuffer_operatorin(l); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(Float_t &f) { + TXMLBuffer_operatorin(f); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(Double_t &d) { + TXMLBuffer_operatorin(d); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator>>(Char_t *c) { + BeforeIOoperation(); + if (IsConvertBasicTypes()) { + const char* buf = XmlReadValue(xmlNames_CharStar); + strcpy(c, buf); + return *this; + } else return TBuffer::operator>>(c); +} + +#define TXMLBuffer_operatorout(vname) \ +{ \ + BeforeIOoperation(); \ + if (IsConvertBasicTypes()) { \ + XmlWriteBasic(vname); \ + return *this; \ + } else { \ + return TBuffer::operator<<(vname); \ + } \ +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(Bool_t b) { + TXMLBuffer_operatorout(b); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(Char_t c) { + TXMLBuffer_operatorout(c); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(UChar_t c) { + TXMLBuffer_operatorout(c); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(Short_t h) { + TXMLBuffer_operatorout(h); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(UShort_t h) { + TXMLBuffer_operatorout(h); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(Int_t i) { + TXMLBuffer_operatorout(i); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(UInt_t i) { + TXMLBuffer_operatorout(i); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(Long_t l) { + TXMLBuffer_operatorout(l); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(ULong_t l) { + TXMLBuffer_operatorout(l); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(Long64_t l) { + TXMLBuffer_operatorout(l); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(ULong64_t l) { + TXMLBuffer_operatorout(l); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(Float_t f) { + TXMLBuffer_operatorout(f); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(Double_t d) { + TXMLBuffer_operatorout(d); +} + +//______________________________________________________________________________ +TBuffer& TXMLBuffer::operator<<(const Char_t *c) { + BeforeIOoperation(); + if (IsConvertBasicTypes()) { + XmlWriteValue(c, xmlNames_CharStar); + return *this; + } else return TBuffer::operator<<(c); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(Char_t value) { + char buf[50]; + sprintf(buf,"%d", value); + return XmlWriteValue(buf, xmlNames_Char); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(Short_t value) { + char buf[50]; + sprintf(buf,"%hd", value); + return XmlWriteValue(buf, xmlNames_Short); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(Int_t value) { + char buf[50]; + sprintf(buf,"%d", value); + return XmlWriteValue(buf, xmlNames_Int); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(Long_t value) { + char buf[50]; + sprintf(buf,"%ld", value); + return XmlWriteValue(buf, xmlNames_Long); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(Long64_t value) { + char buf[50]; + sprintf(buf,"%lld", value); + return XmlWriteValue(buf, xmlNames_Long64); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(Float_t value) { + char buf[200]; + sprintf(buf,"%f", value); + return XmlWriteValue(buf, xmlNames_Float); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(Double_t value) { + char buf[1000]; + sprintf(buf,"%f", value); + return XmlWriteValue(buf, xmlNames_Double); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(Bool_t value) { + return XmlWriteValue(value ? "true" : "false", xmlNames_Bool); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(UChar_t value) { + char buf[50]; + sprintf(buf,"%u", value); + return XmlWriteValue(buf, xmlNames_UChar); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(UShort_t value) { + char buf[50]; + sprintf(buf,"%hu", value); + return XmlWriteValue(buf, xmlNames_UShort); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(UInt_t value) { + char buf[50]; + sprintf(buf,"%u", value); + return XmlWriteValue(buf, xmlNames_UInt); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(ULong_t value) { + char buf[50]; + sprintf(buf,"%lu", value); + return XmlWriteValue(buf, xmlNames_ULong); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteBasic(ULong64_t value) { + char buf[50]; + sprintf(buf,"%llu", value); + return XmlWriteValue(buf, xmlNames_ULong64); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteValue(const char* value, + const char* name) { + TXMLLayout mode = GetXmlLayout(); + + xmlNodePointer node = 0; + + if (mode==kGeneralized) { + // node = XmlCreateMember(name, name_t, value); + } else { + if (fCanUseCompact) node = StackNode(); + else node = gXML->NewChild(StackNode(), 0, name, 0); + + gXML->NewProp(node, 0, "v", value); + } + + fCanUseCompact = kFALSE; + + return node; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(Char_t& value) { + const char* res = XmlReadValue(xmlNames_Char); + if (res) { + int n; + sscanf(res,"%d", &n); + value = n; + } else + value = 0; + +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(Short_t& value) { + const char* res = XmlReadValue(xmlNames_Short); + if (res) + sscanf(res,"%hd", &value); + else + value = 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(Int_t& value) { + const char* res = XmlReadValue(xmlNames_Int); + if (res) + sscanf(res,"%d", &value); + else + value = 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(Long_t& value) { + const char* res = XmlReadValue(xmlNames_Long); + if (res) + sscanf(res,"%ld", &value); + else + value = 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(Long64_t& value) { + const char* res = XmlReadValue(xmlNames_Long64); + if (res) + sscanf(res,"%lld", &value); + else + value = 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(Float_t& value) { + const char* res = XmlReadValue(xmlNames_Float); + if (res) + sscanf(res,"%f", &value); + else + value = 0.; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(Double_t& value) { + const char* res = XmlReadValue(xmlNames_Double); + if (res) + sscanf(res,"%lf", &value); + else + value = 0.; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(Bool_t& value) { + const char* res = XmlReadValue(xmlNames_Bool); + if (res) + value = (strcmp(res,"true")==0); + else + value = kFALSE; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(UChar_t& value) { + const char* res = XmlReadValue(xmlNames_UChar); + if (res) { + unsigned int n; + sscanf(res,"%ud", &n); + value = n; + } else + value = 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(UShort_t& value) { + const char* res = XmlReadValue(xmlNames_UShort); + if (res) + sscanf(res,"%hud", &value); + else + value = 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(UInt_t& value) { + const char* res = XmlReadValue(xmlNames_UInt); + if (res) + sscanf(res,"%u", &value); + else + value = 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(ULong_t& value) { + const char* res = XmlReadValue(xmlNames_ULong); + if (res) + sscanf(res,"%lu", &value); + else + value = 0; +} + +//______________________________________________________________________________ +void TXMLBuffer::XmlReadBasic(ULong64_t& value) { + const char* res = XmlReadValue(xmlNames_ULong64); + if (res) + sscanf(res,"%llu", &value); + else + value = 0; +} + +//______________________________________________________________________________ +const char* TXMLBuffer::XmlReadValue(const char* name) { + if (fErrorFlag>0) return 0; + + TXMLLayout mode = GetXmlLayout(); + + if (mode==kGeneralized) { + // if (!VerifyMember(name, name_t, -1, "XmlReadValue")) return 0; + // fValueBuf = gXML->GetProp(StackNode(), xmlNames_Value); + // ShiftStack("general"); + } else { + + if (gDebug>4) + cout << " read value " << name << " = " ; + + Bool_t trysimple = fCanUseCompact; + fCanUseCompact = kFALSE; + + if (trysimple) + if (gXML->HasProp(Stack(1)->fNode,"v")) + fValueBuf = gXML->GetProp(Stack(1)->fNode, "v"); + else + trysimple = kFALSE; + + if (!trysimple) { + if (!VerifyStackNode(name, "XmlReadValue")) return 0; + fValueBuf = gXML->GetProp(StackNode(), "v"); + } + + if (gDebug>4) + cout << fValueBuf << endl; + + if (!trysimple) + ShiftStack("readvalue"); + } + + return fValueBuf.Data(); +} + + +// ******************************** new stuff ***********************************8 + +//______________________________________________________________________________ +xmlNodePointer TXMLBuffer::XmlWriteObjectNew(const void* obj, + const TClass* cl) { + xmlNodePointer objnode = gXML->NewChild(StackNode(), 0, xmlNames_Object, 0); + + if (!cl) obj = 0; + if (ProcessPointer(obj, objnode)) return objnode; + + TString clname = XmlConvertClassName(cl); + + gXML->NewProp(objnode, 0, "class", clname); + + RegisterPointer(obj, objnode); + + PushStack(objnode); + + ((TClass*)cl)->Streamer((void*)obj, *this); + + PopStack(); + + if (gDebug>1) + cout << "Done write of " << cl->GetName() << endl; + + return objnode; +} + +//______________________________________________________________________________ +void* TXMLBuffer::XmlReadObjectNew(void* obj) { + + xmlNodePointer objnode = StackNode(); + + if (fErrorFlag>0) return obj; + + if (objnode==0) return obj; + + if (!VerifyNode(objnode, xmlNames_Object, "XmlReadObjectNew")) return obj; + + if (ExtractPointer(objnode, obj)) + return obj; + + TString clname = gXML->GetProp(objnode, "class"); + TClass* objClass = XmlDefineClass(clname); + + if (objClass==0) { + cerr << "Cannot find class " << clname << endl; + return obj; + } + + if (gDebug>1) + cout << "Reading object of class " << clname << endl; + + if (obj==0) obj = objClass->New(); + + ExtractObjectId(objnode, obj); + + PushStack(objnode); + + objClass->Streamer((void*)obj, *this); + + PopStack(); + + ShiftStack("readobj"); + + if (gDebug>1) + cout << "Read object of class " << clname << " done" << endl << endl; + + return obj; +} + + + +//______________________________________________________________________________ +void TXMLBuffer::IncrementLevel(TStreamerInfo* info) { + if (info==0) return; + + fCanUseCompact = kFALSE; + fExpectedChain = kFALSE; + + TString clname = XmlConvertClassName(info->GetClass()); + + if (gDebug>2) + cout << " TXMLBuffer::StartInfo " << clname << endl; + + if (IsWriting()) { + xmlNodePointer classnode = gXML->NewChild(StackNode(), 0, xmlNames_Class, 0); + gXML->NewProp(classnode, 0, "name", clname); + + if (fVersionBuf>=0) { + char sbuf[20]; + sprintf(sbuf,"%d", fVersionBuf); + gXML->NewProp(classnode, 0, xmlNames_Version, sbuf); + fVersionBuf = -111; + } + + TXMLStackObj* stack = PushStack(classnode); + stack->fInfo = info; + } else { + if (!VerifyNode(StackNode(), xmlNames_Class, "StartInfo")) return; + if (!VerifyProp(StackNode(), "name", clname, "StartInfo")) return; + + TXMLStackObj* stack = PushStack(StackNode()); + stack->fInfo = info; + + } +} + +//______________________________________________________________________________ +void TXMLBuffer::CreateElemNode(const TStreamerElement* elem, Int_t number) { + xmlNodePointer elemnode = 0; + + if (GetXmlLayout()==kGeneralized) { + elemnode = gXML->NewChild(StackNode(), 0, xmlNames_Member, 0); + gXML->NewProp(elemnode, 0, xmlNames_Name, elem->GetName()); + char sbuf[20]; + sprintf(sbuf,"%d", elem->GetType()); + gXML->NewProp(elemnode, 0, xmlNames_Type, sbuf); + } else { + + elemnode = gXML->NewChild(StackNode(), 0, elem->GetName(), 0); + } + + TXMLStackObj* curr = PushStack(elemnode); + curr->fLastElem = (TStreamerElement*)elem; + curr->fElemNumber = number; +} + +//______________________________________________________________________________ +Bool_t TXMLBuffer::VerifyElemNode(const TStreamerElement* elem, Int_t number) { + if (GetXmlLayout()==kGeneralized) { + if (!VerifyNode(StackNode(), xmlNames_Member)) return kFALSE; + if (!VerifyProp(StackNode(), xmlNames_Name, elem->GetName())) return kFALSE; + char sbuf[20]; + sprintf(sbuf,"%d", elem->GetType()); + if (!VerifyProp(StackNode(), xmlNames_Type, sbuf)) return kFALSE; + } else { + if (!VerifyNode(StackNode(), elem->GetName())) return kFALSE; + } + + TXMLStackObj* curr = PushStack(StackNode()); // set pointer to first data inside element + curr->fLastElem = (TStreamerElement*)elem; + curr->fElemNumber = number; + return kTRUE; +} + + + +//______________________________________________________________________________ +void TXMLBuffer::SetStreamerElementNumber(Int_t number) { + CheckVersionBuf(); + + TXMLStackObj* stack = dynamic_cast<TXMLStackObj*> (fStack.Last()); + if (stack==0) { + cerr << "fatal error in SeStreamerElementNumber" << endl; + return; + } + + fExpectedChain = kFALSE; + fCanUseCompact = kFALSE; + + if (IsWriting()) { + + if (stack->fInfo==0) { // this is not a first element + PopStack(); + stack = dynamic_cast<TXMLStackObj*> (fStack.Last()); + } + + TStreamerInfo* info = stack->fInfo; + + TStreamerElement* elem = info->GetStreamerElementReal(number, 0); + + Int_t comp_type = info->GetTypes()[number]; + + Bool_t isBasicType = (elem->GetType()>0) && (elem->GetType()<20); + + fCanUseCompact = isBasicType && (elem->GetType()==comp_type); + + fExpectedChain = isBasicType && (comp_type - elem->GetType() == TStreamerInfo::kOffsetL); + + CreateElemNode(elem, number); + + if (fExpectedChain && (gDebug>3)) { + cout << "Expects chain for class " << info->GetName() + << " in elem " << elem->GetName() << " number " << number << endl; + } + + } else { + if (stack->fInfo==0) { // this is not a first element + PopStack(); // go level back + ShiftStack("startelem"); // shift to next element + stack = dynamic_cast<TXMLStackObj*> (fStack.Last()); + } + + TStreamerInfo* info = stack->fInfo; + + TStreamerElement* elem = info->GetStreamerElementReal(number, 0); + + Int_t comp_type = info->GetTypes()[number]; + + Bool_t isBasicType = (elem->GetType()>0) && (elem->GetType()<20); + + fCanUseCompact = isBasicType && (elem->GetType()==comp_type); + + fExpectedChain = isBasicType && (comp_type - elem->GetType() == TStreamerInfo::kOffsetL); + + if (!VerifyElemNode(elem, number)) return; + } +} + + +//______________________________________________________________________________ +void TXMLBuffer::StartElement(TStreamerElement* elem) { + CheckVersionBuf(); + + TXMLStackObj* stack = dynamic_cast<TXMLStackObj*> (fStack.Last()); + if (stack==0) { + cerr << "Fatal error in StartElement" << endl; + return; + } + + TString elemname = elem->GetName(); + + fCanUseCompact = (elem->GetType()>0) && (elem->GetType()<20); + + if (gDebug>2) + cout << " TXMLBuffer::StartElement " << elemname << endl; + + if (IsWriting()) { + + if (stack->fInfo==0) // this is not a first element + PopStack(); + xmlNodePointer elemnode = gXML->NewChild(StackNode(), 0, elemname , 0); + + TXMLStackObj* curr = PushStack(elemnode); + curr->fLastElem = elem; + } else { + if (stack->fInfo==0) { // this is not a first element + PopStack(); // go level back + ShiftStack("startelem"); // shift to next element + } + + if (!VerifyNode(StackNode(), elemname, "StartElement")) return; + + TXMLStackObj* curr = PushStack(StackNode()); // set pointer to first data inside element + curr->fLastElem = elem; + } +} + +//______________________________________________________________________________ +void TXMLBuffer::DecrementLevel(TStreamerInfo* info) { + CheckVersionBuf(); + + if (info==0) return; + + fCanUseCompact = kFALSE; + fExpectedChain = kFALSE; + + // cout << " <++++ " << info->GetName() << endl; + + if (gDebug>2) + cout << " TXMLBuffer::StopInfo " << info->GetClass()->GetName() << endl; + + TXMLStackObj* stack = dynamic_cast<TXMLStackObj*> (fStack.Last()); + + if (IsWriting()) { + if (stack->fInfo==0) PopStack(); // remove stack of last element + PopStack(); + } else { + if (stack->fInfo==0) PopStack(); // back from data of last element + PopStack(); // back from data of stack info + ShiftStack("declevel"); // shift to next element after streamer info + } +} + + +//______________________________________________________________________________ +void TXMLBuffer::BeforeIOoperation() { + // this function is called before any IO operation of TBuffer + CheckVersionBuf(); +} + diff --git a/xml/src/TXMLDtdGenerator.cxx b/xml/src/TXMLDtdGenerator.cxx new file mode 100644 index 00000000000..5e096984ae8 --- /dev/null +++ b/xml/src/TXMLDtdGenerator.cxx @@ -0,0 +1,602 @@ +// @(#)root/xml:$Name: $:$Id: TXMLDtdGenerator.cxx,v 1.0 2004/04/21 15:06:45 brun Exp $ +// Author: Sergey Linev 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#include "TXMLDtdGenerator.h" + +#include "TStreamerElement.h" +#include "TStreamerInfo.h" +#include "TCollection.h" + +#include "Riostream.h" + +ClassImp(TXMLDtdGenerator); + +//______________________________________________________________________________ +TXMLDtdGenerator::TXMLDtdGenerator() : TXMLSetup() { +} + +//______________________________________________________________________________ +TXMLDtdGenerator::TXMLDtdGenerator(const char* setup) : TXMLSetup(setup) { +} + +//______________________________________________________________________________ +TXMLDtdGenerator::TXMLDtdGenerator(const TXMLSetup& setup) : TXMLSetup(setup) { +} + +//______________________________________________________________________________ +TXMLDtdGenerator::~TXMLDtdGenerator() { +} + +//______________________________________________________________________________ +void TXMLDtdGenerator::AddClassSpace(TCollection* col) { + if (col==0) col = gROOT->GetListOfClasses(); + fClassSpace.AddAll(col); +} + +//______________________________________________________________________________ +void TXMLDtdGenerator::AddInstrumentedClass(TStreamerInfo* info) { + if (info==0) return; + if (fInstrumentedClasses.FindObject(info)==0) + fInstrumentedClasses.Add(info); + TClass* cl = (TClass*) fBlackClasses.FindObject(info->GetClass()); + if (cl!=0) { + fBlackClasses.Remove(cl); + fBlackClasses.Compress(); + } +} + +//______________________________________________________________________________ +void TXMLDtdGenerator::AddBlackClass(TClass* cl) { + if (cl==0) return; + if (fBlackClasses.FindObject(cl)!=0) return; + + for(int n=0;n<=fInstrumentedClasses.GetLast();n++) { + TStreamerInfo* info = (TStreamerInfo*) fInstrumentedClasses.At(n); + if (cl==info->GetClass()) return; + } + + fBlackClasses.Add(cl); +} + + +//______________________________________________________________________________ +void TXMLDtdGenerator::AddUsedClass(TClass * cl) { + if ((cl!=0) && (fUsedClasses.FindObject(cl)==0)) + fUsedClasses.Add(cl); +} + +//______________________________________________________________________________ +void TXMLDtdGenerator::Produce(const char* fname, TClass* onlyclass) { + if (fname==0) return; + + ofstream fs(fname); + + if (GetXmlLayout()==kGeneralized) + ProduceGeneralDtd(fs, onlyclass); + else + ProduceSpecificDtd(fs, onlyclass); +} + +//______________________________________________________________________________ +Int_t TXMLDtdGenerator::dtdType(TStreamerElement* el) { + if (el==0) return dtd_none; + + Int_t typ = el->GetType(); + + switch (typ) { + // write basic types + case TStreamerInfo::kChar: + case TStreamerInfo::kShort: + case TStreamerInfo::kInt: + case TStreamerInfo::kLong: + case TStreamerInfo::kLong64: + case TStreamerInfo::kFloat: + case TStreamerInfo::kDouble: + case TStreamerInfo::kUChar: + case TStreamerInfo::kUShort: + case TStreamerInfo::kUInt: + case TStreamerInfo::kULong: + case TStreamerInfo::kULong64: + case TStreamerInfo::kDouble32: + if (GetXmlLayout()==0) return dtd_attr; + else return dtd_elem; + + case TStreamerInfo::kOffsetL + TStreamerInfo::kChar: + case TStreamerInfo::kOffsetL + TStreamerInfo::kShort: + case TStreamerInfo::kOffsetL + TStreamerInfo::kInt: + case TStreamerInfo::kOffsetL + TStreamerInfo::kLong: + case TStreamerInfo::kOffsetL + TStreamerInfo::kLong64: + case TStreamerInfo::kOffsetL + TStreamerInfo::kFloat: + case TStreamerInfo::kOffsetL + TStreamerInfo::kDouble: + case TStreamerInfo::kOffsetL + TStreamerInfo::kUChar: + case TStreamerInfo::kOffsetL + TStreamerInfo::kUShort: + case TStreamerInfo::kOffsetL + TStreamerInfo::kUInt: + case TStreamerInfo::kOffsetL + TStreamerInfo::kULong: + case TStreamerInfo::kOffsetL + TStreamerInfo::kULong64: + case TStreamerInfo::kOffsetL + TStreamerInfo::kDouble32: + return dtd_fixarray; + + // write pointer to an array of basic types array[n] + case TStreamerInfo::kOffsetP + TStreamerInfo::kChar: + case TStreamerInfo::kOffsetP + TStreamerInfo::kShort: + case TStreamerInfo::kOffsetP + TStreamerInfo::kInt: + case TStreamerInfo::kOffsetP + TStreamerInfo::kLong: + case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: + case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat: + case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: + case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar: + case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: + case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt: + case TStreamerInfo::kOffsetP + TStreamerInfo::kULong: + case TStreamerInfo::kOffsetP + TStreamerInfo::kULong64: + case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble32: + return dtd_array; + + // array counter [n] + // info used by TBranchElement::FillLeaves + case TStreamerInfo::kCounter: + if (GetXmlLayout()==0) return dtd_attr; + else return dtd_elem; + + // char* + case TStreamerInfo::kCharStar: + return dtd_charstar; + + // special case for TObject::fBits in case of a referenced object + case TStreamerInfo::kBits: + if (GetXmlLayout()==0) return dtd_attr; + else return dtd_elem; + + case TStreamerInfo::kTString: + if (GetXmlLayout()==0) return dtd_attr; + else return dtd_elem; + + // Class* Class not derived from TObject and with comment field //-> + case TStreamerInfo::kAnyp: + case TStreamerInfo::kAnyp + TStreamerInfo::kOffsetL: + + // Class * Class derived from TObject and with comment field //-> + case TStreamerInfo::kObjectp: + case TStreamerInfo::kObjectp + TStreamerInfo::kOffsetL: + return dtd_fastobj1; + + // Class* Class not derived from TObject and no comment + case TStreamerInfo::kAnyP: + case TStreamerInfo::kAnyP + TStreamerInfo::kOffsetL: + + // Class* Class derived from TObject + case TStreamerInfo::kObjectP: + case TStreamerInfo::kObjectP + TStreamerInfo::kOffsetL: + return dtd_fastobj2; + + // Class* Class not derived from TObject and no virtual table and no comment + case TStreamerInfo::kAnyPnoVT: + case TStreamerInfo::kAnyPnoVT + TStreamerInfo::kOffsetL: + return dtd_everyobj; + + // Pointer to container with no virtual table (stl) and no comment + case TStreamerInfo::kSTLp: + // array of pointers to container with no virtual table (stl) and no comment + case TStreamerInfo::kSTLp + TStreamerInfo::kOffsetL: + return dtd_stlp; + + // container with no virtual table (stl) and no comment + case TStreamerInfo::kSTL: + // array of containers with no virtual table (stl) and no comment + case TStreamerInfo::kSTL + TStreamerInfo::kOffsetL: + + case TStreamerInfo::kTObject + TStreamerInfo::kOffsetL: + case TStreamerInfo::kTNamed + TStreamerInfo::kOffsetL: + + case TStreamerInfo::kObject: // Class derived from TObject + case TStreamerInfo::kAny: // Class NOT derived from TObject + case TStreamerInfo::kObject + TStreamerInfo::kOffsetL: + case TStreamerInfo::kAny + TStreamerInfo::kOffsetL: + return dtd_objects; + + case TStreamerInfo::kTString + TStreamerInfo::kOffsetL: + return dtd_fixarray; + + case TStreamerInfo::kTObject: + case TStreamerInfo::kTNamed: + case TStreamerInfo::kBase: + if (el->InheritsFrom(TStreamerBase::Class())) return dtd_base; + return dtd_object; + + case TStreamerInfo::kStreamer: + case TStreamerInfo::kStreamLoop: + return dtd_any; + + } // switch + + return dtd_none; +} + +//______________________________________________________________________________ +const char* TXMLDtdGenerator::dtdBaseTypeName(int typ) { + switch (typ) { + case 0: fDtdBuf = xmlNames_Bool; break; + case TStreamerInfo::kChar: fDtdBuf = xmlNames_Char; break; + case TStreamerInfo::kShort: fDtdBuf = xmlNames_Short; break; +// case TStreamerInfo::kCounter: + case TStreamerInfo::kInt: fDtdBuf = xmlNames_Int; break; + case TStreamerInfo::kLong: fDtdBuf = xmlNames_Long; break; + case TStreamerInfo::kLong64: fDtdBuf = xmlNames_Long64; break; + case TStreamerInfo::kFloat: fDtdBuf = xmlNames_Float; break; + case TStreamerInfo::kDouble: fDtdBuf = xmlNames_Double; break; + case TStreamerInfo::kUChar: fDtdBuf = xmlNames_UChar; break; + case TStreamerInfo::kUShort: fDtdBuf = xmlNames_UShort; break; +// case TStreamerInfo::kBits: + case TStreamerInfo::kUInt: fDtdBuf = xmlNames_UInt; break; + case TStreamerInfo::kULong: fDtdBuf = xmlNames_ULong; break; + case TStreamerInfo::kULong64: fDtdBuf = xmlNames_ULong64; break; +// case TStreamerInfo::kDouble32: fDtdBuf = "Double_t"; break; + case 20: fDtdBuf = xmlNames_String; break; + default: + fDtdBuf = ""; + } + return fDtdBuf.Data(); +} + + +//______________________________________________________________________________ +const char* TXMLDtdGenerator::dtdUseBaseType(TStreamerElement* el) { + if (el==0) return 0; + + int typ = el->GetType() % 20; + if ((typ==TStreamerInfo::kUChar) && + (el->GetTypeNameBasic()[0]=='B')) typ=0; + if (typ==TStreamerInfo::kCounter) typ = TStreamerInfo::kInt; + if (typ==TStreamerInfo::kBits) typ = TStreamerInfo::kUInt; + if (typ==TStreamerInfo::kDouble32) typ = TStreamerInfo::kDouble; + + if (el->GetType() == TStreamerInfo::kTString + TStreamerInfo::kOffsetL) typ = 20; + + fUsedBaseTypes[typ] = kTRUE; + + return dtdBaseTypeName(typ); +} + +void TXMLDtdGenerator::ProduceDtdForItem(ofstream& fs, const char* itemname) { + switch (GetXmlLayout()) { + case kSpecialized: + fs << "<!ELEMENT " << itemname << " EMPTY>" << endl; + fs << "<!ATTLIST " << itemname << " v CDATA #REQUIRED>" << endl; + break; + + case kGeneralized: + break; + } +} + +//______________________________________________________________________________ +void TXMLDtdGenerator::ProduceObjectElement(ofstream& fs, const char* name, TClass* cl, Bool_t isPointer) { + TString elname(name); + + if (!isPointer) { + fs << "<!ELEMENT " << elname << " (" << XmlConvertClassName(cl) << ")>" << endl; + return; + } + + fs << "<!ELEMENT " << elname << " (#PCDATA"; + + TIter iter(&fClassSpace); + TClass* cl1; + + while ((cl1 = (TClass*) iter()) != 0) + if ((cl==0) || cl1->InheritsFrom(cl)) + fs << "|" << XmlConvertClassName(cl1); + + fs << ")*>" << endl; + fs << "<!ATTLIST " << elname << " " << xmlNames_Ptr << " IDREF #IMPLIED>" << endl; +} + +//______________________________________________________________________________ +void TXMLDtdGenerator::ProduceDtdForBlackClass(ofstream& fs, TClass* cl) { + if (cl==0) return; + + TString clname = XmlConvertClassName(cl); + + fs << "<!ELEMENT " << clname << " (#PCDATA|" << xmlNames_Xmlobject << "|" << xmlNames_XmlBlock; + if (IsConvertBasicTypes()) { + fs << "|" << xmlNames_Array; + for (int n=0;n<MaxBaseTypeNum;n++) { + const char* iname = dtdBaseTypeName(n); + if (strlen(iname)>0) + fs << "|" << iname; + } + } + fs << ")*>" << endl; + + fs << "<!ATTLIST " << clname << endl; + if (IsUseNamespaces()) + fs << " xmlns:" << clname << " CDATA \"" << XmlClassNameSpaceRef(cl) << "\"" << endl; + fs << " " << xmlNames_Version << " CDATA #IMPLIED" << endl; + fs << " " << xmlNames_Ref << " ID #IMPLIED>" << endl << endl; +} + +//______________________________________________________________________________ +void TXMLDtdGenerator::ProduceDtdForInstrumentedClass(ofstream& fs, TStreamerInfo* info) { + + if (info==0) return; + TString clname = XmlConvertClassName(info->GetClass()); + + fs << "<!ELEMENT " << clname << " "; + + TObjArray* elements = info->GetElements(); + if (elements==0) return; + bool first = true, canhasblock = IsaSolidDataBlock(); + + // producing list of elements inside class element + for (int n=0;n<=elements->GetLast();n++) { + TStreamerElement* el = dynamic_cast<TStreamerElement*> (elements->At(n)); + + Int_t typ = dtdType(el); + + switch(typ) { + case dtd_none: + case dtd_attr: + continue; + + case dtd_base: + fs << (first ? "(" : ","); first=false; + fs << XmlConvertClassName(el->GetClass()); + canhasblock = true; + continue; + + default: + fs << (first ? "(" : ","); first=false; + if (IsUseNamespaces()) + fs << clname << ":"; + fs << GetElName(el); + canhasblock = canhasblock || + ((typ!=dtd_elem) && (typ!=dtd_fixarray) && (typ!=dtd_array)); + + } // switch + } + + if (canhasblock) { + fs << (first ? "(" : ","); first=false; + fs << xmlNames_XmlBlock << "?"; + } + + if (first) fs << "EMPTY>" << endl; + else fs << ")>" << endl; + + // produce attribute list for class element + + fs << "<!ATTLIST " << clname << endl; + if (IsUseNamespaces()) + fs << " xmlns:" << clname << " CDATA \"" << XmlClassNameSpaceRef(info->GetClass()) << "\"" << endl; + fs << " " << xmlNames_Version << " CDATA #IMPLIED" << endl; + + for (int n=0;n<=elements->GetLast();n++) { + TStreamerElement* el = dynamic_cast<TStreamerElement*> (elements->At(n)); + if (dtdType(el) == dtd_attr) + fs << " " << GetElName(el) << " CDATA #REQUIRED" << endl; + } + fs << " " << xmlNames_Ref << " ID #IMPLIED>" << endl; + + // produce description for each element + + for (int n=0;n<=elements->GetLast();n++) { + TStreamerElement* el = dynamic_cast<TStreamerElement*> (elements->At(n)); + int eltype = dtdType(el); + Int_t arrlen = el->GetArrayLength(); + + TString elname(GetElName(el)); + if (IsUseNamespaces()) + elname = clname + ":" + elname; + + switch(eltype) { + case dtd_none: + case dtd_attr: + continue; + + case dtd_elem: + ProduceDtdForItem(fs, elname); + continue; + + case dtd_charstar: + ProduceDtdForItem(fs, elname); + fs << "<!ATTLIST " << elname << " " << xmlNames_Size << " CDATA #REQUIRED>" << endl; + continue; + + case dtd_fixarray: { + fs << "<!ELEMENT " << elname; + if (arrlen==0) fs << " EMPTY"; else + if (arrlen>10) fs << " (" << dtdUseBaseType(el) << "+)"; else { + fs << " (" << dtdUseBaseType(el); + for (int n=1;n<arrlen;n++) + fs << "," << dtdUseBaseType(el); + fs << ")"; + } + fs << ">" << endl; + continue; + } + + case dtd_array: + fs << "<!ELEMENT " << elname << " (" << dtdUseBaseType(el) << "*)>" << endl; + continue; + + case dtd_fastobj1: + case dtd_fastobj2: + case dtd_everyobj: + case dtd_stlp: + case dtd_objects: { + if ((el->GetStreamer()!=0) && (eltype!=dtd_everyobj)) { + fs << "<!ELEMENT " << elname << " ANY>" << endl; + continue; + } + + TString elitemname(GetElItemName(el)); + if (IsUseNamespaces()) + elitemname = clname + ":" + elitemname; + + if (arrlen>1) { + fs << "<!ELEMENT " << elname << " (" << elitemname; + if (arrlen>10) fs << "+)>" << endl; else + for (int n=1;n<arrlen;n++) + fs << "," << elitemname; + fs << ")>" << endl; + ProduceObjectElement(fs, elitemname, el->GetClass(), eltype!=dtd_objects); + } else + ProduceObjectElement(fs, elname, el->GetClass(), eltype!=dtd_objects); + continue; + } + + case dtd_object: + ProduceObjectElement(fs, elname, el->GetClass(), kFALSE); + continue; + + case dtd_any: + fs << "<!ELEMENT " << elname << " ANY>" << endl; + continue; + + default: + continue; + + } // switch + } + + fs << endl; +} + +//______________________________________________________________________________ +void TXMLDtdGenerator::ProduceGeneralDtd(ofstream& fs, TClass* onlyclass) { + if (onlyclass!=0) { + fs << "<!ELEMENT " << xmlNames_Root << " (" << xmlNames_Object << ")>" << endl; + fs << "<!ATTLIST " << xmlNames_Root << endl + << " " << xmlNames_Setup << " CDATA #REQUIRED" << endl + << " " << xmlNames_Ref << " ID #IMPLIED>" << endl << endl; + } else { + fs << "<!ELEMENT " << xmlNames_Root << " (" << xmlNames_Xmlkey << "*)>" << endl; + fs << "<!ATTLIST " << xmlNames_Root << endl + << " " << xmlNames_Setup << " CDATA #REQUIRED" << endl + << " " << xmlNames_Ref << " ID #IMPLIED>" << endl << endl; + fs << "<!ELEMENT " << xmlNames_Xmlkey << " (" << xmlNames_Object << ")>" << endl; + fs << "<!ATTLIST " << xmlNames_Xmlkey << endl + << " " << xmlNames_Name << " CDATA #REQUIRED" << endl + << " " << xmlNames_Cycle << " CDATA #REQUIRED>" << endl << endl; + } + + fs << "<!ELEMENT " << xmlNames_Object << " (" << xmlNames_Object << "|" + << xmlNames_Member << "|" + << xmlNames_Item << ")*>" << endl; + fs << "<!ATTLIST " << xmlNames_Object << endl + << " " << xmlNames_Class << " CDATA #REQUIRED" << endl + << " " << xmlNames_Version << " CDATA #IMPLIED" << endl + << " " << xmlNames_Ref << " ID #IMPLIED>" << endl << endl; + + fs << "<!ELEMENT " << xmlNames_Member << " (" << xmlNames_Object << "|" << xmlNames_Item << ")*>" << endl; + fs << "<!ATTLIST " << xmlNames_Member << endl; + fs << " " << xmlNames_Name << " CDATA #REQUIRED" << endl; + fs << " " << xmlNames_Type << " CDATA #REQUIRED" << endl; + fs << " " << xmlNames_Value << " CDATA #IMPLIED" << endl; + fs << " " << xmlNames_Size << " CDATA #IMPLIED" << endl; + fs << " " << xmlNames_Ptr << " IDREF #IMPLIED>" << endl << endl; + + fs << "<!ELEMENT " << xmlNames_Item << " (" << xmlNames_Object << "|" << xmlNames_Item << ")*>" << endl; + fs << "<!ATTLIST " << xmlNames_Item << endl; + fs << " " << xmlNames_Type << " CDATA #REQUIRED" << endl; + fs << " " << xmlNames_Value << " CDATA #IMPLIED" << endl; + fs << " " << xmlNames_Size << " CDATA #IMPLIED" << endl; + fs << " " << xmlNames_Ptr << " IDREF #IMPLIED>" << endl << endl; +} + +//______________________________________________________________________________ +void TXMLDtdGenerator::ProduceSpecificDtd(ofstream& fs, TClass* onlyclass) { + for (int n=0;n<MaxBaseTypeNum;n++) + fUsedBaseTypes[n] = kFALSE; + + fClassSpace.Clear(); + fClassSpace.AddAll(&fBlackClasses); + + TIter iter(&fInstrumentedClasses); + TStreamerInfo* info = 0; + + while ((info = (TStreamerInfo*)iter())!=0) + fClassSpace.Add(info->GetClass()); + + if (onlyclass!=0) { + if (fClassSpace.FindObject(onlyclass)==0) + fClassSpace.Add(onlyclass); + if (fInstrumentedClasses.FindObject(onlyclass->GetStreamerInfo())==0) + fInstrumentedClasses.Add(onlyclass->GetStreamerInfo()); + + fs << "<!ELEMENT " << xmlNames_Root << " (" << XmlConvertClassName(onlyclass) << ")>" << endl; + fs << "<!ATTLIST " << xmlNames_Root << endl + << " " << xmlNames_Setup << " CDATA #REQUIRED" << endl + << " " << xmlNames_Ref << " ID #IMPLIED>" << endl << endl; + } else { + fs << "<!ELEMENT " << xmlNames_Root << " (" << xmlNames_Xmlkey << "*)>" << endl; + fs << "<!ATTLIST " << xmlNames_Root << endl + << " " << xmlNames_Setup << " CDATA #REQUIRED" << endl + << " " << xmlNames_Ref << " ID #IMPLIED>" << endl << endl; + fs << "<!ELEMENT " << xmlNames_Xmlkey << " ("; + + TIter it(&fClassSpace); + TClass* cl = 0; + bool first = true; + + while ((cl = (TClass*) it()) != 0) + fs << (first ? first=false, "" : "|") << XmlConvertClassName(cl); + fs << ")>" << endl; + fs << "<!ATTLIST " << xmlNames_Xmlkey << endl + << " " << xmlNames_Name << " CDATA #REQUIRED" << endl + << " " << xmlNames_Cycle << " CDATA #REQUIRED>" << endl << endl; + } + + iter.Reset(); + while ((info = (TStreamerInfo*)iter())!=0) + ProduceDtdForInstrumentedClass(fs, info); + + TIter iter2(&fBlackClasses); + TClass* cl = 0; + while ((cl = (TClass*)iter2())!=0) + ProduceDtdForBlackClass(fs, cl); + +/* if (fUsedBaseTypes[TStreamerInfo::kDouble32]) { + fUsedBaseTypes[TStreamerInfo::kDouble32] = kFALSE; + fUsedBaseTypes[TStreamerInfo::kDouble] = kTRUE; + } +*/ + + for (int n=0;n<MaxBaseTypeNum;n++) + if (fUsedBaseTypes[n] || IsConvertBasicTypes()) { + const char* iname = dtdBaseTypeName(n); + if (strlen(iname)>0) + ProduceDtdForItem(fs, iname); + } + + if (IsConvertBasicTypes()) { + fs << "<!ELEMENT " << xmlNames_Array << " "; + bool first = true; + for (int n=0;n<MaxBaseTypeNum;n++) { + const char* iname = dtdBaseTypeName(n); + if (strlen(iname)>0) { + fs << (first ? "(": "|") << iname; + first = false; + } + } + fs << ")*>" << endl; + fs << "<!ATTLIST " << xmlNames_Array << " " << xmlNames_Size << " CDATA #IMPLIED>" << endl; + } + + if ((fBlackClasses.GetLast()>=0) || IsaSolidDataBlock()) { + fs << endl << "<!ELEMENT " << xmlNames_XmlBlock << " (#PCDATA)>" << endl; + fs << "<!ATTLIST " << xmlNames_XmlBlock << endl + << " " << xmlNames_Size << " CDATA #REQUIRED" << endl + << " " << xmlNames_Zip << " CDATA #IMPLIED>" << endl; + ProduceObjectElement(fs, xmlNames_Xmlobject, 0, kTRUE); + } +} + diff --git a/xml/src/TXMLEngine.cxx b/xml/src/TXMLEngine.cxx new file mode 100644 index 00000000000..aa6506a2b92 --- /dev/null +++ b/xml/src/TXMLEngine.cxx @@ -0,0 +1,229 @@ +// @(#)root/xml:$Name: $:$Id: TXMLEngine.cxx,v 1.0 2004/04/21 15:06:45 brun Exp $ +// Author: Sergey Linev 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#include "TXMLEngine.h" + +#include "Riostream.h" +#include "libxml/tree.h" + +TXMLEngine* gXML; + +ClassImp(TXMLEngine); + +//______________________________________________________________________________ +TXMLEngine* TXMLEngine::fgInstance = new TXMLEngine(); + +//______________________________________________________________________________ +TXMLEngine::TXMLEngine() { + gXML = this; +}; + +//______________________________________________________________________________ +TXMLEngine::~TXMLEngine() { +} + +//______________________________________________________________________________ +Bool_t TXMLEngine::HasProp(xmlNodePointer node, const char* name) { + + if ((node==0) || (name==0)) return kFALSE; + return xmlHasProp((xmlNodePtr) node, (const xmlChar*) name) != 0; +} + +//______________________________________________________________________________ +const char* TXMLEngine::GetProp(xmlNodePointer node, const char* name) { + if (node==0) return 0; + xmlChar* prop = xmlGetProp((xmlNodePtr) node, (const xmlChar*) name); + if (prop) { + fStrBuf = (const char*) prop; + xmlFree(prop); + return fStrBuf.Data(); + } + return 0; +} + +//______________________________________________________________________________ +xmlAttrPointer TXMLEngine::NewProp(xmlNodePointer node, + xmlNsPointer ns, + const char* name, + const char* value) { + if (ns==0) + return (xmlAttrPointer) xmlNewProp((xmlNodePtr) node, + (const xmlChar*) name, + (const xmlChar*) value); + else + return (xmlAttrPointer) xmlNewNsProp((xmlNodePtr) node, + (xmlNsPtr) ns, + (const xmlChar*) name, + (const xmlChar*) value); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLEngine::NewChild(xmlNodePointer parent, + xmlNsPointer ns, + const char* name, + const char* content) { + xmlNodePointer node = xmlNewNode((xmlNsPtr) ns, (const xmlChar*) name); + if (parent!=0) + xmlAddChild((xmlNodePtr) parent, (xmlNodePtr) node); + if (content!=0) + xmlNodeAddContent((xmlNodePtr) node, (const xmlChar*) content); + return node; +} + +//______________________________________________________________________________ +xmlNsPointer TXMLEngine::NewNS(xmlNodePointer node, + const char* reference, + const char* name) { + return (xmlNsPointer) xmlNewNs((xmlNodePtr) node, (const xmlChar*) reference, (const xmlChar*) name); +} + +//______________________________________________________________________________ +void TXMLEngine::AddChild(xmlNodePointer parent, xmlNodePointer child) { + xmlAddChild((xmlNodePtr) parent, (xmlNodePtr) child); +} + +//______________________________________________________________________________ +void TXMLEngine::UnlinkChild(xmlNodePointer node) { + xmlUnlinkNode((xmlNodePtr) node); +} + +//______________________________________________________________________________ +void TXMLEngine::FreeNode(xmlNodePointer node) { + xmlFreeNode((xmlNodePtr) node); +} + +//______________________________________________________________________________ +const char* TXMLEngine::GetNodeName(xmlNodePointer node) { + if (node==0) return 0; + return (const char*) ((xmlNodePtr) node)->name; +} + +//______________________________________________________________________________ +const char* TXMLEngine::GetNodeContent(xmlNodePointer node) { + if (node==0) return 0; + xmlChar* cont = xmlNodeGetContent((xmlNodePtr) node); + if (cont) { + fStrBuf = (const char*) cont; + xmlFree(cont); + return fStrBuf.Data(); + } + return 0; +} + +//______________________________________________________________________________ +xmlNodePointer TXMLEngine::GetChild(xmlNodePointer node) { + if (node==0) return 0; + return ((xmlNodePtr) node)->xmlChildrenNode; +} + +//______________________________________________________________________________ +xmlNodePointer TXMLEngine::GetParent(xmlNodePointer node) { + if (node==0) return 0; + return ((xmlNodePtr) node)->parent; +} + + + +//______________________________________________________________________________ +xmlNodePointer TXMLEngine::GetNext(xmlNodePointer node) { + if (node==0) return 0; + return ((xmlNodePtr) node)->next; +} + +//______________________________________________________________________________ +void TXMLEngine::ShiftToNext(xmlNodePointer &node, Bool_t skipempty) { + if (node==0) return; + node = ((xmlNodePtr) node)->next; + + if (skipempty) + while (node && xmlIsBlankNode((xmlNodePtr) node)) + node = ((xmlNodePtr) node)->next; +} + +//______________________________________________________________________________ +void TXMLEngine::SkipEmpty(xmlNodePointer &node) { + while (node && xmlIsBlankNode((xmlNodePtr) node)) + node = ((xmlNodePtr) node) ->next; +} + +//______________________________________________________________________________ +xmlDocPointer TXMLEngine::NewDoc(const char* version) { + return xmlNewDoc((const xmlChar*)version); +} + +//______________________________________________________________________________ +void TXMLEngine::AssignDtd(xmlDocPointer doc, const char* dtdname, const char* rootname) { + xmlCreateIntSubset((xmlDocPtr) doc, + (const xmlChar*) rootname, + (const xmlChar*) "-//CERN//ROOT//v 1.0//EN", + (const xmlChar*) dtdname); +} + +//______________________________________________________________________________ +void TXMLEngine::FreeDoc(xmlDocPointer doc) { + xmlFreeDoc((xmlDocPtr) doc); +} + +//______________________________________________________________________________ +void TXMLEngine::SaveDoc(xmlDocPointer doc, const char* filename, Int_t layout) { + xmlSaveFormatFile(filename, (xmlDocPtr) doc, layout); +} + +//______________________________________________________________________________ +void TXMLEngine::DocSetRootElement(xmlDocPointer doc, xmlNodePointer node) { + xmlDocSetRootElement((xmlDocPtr) doc, (xmlNodePtr) node); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLEngine::DocGetRootElement(xmlDocPointer doc) { + return (xmlNodePointer) xmlDocGetRootElement((xmlDocPtr) doc); +} + +//______________________________________________________________________________ +xmlDocPointer TXMLEngine::ParseFile(const char* filename) { + return (xmlDocPointer) xmlParseFile(filename); +} + +//______________________________________________________________________________ +Bool_t TXMLEngine::ValidateDocument(xmlDocPointer doc, Bool_t doout) { + xmlValidCtxt cvp; + cvp.userData = doout ? (void *) stderr : 0; + cvp.error = doout ? (xmlValidityErrorFunc) fprintf : 0; + cvp.warning = doout ? (xmlValidityWarningFunc) fprintf : 0; + + xmlDocPtr docptr = (xmlDocPtr) doc; + + int res = xmlValidateDocument(&cvp, docptr); + + if ((docptr->intSubset!=0) || (docptr->extSubset!=0)) { + xmlDtdPtr i = docptr->intSubset; + xmlDtdPtr e = docptr->extSubset; + if (i==e) e = 0; + if (e!=0) { + xmlUnlinkNode((xmlNodePtr) docptr->extSubset); + docptr->extSubset = 0; + xmlFreeDtd(e); + } + if (i!=0) { + xmlUnlinkNode((xmlNodePtr) docptr->intSubset); + docptr->intSubset = 0; + xmlFreeDtd(i); + } + } + + if (doout) + if (res==1) cout << "Validation done" << endl; + else cout << "Validation failed" << endl; + + return (res == 1); +} + + diff --git a/xml/src/TXMLFile.cxx b/xml/src/TXMLFile.cxx new file mode 100644 index 00000000000..db670903886 --- /dev/null +++ b/xml/src/TXMLFile.cxx @@ -0,0 +1,669 @@ +// @(#)root/xml:$Name: $:$Id: TXMLFiler.cxx,v 1.0 2004/04/21 15:06:45 brun Exp $ +// Author: Sergey Linev, Rene Brun 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +//________________________________________________________________________ +// +// The main motivation for the XML format is to facilitate the +// communication with other non ROOT applications. Currently +// writing and reading XML files is limited to ROOT applications. +// It is our intention to develop a simple reader independent +// of the ROOT libraries that could be used as an example for +// real applications. +// The XML format should be used only for small data volumes, +// typically histogram files, pictures, geometries, calibrations. +// The XML file is built in memory before being dumped to disk. +// +// Like for normal ROOT files, XML files use the same I/O mechanism +// exploiting the ROOT/CINT dictionary. Any class having a dictionary +// can be saved in XML format. +// +// This first implementation does not support subdirectories +// or Trees. +// +// The shared library libRXML.so may be loaded dynamically +// via gSystem->Load("libRXML"). This library is automatically +// loaded by the plugin manager as soon as a XML file is created +// via, eg +// TFile::Open("file.xml","recreate"); +// TFile::Open returns a TXMLFile object. When a XML file is open in write mode, +// one can use the normal TObject::Write to write an object in the file. +// Alternatively one can use the new functions TDirectory::WriteObject and +// TDirectory::WriteObjectAny to write a TObject* or any class not deriving +// from TObject. +// +// example of a session saving a histogram to a XML file +// ===================================================== +// TFile *f = TFile::Open("Example.xml","recreate"); +// TH1F *h = new TH1F("h","test",1000,-2,2); +// h->FillRandom("gaus"); +// h->Write(); +// delete f; +// +// example of a session reading the histogram from the file +// ======================================================== +// TFile *f = TFile::Open("Example.xml"); +// TH1F *h = (TH1F*)f->Get("h"); +// h->Draw(); +// +// A new option in the canvas "File" menu is available to save +// a TCanvas as a XML file. One can also do +// canvas->Print("Example.xml"); +// +// Configuring ROOT with the option "xml" +// ====================================== +// The XML package uses the public XML parser and toolkit +// from Gnome. You should download the latest version 2-6.9 +// from http://www.xmlsoft.org/downloads.html. +// +// On Unix systems dowload "libxml2-2.6.9.tar.gz" and create +// XMLDIR pointing to the directory libxml2-2.6.9. in the XMLDIR +// directory, run the normal +// ./configure +// make +// +// On Windows, from the same web site download +// libxml2-2.6.9.win32.zip +// iconv-1.9.1.win32.zip +// unzip the two files, then copy the file iconv.h from the iconv/include file +// to $XMLDIR/include. Also copy iconv.dll, iconv.lib and iconv_a.lib +// from the iconv/lib directory to $XMLDIR/lib. +// +// You are now ready to configure ROOT with the XML option. do: +// ./configure -enable-xml -enable-xxxxx, etc +// +// documentation +// ============= +// The "xml" package is currently under development. A more complete +// documentation will be provided shortly in the classes reference guide. +// See classes TXMLFile, TXMLKey, TXMLBuffer, TXMLEngine, TXMLSetup +// and TXMLDtdGenerator. +// An example of XML file corresponding to the small example below +//can be found at http://root.cern.ch/root/Example.xml +// +//______________________________________________________________________________ + +#include "TXMLFile.h" + +#include "TROOT.h" +#include "TList.h" +#include "TBrowser.h" +#include "TObjArray.h" +#include "TXMLBuffer.h" +#include "TXMLKey.h" +#include "TObjArray.h" +#include "TXMLDtdGenerator.h" +#include "TArrayC.h" +#include "TStreamerInfo.h" +#include "TStreamerElement.h" + +#include "Riostream.h" + +ClassImp(TXMLFile); + +//______________________________________________________________________________ +TXMLFile::TXMLFile() : + TFile(), + TXMLSetup(), + fDoc(0), + fDtdGener(0) { +} + + +//______________________________________________________________________________ +TXMLFile::TXMLFile(const char* filename, Option_t* option, const char* title, Int_t compression) : + TFile(), + TXMLSetup(), + fDoc(0), + fDtdGener(0) { + + SetName(filename); + SetTitle(title); + SetCompressionLevel(compression); + fOption = option; + fOption.ToLower(); + + fRealName = filename; + if (strncmp(filename,"xml:",4)==0) + fRealName.Remove(0,4); + + if (strlen(option) == 0) fOption = "read"; + if (fOption=="new") fOption="create"; + if (fOption=="recreate") fOption="create"; + if (fOption=="create") fOption = "2oxoo"; + + gDirectory = 0; + TDirectory::Build(); + gROOT->cd(); + + + int len = gROOT->GetListOfStreamerInfo()->GetSize()+1; + if (len<5000) len = 5000; + fClassIndex = new TArrayC(len); + fClassIndex->Reset(0); + + fWritable = fOption != "read"; + if (!IsWritable()) { + ReadFromFile(); + } else { + ReadSetupFromStr(fOption); + fDoc = gXML->NewDoc(0); + xmlNodePointer fRootNode = gXML->NewChild(0, 0, xmlNames_Root, 0); + gXML->DocSetRootElement(fDoc, fRootNode); + StoreSetup(fRootNode); + gXML->NewProp(fRootNode, 0, xmlNames_Ref, xmlNames_Null); + fDtdGener = new TXMLDtdGenerator(*this); + } + + gROOT->GetListOfFiles()->Add(this); + cd(); + + fNProcessIDs = 0; + TKey* key = 0; + TIter iter(fKeys); + while ((key = (TKey*)iter())!=0) { + if (!strcmp(key->GetClassName(),"TProcessID")) fNProcessIDs++; + } + + fProcessIDs = new TObjArray(fNProcessIDs+1); +} + + +//______________________________________________________________________________ +TXMLFile::~TXMLFile() { + if ((fDoc!=0) && IsWritable()) SaveToFile(); + if (fDtdGener) delete fDtdGener; + if (fDoc) gXML->FreeDoc(fDoc); + + gROOT->GetListOfFiles()->Remove(this); + + if (gFile==this) + gROOT->cd(); +} + + +// redefined virtual function of TFile + +//______________________________________________________________________________ +void TXMLFile::Browse(TBrowser *b) +{ + if (b) { + TObject *obj = 0; + TXMLKey *key = 0; + TIter next(fKeys); + + cd(); + + while ((key = (TXMLKey*)next())) { + obj = key->GetObject(); + if (obj) b->Add(obj, obj->GetName()); + } + } +} + + +//______________________________________________________________________________ +Bool_t TXMLFile::cd(const char*) { + gFile = this; + gDirectory = this; + return kTRUE; +} + + +//______________________________________________________________________________ +void TXMLFile::operator=(const TXMLFile &) { +} + +//______________________________________________________________________________ +Bool_t TXMLFile::IsOpen() const { + return kTRUE; +} + +//______________________________________________________________________________ +Int_t TXMLFile::ReOpen(Option_t*) { + return 0; +} + + +// **************************** XML specific functions ********************************* + +//______________________________________________________________________________ +Int_t TXMLFile::WriteObject(const TObject* obj, const char* name, Option_t *) { + new TXMLKey(this, obj, name); + return 0; +} + +//______________________________________________________________________________ +Int_t TXMLFile::WriteObjectAny(const void* obj, const TClass* cl, const char* name,Option_t *) { + new TXMLKey(this, obj, cl, name); + return 0; +} + + +//______________________________________________________________________________ +void TXMLFile::ProduceFileNames(const char* filename, TString& fname, TString& dtdname) { + fname = filename; + dtdname = filename; + + Bool_t hasxmlext = kFALSE; + + if (fname.Length()>4) { + TString last = fname(fname.Length()-4,4); + last.ToLower(); + hasxmlext = (last==".xml"); + } + + if (hasxmlext) { + dtdname.Replace(dtdname.Length()-4,4,".dtd"); + } else { + fname+=".xml"; + dtdname+=".dtd"; + } +} + + +//______________________________________________________________________________ +void TXMLFile::SaveToFile() { + if (fDoc==0) return; + + xmlNodePointer fRootNode = gXML->DocGetRootElement(fDoc); + + TString fname, dtdname; + ProduceFileNames(fRealName, fname, dtdname); + + TIter iter(GetListOfKeys()); + TXMLKey* key = 0; + + while ((key=(TXMLKey*)iter()) !=0) + gXML->AddChild(fRootNode, key->KeyNode()); + + xmlNodePointer sinfonode = CreateStreamerInfoNode(); + if (sinfonode) + gXML->AddChild(fRootNode, sinfonode); + + if (fDtdGener && IsUseDtd()) + gXML->AssignDtd(fDoc, dtdname, xmlNames_Root); + + Int_t layout = GetCompressionLevel()>2 ? 0 : 1; + + gXML->SaveDoc(fDoc, fname, layout); + + if (fDtdGener && IsUseDtd()) { + fDtdGener->Produce(dtdname); + } + + iter.Reset(); + while ((key=(TXMLKey*)iter()) !=0) + gXML->UnlinkChild(key->KeyNode()); + + + if (sinfonode) { + gXML->UnlinkChild(sinfonode); + gXML->FreeNode(sinfonode); + } +} + +//______________________________________________________________________________ +Bool_t TXMLFile::ReadFromFile() { + fDoc = gXML->ParseFile(fRealName); + if (fDoc==0) return kFALSE; + + xmlNodePointer fRootNode = gXML->DocGetRootElement(fDoc); + + if (fRootNode==0) { + gXML->FreeDoc(fDoc); + fDoc=0; + return kFALSE; + } + + ReadSetup(fRootNode); + + ReadStreamerInfos(fRootNode); + + if (IsUseDtd()) + if (!gXML->ValidateDocument(fDoc, gDebug>0)) { + gXML->FreeDoc(fDoc); + fDoc=0; + return kFALSE; + } + + gFile = this; + gDirectory = this; + + xmlNodePointer keynode = gXML->GetChild(fRootNode); + gXML->SkipEmpty(keynode); + while (keynode!=0) { + xmlNodePointer next = gXML->GetNext(keynode); + gXML->UnlinkChild(keynode); + + TXMLKey* key = new TXMLKey(this, keynode); + + if (gDebug>2) + cout << "Adding key " << gXML->GetNodeName(keynode) << " name = " << key->GetName() << endl; + fKeys->Add(key); + + keynode = next; + gXML->SkipEmpty(keynode); + } + + return kTRUE; +} + +//______________________________________________________________________________ +TObject* TXMLFile::Get(const char* name) { + TXMLKey* key = dynamic_cast<TXMLKey*> (GetKey(name)); + if (key==0) return 0; + return key->GetObject(); +} + +//______________________________________________________________________________ +void* TXMLFile::GetAny(const char* name) { + TXMLKey* key = dynamic_cast<TXMLKey*> (GetKey(name)); + if (key==0) return 0; + return key->GetObjectAny(); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLFile::CreateStreamerInfoNode() { + TObjArray list; + + TIter iter(gROOT->GetListOfStreamerInfo()); + + TStreamerInfo* info = 0; + + while ((info = (TStreamerInfo*) iter()) !=0 ) { + Int_t uid = info->GetNumber(); + if (fClassIndex->fArray[uid]) + list.Add(info); + } + + if (list.GetSize()==0) return 0; + + xmlNodePointer rootnode = gXML->NewChild(0, 0, "StreamerInfos"); + for (int n=0;n<=list.GetLast();n++) { + TStreamerInfo* info = (TStreamerInfo*) list.At(n); + + xmlNodePointer infonode = gXML->NewChild(rootnode, 0, "TStreamerInfo"); + + gXML->NewProp(infonode,0,"name", info->GetName()); + gXML->NewProp(infonode,0,"title", info->GetTitle()); + + char sbuf[100]; + + sprintf(sbuf, "%d", info->IsA()->GetClassVersion()); + gXML->NewProp(infonode, 0, "v", sbuf); + + sprintf(sbuf, "%d", info->GetClassVersion()); + gXML->NewProp(infonode,0,"classversion", sbuf); + + sprintf(sbuf, "%d", info->GetCheckSum()); + gXML->NewProp(infonode,0,"checksum", sbuf); + + TIter iter(info->GetElements()); + TStreamerElement* elem=0; + while ((elem= (TStreamerElement*) iter()) != 0) { + StoreStreamerElement(infonode, elem); + } + } + + return rootnode; +} + +//______________________________________________________________________________ +void TXMLFile::ReadStreamerInfos(xmlNodePointer fRootNode) { + + xmlNodePointer startnode = gXML->GetChild(fRootNode); + gXML->SkipEmpty(startnode); + + while (startnode!=0) { + if (strcmp("StreamerInfos",gXML->GetNodeName(startnode))==0) break; + gXML->ShiftToNext(startnode); + } + + if (startnode==0) return; + + // to exclude reading of streamer infos + gXML->UnlinkChild(startnode); + gXML->FreeNode(startnode); + return; + + TObjArray infos; + + xmlNodePointer sinfonode = gXML->GetChild(startnode); + gXML->SkipEmpty(sinfonode); + + while (sinfonode!=0) { + if (strcmp("TStreamerInfo",gXML->GetNodeName(sinfonode))==0) { + TString fname = gXML->GetProp(sinfonode,"name"); + TString ftitle = gXML->GetProp(sinfonode,"title"); + + TStreamerInfo* info = new TStreamerInfo(gROOT->GetClass(fname), ftitle); + + infos.Add(info); + + Int_t clversion = atoi(gXML->GetProp(sinfonode,"classversion")); + info->SetClassVersion(clversion); + Int_t checksum = atoi(gXML->GetProp(sinfonode,"checksum")); + info->SetCheckSum(checksum); + + xmlNodePointer node = gXML->GetChild(sinfonode); + gXML->SkipEmpty(node); + while (node!=0) { + ReadStreamerElement(node, info); + gXML->ShiftToNext(node); + } + } + gXML->ShiftToNext(sinfonode); + } + + gXML->UnlinkChild(startnode); + + gXML->FreeNode(startnode); + + // loop on all TStreamerInfo classes + TStreamerInfo *info; + TIter next(&infos); + while ((info = (TStreamerInfo*)next())) { + if (info->IsA() != TStreamerInfo::Class()) { + Warning("ReadStreamerInfo","%s: not a TStreamerInfo object", GetName()); + continue; + } + info->BuildCheck(); + Int_t uid = info->GetNumber(); + Int_t asize = fClassIndex->GetSize(); + if (uid >= asize && uid <100000) fClassIndex->Set(2*asize); + if (uid >= 0 && uid < fClassIndex->GetSize()) fClassIndex->fArray[uid] = 1; + else { + printf("ReadStreamerInfo, class:%s, illegal uid=%d\n",info->GetName(),uid); + } + if (gDebug > 0) + printf(" -class: %s version: %d info read at slot %d\n",info->GetName(), info->GetClassVersion(),uid); + } + fClassIndex->fArray[0] = 0; + + infos.Clear(); +} + + +//______________________________________________________________________________ +void TXMLFile::StoreStreamerElement(xmlNodePointer infonode, TStreamerElement* elem) { + TClass* cl = elem->IsA(); + + xmlNodePointer node = gXML->NewChild(infonode, 0, cl->GetName()); + + char sbuf[100], namebuf[100]; + + gXML->NewProp(node,0,"name",elem->GetName()); + if (strlen(elem->GetTitle())>0) + gXML->NewProp(node,0,"title",elem->GetTitle()); + + sprintf(sbuf, "%d", cl->GetClassVersion()); + gXML->NewProp(node,0,"v",sbuf); + + sprintf(sbuf, "%d", elem->GetType()); + gXML->NewProp(node,0,"type", sbuf); + + if (strlen(elem->GetTypeName())>0) + gXML->NewProp(node,0,"typename", elem->GetTypeName()); + + sprintf(sbuf, "%d", elem->GetSize()); + gXML->NewProp(node,0,"size", sbuf); + + if (elem->GetArrayDim()>0) { + sprintf(sbuf, "%d", elem->GetArrayDim()); + gXML->NewProp(node,0,"numdim", sbuf); + + for (int ndim=0;ndim<elem->GetArrayDim();ndim++) { + sprintf(namebuf, "dim%d", ndim); + sprintf(sbuf, "%d", elem->GetMaxIndex(ndim)); + gXML->NewProp(node,0, namebuf, sbuf); + } + } + + if (cl == TStreamerBase::Class()) { + TStreamerBase* base = (TStreamerBase*) elem; + sprintf(sbuf, "%d", base->GetBaseVersion()); + gXML->NewProp(node,0, "baseversion", sbuf); + } else + if (cl == TStreamerBasicPointer::Class()) { + TStreamerBasicPointer* bptr = (TStreamerBasicPointer*) elem; + sprintf(sbuf, "%d", bptr->GetCountVersion()); + gXML->NewProp(node, 0, "countversion", sbuf); + gXML->NewProp(node, 0, "countname", bptr->GetCountName()); + gXML->NewProp(node, 0, "countclass", bptr->GetCountClass()); + } else +// if (cl == TStreamerBasicType::Class()) { +// } else + if (cl == TStreamerLoop::Class()) { + TStreamerLoop* loop = (TStreamerLoop*) elem; + sprintf(sbuf, "%d", loop->GetCountVersion()); + gXML->NewProp(node, 0, "countversion", sbuf); + gXML->NewProp(node, 0, "countname", loop->GetCountName()); + gXML->NewProp(node, 0, "countclass", loop->GetCountClass()); + } else +// if (cl == TStreamerObject::Class()) { +// } else +// if (cl == TStreamerObjectAny::Class()) { +// } else +// if (cl == TStreamerObjectAnyPointer::Class()) { +// } else +// if (cl == TStreamerObjectPointer::Class()) { +// } else + if ((cl == TStreamerSTL::Class()) || (cl == TStreamerSTLstring::Class())) { + TStreamerSTL* stl = (TStreamerSTL*) elem; + + sprintf(sbuf, "%d", stl->GetSTLtype()); + gXML->NewProp(node,0,"STLtype", sbuf); + + sprintf(sbuf, "%d", stl->GetCtype()); + gXML->NewProp(node,0,"Ctype", sbuf); + } +} + + +//______________________________________________________________________________ +void TXMLFile::ReadStreamerElement(xmlNodePointer node, TStreamerInfo* info) { + TStreamerElement* elem = 0; + + TClass* cl = gROOT->GetClass(gXML->GetNodeName(node)); + if (cl==0) return; + +// Int_t elemversion = gXML->GetProp(node,"v"); + + TString fname = gXML->GetProp(node,"name"); + TString ftitle = gXML->GetProp(node,"title"); + TString ftypename = gXML->GetProp(node,"typename"); + int ftype = atoi(gXML->GetProp(node,"type")); + int fsize = atoi(gXML->GetProp(node,"size")); + + if (cl == TStreamerElement::Class()) { + elem = new TStreamerElement(); + } else + if (cl == TStreamerBase::Class()) { + int basever = atoi(gXML->GetProp(node,"baseversion")); + TStreamerBase* base = new TStreamerBase(); + base->SetBaseVersion(basever); + elem = base; + } else + if (cl == TStreamerBasicPointer::Class()) { + TString countname = gXML->GetProp(node,"countname"); + TString countclass = gXML->GetProp(node,"countclass"); + Int_t countversion = atoi(gXML->GetProp(node,"countversion")); + + TStreamerBasicPointer* bptr = new TStreamerBasicPointer(); + bptr->SetCountVersion(countversion); + bptr->SetCountName(countname); + bptr->SetCountClass(countclass); + + elem = bptr; + } else + if (cl == TStreamerBasicType::Class()) { + elem = new TStreamerBasicType(); + } else + if (cl == TStreamerLoop::Class()) { + TString countname = gXML->GetProp(node,"countname"); + TString countclass = gXML->GetProp(node,"countclass"); + Int_t countversion = atoi(gXML->GetProp(node,"countversion")); + TStreamerLoop* loop = new TStreamerLoop(); + loop->SetCountVersion(countversion); + loop->SetCountName(countname); + loop->SetCountClass(countclass); + elem = loop; + } else + if (cl == TStreamerObject::Class()) { + elem = new TStreamerObject(); + } else + if (cl == TStreamerObjectAny::Class()) { + elem = new TStreamerObjectAny(); + } else + if (cl == TStreamerObjectAnyPointer::Class()) { + elem = new TStreamerObjectAnyPointer(); + } else + if (cl == TStreamerObjectPointer::Class()) { + elem = new TStreamerObjectPointer(); + } else + if ((cl == TStreamerSTL::Class()) || (cl == TStreamerSTLstring::Class())) { + int fSTLtype = atoi(gXML->GetProp(node,"STLtype")); + int fCtype = atoi(gXML->GetProp(node,"Ctype")); + TStreamerSTL* stl = 0; + if (cl==TStreamerSTL::Class()) stl = new TStreamerSTL(); + else stl = new TStreamerSTLstring(); + stl->SetSTLtype(fSTLtype); + stl->SetCtype(fCtype); + elem = stl; + } + + if (elem==0) return; + + elem->SetName(fname); + elem->SetTitle(ftitle); + elem->SetType(ftype); + elem->SetTypeName(ftypename); + elem->SetSize(fsize); + + char namebuf[100]; + + if (gXML->HasProp(node, "numdim") && (elem!=0)) { + int numdim = atoi(gXML->GetProp(node,"numdim")); + elem->SetArrayDim(numdim); + for (int ndim=0;ndim<numdim;ndim++) { + sprintf(namebuf, "dim%d", ndim); + int maxi = atoi(gXML->GetProp(node, namebuf)); + elem->SetMaxIndex(ndim, maxi); + } + } + + info->GetElements()->Add(elem); +} + + + + + diff --git a/xml/src/TXMLKey.cxx b/xml/src/TXMLKey.cxx new file mode 100644 index 00000000000..0e469746642 --- /dev/null +++ b/xml/src/TXMLKey.cxx @@ -0,0 +1,162 @@ +// @(#)root/xml:$Name: $:$Id: TXMLKey.cxx,v 1.0 2004/04/21 15:06:45 brun Exp $ +// Author: Sergey Linev, Rene Brun 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#include "TXMLKey.h" + +#include "TXMLBuffer.h" +#include "TXMLFile.h" +#include "TClass.h" +#include "TBrowser.h" +#include "Riostream.h" + +ClassImp(TXMLKey); + +//______________________________________________________________________________ +TXMLKey::TXMLKey() : + TKey(), + fFile(0), + fKeyNode(0), + fObject(0) { +} + +//______________________________________________________________________________ +TXMLKey::TXMLKey(TXMLFile* file, const TObject* obj, const char* name) : + TKey(), + fFile(file), + fKeyNode(0), + fObject((void*)obj) { + if (name) SetName(name); else + if (obj!=0) {SetName(obj->GetName()); fClassName=obj->ClassName();} + else SetName("Noname"); + + StoreObject(file, (void*)obj, obj ? obj->IsA() : 0); +} + +//______________________________________________________________________________ +TXMLKey::TXMLKey(TXMLFile* file, const void* obj, const TClass* cl, const char* name) : + TKey(), + fFile(file), + fKeyNode(0), + fObject((void*)obj) { + fClassName = cl->GetName(); + if (name) SetName(name); + else SetName("Noname"); + + StoreObject(file, obj, cl); +} + +//______________________________________________________________________________ +TXMLKey::TXMLKey(TXMLFile* file, xmlNodePointer keynode) : + TKey(), + fFile(file), + fKeyNode(keynode), + fObject(0) { + SetName(gXML->GetProp(keynode, xmlNames_Name)); + fCycle = atoi(gXML->GetProp(keynode, xmlNames_Cycle)); + + xmlNodePointer objnode = gXML->GetChild(keynode); + gXML->SkipEmpty(objnode); + if (file->GetXmlLayout() == TXMLSetup::kGeneralized) + fClassName = gXML->GetProp(objnode, xmlNames_Class); + else + fClassName = gXML->GetNodeName(objnode); +} + +//______________________________________________________________________________ +TXMLKey::~TXMLKey() { + if (fKeyNode) + gXML->FreeNode(fKeyNode); +} + +//______________________________________________________________________________ +void TXMLKey::Browse(TBrowser *b) +{ + // Browse object corresponding to this key + + TObject *obj = gDirectory->GetList()->FindObject(GetName()); + if (obj && !obj->IsFolder()) { + if (obj->InheritsFrom(TCollection::Class())) + obj->Delete(); // delete also collection elements + delete obj; + obj = 0; + } + + if (b && obj) { + obj->Browse(b); + b->SetRefreshFlag(kTRUE); + } +} + +//______________________________________________________________________________ +void TXMLKey::Delete(Option_t * /*option*/) { +} + +//______________________________________________________________________________ +void TXMLKey::StoreObject(TXMLFile* file, const void* obj, const TClass* cl) { + fCycle = file->AppendKey(this); + + TXMLBuffer buffer(TBuffer::kWrite, *file, file); + buffer.SetParent(0); + buffer.SetDtdGenerator(file->GetDtdGenerator()); + xmlNodePointer node = buffer.XmlWrite(obj, cl); + + fKeyNode = gXML->NewChild(0, 0, xmlNames_Xmlkey, 0); + gXML->NewProp(fKeyNode, 0, xmlNames_Name, GetName()); + + char sbuf[100]; + sprintf(sbuf, "%d", fCycle); + gXML->NewProp(fKeyNode, 0, xmlNames_Cycle, sbuf); + + if (node!=0) + gXML->AddChild(fKeyNode, node); + + if (cl) fClassName = cl->GetName(); +} + +//______________________________________________________________________________ +xmlNodePointer TXMLKey::ObjNode() { + if (fKeyNode==0) return 0; + TXMLSetup setup; + xmlNodePointer node = gXML->GetChild(fKeyNode); + gXML->SkipEmpty(node); + return node; +} + +//______________________________________________________________________________ +TObject* TXMLKey::GetObject() { + if (fKeyNode==0) return 0; + if (fObject) return (TObject*)fObject; + TXMLBuffer buffer(TBuffer::kRead, *fFile); + fObject = buffer.XmlRead(ObjNode()); + return (TObject*)fObject; +} + +//______________________________________________________________________________ +void* TXMLKey::GetObjectAny() { + if (fKeyNode==0) return 0; + if (fObject) return fObject; + TXMLBuffer buffer(TBuffer::kRead, *fFile); + fObject = buffer.XmlRead(ObjNode()); + return fObject; +} + +//______________________________________________________________________________ +void TXMLKey::ls(Option_t *) const +{ +//*-*-*-*-*-*-*-*-*-*-*-*-*List Key contents-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +//*-* ================= + TROOT::IndentLevel(); + cout <<"KEY: "<<fClassName<<"\t"<<GetName()<<";"<<GetCycle()<<"\t"<<GetTitle()<<endl; +} + + + + diff --git a/xml/src/TXMLSetup.cxx b/xml/src/TXMLSetup.cxx new file mode 100644 index 00000000000..187d91fcb09 --- /dev/null +++ b/xml/src/TXMLSetup.cxx @@ -0,0 +1,183 @@ +// @(#)root/xml:$Name: $:$Id: TXMLSetup.cxx,v 1.0 2004/04/21 15:06:45 brun Exp $ +// Author: Sergey Linev 10.05.2004 + +/************************************************************************* + * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#include "TXMLSetup.h" + +#include "TROOT.h" +#include "TClass.h" +#include "TStreamerElement.h" +#include "Riostream.h" + +ClassImp(TXMLSetup); + +const char* NameSpaceBase = "http://root.cern.ch/"; + +const char* xmlNames_Root = "root"; +const char* xmlNames_Setup = "setup"; +const char* xmlNames_Version = "version"; +const char* xmlNames_Ptr = "ptr"; +const char* xmlNames_Ref = "ref"; +const char* xmlNames_Null = "null"; +const char* xmlNames_IdBase = "id"; +const char* xmlNames_Size = "size"; +const char* xmlNames_Xmlobject = "XmlObject"; +const char* xmlNames_Xmlkey = "XmlKey"; +const char* xmlNames_Cycle = "cycle"; +const char* xmlNames_XmlBlock = "XmlBlock"; +const char* xmlNames_Zip = "zip"; +const char* xmlNames_Object = "Object"; +const char* xmlNames_Class = "Class"; +const char* xmlNames_Member = "Member"; +const char* xmlNames_Item = "Item"; +const char* xmlNames_Name = "name"; +const char* xmlNames_Type = "type"; +const char* xmlNames_Value = "value"; + +const char* xmlNames_Array = "Array"; +const char* xmlNames_Bool = "Bool_t"; +const char* xmlNames_Char = "Char_t"; +const char* xmlNames_Short = "Short_t"; +const char* xmlNames_Int = "Int_t"; +const char* xmlNames_Long = "Long_t"; +const char* xmlNames_Long64 = "Long64_t"; +const char* xmlNames_Float = "Float_t"; +const char* xmlNames_Double = "Double_t"; +const char* xmlNames_UChar = "UChar_t"; +const char* xmlNames_UShort = "UShort_t"; +const char* xmlNames_UInt = "UInt_t"; +const char* xmlNames_ULong = "ULong_t"; +const char* xmlNames_ULong64 = "ULong64_t"; +const char* xmlNames_String = "string"; +const char* xmlNames_CharStar = "CharStar"; + +//______________________________________________________________________________ +TXMLSetup::TXMLSetup() : + fXmlLayout(kSpecialized), + fSolidDataBlock(kTRUE), + fConvertBasicTypes(kTRUE), + fUseDtd(kFALSE), + fUseNamespaces(kFALSE), + fRefCounter(0) { +} + +//______________________________________________________________________________ +TXMLSetup::TXMLSetup(const char* opt) : fRefCounter(0) { + ReadSetupFromStr(opt); +} + + +//______________________________________________________________________________ +TXMLSetup::TXMLSetup(const TXMLSetup& src) : + fXmlLayout(src.fXmlLayout), + fSolidDataBlock(src.fSolidDataBlock), + fConvertBasicTypes(src.fConvertBasicTypes), + fUseDtd(src.fUseDtd), + fUseNamespaces(src.fUseNamespaces), + fRefCounter(0) { +} + +//______________________________________________________________________________ +TXMLSetup::~TXMLSetup() { +} + +//______________________________________________________________________________ +void TXMLSetup::StoreSetup(xmlNodePointer node) { + if (node==0) return; + + char setupstr[10] = "1xxxx"; + + setupstr[0] = char(48+fXmlLayout); + setupstr[1] = fSolidDataBlock ? 'x' : 'o'; + setupstr[2] = fConvertBasicTypes ? 'x' : 'o'; + setupstr[3] = fUseDtd ? 'x' : 'o'; + setupstr[4] = fUseNamespaces ? 'x' : 'o'; + + gXML->NewProp(node, 0, xmlNames_Setup, setupstr); +} + +//______________________________________________________________________________ +Bool_t TXMLSetup::ReadSetupFromStr(const char* setupstr) { + if ((setupstr==0) || (strlen(setupstr)<6)) return kFALSE; + Int_t lay = TXMLLayout(setupstr[0] - 48); + if (lay==kGeneralized) fXmlLayout = kGeneralized; + else fXmlLayout = kSpecialized; + + fSolidDataBlock = setupstr[1]=='x'; + fConvertBasicTypes = kTRUE; + fUseDtd = kFALSE; + fUseNamespaces = setupstr[4]=='x'; + return kTRUE; +} + + +//______________________________________________________________________________ +void TXMLSetup::PrintSetup() { + cout << " *** Setup printout ***" << endl; + cout << "Attribute mode = " << fXmlLayout << endl; + cout << "Solid data block = " << (fSolidDataBlock ? "true" : "false") << endl; + cout << "Convert basic types = " << (fConvertBasicTypes ? "true" : "false") << endl; + cout << "Use dtd = " << (fUseDtd ? "true" : "false") << endl; + cout << "Use name spaces = " << (fUseNamespaces ? "true" : "false") << endl; +} + +//______________________________________________________________________________ +Bool_t TXMLSetup::ReadSetup(xmlNodePointer node) { + if (node==0) return kFALSE; + + return ReadSetupFromStr(gXML->GetProp(node, xmlNames_Setup)); +} + +//______________________________________________________________________________ +const char* TXMLSetup::XmlConvertClassName(const TClass* cl) { + if (cl==0) return 0; + fStrBuf = cl->GetName(); + fStrBuf.ReplaceAll('<','_'); + fStrBuf.ReplaceAll('>','_'); + fStrBuf.ReplaceAll(',','_'); + return fStrBuf.Data(); +} + +//______________________________________________________________________________ +const char* TXMLSetup::XmlClassNameSpaceRef(const TClass* cl) { + TString clname = XmlConvertClassName(cl); + fStrBuf = NameSpaceBase; + fStrBuf += clname; + return fStrBuf.Data(); +} + +//______________________________________________________________________________ +const char* TXMLSetup::GetElName(TStreamerElement* el) { + if (el==0) return 0; + return el->GetName(); +} + +//______________________________________________________________________________ +const char* TXMLSetup::GetElItemName(TStreamerElement* el) { + if (el==0) return 0; + fStrBuf = el->GetName(); + fStrBuf+="_item"; + return fStrBuf.Data(); +} + + +//______________________________________________________________________________ +TClass* TXMLSetup::XmlDefineClass(const char* xmlClassName) { + if (strchr(xmlClassName,'_')==0) return gROOT->GetClass(xmlClassName); + + TIter iter(gROOT->GetListOfClasses()); + TClass* cl = 0; + while ((cl = (TClass*) iter()) != 0) { + const char* name = XmlConvertClassName(cl); + if (strcmp(xmlClassName,name)==0) return cl; + } + return 0; +} + -- GitLab